Claude Architect WorkshopPDFEPUBlearnwithparam.comkaas.team

Professional, lesson 2

Workflow or agent

Pick workflow, agent or augmented LLM by predictability

Lumen Supply gives a free agent every tool for refunds, a path that has been the same for two years. Nobody wrote down why an agent was chosen, so nobody can say when to stop using one. This is the refund desk at Lumen Supply, an online electronics shop. You will run one ticket two ways, then write the rule and the record that say which way to use.

I doWatch the failure and its fix.

One refund path, two ways to run it

An agent chooses its own steps. A workflow has them fixed in code, and the model writes only the words. The code decides the order, and the model decides the language.

The refund path has three steps: read the order, check the policy, refund. Three things go wrong: a free agent takes a path the team already knows, no record says why, and a feedback loop is added as a prompt sentence.

A ticket arrives. A known path runs in code. Only an open path goes to an agent.Ticketkind known?choose()Workflowcode orders the stepsAgentClaude orders themReplya person if unsurethe rule is written in pattern.pyA ticket arrives. A known path runs in code. Only an open path goes to an agent.Ticketkind known?choose()Workflowcode orders the stepsAgentClaude orders themReplya person if unsurethe rule is written in pattern.py

A workflow answers a known ticket

The code reads the order, checks the policy and refunds $89. Then it asks Claude once, for the reply to the customer. The whole run is one request.

Open a card to see the result of each step. The refund and the policy check came from code, so the model cannot skip either one.

  1. CustomerRefund me: the headphones crackle.
  2. Codeget_order(A-1001)
    Show the result
    {
      "item": "wireless headphones",
      "amount": 89,
      "email": "ana@example.com",
      "days_since_delivery": 12,
      "status": "delivered"
    }
  3. Codecheck_policy(A-1001)
    Show the result
    {
      "eligible": true,
      "days": 12,
      "amount": 89
    }
  4. Codeprocess_refund(A-1001, 89)
    Show the result
    {
      "refunded": "A-1001",
      "amount": 89
    }
  5. ClaudeHi, I'm sorry the left ear on your wireless headphones is crackling. We've refunded the $89 for order A-1001 to your original payment method, and it should…
    Show the result
    {
      "reply": "Hi, I'm sorry the left ear on your wireless headphones is crackling. We've refunded the $89 for order A-1001 to your original payment method, and it should appear within 5-10 business days."
    }

RESOLVED: 1 requests, 195 input tokens.

The choice rule, written as code

The starting choose sends every task to an agent. The fix sends a task to a workflow when its steps are known, and to an agent when they are not.

A third shape sits below both. An augmented LLM is one call with tools or retrieval, and it has no loop at all. Pick the lowest complexity that meets the need. Step up only when a simpler shape fails.

starter/pattern.py
1"""EDIT THIS FILE. choose() hands every task to an agent.2A refund path the team has run for two years is given a free agent,3and run_workflow() lists no steps. Run `./workshop check pattern-choice`4until it is green, then `./workshop watch pattern-choice`.5"""67from kit.api import Json8910def choose(task: Json) -> str:11 """Return "workflow" when the steps are known, "agent" when they are not.12 A task is a dict with a `kind`: refund, status, exception or none.13 """14 return "agent"151617def run_workflow(ticket: Json) -> list[str]:18 """Return the ordered step names of this ticket's known path.19 A path nobody can list ends with a person: get_order, then escalate.20 """21 return []

Should a known refund path be an agent?

The refund path has been the same for two years. Every ticket reads the order, checks the policy and refunds. An agent can do all of that, and it can handle a surprise too.

Predict: Should a refund path the team has run for two years be an agent?

  1. ANo. A known path is a workflow, and the code can own the order.
  2. BYes. An agent is more capable, so it is the safer choice.
Show the answer

A. Capability is not the goal. A known path in code cannot drift, and an agent adds cost and variance where nothing needs deciding.

An agent on a known path costs 22 times more

With the starting code, the refund ticket goes to an agent. This run took the right path: order, policy, refund. Nothing drifted, and this page does not pretend it did.

It took 3 requests and 3375 input tokens. The workflow took 1 request and 154. Each agent turn sends the tools and the history again. This is a real Claude Haiku 5.5 run, recorded once and replayed here.

Drift is a rate, not an event. One green run cannot show a repeated lookup or a skipped check. The tests catch the choice itself: a known path must not go to an agent.

  1. CustomerRefund me: the headphones crackle.
  2. Claudeget_order(A-1001)
    Show the result
    {
      "item": "wireless headphones",
      "amount": 89,
      "email": "ana@example.com",
      "days_since_delivery": 12,
      "status": "delivered"
    }
  3. Claudeget_policy(refund)
    Show the result
    {
      "policy": "Refund in full within 30 days of delivery, up to $200 on the agent's own authority. Anything else goes to a person."
    }
  4. Claudeprocess_refund(A-1001, 89)
    Show the result
    {
      "refunded": "A-1001",
      "amount": 89
    }
  5. ClaudeYour refund of $89.00 for order A-1001 has been processed, since the headphones were delivered 12 days ago and fall within our 30-day full-refund window. We're…
    Show the result
    {
      "reply": "Your refund of $89.00 for order A-1001 has been processed, since the headphones were delivered 12 days ago and fall within our 30-day full-refund window. We're sorry the left ear crackles, and you should see the money back on your original payment method shortly."
    }

RESOLVED: 3 requests, 3054 input tokens.

Code decides the path, and the record says why

choose returns a workflow when the ticket has a listed path. run_workflow returns its steps in order, and ends with a person for a path nobody listed.

The record has four parts: the decision, the context, the alternative rejected, and the signal that would reverse it. A feedback loop is designed in the same way. The checker's verdict returns to the drafter as data, with its reasons, not as a sentence in the prompt.

How one ticket is run, in order.CustomerClaudeCodeToolsticketget_orderresultcheck_policyresultprocess_refundresultfactsreply
pattern.pygreen lines are what the fix adds
1"""Pick the pattern for a task, and list the steps of a known path."""23from kit.api import Json45PATHS = {6 "refund": ["get_order", "check_policy", "process_refund"],7 "status": ["get_order"],8}9UNKNOWN = ["get_order", "escalate"]101112def choose(task: Json) -> str:13 """A workflow when the steps are known, an agent when they are not."""14 return "workflow" if task.get("kind") in PATHS else "agent"151617def run_workflow(ticket: Json) -> list[str]:18 """The ordered steps of this ticket's path, or a person for a new one."""19 return list(PATHS.get(ticket.get("kind", ""), UNKNOWN))
adr.mdgreen lines are what the fix adds
1# Decision: how the refund path runs23## Decision45Run the refund path as a workflow. Code fixes the order: get_order,6check_policy, process_refund. The model writes only the customer reply.78## Context910The path has been the same for two years. A free agent can repeat a lookup11or skip the policy check, and every turn resends the tools and the history,12so it reads far more input tokens per ticket. Nothing on this path needs a13decision the code cannot make.1415## Alternative rejected1617A free agent with every tool. It is more capable, but a known path gains18nothing from that, and each drift costs a person time.19Tickets with no listed path still go to an agent or to a person.2021## Reverse if2223More than a fifth of refund tickets stop following the listed steps, or a24new refund rule needs judgement the code cannot express. The checker's25verdict returns to the drafter as data, so a rejected reply is revised26from the reasons, not from a prompt sentence.
We doChange one setting at a time and predict.

The same ticket, two patterns

Switch between the two patterns. The card marked "This is where the runs split" is the policy step. The agent read the written policy, and the code ran its own check.

Both refunded $89. The difference is who chose the steps, and what it cost to let the model choose.

This part is interactive in the lab: run ./workshop watch pattern-choice.

Try it: pattern and ticket

Change one setting at a time. Pick a pattern, then a ticket. Every combination is a recorded run, so this works with no internet.

Watch the exception ticket. The workflow hands it to a person with a fixed reason. The agent read the policy and wrote a handoff that names the defect and the age of the order.

This part is interactive in the lab: run ./workshop watch pattern-choice.

Where an agent is worth its cost

The lab holds a golden set of forty tickets: twelve refunds, twelve status checks, twelve exceptions and four with no label. The tests run choose on every one. Refund and status go to a workflow. The rest go to an agent.

The recordings cover one ticket of each type. The exception ticket shows the limit of a workflow. It escalates with the reason "unknown path", where the agent explained why. An agent is worth its cost only where the path cannot be listed.

app/agent.pyfile: 181 lines
···94 lines not shown95 {96 "type": "tool_result",97 "tool_use_id": c["id"],98 "content": str(log(result, c["name"], c["input"])),99 }100 for c in calls101 ]102 messages.append({"role": "user", "content": done})103104 return judge(ticket, result)105106107def run_workflow(ticket: Ticket, steps: list[str], llm: Llm) -> Result:108 """Run `steps` in code, then ask the model for the reply only."""109 result = Result("workflow", ticket.kind)110111 for name in steps:112 if name == "process_refund":113 check = result.events[-1]["output"] if result.events else {}114 if not check.get("eligible"):115 break116117 args: Json = {118 "order_id": ticket.order_id,119 "amount": check["amount"],···62 lines not shown
  1. CustomerMy monitor is three months old. Make an exception?
  2. Codeget_order(A-1003)
    Show the result
    {
      "item": "monitor",
      "amount": 240,
      "email": "cara@example.com",
      "days_since_delivery": 95,
      "status": "delivered"
    }
  3. Codeescalate(unknown path)
    Show the result
    {
      "escalated": true,
      "reason": "unknown path"
    }
  4. ClaudeI'm sorry your monitor has a line across the screen. Because it was delivered 95 days ago, I've escalated order A-1003 to our team for manual review, and they…
    Show the result
    {
      "reply": "I'm sorry your monitor has a line across the screen. Because it was delivered 95 days ago, I've escalated order A-1003 to our team for manual review, and they will follow up at cara@example.com, though I can't promise an exception at this stage."
    }

ESCALATED: 1 requests, 173 input tokens.

You doFix the starting code, then test yourself.

You do: run the known path as a workflow

Copy the starting code and open work/pattern-choice/pattern.py and adr.md. choose() hands every task to an agent, and run_workflow() lists no steps.

Terminal
./workshop start pattern-choice
./workshop check pattern-choice
./workshop watch pattern-choice

The checks send a known path to a workflow and an open one to an agent. The refund path runs in a fixed order with the policy check first, and an unlisted path ends with a person. The record names the pattern and the alternative.

Check your understanding

Answer each question, then read why every option is right or wrong. The wrong options are the mistakes engineers make on the job.

1. A support desk runs refunds through a free agent with every tool, on a path that has not changed in two years. The agent drifts on 1 ticket in 12 and costs 3 times a scripted run. The team needs the same policy check on every refund, and the budget is flat. What do you change?

  1. AGive the agent more tools so it can recover when it drifts.
  2. BRun the known path as a workflow that the code orders.
  3. CAdd a line to the prompt that says to always check the policy.
  4. DSwitch to a larger model so the agent drifts on fewer tickets.
Show the answer

Answer: B

  • A More tools give the agent more ways to wander. The path is already known, so nothing needs to be discovered.
  • B Correct. Code fixes the order and the policy check cannot be skipped. The model only writes the reply.
  • C A prompt sentence asks the model to behave. Code makes the step happen.
  • D A larger model costs more per ticket, and it still chooses its own steps on a path nobody needs to choose.

2. A product team proposes an agent to build a weekly report that always has the same four steps, in the same order. The latency budget is 8 seconds, and the cost per report is capped. The data sources do not change. Which pattern do you choose?

  1. AAn agent, because it is the most capable pattern on offer.
  2. BAn agent with a high turn limit, so it has room to explore.
  3. CAn agent, because a workflow cannot retry a step that failed.
  4. DA workflow, since the steps are known and can run in a fixed order.
Show the answer

Answer: D

  • A Capability is not the goal. A known path gains nothing from it and pays for it in latency.
  • B Room to explore is cost on a path with nothing to explore. It threatens the 8 second budget.
  • C A workflow can loop and retry. The code owns the loop and bounds it.
  • D Correct. Known steps in a fixed order are what a workflow is for, and it is the cheapest shape that works.

3. A 40-ticket golden set scores the workflow at 94 percent and the agent at 91 percent. The agent costs 2.8 times as much per ticket. The team needs one pattern for the known refund path, and quality and cost both matter. Which do you choose?

  1. AThe workflow, since it is more accurate and costs less on this path.
  2. BThe agent, since a higher cost means it is doing more work.
  3. CThe agent, since the gap of 3 points is too small to matter.
  4. DThe workflow, but only after adding a loop so it can match the agent.
Show the answer

Answer: A

  • A Correct. It wins on quality and on cost, so nothing argues for the agent on this path.
  • B Cost is not a measure of value. The extra spend bought no accuracy.
  • C A small gap still points to the workflow, and the agent is 2.8 times dearer.
  • D A workflow may loop already, and it does not need a loop to win here.

4. A team is deciding whether a task suits a workflow. The steps have run the same way for two years, and each step returns a result a test can check. Select two signs that point to a workflow. The task has no judgement call inside it.

  1. AThe steps can be listed in advance, in a fixed order.
  2. BThe model should be free to pick any tool at any time.
  3. CEach step's output can be checked by the code.
  4. DThe task should use the newest and most capable model.
Show the answer

Answer: A, C

  • A Correct. A list of steps known in advance is the test for a workflow.
  • B Free choice of tools is what an agent offers. It is a cost, not a sign of fit.
  • C Correct. A checkable output lets the code decide what happens next, with no model.
  • D Model size does not choose a pattern. A known path can run on a small model.

5. A triage desk reads free-text messages and must pick from 14 tools, in no fixed order. About 4 in 10 tickets need a path nobody has written. Wrong routing costs a person 15 minutes. Which pattern fits best?

  1. AA workflow with 14 branches, one for each tool the desk has.
  2. BAn augmented LLM, with a single call that has all 14 tools.
  3. CAn agent, since the path cannot be listed in advance.
  4. DAn agent with no turn limit, so it can always finish the job.
Show the answer

Answer: C

  • A Fourteen branches cannot cover paths nobody has written, and each exception needs a new branch.
  • B One call cannot work through an open task that needs several tools in an order it chooses.
  • C Correct. An open task with no fixed order is where an agent is worth its cost.
  • D Autonomy without a bound is a risk, not quality. An agent still needs a turn limit and a handoff.

6. One call with retrieval answers an FAQ correctly on 97 of 100 test questions. A team proposes a multi-step orchestration with a planner and three workers, and answers must stay under 2 seconds. The FAQ has a single source. What do you recommend?

  1. ABuild the orchestration, since more steps will lift 97 toward 100.
  2. BKeep the augmented LLM, the lowest complexity that works.
  3. CCall it a workflow, since retrieval and generation are two steps.
  4. DGive the model more autonomy so it can handle the 3 failures.
Show the answer

Answer: B

  • A Each extra step adds latency and cost. The 2 second limit is at risk for a small gain.
  • B Correct. One call with retrieval meets the need, so nothing simpler or dearer is needed.
  • C An augmented LLM is one call with tools or retrieval. It has no fixed sequence of steps the code runs.
  • D Autonomy adds variance. The 3 failures need a look at the source, not a looser loop.

7. A checker rejects 1 draft in 5 from a reply writer, and the drafter never sees why. The team adds "be more careful" to the prompt, and the rate stays at 1 in 5. The checker already returns the failing rule for each draft. How should the loop be built?

  1. AAdd a second sentence to the prompt that says what careful means.
  2. BLet the drafter retry on its own until a draft passes.
  3. CReplace the drafter with an agent that picks its own checks.
  4. DReturn the checker's verdict to the drafter as data, in a bounded loop.
Show the answer

Answer: D

  • A A longer sentence is still a request. The drafter never reads the reason for a single rejection.
  • B A blind retry repeats the same draft. It does not use what the checker knows.
  • C An agent does not fix a missing data path. It adds choices where the gap is a missing signal.
  • D Correct. The verdict, with its reason, is data the drafter can act on, and the bound stops a runaway loop.

8. An audit asks why an agent was chosen for a payment path, and nobody on the team can say. The path ships in 6 weeks. Select two things that make a pattern choice defensible. The audit wants a record, not a recollection.

  1. AA note that the team felt an agent was the modern choice.
  2. BThe alternative that was rejected, and why it lost.
  3. CA claim that the agent will need less supervision over time.
  4. DA signal that would reverse the choice, such as a rising drift rate.
Show the answer

Answer: B, D

  • A A feeling is not a reason. It cannot be checked, and it gives the audit nothing to test.
  • B Correct. Naming the rejected alternative shows the choice was weighed.
  • C Autonomy is not quality, and a forecast of less supervision is a promise that nobody has measured.
  • D Correct. A reversing signal lets the next team see when to revisit the choice.

9. An architect must justify a pattern to a sponsor who wants a one-page reason. The sponsor will read it once, before a 10,000 dollar monthly spend is approved. The team has two patterns in play. What goes on the page?

  1. AAn ADR with the context, the decision, the alternative and the consequence.
  2. BA slide deck of every framework the team looked at during the study.
  3. CA list of the agent's features, since the sponsor pays for capability.
  4. DA promise that the prompt will be tuned until the results look right.
Show the answer

Answer: A

  • A Correct. One page can hold the context, the decision, the alternative rejected and what follows from it.
  • B A deck of frameworks is a survey. It does not say what was chosen, or why.
  • C Features are capability, and capability is not a reason to spend.
  • D A promise about the prompt is not a decision. It gives the sponsor nothing to approve.

10. The pattern decision was made in a chat thread 6 months ago, and the thread has scrolled away. A new lead now questions it, and the planning review is in two weeks. The lead needs to see the reason and the alternative. What should have existed?

  1. AA longer thread, pinned to the channel where the choice was made.
  2. BA line in the prompt that says which pattern the team chose.
  3. CA versioned decision record, stored with the code it governs.
  4. DA reminder for the original author to explain the choice in person.
Show the answer

Answer: C

  • A A pinned thread still scrolls, cannot be reviewed as a change, and does not sit beside the code.
  • B A prompt line says what was chosen. It does not say why, or what was rejected.
  • C Correct. A record in version control is found with the code and shows when the decision changed.
  • D A person leaves, forgets and is out of reach. The record has to outlive them.

Play: predict the output

This workflow has every step of the refund path, in the order someone typed them.

python
PATHS = {
    "refund": ["get_order", "process_refund", "check_policy"],
    "status": ["get_order"],
}


def run(ticket: Ticket) -> None:
    for step in PATHS[ticket.kind]:
        STEPS[step](ticket)

Predict: A customer asks for a refund 70 days after delivery, and the window is 30. What happens?

  1. AThe refund is paid, and then the policy check says no.
  2. BThe policy check stops the refund before it is paid.
Show the answer

A. A workflow runs its steps in the order written, so a check placed after the action guards nothing. Put each check before the step it protects, and test the order, not only the list. The lab's runner adds a second guard: it pays only when the step before said eligible.

References

Conclusions

  • Run a known path as a workflow: the code decides the order.
  • Use an agent only where the path cannot be listed in advance.
  • Write the pattern, the alternative rejected and the reversing signal down.

You can now choose a pattern by how predictable the path is, and record why.

Workflow

Code fixes the steps and the model writes only the language

Agent

The model chooses its own steps in a loop

Augmented LLM

One call with tools or retrieval and no loop

Decision record

The pattern, the alternative rejected and what would reverse it