AWS Builder Center
Cross-Agent Semantic Memory for Continuous Learning with Amazon Bedrock AgentCore

Cross-Agent Semantic Memory for Continuous Learning with Amazon Bedrock AgentCore

Learn how to architect shared semantic memory across multiple AI agents using Amazon Bedrock AgentCore Memory. This post covers namespace design patterns, memory strategies (semantic, preference, summary), and continuous learning loops that let specialized agents — sales, support, recommendations — share customer knowledge without custom synchronization infrastructure.

Introduction

Modern enterprise AI systems rarely rely on a single agent. Organizations deploy specialized agents for sales, customer support, billing, recommendations, and more — each handling a distinct domain. But when these agents operate in isolation, customers experience fragmented interactions: repeating preferences, re-explaining context, and receiving inconsistent responses across touchpoints.
Amazon Bedrock AgentCore Memory solves this by providing a fully managed memory layer that enables multiple agents to share semantic knowledge, learn continuously from interactions, and deliver coherent, personalized experiences across an entire agent ecosystem.
In this post, we explore how to architect cross-agent semantic memory using AgentCore Memory's namespace system and memory strategies, enabling continuous learning that spans agent boundaries.

The problem: Siloed agent knowledge

Consider a typical enterprise with multiple AI agents:
  • A Sales Agent that helps customers discover products
  • A Support Agent that resolves issues and handles returns
  • A Recommendations Agent that suggests relevant products
  • An Onboarding Agent that guides new customers through setup
Without shared memory, each agent starts every interaction from zero. The Support Agent doesn't know what the Sales Agent discussed. The Recommendations Agent can't leverage preferences expressed during support conversations. Customers repeat themselves, and the experience feels disconnected.
Traditional approaches to solving this — shared databases, event buses, or custom RAG pipelines — require significant engineering effort and ongoing maintenance. They also typically store raw conversation logs rather than extracted semantic knowledge, resulting in noisy retrieval and high token consumption.

Solution overview: Shared semantic memory with AgentCore

AgentCore Memory provides the building blocks for cross-agent knowledge sharing through three key mechanisms:
  1. Hierarchical namespaces — Logical paths that organize memories and control access across agents
  2. Memory strategies — Configurable extraction pipelines that transform raw conversations into structured knowledge
  3. Semantic retrieval — Meaning-based search across the shared memory store
The architecture looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────┐ ┌─────────────┐ ┌──────────────────┐
│ Sales Agent │ │Support Agent│ │Recommendations │
│ │ │ │ │Agent │
└──────┬──────┘ └──────┬──────┘ └────────┬─────────┘
│ │ │
│ Write/Read │ Write/Read │ Read
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ AgentCore Memory (Shared Store) │
│ │
│ /org-123/customer-{actorId}/preferences/ │
│ /org-123/customer-{actorId}/facts/ │
│ /org-123/customer-{actorId}/interactions/{sessionId}/ │
└─────────────────────────────────────────────────────────────┘
All agents read from and write to the same memory resource, organized by customer-scoped namespaces. The semantic extraction ensures only meaningful knowledge is persisted, not raw conversation logs.

Implementation walkthrough

Step 1: Create a shared memory resource

First, create a single memory resource that all agents will share. Define memory strategies that extract the types of knowledge relevant across your agent ecosystem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import boto3
import time

# AgentCore uses a split-plane model:
# - Control plane client for resource management (create/update/delete memory)
# - Data plane client for runtime operations (create events, retrieve records)
control_client = boto3.client("bedrock-agentcore-control")
data_client = boto3.client("bedrock-agentcore")

response = control_client.create_memory(
name="CrossAgentCustomerMemory",
description="Shared memory store for all customer-facing agents",
eventExpiryDuration=90, # Retain raw events for 90 days
memoryStrategies=[
{
"semanticMemoryStrategy": {
"name": "customer_facts",
"namespaceTemplates": ["/org-123/customer-{actorId}/facts/"]
}
},
{
"userPreferenceMemoryStrategy": {
"name": "customer_preferences",
"namespaceTemplates": ["/org-123/customer-{actorId}/preferences/"]
}
},
{
"summaryMemoryStrategy": {
"name": "interaction_summaries",
"namespaceTemplates": [
"/org-123/customer-{actorId}/interactions/{sessionId}/"
]
}
}
]
)

memory_id = response["memory"]["id"]
print(f"Created shared memory resource: {memory_id}")

# Wait for the memory resource to become ACTIVE before use
while True:
mem_status = control_client.get_memory(memoryId=memory_id)
status = mem_status["memory"]["status"]
if status == "ACTIVE":
print("Memory resource is now ACTIVE.")
break
elif status == "FAILED":
raise Exception("Memory resource creation FAILED.")
print("Waiting for memory to become active...")
time.sleep(10)
The namespace template uses {actorId} and {sessionId} placeholders that are dynamically resolved when events are ingested. This ensures memories are automatically scoped to the correct customer without hardcoding identifiers.

Step 2: Ingest events from multiple agents

Each agent writes conversation events to the shared memory resource. The key design decision is the actorId — use a consistent customer identifier across all agents so their memories land in the same namespace.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from datetime import datetime

def store_agent_event(memory_id, customer_id, session_id, role, message):
"""Store a conversation event from any agent."""
data_client.create_event(
memoryId=memory_id,
actorId=customer_id, # Consistent customer ID across agents
sessionId=session_id,
eventTimestamp=datetime.now(),
payload=[
{
"conversational": {
"content": {"text": message},
"role": role
}
}
]
)

# Sales Agent conversation
store_agent_event(
memory_id=memory_id,
customer_id="customer-456",
session_id="sales-session-001",
role="USER",
message="I'm looking for a waterproof camera under $500 for scuba diving in Bali next month."
)

store_agent_event(
memory_id=memory_id,
customer_id="customer-456",
session_id="sales-session-001",
role="ASSISTANT",
message="I'd recommend the AquaShot Pro X200. It's rated to 40m depth and costs $449."
)

# Support Agent conversation (different session, same customer)
store_agent_event(
memory_id=memory_id,
customer_id="customer-456",
session_id="support-session-002",
role="USER",
message="The camera I ordered last week hasn't shipped yet. Order #ORD-7891."
)
After these events are stored, AgentCore Memory asynchronously extracts long-term memories:
  • Facts extracted: "Customer is planning a scuba diving trip to Bali", "Customer ordered AquaShot Pro X200", "Order number is ORD-7891"
  • Preferences extracted: "Budget up to $500 for camera equipment", "Interested in underwater photography"

Step 3: Retrieve shared memories from any agent

Any agent in the ecosystem can now query the shared memory to get context about a customer before or during a conversation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def get_customer_context(memory_id, customer_id, query):
"""Retrieve relevant memories for a customer from the shared store."""

# Get preferences
preferences = data_client.retrieve_memory_records(
memoryId=memory_id,
namespace=f"/org-123/customer-{customer_id}/preferences/",
searchCriteria={
"searchQuery": query,
"topK": 5
}
)

# Get facts
facts = data_client.retrieve_memory_records(
memoryId=memory_id,
namespace=f"/org-123/customer-{customer_id}/facts/",
searchCriteria={
"searchQuery": query,
"topK": 5
}
)

return {
"preferences": preferences.get("memoryRecordSummaries", []),
"facts": facts.get("memoryRecordSummaries", [])
}

# Recommendations Agent retrieves context it never directly collected
context = get_customer_context(
memory_id=memory_id,
customer_id="customer-456",
query="What products would interest this customer?"
)

# Returns preferences about underwater photography, $500 budget,
# and facts about the Bali diving trip — all learned from other agents

Step 4: Build the continuous learning loop

The continuous learning aspect comes from the consolidation pipeline. As new interactions happen, AgentCore Memory automatically:
  1. Extracts new memories from fresh conversations
  2. Compares them semantically against existing memories
  3. Resolves conflicts (newer information takes priority)
  4. Merges related memories to reduce redundancy
1
2
3
4
5
6
7
8
9
10
11
12
13
# Two weeks later — customer updates their preferences via Support Agent
store_agent_event(
memory_id=memory_id,
customer_id="customer-456",
session_id="support-session-003",
role="USER",
message="I actually decided to increase my budget to $800. Can you help me upgrade my order?"
)

# The consolidation process automatically:
# - Detects conflict: old memory says "$500 budget", new info says "$800"
# - Updates the preference record to reflect "$800 budget"
# - All agents now see the updated budget on next retrieval
No manual intervention required. The memory system evolves with every interaction.

Designing namespace strategies for multi-agent systems

The namespace hierarchy is the most critical design decision for cross-agent memory. Here are patterns that work well:

Pattern 1: Customer-centric (recommended for most use cases)

1
2
3
/org-{orgId}/customer-{customerId}/preferences/
/org-{orgId}/customer-{customerId}/facts/
/org-{orgId}/customer-{customerId}/interactions/{sessionId}/
All agents share a single view of the customer. Best for B2C applications where personalization is the primary goal.

Pattern 2: Domain-scoped with cross-references

1
2
3
/org-{orgId}/sales/customer-{customerId}/
/org-{orgId}/support/customer-{customerId}/
/org-{orgId}/shared/customer-{customerId}/preferences/
Each agent has its own namespace for domain-specific memories, plus a shared namespace for cross-cutting knowledge. Best when agents need both private and shared context.

Pattern 3: Multi-tenant with agent isolation

1
2
/tenant-{tenantId}/customer-{customerId}/agent-{agentId}/
/tenant-{tenantId}/customer-{customerId}/shared/
Useful in SaaS platforms where tenant isolation is required but agents within a tenant should collaborate.

Best practices

Use consistent actor IDs across agents. The actorId is the key that ties memories together. Use a stable customer identifier (not session-specific IDs) so all agents contribute to and read from the same memory namespace.
Follow naming constraints. Memory names and strategy names must match the pattern [a-zA-Z][a-zA-Z0-9_]{0,47}. Use underscores instead of hyphens — customer_facts works, customer-facts does not.
Use separate clients for control and data operations. AgentCore uses a split-plane model: bedrock-agentcore-control for resource management (create/update/delete memory) and bedrock-agentcore for runtime operations (create events, retrieve records).
Design namespace templates before building agents. The namespace structure determines what's shared and what's isolated. Plan this upfront as changing it later requires migrating existing memories.
Account for extraction latency. Long-term memory extraction is asynchronous. If Agent B needs to read memories written by Agent A moments ago, combine short-term event retrieval (synchronous) with long-term memory retrieval for complete context.
Use semantic strategy for cross-agent facts, preference strategy for personalization. Semantic memory captures objective facts ("customer has 3 office locations"). Preference memory captures subjective choices ("prefers email over phone"). Both are valuable for cross-agent sharing but serve different retrieval needs.
Implement namespace-level access control for sensitive domains. Not all agents should read all memories. A billing agent might write payment-related facts to a restricted namespace that the recommendations agent cannot access.
Monitor consolidation patterns. Use AgentCore Observability to track how memories are being merged and updated. Frequent conflicts in a namespace might indicate that your extraction strategy needs tuning.

Conclusion

Cross-agent semantic memory lets a collection of independent AI agents operate as a cohesive, learning system. Amazon Bedrock AgentCore Memory's namespace hierarchy, semantic extraction strategies, and automatic consolidation enable multi-agent architectures where knowledge flows between agents. The entire system gets smarter with every customer interaction.
You don't need to build custom synchronization logic between agents. AgentCore Memory's shared namespace model means any agent that writes a meaningful interaction automatically enriches the knowledge available to every other agent in the ecosystem.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article