Academy

You might not need an agent

Reaching for an autonomous agent when the path is already known is the most common way to build something expensive that a simpler workflow would have handled better.

The Felesh team Updated 8 min

You have a task. It needs to call an API, summarise the result, and write the output to a file. You reach for an agent. It feels like the right tool — modern, flexible, capable of reasoning its way through whatever comes up. The agent runs. It gets partway through, second-guesses itself, calls the API twice, writes an incomplete file, and loops. Five minutes and a few thousand tokens later, you have a bug report to write.

The three-step pipeline you needed was knowable before you wrote a line of code. The path was fixed. An agent was the wrong shape for a fixed path.

The same three-step task, as a workflow and as an agentOne task, fetch order 2210 from an API, summarise it, write summary.md, run two ways. As a workflow the code runs three calls in order: call the API, summarise in 3 lines, write the file. As an agent the model decides each step: it calls the API, then calls the same API again, writes half a summary, and loops back to the repeated call.workflow: the code sets the pathcall API/orders/2210summarise3 lineswrite filesummary.md3 calls, in order, every runagent: the model decides each stepcall API/orders/2210call APIsame call, againwrite filehalf a summarysecond-guesses, calls again, loops
A fixed path is three calls in order; handed to an agent, the same task re-decides every step, repeats a call and loops.

The alternatives you should reach for first

Not everything that involves an LLM needs an agent. Anthropic’s Building Effective Agents draws a clear and useful line: a workflow is a system where the LLM’s actions are orchestrated by predetermined logic; an agent is a system where the LLM itself decides the steps. The distinction matters because agents are expensive to run and hard to predict. Most tasks don’t justify both of those costs.

The workflow patterns are the boring defaults — and boring defaults are right more often than they get credit for:

Prompt chaining runs a fixed sequence: the output of one LLM call becomes the input of the next. Translation then editing then formatting. Extraction then summarisation. The path is a list. Code it as a list.

Routing inspects the input and sends it down one of several fixed branches. A customer message is classified — billing, technical, general — and handed to the branch that knows how to respond. The LLM decides which branch at the start, then the branch runs deterministically. No open-ended step-picking at runtime.

Parallelisation runs several fixed calls at the same time and combines the results. You need three independent analyses of a document: run them in parallel, join the outputs. No coordination overhead, no shared state, nothing for the models to trip over.

Evaluator-optimiser runs one call to produce an output, then a second to critique it, in a fixed loop until a criterion is met or a step count is reached. The loop is bounded. The logic is known in advance. The model doesn’t invent the loop; the code drives it.

Four workflow patterns, each with its fixed shapeA table of four patterns with a worked line each. Chaining is a list: extract, summarise, format, each output feeding the next call. Routing is a fork where one classify call picks one branch, for example a message about being charged twice goes to billing. Parallelisation splits and joins: three analyses of one contract run together and the outputs are joined. The evaluator loop is a bounded cycle: draft, critique, redraft, stopping at a pass or after 3 rounds.patternshapeworked linechaininga listroutingone branchparallelsplit, joinevaluatorbounded loopextract, summarise, formateach output feeds the next call“charged twice”: billingone classify call, then code3 analyses of one contractrun together, join the outputsdraft, critique, redraftstop at a pass or 3 roundsin all four, code owns the loop and the order
All four workflow patterns keep the path in code; the model only fills the slots in it.

Each of these patterns uses an LLM for what an LLM is genuinely good at — language understanding, flexible generation, qualitative judgement — without asking the model to manage its own execution. The structure comes from code. The LLM fills slots in that structure.

When an agent actually earns its place

There is a real class of tasks where the path genuinely cannot be drawn in advance. The next step depends on what the current step finds. The work requires making a sequence of decisions where each decision narrows the space of reasonable next decisions — and that narrowing can’t be reduced to a finite set of branches you write beforehand.

A research task that needs to follow a trail: find a paper, scan its references, follow two of them, find a contradiction, look for a third source to resolve it. You don’t know when you start which references matter or whether the contradiction will appear. An agent earns its place here because the LLM must direct its own steps; there’s no other way to encode “follow what’s relevant”.

A research trail drawn by what each step findsPaper A cites five references. The agent follows only two: reference 2, a trial, which says the effect rose, and reference 4, an audit, which says it fell. The two findings contradict each other, so the agent looks for a third source, source C, which settles it. The three references it did not follow are drawn dashed.readreferenceswhat it findspaper Aref 1 surveyref 2 trialref 3 reviewref 4 auditref 5 thesiseffect roseeffect felldisagreesource C settlesnot followedthe path came from what each step found
A research path exists only after the work: two of five references are followed, the contradiction decides the next move, and none of it could be listed in advance.

A debugging task where the agent reads an error, hypothesises a cause, writes a fix, runs the tests, reads the new error, and updates its hypothesis. The loop length is unknown. The branches are too many to enumerate. You need a model that can revise its plan from evidence.

The deciding question is whether the path is knowable before execution. If yes, encode it. A workflow is more predictable, cheaper to run, easier to debug, and faster to iterate. If no — if the task genuinely requires the model to discover the structure as it goes — then an agent is the right tool, and you should build one deliberately.

Where an agent loses

The cost of choosing an agent when a workflow would have sufficed is specific and documented. Anthropic, writing about its own multi-agent research system, reported that agents use about 4 times the tokens of a chat interaction and multi-agent systems about 15 times (one team’s measurement on its own workload, not a universal figure — treat it as an order of magnitude). For a simple or medium-complexity task, that overhead buys nothing. You paid for the model to manage its own reasoning; the task didn’t need managed reasoning.

Agents also introduce failure modes that workflows don’t have. An agent can stall in a reasoning loop. It can take an action that seemed locally reasonable but is globally wrong. It can lose the thread across a long context and contradict a decision it made ten steps ago. These are not bugs to be fixed — they are properties of open-ended planning in a model. Workflows, by contrast, fail in well-understood, reproducible ways: a step fails, an output is malformed, a branch condition mismatches. Failures that have shapes are failures you can handle.

What an agent costs and how each approach failsTop: tokens for one task, a single call is 1 unit and a fully autonomous agent is about 15 units, an order of magnitude from community research, not a precise figure. Below, three failures side by side. The agent stalls in a loop with no step saying it is stuck, the workflow has a step fail and retries that one step. The agent is wrong overall though each step looked reasonable, the workflow has a malformed output that a schema check rejects. The agent contradicts its step 3 at step 13 in a long context, the workflow has a branch mismatch and the log names the branch.tokens for one taskone callagent×1≈ ×15a widely cited order of magnitude, not a measured constantagent: failures with no shapeworkflow: failures with a shapestalls in a loopno step says it is stucka step failsretry that one stepwrong overalleach step looked reasonableoutput malformeda schema check rejects itcontradicts step 3at step 13, long contextbranch mismatchesthe log names the branch
An agent costs about fifteen times a single call and fails in shapes no one listed; a workflow fails in shapes you can catch.

Agents are not better. They are different — and the difference is appropriate for a narrower set of tasks than they are typically given.

The escalation line

Start with the simplest pattern that could work: a single prompt, then a chain, then routing, then parallelisation, then an evaluator loop. Reach for a single-agent architecture only when that landscape can’t be mapped in advance. Reach for a multi-agent structure only when a single agent has genuinely hit its ceiling — and that ceiling has its own discussion.

The escalation ladder, stopping at the first rung that holdsSeven rungs from simplest to most complex, tried on one task: tag a ticket, then draft the reply. A single prompt does not hold, because tag and draft blur together. A prompt chain holds: tag, then draft. The climb stops there. Routing, parallelisation, the evaluator loop, a single agent and a multi-agent structure are never reached and are drawn dashed.simplest first, task: tag a ticket, then draft the replysingle promptno: tag and draft blur togetherprompt chainyes: tag, then draftroutingnot reachedparallelisationnot reachedevaluator loopnot reachedsingle agentnot reachedmulti-agentnot reachedstop at the first rung that holds
Climb one rung at a time and stop at the first rung that holds; for this task that is a two-step chain.

The anatomy of what a multi-agent structure looks like when it’s genuinely warranted lives in a separate place: The Coordinator, the Worker, and the Delegator. That post covers the pattern. This one is about deciding whether you need it at all.

The most important judgement in building with LLMs is not how to architect a sophisticated system. It is knowing when a sophisticated system is the wrong answer.