# Multi-Agent Memory Architecture: How to Share Context Across AI Agents > Multiple AI agents sharing a single memory store need namespace isolation, typed edges for cross-agent context, and concurrent-safe read patterns. Feather DB handles all three with its entity system, graph traversal API, and in-process concurrency model. - **Category**: Theory - **Read time**: 9 min read - **Date**: July 10, 2026 - **Author**: Feather DB (Engineering) - **URL**: https://getfeather.store/theory/multi-agent-memory-architecture --- Multi-agent systems where multiple AI agents share context require three things from their memory layer: namespace isolation (agent A's private memories cannot bleed into agent B's context), typed edges for cross-agent knowledge sharing (agent A can link its findings to agent B's context explicitly), and concurrent-safe read access. Feather DB handles all three through its entity system, graph traversal API, and in-process concurrency model — multiple agents share a single `.feather` file with strong isolation guarantees and sub-millisecond concurrent reads. ## Why Multi-Agent Memory Is Different Single-agent memory is a solved problem: one agent, one memory store, query by entity ID. Multi-agent memory introduces three challenges that single-agent architectures don't face: - **Isolation:** Agent A's memories about User X must not appear in Agent B's context for the same user. A support agent's private diagnostic notes should not surface in the sales agent's context. - **Controlled sharing:** Some information should cross agent boundaries. A research agent's findings should be accessible to the report-writing agent. A data-gathering agent should be able to share context with an analysis agent. - **Concurrency:** Multiple agents querying the same store simultaneously must not corrupt each other's reads or produce inconsistent results. Feather DB addresses all three with a namespace + entity model, typed edges for explicit sharing, and a reader-writer locking model that allows concurrent reads with exclusive writes. ## Namespace Model: Isolation by Design Every memory in Feather DB has metadata fields. The multi-agent isolation pattern uses two fields: `user_id` (who this memory is about) and `agent_id` (which agent owns this memory). Shared memories omit the `agent_id` field and are accessible to all agents. ``` import feather_db as fdb from datetime import datetime # Shared memory store for all agents db = fdb.FeatherDB("multi_agent_memory.feather") def store_agent_memory( text: str, user_id: str, agent_id: str, importance: float = 0.6, shared: bool = False ) -> str: """ Store a memory with namespace isolation. If shared=True, omit agent_id so all agents can access it. """ metadata = { "user_id": user_id, "stored_at": datetime.now().isoformat(), "shared": shared } if not shared: metadata["agent_id"] = agent_id return db.add( text=text, metadata=metadata, importance=importance ) def recall_agent_context( query: str, user_id: str, agent_id: str, include_shared: bool = True, top_k: int = 8 ) -> list: """ Retrieve memories for a specific agent. By default, includes both private agent memories and shared memories. """ results = [] # Agent-private memories private_memories = db.search( query=query, top_k=top_k // 2, filters={"user_id": user_id, "agent_id": agent_id} ) results.extend(private_memories) if include_shared: # Shared memories (accessible to all agents) shared_memories = db.search( query=query, top_k=top_k // 2, filters={"user_id": user_id, "shared": True} ) results.extend(shared_memories) # Re-rank combined results by score results.sort(key=lambda x: x['score'], reverse=True) return results[:top_k] ``` ## Cross-Agent Context Sharing with Typed Edges When Agent A discovers something that Agent B should know, the recommended pattern is not to copy the memory — it is to link it. Feather DB's typed edges allow Agent A to create a link from its memory to Agent B's context namespace, without duplicating data: ``` # Agent A (research agent) stores a finding research_agent_id = "research_agent" analysis_agent_id = "analysis_agent" research_finding_id = store_agent_memory( text="User's customer churn rate increased 23% in Q2 2026, primarily from the enterprise tier", user_id="client_acme", agent_id=research_agent_id, importance=0.9, shared=False # Private to research agent initially ) # Research agent decides to share this with the analysis agent shared_context_id = store_agent_memory( text="[Shared from research] ACME churn: +23% Q2 2026, enterprise tier dominant driver", user_id="client_acme", agent_id=analysis_agent_id, importance=0.9, shared=False # Private to analysis agent ) # Link the shared copy to the original for provenance db.link_nodes( source_id=shared_context_id, target_id=research_finding_id, edge_type="derived_from", weight=1.0 ) # When analysis agent retrieves context, it gets the shared copy # and can traverse to the original finding via context_chain() analysis_context = db.context_chain( query="ACME churn data", hops=2, filters={"user_id": "client_acme", "agent_id": analysis_agent_id} ) # Returns: the shared copy + the original finding (via derived_from edge) ``` ## Complete Multi-Agent System: 4-Agent Pipeline Here is a complete 4-agent system where agents specialize in research, analysis, writing, and review — sharing context through Feather DB: ``` import feather_db as fdb from openai import OpenAI from dataclasses import dataclass from typing import Optional db = fdb.FeatherDB("pipeline_memory.feather") client = OpenAI() @dataclass class Agent: agent_id: str role: str system_prompt: str def recall(self, query: str, user_id: str, top_k: int = 8) -> list: """Recall memories accessible to this agent.""" private = db.search( query=query, top_k=top_k // 2, filters={"user_id": user_id, "agent_id": self.agent_id} ) shared = db.search( query=query, top_k=top_k // 2, filters={"user_id": user_id, "shared": True} ) combined = sorted(private + shared, key=lambda x: x['score'], reverse=True) return combined[:top_k] def remember(self, text: str, user_id: str, importance: float = 0.7, shared: bool = False) -> str: """Store a memory from this agent.""" metadata = { "user_id": user_id, "agent_id": self.agent_id, "stored_at": __import__('datetime').datetime.now().isoformat(), "shared": shared } return db.add(text=text, metadata=metadata, importance=importance) def run(self, task: str, user_id: str) -> str: """Execute the agent's task with memory context.""" memories = self.recall(task, user_id) context = "\n".join([f"- {m['text']}" for m in memories]) response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": f"{self.system_prompt}\n\nContext:\n{context}"}, {"role": "user", "content": task} ] ) return response.choices[0].message.content # Define the 4-agent pipeline research_agent = Agent( agent_id="research", role="Researcher", system_prompt="You are a research agent. Gather and synthesize factual information." ) analysis_agent = Agent( agent_id="analysis", role="Analyst", system_prompt="You are an analysis agent. Identify patterns and insights from research." ) writing_agent = Agent( agent_id="writing", role="Writer", system_prompt="You are a writing agent. Produce clear, structured content from analysis." ) review_agent = Agent( agent_id="review", role="Reviewer", system_prompt="You are a review agent. Check accuracy, clarity, and completeness." ) def run_pipeline(task: str, user_id: str) -> dict: """Run the 4-agent pipeline with shared memory.""" # Step 1: Research print("Research agent running...") research_output = research_agent.run(task, user_id) research_id = research_agent.remember( f"Research findings: {research_output[:500]}", user_id=user_id, importance=0.85, shared=True # Make available to downstream agents ) # Step 2: Analysis (has access to research via shared memory) print("Analysis agent running...") analysis_output = analysis_agent.run( f"Analyze this research and extract key insights: {research_output}", user_id=user_id ) analysis_id = analysis_agent.remember( f"Analysis insights: {analysis_output[:500]}", user_id=user_id, importance=0.85, shared=True # Make available to writing agent ) # Link analysis to research for provenance db.link_nodes(analysis_id, research_id, "derived_from", 1.0) # Step 3: Writing (has access to both research and analysis) print("Writing agent running...") writing_output = writing_agent.run( f"Write a comprehensive report based on this analysis: {analysis_output}", user_id=user_id ) # Step 4: Review print("Review agent running...") review_output = review_agent.run( f"Review this draft for accuracy and completeness: {writing_output}", user_id=user_id ) return { "research": research_output, "analysis": analysis_output, "draft": writing_output, "review": review_output } ``` ## Concurrency Model: Concurrent Reads, Safe Writes Multiple agents running simultaneously will query Feather DB concurrently. Feather DB uses a reader-writer locking model: - **Concurrent reads:** Any number of agents can read simultaneously without blocking each other. A 0.19ms read does not block while 10 other reads are in progress. - **Exclusive writes:** Writes acquire an exclusive lock. If Agent A and Agent B both write simultaneously, one waits (typically under 1ms). For most agent pipelines, this is not a bottleneck — reads dominate writes by 10:1 or more. - **Single-file model:** For extremely high write concurrency (thousands of agents writing simultaneously), use Feather DB Cloud (Q3 2026) which distributes write load across nodes. ``` import threading import feather_db as fdb db = fdb.FeatherDB("concurrent_memory.feather") def simulate_concurrent_reads(n_agents: int, query: str, user_id: str): """Simulate concurrent reads from multiple agents.""" results = {} errors = [] def agent_read(agent_id: int): try: memories = db.search( query=query, top_k=5, filters={"user_id": user_id} ) results[agent_id] = len(memories) except Exception as e: errors.append(str(e)) # Launch n_agents concurrent reads threads = [threading.Thread(target=agent_read, args=(i,)) for i in range(n_agents)] for t in threads: t.start() for t in threads: t.join() print(f"{n_agents} concurrent reads: {len(results)} succeeded, {len(errors)} errors") # Output: 50 concurrent reads: 50 succeeded, 0 errors simulate_concurrent_reads(n_agents=50, query="user background", user_id="user_001") ``` ## Deployment Patterns for Multi-Agent Systems ### Pattern 1: Shared file, multiple processes All agents access the same `.feather` file. Works well for up to ~100 concurrent agents. Deploy agents as separate Python processes, point them all to the same file path. ### Pattern 2: Shard by user Each user has their own `.feather` file. All agents for user X use `memory_X.feather`. This eliminates cross-user contention entirely and makes user data deletion trivial (delete the file). ### Pattern 3: Shard by agent type Research agents use `research.feather`; writing agents use `writing.feather`. Shared context is explicitly copied (with a derived_from link) between files. Higher complexity, maximum isolation. ## FAQ ### How do I prevent one agent's memories from contaminating another agent's context? Always include `"agent_id": agent_id` in the filter for every `db.search()` call. Shared memories use `"shared": True` in their metadata and are queried with a separate `"shared": True` filter. The two filter conditions never overlap with agent-private queries. ### Can two agents write to the same memory at the same time? Feather DB's write lock ensures only one write proceeds at a time. The waiting write queues and completes as soon as the lock is released — typically under 1ms wait time. There is no data corruption from concurrent writes. ### How do agents discover what other agents have found? Two mechanisms: (1) shared memories (`"shared": True`) are accessible to all agents; (2) explicit edges (`db.link_nodes()`) allow one agent's memory to surface in another's `context_chain()` traversal via a `derived_from` or `refines` edge. ### What is the maximum number of agents that can share a single Feather DB file? Read concurrency is unlimited — any number of agents can read simultaneously. Write concurrency serializes, but with typical agent write rates (a few writes per minute per agent), a single file handles hundreds of concurrent agents without bottleneck. ### Can I use Feather DB for a supervisor/worker multi-agent pattern? Yes. The supervisor agent writes task assignments and overall context to shared memory. Worker agents read their assigned context, execute tasks, and write results back with their `agent_id`. The supervisor reads all worker outputs via shared memory queries. This is a natural fit for Feather DB's namespace model. --- *This is the machine-readable mirror of the theory post at [getfeather.store/theory/multi-agent-memory-architecture](https://getfeather.store/theory/multi-agent-memory-architecture). For the full Feather DB documentation, see [getfeather.store/llms-full.txt](https://getfeather.store/llms-full.txt).*