Guillaume Duvernay

Mastering n8n sub-workflows can make you dangerously good at AI

n8nagentsAI efficiencyarchitecture

A sub-workflow in n8n is a workflow whose trigger is When executed by another workflow. You define what comes in, you build the steps, and the output of the last node is what the caller gets back.

It’s a function, or a microservice if you prefer that word. You can build everything without ever using one, which is why a lot of people never do.

I want to make a bigger claim than the title of the video suggests. Getting good at these is not an n8n skill. It’s where you learn, on a canvas where every step is visible, the four things that decide whether anything you build with AI is affordable: cut a repeated job into steps, give each step only the context it needs, pick a model per step, and stop handing decisions to an agent once you already know the order. n8n is not the subject. It’s the place those four are easiest to see.

Two things sub-workflows are good for. The first is the obvious one and saves you maintenance. The second is the one that taught me all of that.

The boring benefit: build it once

Sales ops example. One workflow handles demo requests. Another takes a CSV of event attendees. Both of them, at some point, need to enrich a lead: take an email, get the company and the industry from a data provider, have a model summarise what the company does, score the lead.

That’s five or six nodes. You can build them in the demo request workflow, then build them again in the CSV workflow, then again in the eight other places that end up needing the same thing.

The last node's output is the sub-workflow's output, so I end these with an Edit Fields node. It's the contract, and it's worth writing explicitly rather than letting whatever the previous node returned leak out.

The payoff shows up in six months, when the data provider changes or someone wants one more field on the output. You edit one workflow. Every caller has it.

The interesting benefit: a tool that returns only what matters

Here’s the setup. A biology course lives in Airtable: 15 chapters, each with a name, a summary, and the full content. An agent answers questions about it.

This agent is already better than the naive version. It has two tools rather than one big dump: search all chapters, which returns just IDs and summaries, and get a chapter’s content. The system prompt tells it to read the summaries first, pick one to three chapters, then fetch those.

That two-step design is already most of the win.

Measured by pasting the actual tool outputs into a character counter. The third bar is what a naive setup sends on every single question, including the ones about one chapter.

So why change anything. Two reasons, and neither is about the word count.

The large model runs once per tool call

Look at an execution. GPT-5.1 is connected, it’s expensive and it’s good, and it was called three times: once deciding to search chapters, once deciding to fetch content, once writing the answer.

Every one of those calls carries the system message and the accumulated memory of the previous tool results. The input grows on each turn.

Two of those three calls did no reasoning worth an expensive model. They picked which chapters looked relevant from a list of summaries.

The tool returns fields you didn’t ask for

Airtable’s Get Record tool has no field filter. Ask for a chapter’s full content and you also get the chapter name, the created time and the summary, which you already had from the first call and are now carrying twice.

You can’t fix that on the tool. You can fix it one step later, if there is a step.

One sub-workflow, doing the whole retrieval

Delete both tools. Replace them with a single sub-workflow tool that goes from a topic to the full content of the right chapters.

The one tinted node is the only model on this canvas, and it is a small one. Everything else is data moving, which is what n8n is actually for.

The selection step is the one worth dwelling on. Its system prompt is one sentence: the user message names a topic, find the one to three relevant chapters, and here is the full list of chapters with their summaries. Its structured output is a list of record IDs.

That’s a sorting job against a list of 15 summaries. GPT-4.1 Mini does it correctly and does it fast, and I never pay frontier prices for it.

Two into one on the deciding, and the step that got cut is the one that carried the most accumulated memory.

And because there’s a Set node between Airtable and the output, I return the chapter title and the full content. Nothing else travels.

The agent’s system prompt also gets shorter, which I didn’t expect to matter as much as it does. It’s now: answer from the biology course, always call this tool first, then answer only from what it gave you. One tool, no ordering rules, nothing to get wrong.

The same trick on a web search tool

Second example, same shape. An agent with a web search tool, in my case Linkup, though Perplexity or anything else behaves the same.

Wire the API in directly and you hit two problems. It takes one question per call, so a broad question has to be asked in pieces, one round trip each. And the response includes the full list of sources, which lands in the context whether you want it or not.

Four nodes, and two of them exist only to throw things away. The API call in the middle is the part you would have got from wiring the API in directly.

Ask something like how SEO and generative engine optimisation fit together in 2026, and the agent breaks it into three searches by itself: trends and strategies, how to optimise for both, best practices by company size. One tool call, three parallel searches, one clean aggregated item back.

The parallelism is the part that shows up as felt speed. Three sequential ten-second calls is half a minute of the user watching a spinner.

It’s one skeleton, not three workflows

I built a third one of these for a RAG agent, on a vectorized course in Supabase. It looks different on the canvas and it’s the same thing again.

Every one of my retrieval sub-workflows is this. The steps that vary are the source in the middle and whether there is anything to filter on.

The filter is the step the other two don’t have, and it’s there because a vector store hands back a similarity score and Airtable doesn’t. When the source gives you a number, you can throw away the results that aren’t good enough. In that workflow the line is 0.4, and anything under it never reaches the agent.

Two things I learned building the third one that I’d now do in all of them.

Name the output fields. The aggregate at the end doesn’t produce an anonymous blob, it produces a field called Knowledge base retrieval, and inside it each entry pairs Query to the knowledge base with Chunks returned. The model reads those names. Handing it an array and hoping it works out which result answers which question is a cost you pay in the final answer.

Say when you found nothing. A filter that removes everything produces no items, and no items means the next node never runs and the agent gets silence. So there’s an IF after the filter, and its empty branch writes a sentence: nothing reached the relevance threshold for this query. In n8n that also means setting the filter to always output data, otherwise the branch you wrote for this case never fires.

That second one changes what the agent can do. Its system prompt ends with an instruction to say it doesn’t know rather than answer from general knowledge, and that instruction is only honest if the retrieval below it is honest about coming back empty.

None of this is really about n8n

All three do one thing: they put steps between the agent and the raw response, and in those steps they throw things away. Here is why I think that’s worth more than a workflow.

Cutting a repeated job into steps is the whole game. A job you run once can be sloppy. A job you run three hundred times pays for its sloppiness three hundred times, and an agent deciding the order on every one of those runs is paying a model to rediscover a drawing you could have made on paper. The moment you know the steps, writing them down is not a loss of flexibility, it’s the point.

Each step gets the context it needs and nothing else. That’s what every clean-up node in this article is doing. It’s also what I measured with Jev: putting a small classifier in front of an agent to decide which skills it preloads and to strip the fields it will never read out of every tool response came out 29% cheaper on average and 61% on the best task, with no drop in quality. Same idea, one level up. Context is not free and most of what arrives in it was never going to be read.

The right model for each step. A sorting job against fifteen summaries is not a frontier-model job. Once the steps are separate, that stops being an opinion and becomes a setting you can change per node.

Then orchestrate, rather than delegate. The steps have to hand each other something useful, which is why the output fields get names and why an empty result says so out loud. That’s orchestration, and it’s the part an agent does invisibly and badly.

It’s the same reasoning that made me stop reaching for MCP on anything I repeat: a script against the API can do the filtering, the mapping and the loop without a model in the middle, and MCP cannot, because the model is the middle.

Agents hide all four, which is exactly why it’s worth having built one by hand. When I’m in Claude Code and something feels slow or expensive, the thing I go looking for is the step that returned everything when I needed three fields. It’s nearly always there, and I only know to look because I once wired that step up myself and watched the token count.

Sources