Shared Archival Memory: Multi-Agent Knowledge Bases (Tutorial)

Shared Archival Memory: Multi-Agent Knowledge Bases

Status: Available on Letta Cloud (November 2025)
Coming to self-hosted: Soon

Shared archives allow multiple agents to read from and write to the same external knowledge base. This is perfect for multi-agent systems where agents need to collaborate on shared knowledge.

Key Concepts

Archives vs Memory Blocks:

  • Memory blocks: In-context, always visible to the agent
  • Archives: Out-of-context, retrieved via archival_memory_search

Sharing pattern:

  • Attach the same archive_id to multiple agents
  • All agents can insert and search the shared archive
  • Changes are immediately visible to all agents

Tutorial: Building a Research Team

Let’s build a system where multiple agents collaborate on research by sharing findings in a common archive.

Step 1: Create a Shared Archive

from letta_client import Letta

client = Letta(token="your_letta_api_key")

# Create shared archive
research_archive = client.archives.create(
    name="research_findings",
    description="Shared knowledge base for research team",
    embedding_config={
        "embedding_endpoint_type": "openai",
        "embedding_model": "text-embedding-ada-002",
        "embedding_dim": 1536,
        "embedding_chunk_size": 300
    }
)

print(f"Created archive: {research_archive.id}")

Step 2: Create Research Agents

# Research Agent 1: Literature Review Specialist
literature_agent = client.agents.create(
    name="literature_reviewer",
    system="You are a literature review specialist. "
           "When you find important research findings, store them in archival memory.",
    memory_blocks=[
        client.blocks.create(
            label="persona",
            value="I specialize in reviewing academic papers and extracting key findings."
        )
    ],
    tool_ids=[
        # Get archival memory tool IDs
        *[t.id for t in client.tools.list() if t.name in [
            "archival_memory_insert",
            "archival_memory_search"
        ]]
    ]
)

# Research Agent 2: Data Analysis Specialist
data_agent = client.agents.create(
    name="data_analyst",
    system="You are a data analysis specialist. "
           "Search archival memory for relevant research before answering questions.",
    memory_blocks=[
        client.blocks.create(
            label="persona",
            value="I analyze data and synthesize findings from the research archive."
        )
    ],
    tool_ids=[
        *[t.id for t in client.tools.list() if t.name in [
            "archival_memory_insert",
            "archival_memory_search"
        ]]
    ]
)

print(f"Created agents: {literature_agent.id}, {data_agent.id}")

Step 3: Attach Shared Archive to Both Agents

# Attach archive to literature agent
client.agents.archives.attach(
    agent_id=literature_agent.id,
    archive_id=research_archive.id
)

# Attach same archive to data agent
client.agents.archives.attach(
    agent_id=data_agent.id,
    archive_id=research_archive.id
)

print("Shared archive attached to both agents")

Step 4: Test Shared Knowledge

# Agent 1 stores a finding
lit_response = client.agents.messages.create(
    agent_id=literature_agent.id,
    messages=[{
        "role": "user",
        "content": "I found an important study: 'Memory systems in AI show 40% improvement "
                   "with hierarchical organization (Smith et al., 2024)'. Store this finding."
    }]
)

print("Literature agent stored finding")

# Agent 2 searches for it
data_response = client.agents.messages.create(
    agent_id=data_agent.id,
    messages=[{
        "role": "user",
        "content": "What research findings do we have about memory system improvements?"
    }]
)

print("Data agent retrieved shared knowledge:")
for msg in data_response.messages:
    if msg.role == "assistant":
        print(msg.content)

Use Cases

1. Customer Support Team

Multiple support agents share a knowledge base of solutions:

support_archive = client.archives.create(
    name="support_solutions",
    description="Shared database of customer issues and resolutions"
)

# Attach to all support agents
for agent in support_agents:
    client.agents.archives.attach(
        agent_id=agent.id,
        archive_id=support_archive.id
    )

2. Worker → Supervisor Pattern

Workers collect data, supervisor synthesizes:

# Workers write to shared archive
worker_message = "Store this sales data: Q4 revenue increased 15% YoY"

# Supervisor reads from same archive
supervisor_query = "Summarize all sales trends from worker reports"

3. Multi-Domain Experts

Specialists contribute to shared knowledge:

domains = ["legal", "technical", "financial"]

# Each specialist writes domain-specific insights to shared archive
# Generalist agent searches across all domains for comprehensive answers

Checking Archive Attachments

# List all archives for an agent
archives = client.archives.list(agent_id=literature_agent.id)

for archive in archives:
    print(f"Archive: {archive.name} ({archive.id})")
    
# List all agents using an archive
agents_using_archive = client.agents.list(archive_id=research_archive.id)

Important Notes

  1. Tool attachment required: Agents need archival_memory_insert and archival_memory_search tools
  2. Embedding consistency: All agents sharing an archive must use compatible embeddings
  3. Immediate updates: Changes are visible to all agents without delay
  4. Search scope: Agents can only search their attached archives

Detaching Archives

# Remove archive from an agent
client.agents.archives.detach(
    agent_id=data_agent.id,
    archive_id=research_archive.id
)

Questions or Issues?

Reply to this thread with:

  • What you’re building with shared archives
  • Issues you encounter
  • Feature requests

This is a new feature - your feedback helps shape it!

You’ll need to re-write this. You used the embedding configuration which is only available on self-hosted, but this feature is only available on Letta Cloud.

Good catch - fixing now. Here’s the corrected version for Letta Cloud:


Shared Archival Memory: Multi-Agent Knowledge Bases (Cloud)

Status: Available on Letta Cloud (November 2025)

Tutorial: Building a Research Team

Step 1: Create a Shared Archive (Cloud)

from letta_client import Letta

client = Letta(token="your_letta_api_key")

# Create shared archive - Cloud handles embedding config automatically
research_archive = client.archives.create(
    name="research_findings",
    description="Shared knowledge base for research team"
)

print(f"Created archive: {research_archive.id}")

Step 2: Create Research Agents

# Research Agent 1: Literature Review Specialist
literature_agent = client.agents.create(
    name="literature_reviewer",
    system="You are a literature review specialist. "
           "When you find important research findings, store them in archival memory.",
    memory_blocks=[
        client.blocks.create(
            label="persona",
            value="I specialize in reviewing academic papers and extracting key findings."
        )
    ]
)

# Research Agent 2: Data Analysis Specialist
data_agent = client.agents.create(
    name="data_analyst",
    system="You are a data analysis specialist. "
           "Search archival memory for relevant research before answering questions.",
    memory_blocks=[
        client.blocks.create(
            label="persona",
            value="I analyze data and synthesize findings from the research archive."
        )
    ]
)

print(f"Created agents: {literature_agent.id}, {data_agent.id}")

Note: Agents automatically have access to archival memory tools on Cloud - no manual tool attachment needed.

Step 3: Attach Shared Archive to Both Agents

# Attach archive to literature agent
client.agents.archives.attach(
    agent_id=literature_agent.id,
    archive_id=research_archive.id
)

# Attach same archive to data agent
client.agents.archives.attach(
    agent_id=data_agent.id,
    archive_id=research_archive.id
)

print("Shared archive attached to both agents")

Step 4: Test Shared Knowledge

# Agent 1 stores a finding
lit_response = client.agents.messages.create(
    agent_id=literature_agent.id,
    messages=[{
        "role": "user",
        "content": "I found an important study: 'Memory systems in AI show 40% improvement "
                   "with hierarchical organization (Smith et al., 2024)'. Store this finding."
    }]
)

print("Literature agent stored finding")

# Agent 2 searches for it
data_response = client.agents.messages.create(
    agent_id=data_agent.id,
    messages=[{
        "role": "user",
        "content": "What research findings do we have about memory system improvements?"
    }]
)

print("Data agent retrieved shared knowledge:")
for msg in data_response.messages:
    if msg.role == "assistant":
        print(msg.content)

Key Differences: Cloud vs Self-Hosted

Feature Letta Cloud Self-Hosted
Embedding config Automatic Manual specification required
Archive sharing :white_check_mark: Available now Coming soon
Tool attachment Automatic May need manual attachment

The rest of the use cases (customer support, worker/supervisor, multi-domain) work the same way - just use the simplified Cloud archive creation pattern above.

Could we do this in typescript?

Yes! The TypeScript SDK supports shared archival memory.

Here’s the tutorial translated to TypeScript:

Step 1: Create a Shared Archive

import { Letta } from '@letta-ai/letta-client';

const client = new Letta({
  apiKey: 'your_letta_api_key'
});

// Create shared archive
const researchArchive = await client.archives.create({
  name: 'research_findings',
  description: 'Shared knowledge base for research team',
  embeddingConfig: {
    embeddingEndpointType: 'openai',
    embeddingModel: 'text-embedding-ada-002',
    embeddingDim: 1536,
    embeddingChunkSize: 300
  }
});

console.log(`Created archive: ${researchArchive.id}`);

Step 2: Create Research Agents

// Get archival memory tool IDs
const tools = await client.tools.list();
const archivalTools = tools.filter(t => 
  ['archival_memory_insert', 'archival_memory_search'].includes(t.name)
);

// Create persona block
const personaBlock1 = await client.blocks.create({
  label: 'persona',
  value: 'I specialize in reviewing academic papers and extracting key findings.'
});

// Research Agent 1: Literature Review Specialist
const literatureAgent = await client.agents.create({
  name: 'literature_reviewer',
  system: 'You are a literature review specialist. When you find important research findings, store them in archival memory.',
  blockIds: [personaBlock1.id],
  toolIds: archivalTools.map(t => t.id)
});

// Research Agent 2: Data Analysis Specialist
const personaBlock2 = await client.blocks.create({
  label: 'persona',
  value: 'I analyze data and synthesize findings from the research archive.'
});

const dataAgent = await client.agents.create({
  name: 'data_analyst',
  system: 'You are a data analysis specialist. Search archival memory for relevant research before answering questions.',
  blockIds: [personaBlock2.id],
  toolIds: archivalTools.map(t => t.id)
});

console.log(`Created agents: ${literatureAgent.id}, ${dataAgent.id}`);

Step 3: Attach Shared Archive

// Attach archive to both agents
await client.agents.archives.attach({
  agentId: literatureAgent.id,
  archiveId: researchArchive.id
});

await client.agents.archives.attach({
  agentId: dataAgent.id,
  archiveId: researchArchive.id
});

console.log('Shared archive attached to both agents');

Step 4: Test Shared Knowledge

// Agent 1 stores a finding
const litResponse = await client.agents.messages.create({
  agentId: literatureAgent.id,
  messages: [{
    role: 'user',
    content: "I found an important study: 'Memory systems in AI show 40% improvement with hierarchical organization (Smith et al., 2024)'. Store this finding."
  }]
});

console.log('Literature agent stored finding');

// Agent 2 searches for it
const dataResponse = await client.agents.messages.create({
  agentId: dataAgent.id,
  messages: [{
    role: 'user',
    content: 'What research findings do we have about memory system improvements?'
  }]
});

console.log('Data agent retrieved shared knowledge:');
dataResponse.messages
  .filter(msg => msg.role === 'assistant')
  .forEach(msg => console.log(msg.content));

Checking Archive Attachments

// List all archives for an agent
const archives = await client.archives.list({
  agentId: literatureAgent.id
});

archives.forEach(archive => {
  console.log(`Archive: ${archive.name} (${archive.id})`);
});

// List all agents using an archive
const agentsUsingArchive = await client.agents.list({
  archiveId: researchArchive.id
});

Installation

npm install @letta-ai/letta-client@alpha

The TypeScript SDK is currently in alpha but fully functional for shared archival memory operations!