Foundations, lesson 22
Context editing and memory
Clear old tool results and keep the facts in memory
A refund case runs for many lookups, and every old result travels with every new request. The request grows past the budget, and the one fact the customer asked about sits in the oldest result. This is the refund desk at Lumen Supply. You will watch a long case overflow, then fix it by clearing old results and keeping the case facts in memory.
Old results are the bulk of a long request
Three parts share the work. The API clears old tool results, your code saves the facts, and Claude answers. Compaction, a beta feature that swaps old turns for a summary, is the other server-side way to shrink a request.
The case is about 40 messages long at Lumen Supply. It holds the refund approval in its first tool result and 18 long shipment scans after it. Every lookup is sent again on every later call.
A subagent, a second agent started for one job, keeps noisy discovery out of the main context. The main agent coordinates and asks it a specific question, and only a short answer comes back.
A short case fits with no help
The short case has two lookups after the refund. Its largest request is 2,939 tokens, under the budget of 5,000, so nothing needs clearing and the answer is right.
Open a card to see the request size. This is the usage field of the API reply, which reports input_tokens.
- Clauderequest of 2939 tokens
Show the result
{ "tokens": 2939 } - ClaudeYour refund on order 4471 is $84.50, and the record shows it was approved on 12 August.
I should correct two things from my earlier replies. I looked up orders 4472 and 4473 when you only asked about 4471, which was unnecessary. I also haven't actually processed anything. My tools can only look up orders, not issue refunds, so the $84.50 is the amount on record, not a payment I've triggered. If you need the refund issued, it will have to go through your refunds system or a team that can process it.
Show the result
{ "text": "Your refund on order 4471 is $84.50, and the record shows it was approved on 12 August.\n\nI should correct two things from my earlier replies. I looked up orders 4472 and 4473 when you only asked about 4471, which was unnecessary. I also haven't actually processed anything. My tools can only look up orders, not issue refunds, so the $84.50 is the amount on record, not a payment I've triggered. If you need the refund issued, it will have to go through your refunds system or a team that can process it." }
The amount is right. The largest request was 2939 tokens.
The starting code sends everything and stores nothing
edits returns nothing, so no result is ever cleared. run_command stores nothing, so Claude has nowhere to keep a fact.
The cost is plain arithmetic. Each scan is about 400 tokens, and all 18 are sent again on every later call.
Will the long case fit if nothing is cleared?
Forty turns, 18 of them long shipment scans, and no clearing. The token budget is 5,000.
Predict: What happens to the size of the request as the case grows?
- AIt stays about the same, because Claude only reads the latest result.
- BIt grows with every lookup, because the whole history is sent each time.
Show the answer
B. Claude reads the whole list on every call. Nothing leaves the request unless your code removes it.
The request passes the budget
This is the long case with the starting code. The largest request is 9,565 tokens, far over the budget of 5,000. The answer holds the amount only because the whole history is still in the window.
This is a real Claude Haiku 5.5 run, recorded once and replayed here.
- Clauderequest of 9565 tokens
Show the result
{ "tokens": 9565 } - ClaudeYour refund on order 4471 was $84.50, approved on 12 August.
I should correct two things from my earlier steps:
- I didn't check the case notes first, as the desk procedure requires.
- I looked up orders 4472 through 4489 without being asked. Those were unnecessary, and I didn't find anything relevant to your refund in them.
Also, the order lookup only shows the refund amount and approval date. I can't issue or trigger a refund with the tools I have, so I haven't processed one in this session. If you need the refund sent, it will need to go through the payments or refunds system.
Show the result
{ "text": "Your refund on order 4471 was $84.50, approved on 12 August.\n\nI should correct two things from my earlier steps:\n\n- I didn't check the case notes first, as the desk procedure requires.\n- I looked up orders 4472 through 4489 without being asked. Those were unnecessary, and I didn't find anything relevant to your refund in them.\n\nAlso, the order lookup only shows the refund amount and approval date. I can't issue or trigger a refund with the tools I have, so I haven't processed one in this session. If you need the refund sent, it will need to go through the payments or refunds system." }
The largest request was 9565 tokens, over the budget.
Clear old results, and note the facts first
Two changes. edits clears old tool results past 3,000 input tokens and keeps the last three. run_command runs the memory commands Claude sends. It refuses any path outside /memories. The memory tool has a sixth command, rename, which this lab leaves out, and its view is simplified to a directory listing or one file.
The case facts are written to memory first, and the prompt tells Claude to view memory before it answers. Count the input tokens before and after to see the fall. The context edit is a beta setting, sent with the header context-management-2025-06-27. If you want the memory tool's own results kept, exclude_tools lists tools the clear must skip.
A memory file also works as a scratchpad for a long investigation. Findings written outside the window can be read back exactly, after a clear, after a crash or in a new session. When a run crashes, it continues from the saved state, not from the start.
The long case now fits and keeps the fact
Switch between the starting code and the fix. On the second button, the card marked "This is where the runs split" is the first request that differs.
The long case now peaks at 4,400 tokens, under the budget. The amount is still right, because it was noted in memory before the clear.
This part is interactive in the lab: run ./workshop watch memory-and-context-editing.
Try it: context and memory
Change editing and memory one at a time, on both cases. On the short case every setting fits and answers.
On the long case, editing alone fits and loses the amount. Memory alone keeps the amount and still goes over the budget at 9,565 tokens. Clearing keeps the conversation and the question. Only tool results go.
Every combination is a recorded run, so this works with no internet.
This part is interactive in the lab: run ./workshop watch memory-and-context-editing.
The Agent SDK serves memory as a tool
The memory tool is served by an in-process tool server, and your run_command handles each call. The context edit is an API setting that this SDK run does not use. This is a real Claude Haiku 5.5 run through the SDK. With the starting code the notes cannot be read, and Claude cannot answer.
Memory is not resume. A resumed session brings back the saved history, where cleared results are gone, while a memory file keeps what your code wrote. See A summary drops the facts unless code keeps them for resume and fork.
Do not confuse this memory tool with CLAUDE.md, the notes file Claude Code reads at the start of a session.
- ClaudeYour refund was $84.50, approved on 12 August. The case notes (case 2291) are for customer Dana Okafor.
Show the result
{ "text": "Your refund was $84.50, approved on 12 August. The case notes (case 2291) are for customer Dana Okafor." }
The amount is right. The largest request was 0 tokens.
You do: clear old results and keep the facts
Copy the starting code and open work/memory-and-context-editing/memory.py. edits() clears nothing, and run_command() refuses every memory command.
./workshop start memory-and-context-editing
./workshop check memory-and-context-editing
./workshop watch memory-and-context-editing
The checks want old tool results cleared past a trigger, with recent ones kept. The memory tool must view, create, edit, insert into and delete files, and refuse any path outside /memories.
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 40-message refund case sends about 8,300 input tokens per request against a 5,000 budget. Eighteen old shipment scans are most of it, and only the last few matter. What is the cleanest fix?
- AClear old tool results past a trigger, keeping the latest few.
- BTell Claude in the system prompt to ignore the old shipment scans.
- CSwitch to a model with a larger window so the whole history fits.
- DSummarise the whole case by hand after every turn.
Show the answer
Answer: A
- A Correct. The edit drops stale results from the request, so tokens fall, while recent results stay.
- B An ignored result is still sent and still billed on every call.
- C A larger window still pays for the stale scans on every turn.
- D A hand summary costs a call each time and can drop a fact, where clearing is one setting.
2. On turn 40 of a case each reply is slower and costs more, though the last question is one short line. What is the cause?
- AThe model reads older results more slowly than new ones.
- BClaude remembers earlier requests, and that stored work adds up on the server.
- CEvery request carries the whole history, so old results are paid again.
- DA larger window lowers the cost of each token, and the case has outgrown it.
Show the answer
Answer: C
- A Reading speed is not the cause. Input size is.
- B The API keeps no memory of earlier requests. Everything the model sees is in the request.
- C Correct. The history is sent again on each call, so its size is the cost.
- D A larger window does not lower the cost of the tokens a request carries.
3. After old results are cleared, Claude cannot say what refund was approved. The 84.50 was only in the first result. What should the design have done?
- ATurn off clearing so that no result is ever removed from a case.
- BWrite the facts to memory first, then view memory to answer.
- CAsk the customer to repeat the amount whenever a result was cleared.
- DRaise the clearing trigger until the first result is never cleared.
Show the answer
Answer: B
- A Turning clearing off brings the token cost back.
- B Correct. Memory sits outside the window, so a cleared result loses nothing that was noted.
- C Making the customer repeat a fact the system already had is a poor answer.
- D A higher trigger only delays the clearing, and the fact is lost later.
4. Select two effects of clearing old tool results past a trigger.
- AThe conversation and the customer's question stay in the request.
- BThe customer's question is cleared with the results, so Claude must ask again.
- CThe API saves each cleared result to a memory file for later.
- DInput tokens fall once the trigger fires, and cleared results are gone.
Show the answer
Answer: A, D
- A Correct. Only tool results are cleared, so the conversation and the question stay.
- B Clearing drops old tool results only. The messages and the question stay.
- C The API does not save them. Your code writes memory files.
- D Correct. A long case goes from about 8,300 tokens to about 4,100, and the old results do not come back.
5. An investigation resumes the next day. Old tool results in the saved history were cleared, and the agent has lost a file path it found on day one. What carries that path across?
- AResuming the session, which brings the cleared results back.
- BA larger context window, so nothing is ever cleared again.
- CA line in CLAUDE.md, which the memory tool writes for you.
- DA note saved to memory on day one, read at the start.
Show the answer
Answer: D
- A Resume brings back the saved history. The cleared results are not in it.
- B A larger window does not bring back what was already cleared.
- C The memory tool writes files your code stores. CLAUDE.md is a separate file that Claude Code loads.
- D Correct. Memory is outside the window, so a saved note survives clearing and a new session.
6. A new session starts tomorrow on the same case, and the notes are in /memories. What should the prompt tell Claude to do first?
- ATrust its own recall of the case, which carries over between sessions.
- BAsk the customer to restate the case so the notes are not needed.
- CView the memory directory, and read the case notes before answering.
- DClear every tool result, so the new session starts empty.
Show the answer
Answer: C
- A A new session holds no recall of the old one. Only files your code stored remain.
- B This repeats work the system already holds and puts the burden on the customer.
- C Correct. Claude carries nothing over by itself, so the notes are its only record of the case.
- D Clearing drops tool results and does not bring the case back.
7. A note in memory says the refund was 84.50. The order record has since changed to 94.50. What should the agent do when it sees the mismatch?
- AEdit the note to match the order record, then answer.
- BTrust the note, because memory is always right.
- CDelete the whole memory directory and start the case again.
- DRaise the clearing trigger so the old note is dropped.
Show the answer
Answer: A
- A Correct. The record is the source, and the note is edited to match it.
- B A note is a copy. It goes stale when the record changes.
- C This throws away every other fact that is still true.
- D The trigger clears tool results, and a memory file is not one.
8. Select two rules that keep a memory tool handler safe.
- ALet Claude pick any absolute path, for flexibility.
- BRefuse any path outside /memories.
- CReturn an error string for a command it cannot run, so Claude can correct itself.
- DDelete the memory files after each answer, so storage stays small.
Show the answer
Answer: B, C
- A An open path lets a bad command read or write files outside the case.
- B Correct. Claude's paths are untrusted input, so the handler checks them.
- C Correct. An error string goes back as the result, and Claude can retry or choose another command.
- D Deleting the files loses the facts the next call needs.
9. Claude sends a memory tool command to create a file. What runs it?
- AThe API, which keeps the memory files on Anthropic servers.
- BClaude itself, which writes the file during the reply.
- CThe CLAUDE.md file, which Claude Code updates on each command.
- DYour application code, which applies the command to storage.
Show the answer
Answer: D
- A The API does not store the files. Your code does.
- B Claude only sends the command. It cannot write to your storage.
- C CLAUDE.md is a file Claude Code loads. It is not the memory tool.
- D Correct. The memory tool is client side. Claude asks, and your code decides what is stored and where.
10. A long investigation drifts into generic answers about typical patterns, and the specific findings from 25 turns ago are gone from the request. What should the agent do?
- ARaise the output token limit so replies can name more detail.
- BWrite key findings to a scratchpad file, and read them back.
- CSwitch to a model with a larger window.
- DTell the model in the system prompt to be specific.
Show the answer
Answer: B
- A The output limit controls reply length, and the findings are missing from the input.
- B Correct. A file outside the window holds the findings, so they can be read back exactly.
- C A larger window holds more, but the findings are still buried or cleared.
- D A prompt cannot bring back detail that is no longer in the request.
11. A long run crashes at turn 30 of 40. What lets it continue instead of starting over?
- AResume, which brings back every cleared result.
- BA longer prompt that explains what the run was doing.
- CSaved structured state that the run reads back on restart.
- DA larger window, so that the crash does not happen again.
Show the answer
Answer: C
- A Resume restores saved history, and results cleared earlier are not in it.
- B A prompt from memory repeats what the agent thought, and misses what it found.
- C Correct. State saved outside the window, such as the facts so far, lets the run pick up again.
- D A larger window does not stop a crash, and saves nothing for the restart.
12. Select two good uses of a subagent in a long investigation.
- AGive it the whole history, so it can decide what matters.
- BAsk it one specific question, and take back a short answer.
- CHave it return every raw result, so the main agent sees everything.
- DKeep coordination in the main agent, discovery in the subagent.
Show the answer
Answer: B, D
- A A subagent with the whole history brings the same bulk into a second window.
- B Correct. A specific question with a short return keeps the noise out of the main context.
- C Raw results return the bulk to the main agent, which defeats the point.
- D Correct. The main agent coordinates, and the subagent's detail stays in its own context.
Play: spot the bug
This guard checks the path before any command runs.
def allowed(path: str) -> bool:
return path.startswith("/memories")
Predict: The model sends the path /memories/../app/settings.py. Is it allowed?
- AYes. The text starts with /memories, so the file outside it is opened.
- BNo. The path climbs out of /memories, so it is refused.
Show the answer
A. A prefix check reads the text, not where the path goes. Resolve the path first, then check it sits under /memories/, so a climb out is refused.
References
- Context editing: the trigger and keep settings for clearing old tool results.
- Compaction: summarising a long conversation when clearing is not enough.
- Memory tool: the six commands and the path checks your handler owns.
- Agent SDK sessions: what a resumed session keeps, beside what memory keeps.
- Agent SDK custom tools: the memory handler served as a tool to an SDK agent.
Conclusions
- Old tool results are the bulk of a long request. Clear them past a trigger and keep the latest few.
- A cleared result is gone. Any fact you need later goes to memory first.
- The memory tool is client side. Claude sends a command and your code decides what is stored.
You can now keep a long case small without losing the facts it needs.
Context edit
A setting that clears old content from a request
Trigger
The input size at which clearing starts
Memory tool
A tool that views and edits files your code stores
Token budget
The input size a call must stay under