📚Academy
likeone
online

Shared Memory and State

Agents that share context and knowledge — the difference between a team and a group of strangers.

What You'll Learn

  • Why isolated agents produce inconsistent results
  • Three models for shared state: context passing, shared memory, and vector stores
  • How to design state schemas that scale
  • Preventing state corruption in multi-agent systems

Agents Without Shared Memory Are Goldfish

Agent A researches a customer's history. Agent B handles the customer's complaint. But Agent B doesn't know what Agent A found. So it asks the customer to repeat everything. Sound familiar? It's the same frustration you feel when a company transfers your call and you have to start over.

Without shared memory, each agent operates in isolation. The system has knowledge, but no individual agent can access the full picture. Shared state fixes this.

Context Passing: The Relay Baton

The simplest approach: each agent receives the accumulated context from all previous agents in its prompt. Agent A's output becomes part of Agent B's input, which becomes part of Agent C's input.

Pros: Simple to implement. No external infrastructure. Every agent has full history.

Cons: Context windows fill up fast. By agent 5 or 6, you're running out of room for the actual task. Doesn't scale.

Python — Context passing: accumulate history in the prompt
def pipeline_with_context(task: str, agents: list) -> str:
    # Each agent sees ALL previous outputs (context grows with each step)
    context = f"Original task: {task}\n"
    for name, system_prompt in agents:
        result = call_agent(system_prompt, context)
        context += f"\n--- {name} output ---\n{result}\n"  # accumulate
    return context

# Problem: by agent 5, the context might be 50,000+ tokens
# That leaves little room for the agent's own reasoning

Shared Memory Store: The Team Database

All agents read from and write to a central store — a database, a key-value store, or even a structured document. Each agent queries only what it needs instead of carrying everything.

Pros: Scales to many agents. Each agent gets relevant context without bloat. Persists across sessions.

Cons: Requires infrastructure. Agents need to know what to query. Stale data is a risk if updates lag.

Python — Shared memory store with Supabase
from supabase import create_client

db = create_client(SUPABASE_URL, SUPABASE_KEY)

class SharedMemory:
    def __init__(self, task_id: str):
        self.task_id = task_id

    def write(self, agent: str, key: str, value: any):
        # Each agent writes to its own namespace
        db.table("agent_memory").upsert({
            "task_id": self.task_id,
            "agent": agent, "key": key, "value": value
        }).execute()

    def read(self, key: str) -> any:
        # Any agent can read any key
        row = db.table("agent_memory").select("value").eq(
            "task_id", self.task_id
        ).eq("key", key).single().execute()
        return row.data["value"]

# Usage: agents share state without carrying it in their context
mem = SharedMemory("content-042")
mem.write("researcher", "findings", research_output)   # researcher writes
findings = mem.read("findings")                        # writer reads

Vector Store: The Semantic Brain

Store agent outputs as embeddings in a vector database. When an agent needs context, it performs a semantic search — "find everything related to customer billing issues" — and gets the most relevant pieces, regardless of when or which agent produced them.

Pros: Handles massive amounts of context. Agents retrieve only what's relevant. Gets smarter as more data accumulates.

Cons: More complex to set up. Embedding quality matters. Results can be unpredictable.

Python — Vector store: semantic search for agent memory (pgvector)
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")  # free, runs locally

def store_memory(text: str, agent: str, task_id: str):
    # Convert text to a vector and store in Supabase with pgvector
    embedding = model.encode(text).tolist()
    db.table("agent_vectors").insert({
        "task_id": task_id, "agent": agent,
        "content": text, "embedding": embedding
    }).execute()

def recall(query: str, task_id: str, limit: int = 3) -> list:
    # Semantic search: find the most relevant agent memories
    query_vec = model.encode(query).tolist()
    result = db.rpc("match_agent_memory", {
        "query_embedding": query_vec,
        "filter_task": task_id,
        "match_count": limit
    }).execute()
    return [r["content"] for r in result.data]

# Editor agent needs billing context — semantic search finds it
relevant = recall("customer billing history", "support-099")
# → Returns the 3 most relevant memories from ANY agent

A State Schema That Works

Shared State Object

{
"task_id": "content-pipeline-042",
"status": "in_progress",
"current_stage": "editing",
"artifacts": {
"research": { "agent": "researcher", "completed": true, "output_ref": "..." },
"draft": { "agent": "writer", "completed": true, "output_ref": "..." },
"review": { "agent": "editor", "completed": false }
},
"shared_context": {
"target_audience": "technical managers",
"tone": "professional but approachable",
"word_limit": 1500
},
"flags": ["needs_fact_check", "client_mentioned_deadline"]
}

Every agent reads shared_context. Each updates its own artifact. Flags communicate cross-cutting concerns.

🔒

This lesson is for Pro members

Unlock all 520+ lessons across 52 courses with Academy Pro.

Already a member? Sign in to access your lessons.

Academy
Built with soul — likeone.ai