Foundations, lesson 6
Long conversations
A summary drops the facts unless code keeps them
After 30 turns your agent summarises the case, and the refund amount and the approval date fall out of the summary. Full order and shipment results fill the rest of the window. The customer asks how much was refunded and the agent has no answer. This is the agent at Lumen Supply, an online electronics shop. You will watch it lose the facts, then fix it with two small functions.
Facts sit outside the summary
Three parts share the work. Code keeps the facts. Code also trims each tool result before Claude reads it. Claude answers the question.
The case is Dana's refund: 30 turns over two days. A long case reaches Claude as a summary of the story, a few recent messages, and a facts block of values that must not be lost.
The facts block answers the question
Dana asks for the refund amount and the approval date on turn 31. The facts block holds both, so Claude answers in one sentence.
Open the harness card. The recorded request is 460 input tokens, and the facts block sits first, under a heading. Without the trim and the facts it is 2,138 tokens, and the answer is missing.
- CustomerRemind me of my refund amount and the date it was approved.
Show the result
Remind me of my refund amount and the date it was approved.
- HarnessClaude is given 1147 characters (460 tokens), with case facts: order_id 1042, customer Dana Cho, amount 89.0, refund_approved_on 2026-02-14
Show the result
{ "order_id": "1042", "customer": "Dana Cho", "amount": 89.0, "refund_approved_on": "2026-02-14" } - ClaudeDana's refund for order 1042 is $89.00, and it was approved on February 14, 2026. I don't have any other details about…
Show the result
Dana's refund for order 1042 is $89.00, and it was approved on February 14, 2026. I don't have any other details about the refund's processing or when the money will reach her account.
1147 characters, 460 tokens given: the reply holds what was asked.
Two functions as written
update returns the facts after one more turn. The starting code returns them unchanged, so no fact is ever kept. trim cuts a tool result to the fields that matter. The starting code returns the whole result.
Each request carries a rolling window: a summary plus the last eight turns. A shipment result of 1,776 characters is paid for on every request while it stays in that window, and the case holds four of them.
What happens when the facts are not kept?
Take the question "How much was my refund?" on turn 31. The order lookup that held the amount was on turn 3. The summary says the agent approved a refund, and nothing more.
Predict: What does the agent reply?
- AIt gives the amount, because the summary keeps the story.
- BIt says it does not have the amount, because the summary dropped it.
Show the answer
B. The amount sat in a tool result on turn 3. The summary kept the story and dropped the number.
The agent has no amount to give
This is the same question with the starting code. The context is over four thousand characters, most of it full shipment results, and none of it holds the amount or the date. The result card is red.
This is a real Claude Haiku 5.5 run, recorded once and replayed here. Claude was told to say when a detail is missing, so it says so and asks Dana again.
- CustomerRemind me of my refund amount and the date it was approved.
Show the result
Remind me of my refund amount and the date it was approved.
- HarnessClaude is given 4426 characters (2138 tokens), with no case facts, only a summary
Show the result
{} - ClaudeI'm sorry, but the case notes confirm that a refund was approved for order 1042 without listing the amount or the…
Show the result
I'm sorry, but the case notes confirm that a refund was approved for order 1042 without listing the amount or the approval date, so I can't give you those details. I can check the order again or help you start the return for the loose keys.
4426 characters, 2138 tokens given: the reply lacks it.
Facts are kept in code, output is trimmed
update copies the customer, order, amount and approval date from the order lookup into the facts. Later turns do not erase them. trim keeps only the fields each tool is used for, and the tests need the result under a quarter of its size.
Put the key facts at the start or the end of the context, under a heading. The middle of a long input is where detail is missed. None of this needs a model.
The same question now has an answer
Use the switch to run the question with the starting code, then the facts block. On the second button, the card marked "This is where the runs split" shows what Claude was given.
Try the approval date too. The starting code gives no date, and the fixed code gives it in one line.
This part is interactive in the lab: run ./workshop watch long-conversations.
Try it: facts and trimming
Change the rules and the question. Two halves are on offer: the facts block without the trim, and the trim without the facts.
The trim alone shrinks the context and still cannot answer. The facts block alone answers with the window still full. The fix needs both.
Every combination is a recorded run, so this works with no internet.
This part is interactive in the lab: run ./workshop watch long-conversations.
The same rules run in the Agent SDK
In the Claude Agent SDK, trim runs as a PostToolUse hook, code the SDK runs right after a tool returns. In this real Claude Haiku 5.5 run, the shipment result reaches Claude at 74 of 1,776 characters. With the starting code, Claude cannot give the amount or the date.
Because a hook is plain code, it is deterministic. A rule that must hold before every refund goes in a PreToolUse hook on the refund tool, for example HookMatcher(matcher=REFUND, hooks=[check]).
A session is one saved conversation, and session_extras picks how the next one starts: {"resume": id} replays the saved history, adding "fork_session": True copies it first, and {} starts fresh. Resume suits a session whose context is still true. Start fresh with a summary and the facts when it is stale, and tell a resumed agent which files changed.
- Customeramount, date and parcel
- Tool result74 of 1776 characters
Show the result
{"order_id": "1042", "status": "delivered", "eta": "delivered 2026-02-06"} - ClaudeYour refund for order 1042 is $89.00, and it was approved on 2026-02-14. Tracking shows the parcel was delivered on…
amount, date and parcel status all present
You do: keep the facts
Copy the starting code and open work/long-conversations/facts.py. update() keeps no case facts, and trim() passes every tool result through whole. By the last turn the amount and date are buried, and the agent asks again.
./workshop start long-conversations
./workshop check long-conversations
./workshop watch long-conversations
The checks keep the customer, order, amount and approval date as facts across later turns, and cut a shipment result to a quarter of its size. Then the recorded long ticket must answer from the facts block.
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 30-turn refund case is summarised three times. On turn 31 the customer asks for the refund amount and the agent asks them again. What is the best fix?
- AKeep the amount and date in a facts block that code rebuilds and puts first.
- BSwitch to a model with a larger context window so the whole history fits.
- CWrite a longer summary prompt and ask the model to keep every number.
- DAsk the customer to repeat the amount at the start of each session.
Show the answer
Answer: A
- A Correct. Code keeps the facts exactly, so no summary can rewrite them.
- B A larger window holds more text but does not stop a summary from dropping the amount.
- C A longer prompt still asks a summary to rewrite itself, and each rewrite blurs numbers again.
- D This moves the work to the customer and leaves the agent unchanged.
2. Each order lookup returns 40 fields and the agent uses 5. After four lookups, 85 percent of the context is tool output. What should change?
- ARaise the output token limit so the model can read the longer results.
- BTell the model in the prompt to ignore the extra fields.
- CSummarise the tool results once the window is nearly full.
- DCut each result to the five fields needed before the model reads it.
Show the answer
Answer: D
- A The output limit controls the reply, and the results still fill the input.
- B The ignored fields still cost tokens on every request.
- C A late summary can blur the values the answer needs.
- D Correct. Trimming keeps the needed fields and drops the rest, so every later turn is cheaper.
3. A 60,000 token input holds two key findings in the middle. The model misses both and finds a third one at the top. What is the best change?
- APut the key findings first, under a clear heading.
- BShorten the sentences around the findings.
- CLeave them in the middle, because the model reads the whole input evenly.
- DRepeat the question twice at the end of the prompt.
Show the answer
Answer: A
- A Correct. The start and the end of a long input are read most reliably, and a heading names what matters.
- B Shorter sentences do not change where the findings sit.
- C Attention is uneven across a long input, and the middle is where detail is most easily missed.
- D The question is not the problem. The findings are hard to find.
4. Select two effects of a history that grows to 30 turns of full tool output.
- AOld detail is buried, so a value from turn 3 is easy to miss.
- BThe model reads the old lines more carefully than the new ones.
- CEvery request carries the whole history, so cost rises each turn.
- DThe model reads the history once, so later turns cost nothing extra.
Show the answer
Answer: A, C
- A Correct. The value is still there, but the model has more to search.
- B Attention does not favour the old lines. Detail in the middle is easily missed.
- C Correct. Each turn resends the history, so it is paid for again.
- D Every request sends the history again, so the cost recurs on each turn.
5. An investigation was left for two weeks, and most of the files it read have changed since. The agent resumes the named session and quotes the old results. What is the best handling?
- AResume and raise the turn limit so the agent has time to notice.
- BStart fresh with a summary and the facts, because the old context is stale.
- CResume again and trust the old results, since the session remembers the work.
- DFork the session so the stale results are copied into a safe branch.
Show the answer
Answer: B
- A More turns do not tell the agent that the files changed.
- B Correct. A fresh start with the facts drops the stale output.
- C A resumed session carries the old results, which are now wrong.
- D A fork copies the same stale history into the branch.
6. A team wants to compare a refactor and a rewrite, both starting from the same 40-turn investigation. Which approach fits?
- AResume the same session twice and run both approaches in it.
- BStart two fresh sessions and paste a summary into each.
- CRun the refactor first, then the rewrite, in one session.
- DFork once per approach, so each branch starts from the same history.
Show the answer
Answer: D
- A Both approaches would write into one history and mix their results.
- B A fresh summary loses detail that the forks would keep.
- C The rewrite would start from the refactor's results, not the original state.
- D Correct. A fork copies the history into a new session, so each branch starts equal.
7. A named session continues after two files changed. The agent still quotes the old file contents. What do you add when you resume?
- AA longer system prompt that says to trust the session.
- BNothing, because a resumed session refreshes its own files.
- CA line that tells the agent which files changed, so it reads them again.
- DA second fork of the same session.
Show the answer
Answer: C
- A Trusting the session is what keeps the old results in use.
- B A session holds what was read then. It does not watch files.
- C Correct. The agent cannot see the change unless it is told, and it can read the two files again.
- D A fork copies the same old results.
8. Select two valid uses of resuming a named session.
- AContinue work after a large refactor changed most of the files.
- BContinue a task in the same session, where the context is current.
- CStart a follow-up on the same task the next morning, when no files changed.
- DBranch into two experiments from one saved point.
Show the answer
Answer: B, C
- A After a large change the old results are stale, and a fresh start with a summary is safer.
- B Correct. The context is still true, so resuming saves the work.
- C Correct. Nothing changed, so the history is still accurate.
- D Branching is a fork, which copies the history into a new session.
9. A shipment tool returns dates in three formats. Downstream code parses 1 in 6 of them wrongly. What is the most reliable fix?
- ANormalise the dates in a PostToolUse hook, before the model reads the result.
- BTell the customer which format to expect.
- CRetry the tool until it returns a format the parser knows.
- DAsk the model in the prompt to rewrite each date before it uses it.
Show the answer
Answer: A
- A Correct. A hook runs every time and reshapes the result before the model sees it.
- B The customer did not choose the format.
- C A retry returns the same mixed formats.
- D A prompt is probable, not certain, and 1 in 6 misses would persist.
10. A business rule must hold before any refund, with no exception. Which control fits?
- AA longer tool description that explains the rule.
- BA hook that checks the rule in code before the refund tool runs.
- CA sentence in the system prompt that states the rule.
- DA reviewer who reads the transcripts each week.
Show the answer
Answer: B
- A A description guides the choice of tool and does not block a call.
- B Correct. A hook is deterministic, so the rule holds on every call.
- C A prompt rule is followed most of the time, and this rule needs every time.
- D A weekly review finds a breach after the refund is paid.
11. A prompt asks the model to trim its own tool output. In a test of 12 replies, 1 skips the trim. What is the best change?
- AReword the prompt to say trim in capital letters.
- BMove the trim into a PostToolUse hook that runs on each result.
- CAdd two examples of a trimmed result to the prompt.
- DLower the temperature and run the test again.
Show the answer
Answer: B
- A Emphasis improves the odds but leaves a chance of a miss.
- B Correct. A hook runs in code, so the trim does not depend on the model.
- C Examples help, and the model can still skip the step.
- D A lower temperature reduces variety and does not make a step certain.
12. Select two things a PostToolUse hook can do.
- AChange what the model decided before it called the tool.
- BLog each result for later review.
- CReshape a tool result before the model reads it.
- DUndo a tool call that already finished.
Show the answer
Answer: B, C
- A The call was already made. A PreToolUse hook acts before it.
- B Correct. The hook sees the result, so it can record it.
- C Correct. The hook can replace the output the model reads.
- D The tool already ran. A hook cannot take that back.
Play: predict the output
This version keeps facts, but it takes them from every tool.
def update(facts: Json, turn: Json) -> Json:
kept = trim(turn["tool"], turn["result"])
return {**facts, **kept}
Predict: Turn 3 looks up order 1042. Turn 9 tracks a shipment for order 1077. What does facts["order_id"] hold after turn 9?
- A1042, the order the case is about.
- B1077, from the shipment lookup.
Show the answer
B. Every result merges into the facts, so a later lookup overwrites a case fact. Take each fact from the tool that owns it, and keep only the keys you named.
References
- Context windows: how every turn and tool result counts against the window.
- Context editing: the API feature that clears old tool results for you.
- Effective context engineering: why a small, curated context beats a full one.
- Agent SDK sessions: resume, fork or start fresh, and what each one keeps.
- Agent SDK hooks: the PostToolUse hook that trims a result in the SDK.
Conclusions
- Case facts are kept in code, outside the summary, and placed first.
- Each tool result is cut to the fields the next step needs.
- Resume, fork or start fresh depends on whether the history is still worth its size.
You can now keep the facts of a long case exact and keep the window small.
Facts block
Values kept in code and placed first, so a summary cannot drop them
Summary
A rewrite of the story that loses specific values
Trim
Cutting a tool result to the fields the next step needs
Fork
A new session that starts from a copy of an old one