You already built a strong pattern:
question → model → maybe tool call → result → model again → final answer
That simple loop is perfect for many jobs: read a file, look up a time, answer from a few passages.
Now meet a job where that shape starts to crack.
One story: a refund helper
Person’s question: “Please refund order 4412.”
Your agent should:
- Look up the order
- If the amount is small → refund now
- If the amount is large → wait for a human to say yes or no
- Only then finish
look up order
│
┌───────────┴───────────┐
▼ ▼
small amount large amount
│ │
▼ ▼
refund now WAIT for human
│
▼
yes → refund
no → stopA straight “keep calling tools until done” loop does not match this picture well.
What still works with a simple loop
| Job | Simple loop? |
|---|---|
| “What’s in notes.txt?” | Yes |
| “What time is it, and what’s in notes.txt?” | Yes |
| “Answer from our handbook” (RAG) | Yes — retrieve, then one answer |
One main path. Finish in this program run. No long wait for a person.
Crack 1 — two paths (branching)
In the refund story, step 2 is a fork:
- Path A: refund now
- Path B: wait for a human
In a simple loop you hide that fork inside many if checks in one function. It works for a while. Then every new rule (“VIP customers skip approval”, “EU orders need a second check”) adds more ifs. The path becomes hard to see and hard to test.
You want the branches to be visible: “after lookup, go left or right.”
Crack 2 — wait for a human
Path B needs a pause.
The person (or a manager) is not inside your while loop. They may click “Approve” tomorrow.
A simple loop wants to finish now, in one run:
step 1 → step 2 → step 3 → done
If you stop the program to wait, you lose your place unless you invent save/resume yourself.
Example:
| Moment | What you need |
|---|---|
| Monday 10:00 | Agent looked up a large refund; needs approval |
| Monday 10:01 | Program exits — waiting |
| Tuesday 09:00 | Human says yes |
| Tuesday 09:01 | Agent must continue, not look up the order from scratch as if nothing happened |
That “continue later” is not natural for a plain loop.
Crack 3 — memory scattered in the loop
While the loop runs, facts live in local variables and chat history:
- order id
- amount
- “waiting for human?”
- “already refunded?”
Easy to forget one update on one branch. Then the model sees a confused history and makes a wrong tool call.
You will want one clear place for those facts. That place is called state — next chapter.
Simple picture: loop vs what comes next
| Simple loop | What we need for refunds |
|---|---|
| Mostly one straight path | Clear branches |
| Finish in one run | Pause and resume |
| Facts in local variables | One shared state object |
Simple loop: ● → ● → ● → ● → done
Refund job: ● → ● → ●
↘ ↖
waitSame tools. Same model. Different shape of control.
Worked walk-through
Order 4412 — amount $12 (small)
- Look up order → $12
- Branch: small → refund now
- Final answer: “Refunded $12 for order 4412.”
Simple loop is fine.
Order 4412 — amount $900 (large)
- Look up order → $900
- Branch: large → must wait
- Simple loop has no clean “sleep until Tuesday”
- If you restart cold, you may look up again, or worse, refund twice
Here the simple loop breaks as a design — not because the model is “dumb,” but because the job needs pause + memory of where you stopped.
What we will build next (preview only)
| Chapter | Fixes |
|---|---|
| Explicit State | One object that holds order id, amount, approved, and so on |
| Branching and Graphs | Named steps and clear “go here next” paths |
| Persistence and Human-in-the-Loop | Save, wait for a human, continue |
This chapter only names the pain. Do not rush to a big framework. Learn the ideas first — they work in any language.
Words to keep
| Word | Meaning |
|---|---|
| Simple loop | Call model → tool → model again until a final answer, in one run |
| Branch | Two (or more) different next steps from the same point |
| Pause / resume | Stop for a human (or later time), then continue without losing the job |
| State | The facts the workflow must remember (next chapter) |
See it in Code
The Code panel runs a tiny refund helper. A small amount finishes in the loop. A large amount hits “need human approval” and stops — that is the crack. Check the Example console.