Multi-agent workflows have an amnesia problem
Every agent in a pipeline starts from zero unless something manually threads context between them. Salesforce measured what that actually costs, and it is not small.
Everyone is building multi-agent systems right now. Subagents, fleets, swarms, pipelines, pick your framework's word for it. The idea is always the same: break a task into pieces, hand each piece to its own agent, run them in parallel or in sequence, stitch the results back together.
It works. It is genuinely faster than one agent doing everything serially.
It also has a hole nobody talks about enough: the agents don't remember each other.
The number that made this a real problem, not a vibe
Salesforce ran this exact question through an actual benchmark instead of a hot take. CRMArena-Pro tested nine leading models across 4,280 realistic business tasks, sales, case resolution, pricing, the stuff a CRM agent actually has to do.
| Task shape | Success rate |
|---|---|
| Single-turn (one clean ask, one answer) | ~58% |
| Multi-turn (context has to carry across steps) | ~35% |
That's not a small dip. That's most of the value falling off a cliff the moment a task requires the model to still know something it was told two or three steps ago. Salesforce's own writeup says it plainly: generic agents "reset" at each step the way a human never would.
Multi-agent pipelines are the same failure mode, just wearing a different outfit. Instead of one model forgetting turn 1 by turn 3, you have agent 3 that never had turn 1's context in the first place.
What actually happens when you fan out
Say you run a research-then-write pipeline. Agent 1 reads five files and figures out how a system actually behaves. Agent 2 takes that finding and writes documentation. Agent 3 reviews it for accuracy.
Agent 3 does not know what agent 1 discovered. Not automatically. Agent 1's context, the five files it read, the dead ends it ruled out, the thing it almost got wrong before catching itself, evaporates the moment it returns an answer. All that survives is whatever text made it into the return value.
Agent 1 · research
- reads 5 files
- finds 3 caveats
- rules out 2 ideas
- returns: 1 summary
Agent 2 · write
- gets: 1 summary
- writes docs from
- that summary only
- 2 caveats already gone
Agent 3 · review
- gets: 1 doc
- zero visibility into
- what agent 1 saw
- reviews blind
If agent 1's summary was good, you got lucky. If it dropped a caveat that mattered, agent 3 will confidently review documentation built on a gap it has no way of knowing exists.
This is not a bug in any particular framework. It is the model. Anthropic's own subagent docs describe this as intentional: each subagent runs in "its own context window separate from the main conversation," specifically to prevent context pollution. That isolation is exactly what makes parallelism safe. Agent 1 and agent 2 can run at the same time without stepping on each other. But the same isolation means every handoff is a lossy compression step, whether anyone designed it that way on purpose or not.
Unlike human agents who carry context across interactions, most LLMs effectively "reset" at each step.
Source: Salesforce AI Research
The workaround everyone reaches for
Most orchestration setups solve this the same way: a human, or an orchestrating agent, writes everything important into the prompt for the next stage. Thread the file list through. Paste the findings into the next agent's instructions. Write a scratch file and tell the next stage to go read it.
That works, until it does not scale:
- The orchestrator has to know in advance what the next agent will need, which means predicting the future.
- Every new stage means re-threading more state through more prompts.
- Findings that do not obviously matter yet get dropped, then matter three stages later when nobody is carrying them anymore.
You end up doing manually, per pipeline, per run, the exact thing a memory system is supposed to do automatically.
Here is roughly what that manual threading looks like in code, using this project's own workflow orchestration as the example:
// The "everyone reaches for this" pattern: the orchestrator has to
// pre-guess what agent 3 will need from agent 1, and pass it through
// agent 2 by hand.
const findings = await agent('Research how the auth flow works')
const docs = await agent(`Write docs. Known context: ${findings}`)
const review = await agent(`Review this doc: ${docs}. Original findings: ${findings}`)Every arrow in that chain is a human (or an orchestrator standing in for one) deciding what's worth keeping alive. Miss one caveat in findings and it is gone for good by the time review runs, no matter how relevant it turns out to be.
This is the exact gap Empirical's memory tools are built for: a place any agent in a pipeline can write to, that any other agent can query, without an orchestrator predicting the future.
Give your agents a shared memory
What this actually calls for
The fix is not "make the agents smarter." It is giving them somewhere to put what they learn that is not the return value of a function call.
A shared memory layer that any agent in a pipeline can write to, and any other agent can query, removes the prediction problem. Agent 1 does not need to guess what agent 3 will need three stages later. It just records what it found. Agent 3 queries for what is relevant to its own task instead of depending on a summary that already passed through two lossy hops.
// Same pipeline, but agent 1 writes what it finds instead of hoping
// it survives the handoff, and agent 3 asks for what it needs instead
// of depending on what agent 2 remembered to pass along.
await agent('Research how the auth flow works, save findings via record_graph_memory')
await agent('Write docs for the auth flow, query_memories first for context')
await agent('Review the auth docs, query_memories for the original research findings')Same shape of pipeline. The difference is that nothing has to guess what the next stage needs in advance, because the next stage can just ask.
Agent 1 · research
- reads 5 files
- finds 3 caveats
- writes all 3 to memory
Agent 2 · write
- queries memory
- gets what it needs
- writes complete docs
Agent 3 · review
- queries the same memory
- sees all 3 caveats too
- reviews with full context
This is the same problem Empirical already solves for one person moving between ChatGPT, Claude, and a terminal: the tool changes, the context should not have to restart. A multi-agent pipeline is that same problem on a faster clock. The "tool" changes every time control passes to the next agent, and right now, the context restarts every single time that happens.
Proof: two agents that never talked to each other
Everything above is architecture talk until you actually run it. So here it is, unedited, from this project's own CLI. Two commands, run as two completely separate processes, standing in for agent 1 and agent 3 from the pipeline above. Agent 3's process has no conversation history with agent 1 at all, same as a fresh subagent would.
Agent 1 records a finding:
$ empirical memory record --category project \
--summary "The auth flow uses short-lived JWTs (15min) with a refresh \
token rotated on every use, and we deliberately rejected long-lived \
access tokens after a real incident where a leaked token stayed \
valid for 9 days." --tags empirical-demo-agent-memory
{"id":"6a8dd043cf480a6e74493eab", ...
"summary":"The auth flow uses short-lived JWTs (15min) with a refresh
token rotated on every use, and we deliberately rejected long-lived
access tokens after a real incident where a leaked token stayed
valid for 9 days.", ...}Agent 3, a separate process with zero shared context, queries for it:
$ empirical memory query --match "auth flow token" --tags empirical-demo-agent-memory --top-k 1
[{"id":"6a8dd043cf480a6e74493eab",
"summary":"The auth flow uses short-lived JWTs (15min) with a refresh
token rotated on every use, and we deliberately rejected long-lived
access tokens after a real incident where a leaked token stayed
valid for 9 days.", ...}]That is the whole trick. Not a bigger model, not a cleverer prompt. A place to put what agent 1 learned that agent 3 can reach without agent 1 ever knowing agent 3 exists.
Run it yourself: the exact two scripts above, ready to run against your own account, are in empirical-agent-memory-demo.
What we don't know yet
This is a real architectural gap, not a solved problem with a case study attached. The demo above proves the mechanism works, it does not prove it improves outcomes at scale. We have not published benchmarks measuring how much a shared memory layer actually improves multi-agent pipeline quality versus careful manual handoffs, and CRMArena-Pro's numbers are about single-model multi-turn tasks, not multi-agent pipelines specifically, so that comparison earlier is directional, not a citation for our own claim. That is the honest next step: run a real pipeline both ways and publish what actually changes, not just the shape of the argument.
If you are building multi-agent pipelines and hitting this exact wall, that is the conversation worth having.
Stop re-threading context by hand.
Any agent in a pipeline can call record_graph_memory and query_memories through Empirical's MCP tools. No orchestrator has to predict what the next stage needs.