lumo

Module 07 · Lesson 2 of 15Free

Workflows vs agents: when you need autonomy

Level
Intermediate
Topic
Agents: models that plan and act
Reading time
17 min

When you finish this page you can

  1. Tell a workflow from an AI agent by asking who decides the next step, code or the model.
  2. Match each of the five workflow patterns (prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer) to a feature it fits.
  3. Decide whether a feature should be an AI agent from four questions about steps, cost and latency, testing and compounding errors.
  4. Estimate the cost of an AI agent run as a sum over its calls, and explain why its spread is known only after the run.

Builds on 2 lessons

Start with lesson 114 min
  1. Agents: models that act until a goal is met14 min
  2. Design: a ticket summary feature30 min

Video lesson · coming soon

Daniel wants three AI agents

Deskora is a help desk app. A shop’s support team uses it to answer customer emails from one shared inbox. Each customer problem becomes a ticket: one customer’s whole conversation with the support team. About 1,500 shops use Deskora, and 120,000 new tickets arrive a day.

Tomás is the Deskora engineer who builds the AI features. Two are live. The ticket summary puts three lines at the top of a long ticket, so a support agent like Priya can reply sooner. The drafting assistant writes a reply from the shop’s help center, for Priya to check and send. A third feature, Resolve, is proposed. It would prepare replies to “where is my order?” tickets, about 36,000 a day.

Daniel, another Deskora engineer, writes in the team channel: “Let’s rebuild all three as AI agents and let the model work out the steps.”

Tomás has numbers from last week’s Resolve prototype. One ticket took 4 model calls and about $0.04. The next took 8 calls and about $0.09. The summary costs about $0.0006 on a typical ticket, in one call, every time.

This lesson answers one question: which of Deskora’s three features should let the model choose its own steps, and what evidence should move a feature from fixed code to an AI agent?

Deskora’s ticket volume and the summary’s cost are shared course figures. Resolve’s call counts, costs, timings and test results are estimates for this lesson’s scenario.

Check yourselfAnswer in your head first, then reveal
Daniel says the summary would be better as an AI agent, because the model could decide what to do. Write down what the model would be deciding. What is on your list?Show answerHide answer
Almost nothing. A summary has one step: read the thread, write three lines. An AI agent would stop after that one call, adding a loop and nothing else, or call tools it doesn’t need. Choosing steps helps only when there are steps to choose.

Who decides the next step: code or the model

Anthropic’s guide “Building effective agents” (December 2024) groups every system that combines model calls and tools as agentic systems. Then it splits them by one question: who decides what happens next 1?

  • A workflow runs model calls and tools along paths written in code. Your code decides the next step.
  • An AI agent lets the model decide its own steps and which tools to use, until the task is done. Agents builds that loop for Resolve.

Both are built from one block: a model call that can use retrieval, tools and memory, which the guide calls the augmented LLM 1. The six shapes below differ in how those calls connect.

Diagram not drawn yet: workflow-patterns-and-agent-loop.svg

Six small panels in two rows. Panel 1, prompt chaining: input, model call 1, a code check marked pass or fail, model call 2, output; label: code decides. Panel 2, routing: input, a router model call, then three arrows to three handlers labelled Delivery, Returns and Other; label: code decides. Panel 3, parallelization: input splits into three model calls side by side, which join in a code box that merges results; label: code decides. Panel 4, orchestrator-workers: input, an orchestrator model call, a dashed row of worker calls marked N chosen at run time, then a synthesizer call, output; label: model picks the subtasks, code fixes the shape. Panel 5, evaluator-optimizer: a generator call and an evaluator call joined by a feedback arrow in a loop, with a pass arrow to output and a round limit; label: code decides. Panel 6, AI agent: a model call and a tools box joined in a loop, tool calls going out and results coming back, with three exits: done, limit reached, hand back to a person; label: model decides.

Five workflow patterns keep the order of steps in code. In the sixth shape, the AI agent, the model picks each next step from what the tools return.

In the agent loop, each model reply either asks for tools or ends. With tools, the reply stops with stop_reason: "tool_use". Your code runs the tools and sends the results back in the next call 3. It stops when the task is done, when a step limit is hit, or at a checkpoint where a person must decide 1.

So the useful question is which of the six shapes each feature needs.

Five patterns, five Deskora features

Deskora already runs three of the workflow patterns. The other two fit plausible features.

Pattern What code fixes Deskora feature Fits when 1
Prompt chaining The order of calls, with a check between steps The drafting assistant: rewrite the query, search and rerank, write the draft with citations The task splits cleanly into steps
Routing One call labels the input; code picks the handler The ticket router: Delivery tickets go to Resolve, others to the drafting assistant Categories need different handling and can be labelled reliably
Parallelization Independent calls run at once; code merges them The weekly report: one call per ticket, then code counts the results Subtasks don’t depend on each other, or several votes raise confidence
Orchestrator-workers The shape: split, run workers, merge Plausible: one email with three problems, split into one draft section per problem Subtasks can’t be known until the input is read
Evaluator-optimizer A loop of write, grade, revise, with a round limit Plausible: a second call checks each draft against the shop’s rules, at most two rounds Grading criteria are clear and revision measurably helps

The router comes from Structured outputs; the weekly report from Long inputs. The summary isn’t on the table: it is one call plus code checks, as in Design: a ticket summary feature. The guide says one well-built call is enough for many applications 1.

In orchestrator-workers the model chooses the subtasks, but code still fixes the shape: split, run, merge. Several AI agents working together is a separate topic, Multi-agent systems.

Only Resolve is a candidate for the sixth shape. Four questions decide whether it should be.

Four questions decide the shape

Can you list the steps before the ticket arrives?

For a summary or a draft, yes: every ticket goes through the same stages.

For “where is my order?”, often not. With one order and clean tracking, the steps are fixed. With two order numbers, or a parcel marked delivered that never came, the next step depends on what the last lookup returned. The guide puts AI agents here: open problems where the number of steps can’t be predicted or written in advance 1.

Must cost and latency be known before the run?

A workflow’s cost is the sum of its fixed calls, known from the input size before you send anything. An AI agent’s cost depends on how many calls it makes, known only when it stops. Each call also pays again for the tool definitions and every earlier result 3. The guide states the trade: agentic systems give up and cost for better results on hard tasks 1.

How will you test it?

A workflow runs the same steps on every ticket, so you can test each step alone, and a failure points at one step. An AI agent may take a different path on each run of the same ticket. You test the outcome and the path (did it check tracking before proposing a replacement?) over many runs, the subject of Evaluating agents.

How do errors add up over the steps?

Each model decision can be wrong. In a chain, a code check between steps catches many errors early. In an AI agent, a wrong early choice, such as the wrong order, steers every later call.

The rule

P(whole task right) = p^n, for n model decisions that each succeed with probability p

This assumes the decisions fail independently, a simplification. 97% per decision is an assumption for this lesson.

One decision, like the summary

0.97^1 = 97%

A typical Resolve run, 4 decisions

0.97^4 = 0.885, about 89%

A long Resolve run, 8 decisions

0.97^8 = 0.784, about 78%

Chip Huyen gives the same shape of example: 95% per step over 10 steps leaves about 60% 2. The guide warns that autonomy brings higher cost and the chance of compounding errors 1.

Tomás suspected Resolve’s steps couldn’t be listed. He measured it before building an AI agent.

Resolve started as a fixed chain

The guide’s advice is to start with the simplest solution and add steps only when they are needed 1. So Tomás first built Resolve as a chain, with no AI agent:

  1. Code takes the order number the ticket router already extracts.
  2. Code calls get_order on the shop’s store, then get_tracking on the carrier. The shop id comes from the ticket, never from the model.
  3. Code searches the help center for the delivery policy.
  4. One call to Claude Sonnet 5.5 writes the reply and any proposed action, such as a replacement for a parcel lost more than 10 days.
  5. Priya approves or edits. Nothing reaches the customer, and no replacement is sent, without her click.

He ran it on 200 labelled “where is my order?” tickets. One run gave these results:

Result Tickets What the right next step was
Good reply 124 None: the fixed steps were enough
Missing or wrong order number 28 Find the order by the customer’s email
Order split into two parcels 18 Track each parcel
Carrier says delivered, customer says not 16 Check the delivery scan and the shop’s policy
Something else 14 Different on almost every ticket

Illustrative results for this scenario, not measured data.

A customer, Tendai, wrote: “I ordered twice, 51907 and 52114. One parcel never came.” The chain looked up 51907, the first number, which was delivered. The draft said: “Your parcel was delivered on 20 October.” Priya caught it. Sent, it would have told Tendai his missing parcel had arrived.

Tomás could add a branch for two order numbers, another for split parcels, another for disputed deliveries. The last row is the warning: 14 tickets, nearly 14 different next steps.

How should Resolve handle “where is my order?” tickets?

Keep the fixed chain and add a branch for each failure

Cheap and easy to test. Every new cause needs a new branch, branches start to interact, and the “something else” tickets never fit one.

Run every ticket through the AI agent

Handles every shape of ticket. Pays AI agent cost and variance on the 60% that a fixed chain already handles well: about $1,770 a day instead of $1,210.

Why this choice

The check is plain code: one order found, one tracking number, a carrier status Deskora knows. In the sample, 120 of the 200 tickets (60%) pass it. Their steps can be listed, so they keep a workflow’s low cost, fixed time and simple tests.

The other 40% are the measured failure that justifies an AI agent. It gets the same three tools and starts from the lookups the check already made.

The choice would change in three cases. If evals show the AI agent matches the chain on clean tickets at nearly the same cost, Tomás merges the paths. If one failure, say split parcels, grows to half the AI agent’s tickets, its steps can now be listed, so it moves into the fixed path. If the clean share falls, more tickets pay AI agent prices.

Diagram not drawn yet: resolve-two-paths.svg

Left to right. 1: a new ticket reaches the ticket router, which labels it Delivery. 2: a code check calls get_order and get_tracking and asks: one order, one tracking number, a known carrier status? 3a, yes, about 60%: the fixed chain searches the delivery policy and makes one Claude Sonnet 5.5 call, about $0.012 and 8 seconds. 3b, no, about 40%, highlighted as new: the Resolve AI agent loop, a model call and three tools (get_order, get_tracking, search_help_center) in a loop, limited to 12 calls and $0.10, about $0.038 to $0.094 and 18 to 35 seconds; a dashed exit labelled limit reached, hand back with what it found. 4: both paths end at the same box: a prepared reply and any proposed action, which Priya approves or edits.

A code check splits “where is my order?” tickets. Clean ones take a fixed chain; only the ones whose steps can’t be listed enter the AI agent loop. Both end with Priya’s approval.

The two paths in code

Install the SDK with pip install anthropic and set ANTHROPIC_API_KEY. The order data stands in for the store’s API.

python
import json
import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from the environment
MODEL = "claude-sonnet-5-5"
MAX_CALLS = 12  # Resolve's limit per ticket
TASK = "Draft a reply for the support agent to check. Never promise a refund."
ORDERS = {"51907": {"status": "delivered", "delivered_on": "2026-10-20"},
          "52114": {"status": "shipped", "last_scan": "2026-10-16"}}
TOOLS = [{"name": "get_order",
          "description": "Look up one order in this shop's store by its order number.",
          "input_schema": {"type": "object",
                           "properties": {"order_number": {"type": "string"}},
                           "required": ["order_number"],
                           "additionalProperties": False}}]


def get_order(order_number: str) -> str:
    return json.dumps(ORDERS.get(order_number, {"error": "no such order"}))


def text_of(reply: anthropic.types.Message) -> str:
    return "".join(b.text for b in reply.content if b.type == "text")


def fixed_path(ticket: str, order_number: str) -> str:
    # Code decides the steps: one lookup, then one model call.
    prompt = f"Order: {get_order(order_number)}\n\nTicket: {ticket}\n\n{TASK}"
    return text_of(client.messages.create(
        model=MODEL, max_tokens=2000, messages=[{"role": "user", "content": prompt}]))


def agent_path(ticket: str) -> str:
    # The model decides the steps: it asks for lookups until it stops asking.
    messages = [{"role": "user", "content": f"Ticket: {ticket}\n\n{TASK}"}]
    for _ in range(MAX_CALLS):
        reply = client.messages.create(model=MODEL, max_tokens=2000,
                                       tools=TOOLS, messages=messages)
        if reply.stop_reason != "tool_use":
            return text_of(reply)
        messages.append({"role": "assistant", "content": reply.content})
        messages.append({"role": "user", "content": [
            {"type": "tool_result", "tool_use_id": b.id, "content": get_order(**b.input)}
            for b in reply.content if b.type == "tool_use"]})
    return "HANDED BACK: call limit reached"


ticket = "I ordered twice, 51907 and 52114. One parcel never came. Where is it?"
print(fixed_path(ticket, "51907"))  # the first number found: the delivered parcel
print(agent_path(ticket))

fixed_path always makes one lookup and one call, even with the wrong order. agent_path makes as many calls as the model asks for: one run might look up both orders, another only one. Treat your runs as examples.

Running both costs under 2 cents on Claude Sonnet 5.5, as of October 2026: about 1,500 input tokens and 1,350 output tokens across three calls, with about 300 thinking tokens a call assumed. usage.output_tokens_details.thinking_tokens reports the real number.

What each feature costs, and when you know

An AI agent’s cost is a sum over its calls. Each call’s input carries everything before it, so input grows with every step.

The formula

cost of one run = Σ over calls (input tokens × $2 + output tokens × $10) ÷ 1,000,000

Claude Sonnet 5.5 costs $2 per million input tokens and $10 per million output tokens, as of October 2026 4. Thinking tokens are billed as output, and carried as input on later calls.

Assumptions

first call 2,000 input tokens; each tool step 250 output tokens; each lookup result 400 tokens, the policy search 1,000; the final call 550 output tokens

The first call holds about 500 tokens of instructions, 400 of tool definitions, the 286-token tool-use system prompt 4 and an 800-token ticket. Each tool step assumes 200 thinking tokens; the final call assumes 300.

Typical run: 4 calls (order, tracking, policy, reply)

input 2,000 + 2,650 + 3,300 + 4,550 = 12,500; output 3 × 250 + 550 = 1,300; 12,500 × $2 ÷ 1M + 1,300 × $10 ÷ 1M = $0.025 + $0.013 = $0.038

Long run: 8 calls (two orders, two tracking lookups, a timeout and its retry, policy, a second carrier, reply)

input 35,400; output 7 × 250 + 550 = 2,300; 35,400 × $2 ÷ 1M + 2,300 × $10 ÷ 1M = $0.071 + $0.023 = $0.094

Close to Resolve’s limit of $0.10 a ticket. Agent reliability sets that limit and the 12-call one.

Fixed path: 1 call with all lookups in the prompt

3,100 × $2 ÷ 1M + 550 × $10 ÷ 1M = $0.006 + $0.0055 = about $0.012

One day: 36,000 tickets, 60% clean, half of AI agent runs long (assumed)

21,600 × $0.012 + 7,200 × $0.038 + 7,200 × $0.094 = $259 + $274 + $677 = about $1,210

Every ticket through the AI agent: 21,600 × $0.038 + $951 = about $1,770.

This counts model calls only, without retries of failed calls or caching. Resolve’s $0.10 limit assumes prompt caching, which cuts the repeated input most, since every call resends the same opening.

Feature Shape Model calls Cost per task, typical → long Time, typical → long Known before the run?
Ticket summary One call, code checks 1 $0.0006 → $0.002 about 6 s → 12 s, in the background Yes, from thread length
Drafting assistant Prompt chain 2, plus search and rerank about $0.0024 → $0.006 about 6 s → 11 s after Priya presses Draft Yes
Resolve, clean tickets Prompt chain 1 about $0.012 about 8 s Yes
Resolve, other tickets AI agent 4 → 8, at most 12 $0.038 → $0.094, capped at $0.10 about 18 s → 35 s No, only when it stops

Estimates. Summary and drafting figures are on Claude Haiku 5.5, from earlier lessons’ assumptions. Times assume about 100 output tokens a second.

A common belief is that AI agents are unpredictable because their costs vary more. But the summary’s long case costs about 3 times its typical case, and Resolve’s AI agent only about 2.5 times. The difference is when you know. The summary’s cost follows from the thread’s length before the call; the AI agent’s is known only after its last call. Without a limit, a loop that keeps retrying a broken carrier lookup has no ceiling.

Resolve runs when the ticket is routed, before Priya opens it, so 35 seconds is acceptable. The cost tail is what needs the limits.

Deskora’s verdict: two workflows and one AI agent

Tomás replies to Daniel with the table and three decisions:

  • The summary stays one call. It has no steps to choose. If it ever needs data outside the thread, a fixed lookup in code adds it.
  • The drafting assistant stays a chain. Its stages are the same for every ticket, each with its own tests. If the draft step needs order data, a tool call inside that step adds it, as in Function calling; the chain stays fixed.
  • Resolve is an AI agent only for the tickets whose steps can’t be listed. Clean tickets take the fixed chain. The rest go to the AI agent, within 12 calls and $0.10, and Priya approves every action.

The rule behind all three: start with the simplest shape that works. Move to an AI agent only when a measured failure shows the steps can’t be listed. Move steps back into code when they can.

Where this shows up

Inside Resolve’s loop, each call picks the next step from what it has seen so far. How a model reasons, acts and reads results in turns is the next lesson.

Common mistakes

  • Building the AI agent first. Without a fixed chain to compare, you can’t tell what its extra cost buys.
  • Judging by average cost. An average of $0.066 hides a long run near $0.10 and a broken loop with no ceiling. Set a call limit and a cost limit on every AI agent.
  • Adding branches forever. When each new failure needs a different next step, try an AI agent for those tickets.
  • Letting an AI agent act alone. Refunds, replacements and customer messages wait for a person’s approval.
  • Calling every tool use an AI agent. A tool call inside a fixed chain is still a workflow. What matters is who decides the order of steps.

Check your understanding

Check yourselfAnswer in your head first, then reveal
A new carrier’s tracking statuses aren’t in Deskora’s known list, so the clean share of “where is my order?” tickets drops from 60% to 30%. What happens to Resolve’s daily cost, and what should Tomás do?Show answerHide answer
About 10,800 × $0.012 + 25,200 × $0.066 = $130 + $1,663, about $1,790 a day, $580 more than today. The new statuses are a listable case, so the cheaper fix is adding them to the code check, not paying AI agent prices.
Check yourselfAnswer in your head first, then reveal
Daniel proposes an evaluator-optimizer loop for the summary: a second call grades each summary and asks for a rewrite. When would that be worth it?Show answerHide answer
Only if the summary’s failures are ones a clear grading rule can catch and a rewrite measurably fixes, shown on the summary’s eval set. It adds at least one call to every summary, roughly doubling cost, and the code checks already catch the format errors.
Check yourselfAnswer in your head first, then reveal
Resolve’s long runs make 8 decisions at 98% each. Which raises task success more: a model that reaches 99% per decision, or fetching both orders and their tracking in code before the loop, cutting it to 4 decisions at 98%?Show answerHide answer
About the same: 0.99^8 is about 92% and 0.98^4 is about 92%, against 85% today. Moving known steps into code gets there without a pricier model, and it also makes those runs shorter and cheaper.
Check yourselfAnswer in your head first, then reveal
The ticket router labels a damaged-item complaint as Delivery. Its order and tracking look clean. Which Resolve path does it take, and what goes wrong?Show answerHide answer
The fixed path, because the code check only checks the lookups. It drafts a delivery update to someone whose parcel arrived broken. The final call needs a way to say “not a delivery question” and hand back, and the router’s errors need their own tests.

Summary

  1. Only Resolve’s messy tickets need an AI agent. The summary stays one call, the drafting assistant a fixed chain, and Resolve sends clean “where is my order?” tickets down a fixed path and the rest to an AI agent.
  2. In a workflow, code decides the next step. In an AI agent, the model decides, one call at a time, until it finishes, hits a limit or hands back. The five workflow patterns are prompt chaining, routing, parallelization, orchestrator-workers and evaluator-optimizer.
  3. Four questions decide the shape: can the steps be listed, must cost and time be known before the run, how will it be tested, and how many decisions compound.
  4. On Claude Sonnet 5.5, as of October 2026, Resolve’s fixed path costs about $0.012 a ticket. Its AI agent runs cost about $0.038 to $0.094, known only when they end, capped at 12 calls and $0.10.
  5. Start with the simplest shape. Move a ticket type to an AI agent only after a measured failure shows its steps can’t be listed, and move steps back into code once they can.

Report a mistake

Tell us what’s wrong in this lesson and we’ll fix it.