Workflow or agent? Choosing the simplest design that does the job
Fixed workflows and autonomous agents suit different tasks. Five workflow patterns, tool design tips and a way to decide which one you need.

"Should this be an agent?" is one of the most useful questions to ask early in an AI project, and the honest answer is often "not yet". Anthropic's engineering post Building effective agents draws a clean line that I find helpful, and this article builds on it with some practical guidance of my own.
Two different things
The post defines the terms this way:
- A workflow is a system where models and tools follow paths that your code defined in advance.
- An agent is a system where the model decides its own steps and which tools to use as it goes.
Both can be useful. They have different costs. A workflow is predictable: you can draw it on a whiteboard, test each step and estimate its cost. An agent is flexible: it can handle a task whose steps you could not list beforehand, at the price of more variation, more cost and a larger surface for mistakes to compound.
Start with the simplest thing
The advice I would underline is to use the simplest solution that works and add complexity only when it measurably helps. Often that means a single, well-prompted model call with good context. Many tasks, such as classifying a ticket, extracting fields from an invoice or drafting a reply, never need more.
The post also cautions that frameworks can hide the prompts and responses underneath, which makes debugging harder. You do not have to avoid them, but you should be able to explain what is being sent to the model.
Five workflow patterns worth knowing
These are the patterns the post describes. Each is a small step up in complexity from a single call.
- Prompt chaining. Split a task into sequential steps, each model call handling the output of the last, with optional code checks in between. Example: draft an outline, check it against a rule list in plain code, then write the article. You trade a little speed for accuracy.
- Routing. Classify an input first, then send it to a specialised path. Easy questions can go to a smaller, cheaper model; refund requests to one prompt, technical questions to another.
- Parallelization. Run independent subtasks at the same time, or run the same task several times and compare answers (a vote). Useful when you want speed or extra confidence.
- Orchestrator and workers. One model breaks a task into parts at runtime and hands them to worker calls, then combines the results. This fits cases where you cannot know the subtasks in advance, like changes spread across several files.
- Evaluator and optimizer. One call produces, another critiques, and the loop continues until the result is good enough. It helps when you have clear criteria for "better".
Notice that none of these require the model to run open-ended. Your code remains in charge of the overall shape.
When an agent earns its place
The post suggests agents fit open-ended problems where you cannot predict the number of steps or hard-code a path, and where you can trust the model's judgement to a reasonable degree. They loop: act, look at the result from the environment, decide what next. They tend to need guardrails and testing in a sandbox, because autonomy raises cost and lets errors build on each other.
Some questions I ask a team:
- Can you write down the steps? If yes, build a workflow.
- Is a wrong action easy to undo? If not, keep a person in the loop for that step.
- Can you check the result automatically, with tests or rules? Agents do best when they can see whether they succeeded.
- How much variation is acceptable in cost and time? A workflow gives a tight range; an agent does not.
If you answer "no, unpredictable, hard to undo, hard to check", pause. That is a sign to add structure or human approval before adding autonomy. This is the thinking behind how we run agents at vvek: work happens inside an isolated machine, which we described in why every agent gets its own virtual machine, and anything risky goes to a person for approval first.
Tools deserve as much care as prompts
One part of the post that deserves more attention than it gets is the design of the interface between model and tools. The advice is to treat tool definitions like you would a user interface for a person. Ask whether the description and parameters would be obvious to a new colleague. Good definitions include examples, edge cases, required formats and clear boundaries between tools that look similar.
Two practical habits:
- Test with many realistic inputs and watch where the model makes mistakes. Then change the tool, not just the prompt.
- Make mistakes hard to make. The post gives an example where requiring absolute file paths removed a class of errors that relative paths caused.
Here is a small tool definition in that spirit:
{
"name": "create_invoice",
"description": "Create a draft invoice for one customer. Does not send it. Amounts are integers in minor units (e.g. 1999 for 19.99).",
"input_schema": {
"type": "object",
"properties": {
"customer_id": { "type": "string" },
"amount_minor": { "type": "integer" },
"currency": { "type": "string", "description": "ISO 4217 code, e.g. USD" }
},
"required": ["customer_id", "amount_minor", "currency"]
}
}
The description states what the tool does not do, the units are explicit, and the types leave little room for creative interpretation.
Make progress visible
The third principle in the post, besides simplicity and tool design, is transparency: show the plan the agent is following. For users that builds trust, and for you it makes failures much quicker to diagnose. Log each step, each tool call and each result, and keep the logs where you can search them.
A suggested path
- Try one model call with good context and measure it.
- If quality is short, add a chain or a router.
- If the subtasks vary, try an orchestrator with workers.
- Only if the path truly cannot be predicted, let an agent loop, inside a sandbox, with limits on steps and spending.
- At each stage, keep a small set of example tasks you can re-run to see whether the change helped.
The goal is not to avoid agents. It is to reach for them when they pay for their complexity, and to know what you gain when you do.


