The shared-context problem
The default way multi-agent systems share context is the prompt. Agent A finishes, you take what it produced, and you paste it into agent B's input. It works for two agents and one hop. It stops working the moment you have a chain: the context grows with every hand-off, you can't query it after the fact, and there is no boundary between what agent B should see and what it shouldn't. The "shared state" is a string that keeps getting longer and that every agent in the chain can read in full.
AgentCore Memory offers a different mechanism, and it's worth being precise about what it is. Agents don't message each other's memory. They write to and read from one shared memory store, and records are organized by namespace. An agent retrieves by naming a namespace prefix; it gets back only what lives under that prefix. The namespace is the sharing boundary and the isolation boundary at the same time — which is the whole idea, and also where the interesting failure mode lives.
I wanted to prove three things on live infrastructure: (1) a writer agent can deposit context that a reader agent recovers without that context being in the reader's prompt, (2) the recovery is by namespace, not by passing a session id or the text around, and (3) a second actor's namespace sees none of it. I built a minimal multi-agent system to test this.
The setup: one store, two agents, three actors
I modelled a real support workflow. A classifier agent (the "writer") stores a ticket determination under a shared actor namespace. A specialist agent (the "reader") queries that namespace and should recover the determination. A third actor — a different tenant — gets its own unrelated ticket, and a query scoped to its namespace must come back empty.
All three run against the same memory resource with the SEMANTIC strategy. The SEMANTIC strategy's namespace template is:
/strategies/{memoryStrategyId}/actors/{actorId}/
That template matters more than it looks, and I'll come back to why.
The classifier stores a short exchange: a customer posing a two-part incident, and the classifier's determination.
USER: Customer Contoso reports two problems at once: a billing
double-charge and a production API-key authentication failure.
Are these one incident or two separate tickets, and who should own it?
ASSISTANT: Ticket classification: TIER-2 ESCALATION. The billing
double-charge and the production API-key auth failure share a
root cause: an identity-service outage. Treat as a single
multi-system incident, not two tickets. Recommended owner: the
named technical account manager.
The specialist never receives that text. It asks a question — "What is the escalation tier and owner for the Contoso multi-system incident?" — against the shared actor's namespace, and semantic retrieval is left to find the answer.
What happened
The specialist recovered the context on the first poll after extraction. Scoped to the shared actor's namespace, its query came back with a single record — a distilled summary of the incident (Contoso, the billing problem, the API-key auth failure) that the classifier had stored, with the incident text never in the specialist's prompt. The same query scoped to the decoy tenant's namespace returned zero records. Verdict: the specialist recovered the classifier's context by namespace, and it did not leak to the other actor.
Two things to be honest about in that record. First, what came back is the extracted fact — the durable summary of the incident — not the verbatim "TIER-2" label. That is what SEMANTIC does: it distills the conversation into a retrievable fact, and the fact carries the substance a specialist needs (the two simultaneous failures, the customer, the amount) so it doesn't re-derive the situation from scratch. If you need the literal label preserved word-for-word, semantic retrieval is the wrong strategy; a summarization strategy or an exact-record write is. Second, the isolation result is the quiet win: the decoy tenant's namespace returned zero, not "a low-scoring match." The boundary is structural, not a ranking threshold you hope holds.
This lines up with what AWS documents. The namespace-design guidance is explicit that retrieve_memory_records "Returns ONLY records stored at" the given namespace, and that namespaces give you "clean isolation between users, and IAM-based access control." The specification docs go further: you can write IAM policies that restrict retrieval by actor, session, and namespace scope, using those scopes as condition keys. So the isolation I observed at the API level can be enforced at the IAM level too — the application-level scoping and the identity-level policy reinforce each other.
The failure mode that cost me two runs
The first two times I ran this, the specialist got zero records and it looked like a broken feature. It wasn't. The classifier had stored a single lone ASSISTANT message — the determination, by itself. SEMANTIC extraction produced nothing from it, waited out, and I very nearly wrote "namespaced sharing doesn't work."
The fix, and the finding: SEMANTIC extracts facts from a conversation, not from a statement. The working semantic runs earlier always wrote alternating USER/ASSISTANT turns — a real exchange. When I changed the classifier to store the incident as a two-turn exchange (the customer's problem, then the classifier's determination), extraction produced a record within about 60 seconds and the specialist recovered it on the first poll. One message in, nothing out; a turn pair in, a clean fact out.
This is the same shape of trap that single-agent memory hits from a different angle: the feature is fine, but if you feed it the wrong input shape or query the wrong namespace, it hands you zero records and lets you believe it's broken. Two rules fall out of it:
- Write conversations, not lines. If you want SEMANTIC to extract something, give it a turn it can extract from. A determination with no surrounding exchange is not something it will summarize into a durable fact.
-
Build the namespace from the strategy's real template. Querying
/actors/{id}/when the strategy writes to/strategies/{strategyId}/actors/{id}/returns zero and looks identical to "extraction failed." Read the template off the resource; don't assume it.
The namespace design that makes this composable
The pattern that scales isn't "everyone shares one namespace." It's deliberate separation by actor:
- A system/shared actor — for facts that many agents legitimately share (a ticket classification, a research finding, a computed result). Any agent scoped to that actor can read it.
-
A per-user actor (keyed by, say, the caller's JWT
sub) — for context that must never bleed across users.
System facts don't pollute per-user recall, and user facts don't leak across accounts, because they live under different namespaces and retrieval is prefix-scoped. That's the same reasoning AWS's namespace-design guidance gives: treat it like a key schema or an object-storage prefix layout, and design the access patterns up front. This experiment is the minimal proof of the mechanism underneath that design — write under one actor, read it back by namespace, and confirm a different actor sees nothing.
So what
Shared memory across agents is real and it's clean: the specialist recovered the classifier's context by namespace with nothing passed in its prompt, and the isolation boundary returned a hard zero rather than a hopeful low score. That's a genuinely better primitive than prompt-stuffing — it's queryable, it's bounded, and the boundary can be backed by IAM.
The practical finding is the input contract. Semantic sharing works when you write a conversation and query the strategy's real namespace; it silently returns nothing when you write a lone message or guess the namespace prefix. Both mistakes look exactly like a broken feature and neither is. Design for the contract — turn pairs in, correct namespace out — and one memory store becomes the shared context layer a multi-agent system actually needs.
The thing I haven't fully solved: semantic extraction needs a real conversation to extract from. A single message in isolation — even if it's the exact determination the next agent needs — returns zero records and forces you to either feed it a fake exchange or fall back to prompt-stuffing. That's the honest limitation of the approach, and it's the whole reason this post exists.
Part of a series on Amazon Bedrock AgentCore. This post follows AgentCore Memory: What an Agent Remembers When the Session Is Gone — that post covers single-agent memory recovery across sessions; this one extends it to multi-agent sharing with namespace isolation.
Top comments (0)