Chain of Recall is a way to give a long-running AI agent memory without stuffing everything into its context window. Every Trigger, Thread and Worker gets a stable ID. The context keeps only IDs, short summaries and nearby messages, and the agent walks the links between IDs to fetch older facts in a few hops.
The term comes from DeepSeek Harness’s design essay “Exploring Super-agent Design”, posted on 2026-11-01. One caveat before you go further: the essay describes an architecture, not a shipped feature. Parts of it live in a prototype plugin, dsh-superagent-prototype, which the authors call “not an official DeepSeek product.” There’s no Chain of Recall switch to turn on. It’s a pattern you build.
The context-window problem in a long-running agent
A long-running agent hits its context limit because work never stops arriving. A super-agent watching chat, GitHub and CI sees hundreds of events a day, and the window that held yesterday’s work can’t also hold today’s.
The usual responses each cost something:
- Keep everything. The window fills and cost climbs with every turn.
- Summarize old turns. A summary drops the exact error or PR number you need later.
- Retrieve by similarity. Works until the fact you need doesn’t look like your query.
Anthropic’s guide to context engineering for AI agents frames context as a finite resource you curate. Chain of Recall is one concrete way to do that curation, and our explainer on how AI agent memory works covers the wider set of options.
Inline vs spill: context as a cache
The essay treats the context window like a cache with two moves:
- Inline what the agent is likely to need right now: IDs, short summaries, neighboring messages.
- Spill everything else: truncate it and leave a pointer the agent can follow later.
A spilled item isn’t deleted; only its pointer stays in the prompt.
Here’s what that looks like for one CI failure arriving at the Router. This shape is illustrative, not DeepSeek’s code:
{
"trigger_id": "trg_8f21",
"source": "github.check_run",
"thread_id": "thr_pr_412",
"summary": "CI failed on PR #412: 3 of 118 tests red in payments/",
"neighbours": ["trg_8f1c: review comment asking for retry logic"],
"spilled": {
"full_log": "GET /triggers/trg_8f21/payload (41 KB, truncated)"
}
}
If the one-line summary is enough, the agent never pays for the 41 KB log. If not, it fetches the log by ID.

Stable IDs and the reference graph
Chain of Recall works because the IDs never change. In the essay’s design, three kinds of objects carry them:
| Object | What it is | Example ID |
|---|---|---|
| Trigger | One incoming event: a chat message, a webhook, a CI callback | trg_8f21 |
| Thread | A run of related events on one PR, IM topic or email chain | thr_pr_412 |
| Worker | One isolated agent session that handles one task | wkr_77a0 |
A Trigger belongs to a Thread, a Thread is owned by one or more Workers, and a Worker’s report cites the Triggers it acted on. Those links form a reference graph, and that graph is the agent’s memory.
Recall happens by following links one hop at a time, not by loading history or searching for similar text. The sibling guide on how to build a super-agent explains where Triggers, Threads and Workers sit in the full Router and Worker design.
A multi-hop recall walk-through
Say a teammate asks the Router on Friday: “Why did we add retry logic to the payments client?” The original discussion happened on Tuesday and was spilled long ago. Here’s the walk:
- Hop 1: find the Thread. The Router’s context still holds a one-line index entry:
thr_pr_412: payments retry PR, merged Wed. It fetchesGET /threads/thr_pr_412. - Hop 2: find the Worker. The Thread record lists
owner_workers: ["wkr_77a0"]. The Router fetchesGET /workers/wkr_77a0and reads its final report. - Hop 3: find the cause. The report cites
trg_8f21, the CI failure. The Router fetches that Trigger’s payload and reads the timeout errors in the log. - Answer. “CI on PR #412 failed with 3 payment timeouts on Tuesday. Worker wkr_77a0 added retries with backoff and the PR merged Wednesday.”
Three small, exact fetches. Nothing was guessed, and nothing sat in the prompt for three days.

Chain of Recall vs vector memory and summaries
Chain of Recall doesn’t replace other memory techniques. It answers a different question. Vector retrieval, popularized by the retrieval-augmented generation paper, asks “what looks like this?” Chain of Recall asks “what is linked to this?”
| Chain of Recall | Vector memory (RAG) | Rolling summaries | Memory MCP servers | |
|---|---|---|---|---|
| How it recalls | Follows stable ID links | Similarity search over embeddings | Reads a compressed history | Calls a memory tool the server exposes |
| Precision | Exact record by ID | Approximate, ranked by score | Lossy by design | Depends on the server’s store |
| Best for | Event histories: PRs, tickets, CI runs | Large document sets, fuzzy questions | Short sessions, chat continuity | Facts shared across tools and sessions |
| Needs | IDs that never change, fetch-by-ID APIs | An embedding model and an index | A summarizer pass | A running MCP server |
| Weak spot | Can’t find what isn’t linked | Misses facts phrased differently | Drops details | Another service to run and secure |
In practice you’ll combine them: a vector index finds a starting Thread ID, then Chain of Recall walks to exact facts. The MemGPT paper’s operating-system style memory hierarchy is a close relative. If you’d rather start with a ready-made store, see our guide to adding persistent memory to AI agents with MCP.
Two limits. The essay lists long-term memory under open problems and doesn’t claim Chain of Recall solves it. And in its experiment, removing Thread pass-through raised cache-read tokens from 23.2M to 31.8M per run, about 37% more: a cost of a missing feature, not a saving from Chain of Recall.
What the APIs underneath must guarantee
Every hop in the walk-through is an API call. If one call returns a different record, or none, the chain breaks and the agent either stalls or answers from a guess. So the APIs behind Chain of Recall carry four contracts:
- IDs never change. An ID returned today must resolve to the same object next month. No reuse after deletion, no renumbering after a migration.
- Fetch-by-ID is cheap and exact.
GET /threads/{id}returns that one record. It doesn’t search, and it doesn’t return “closest match.” - Unknown IDs fail loudly. A missing ID returns
404 Not Found, as RFC 9110 defines it, with a clear error body. A200with an empty object teaches the agent that a memory exists when it doesn’t. - Cursors page without gaps.
GET /threads/{id}/events?cursor=walks a long Thread in order. Every event appears once, nothing is skipped, and a cursor stays valid while new events arrive.
These contracts break quietly in refactors, so they belong in automated tests. Tool responses also need to stay small, as our guide on agent tool responses and the context window covers in depth.
Let your coding agent test the recall APIs with Apidog CLI
Chain of Recall is only as reliable as its fetch-by-ID endpoints, and a coding agent can write and rerun those checks for you. Apidog CLI gives the agent commands to define the endpoints, create test cases and run them from the terminal.
Set it up once:
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
Then give Claude Code, Codex or whichever agent you use one prompt:
In Apidog project <projectId>, define three endpoints for our agent memory
service: GET /threads/{id}, GET /threads/{id}/events?cursor=, and
GET /workers/{id}. Then create test cases that check:
1. A thread_id returned by GET /threads/{id} resolves to the same record
on a second call, and each owner worker ID resolves via GET /workers/{id}.
2. An unknown thread ID and an unknown worker ID both return 404.
3. Paging GET /threads/{id}/events with the cursor returns every event
once, in order, with no gaps.
Run them against the staging environment and summarize any failures.
The agent reads each payload schema, validates its JSON before it writes anything, and then creates and runs the cases:
apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create --file thread-get.json
apidog endpoint create --project <projectId> --file thread-get.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file id-resolves.json
apidog test-case create --project <projectId> --file id-resolves.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json
The cli reporter prints pass and fail per assertion in the terminal, and the json report gives the agent a file it can read to explain which hop broke. If an ID stops resolving after a migration, you’ll see it in the report before your agent starts answering from a broken chain. To run the same checks on every merge, swap the reporter to -r junit; our walkthrough of Apidog CLI in Claude Code shows the full agent loop.
Where Chain of Recall fits
Use Chain of Recall when your agent’s memory is a history of discrete, linkable events: PRs, tickets, CI runs, support threads, deploys. Those already have natural IDs, and the questions people ask about them (“why did we do this?”, “what happened after that?”) are questions about links.
Use vector retrieval for unstructured documents and fuzzy questions, and summaries for short sessions where losing detail is fine.
Chain of Recall comes from one essay and one prototype: a clear, testable idea, not a product. For the tool behind the essay, start with what DeepSeek Harness is.
FAQ
Is Chain of Recall a DeepSeek feature I can enable? No. It’s a term from DeepSeek Harness’s super-agent essay, and parts live in a prototype plugin the authors say is not an official DeepSeek product. You implement the pattern yourself.
What’s the difference between inline and spill? Inline keeps IDs, short summaries and neighboring messages in the prompt. Spill truncates the rest and leaves a pointer the agent can fetch by ID when needed.
Does Chain of Recall replace RAG? No. RAG finds similar content; Chain of Recall follows exact ID links. Many agents use both.
Did Chain of Recall cut tokens by 37%? No. The 37% figure is about Thread pass-through: removing it raised cache-read tokens from 23.2M to 31.8M per run in the essay’s experiment. The essay doesn’t report a token saving for Chain of Recall itself.
What should a fetch-by-ID API return for an unknown ID? A 404 Not Found with a clear error body. Returning 200 with an empty object makes the agent believe a record exists, which breaks the recall chain silently.
How do I test that my agent’s memory APIs stay stable? Write test cases that assert an ID from one call resolves in the next, unknown IDs return 404, and cursors page without gaps. A coding agent can create and run these with Apidog CLI on every merge.



