Skip to content
Learn Agentic AI
Learn Agentic AI9 min read7 views

Session Sharing Between Multiple Agents

Learn how to share sessions across multiple AI agents in the OpenAI Agents SDK for context continuity, handoff-aware patterns, and building multi-agent support systems.

The Multi-Agent Context Problem

In multi-agent systems, different agents specialize in different tasks. A triage agent routes requests, a billing agent handles payment issues, and a technical support agent solves product problems. When a user is handed off from one agent to another, the receiving agent needs to know what happened before — what the user said, what was tried, and what the outcome was.

Without shared sessions, each agent starts blind. The user has to repeat their problem, and the agent has no context about prior attempts. This creates a frustrating experience and wastes both time and tokens.

Same Session ID Across Different Agents

The simplest form of session sharing is using the same session_id when running different agents. Since sessions are stored by ID, any agent that references the same ID sees the same history.

flowchart TD
    START["Session Sharing Between Multiple Agents"] --> A
    A["The Multi-Agent Context Problem"]
    A --> B
    B["Same Session ID Across Different Agents"]
    B --> C
    C["Context Continuity in Multi-Agent Syste…"]
    C --> D
    D["Handoff-Aware Session Patterns"]
    D --> E
    E["Building a Shared-Context Support System"]
    E --> F
    F["Anti-Patterns to Avoid"]
    F --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE fill:#059669,stroke:#047857,color:#fff
from agents import Agent, Runner
from agents.extensions.sessions import SQLiteSession

session = SQLiteSession(db_path="./shared_sessions.db")

# Two specialized agents
greeter = Agent(
    name="Greeter",
    instructions="You warmly greet users and ask how you can help today.",
)

helper = Agent(
    name="Helper",
    instructions="""You are a knowledgeable assistant. You can see the full
    conversation history including what the Greeter discussed with the user.
    Continue naturally from where the conversation left off.""",
)

async def demo():
    sid = "user-session-001"

    # Greeter handles the initial interaction
    result = await Runner.run(
        greeter, "Hi there!", session=session, session_id=sid
    )
    print(f"Greeter: {result.final_output}")

    # User responds
    result = await Runner.run(
        greeter, "I need help with my billing.", session=session, session_id=sid
    )
    print(f"Greeter: {result.final_output}")

    # Handoff to Helper — same session_id, sees full history
    result = await Runner.run(
        helper,
        "I was transferred here for billing help.",
        session=session,
        session_id=sid,
    )
    print(f"Helper: {result.final_output}")
    # Helper sees the greeting exchange and knows the user needs billing help

The Helper agent sees the entire conversation with the Greeter because they share the same session ID.

Context Continuity in Multi-Agent Systems

For context continuity to work well, agents need clear instructions about how to interpret shared history. The history will contain turns from different agents, and each agent should understand its role in the sequence.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

flowchart TD
    ROOT["Session Sharing Between Multiple Agents"] 
    ROOT --> P0["Context Continuity in Multi-Agent Syste…"]
    P0 --> P0C0["Routing with Shared Sessions"]
    ROOT --> P1["Building a Shared-Context Support System"]
    P1 --> P1C0["Key Patterns in This System"]
    style ROOT fill:#4f46e5,stroke:#4338ca,color:#fff
    style P0 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
    style P1 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
triage_agent = Agent(
    name="TriageAgent",
    instructions="""You are the triage agent. Your job is to understand the
    user's problem and categorize it. Ask clarifying questions if needed.
    When you have enough context, indicate the category clearly:
    - BILLING for payment and subscription issues
    - TECHNICAL for product bugs and how-to questions
    - ACCOUNT for login, password, and profile issues""",
)

billing_agent = Agent(
    name="BillingAgent",
    instructions="""You are the billing specialist. The conversation history
    may contain messages from the TriageAgent who categorized this as a
    billing issue. Review the full history to understand the user's problem
    without asking them to repeat information. Resolve billing issues
    directly using the tools available to you.""",
)

technical_agent = Agent(
    name="TechnicalAgent",
    instructions="""You are the technical support specialist. Review the full
    conversation history — the TriageAgent has already gathered initial
    context. Pick up where they left off and solve the technical issue.
    Never ask the user to repeat information that is already in the history.""",
)

Routing with Shared Sessions

async def handle_support_request(session_id: str, message: str, current_agent: str):
    """Route to the appropriate agent while maintaining session continuity."""

    agents = {
        "triage": triage_agent,
        "billing": billing_agent,
        "technical": technical_agent,
    }

    agent = agents[current_agent]

    result = await Runner.run(
        agent, message, session=session, session_id=session_id
    )

    # Check if triage agent wants to hand off
    output = result.final_output.upper()
    if current_agent == "triage":
        if "BILLING" in output:
            return result.final_output, "billing"
        elif "TECHNICAL" in output:
            return result.final_output, "technical"

    return result.final_output, current_agent

Handoff-Aware Session Patterns

The OpenAI Agents SDK has built-in handoff support. When combining handoffs with shared sessions, the receiving agent automatically gets the full context.

from agents import Agent, Runner, handoff

billing_agent = Agent(
    name="BillingAgent",
    instructions="Handle billing inquiries. You have full conversation context.",
)

technical_agent = Agent(
    name="TechnicalAgent",
    instructions="Handle technical issues. You have full conversation context.",
)

triage_agent = Agent(
    name="TriageAgent",
    instructions="""Understand the user's issue and hand off to the right specialist.
    Use the transfer_to_billing or transfer_to_technical tools.""",
    handoffs=[
        handoff(billing_agent, tool_name="transfer_to_billing",
                tool_description="Transfer to billing for payment issues"),
        handoff(technical_agent, tool_name="transfer_to_technical",
                tool_description="Transfer to technical for product issues"),
    ],
)

async def support_flow(session_id: str, message: str):
    result = await Runner.run(
        triage_agent,
        message,
        session=session,
        session_id=session_id,
    )

    # If a handoff occurred, result.last_agent is the target agent
    print(f"Handled by: {result.last_agent.name}")
    print(f"Response: {result.final_output}")

    return result

When a handoff occurs, the target agent receives the full session history including all turns with the triage agent. The transition is seamless.

Building a Shared-Context Support System

Here is a complete multi-agent support system with session sharing, handoffs, and escalation:

import asyncio
from agents import Agent, Runner, handoff
from agents.extensions.sessions import SQLiteSession, SessionSettings

session = SQLiteSession(db_path="./support_system.db")
settings = SessionSettings(limit=50)

# Level 1: Automated support
l1_billing = Agent(
    name="L1Billing",
    instructions="""You handle routine billing questions: checking balances,
    explaining charges, updating payment methods. If the issue requires
    a refund over $50 or involves a disputed charge, escalate to L2.""",
    handoffs=[],  # Will be set after L2 is defined
)

l1_technical = Agent(
    name="L1Technical",
    instructions="""You handle common technical issues: password resets,
    basic troubleshooting, feature explanations. If the issue requires
    backend investigation or is a confirmed bug, escalate to L2.""",
    handoffs=[],
)

# Level 2: Senior support (has more tools and authority)
l2_support = Agent(
    name="L2Support",
    instructions="""You are a senior support agent. You handle escalated issues
    that L1 agents cannot resolve. Review the FULL conversation history to
    understand what has already been tried. Never ask the user to repeat
    steps that are documented in the history.

    You can issue refunds, file bug reports, and make account changes.
    If you cannot resolve the issue, create a ticket for engineering.""",
)

# Configure handoffs after all agents are defined
l1_billing.handoffs = [
    handoff(l2_support, tool_name="escalate_to_senior",
            tool_description="Escalate to senior support for complex billing issues"),
]
l1_technical.handoffs = [
    handoff(l2_support, tool_name="escalate_to_senior",
            tool_description="Escalate to senior support for complex technical issues"),
]

# Triage agent
triage = Agent(
    name="Triage",
    instructions="""Greet the user and understand their issue.
    Route to billing for payment/subscription issues.
    Route to technical for product/feature issues.""",
    handoffs=[
        handoff(l1_billing, tool_name="route_to_billing",
                tool_description="Route to billing support"),
        handoff(l1_technical, tool_name="route_to_technical",
                tool_description="Route to technical support"),
    ],
)

async def support_conversation():
    sid = "ticket-2026-0314-001"

    messages = [
        "Hi, I was charged twice for my subscription this month.",
        "Yes, I can see two charges of $29.99 on March 1st and March 3rd.",
        "I'd like a refund for the duplicate charge.",
        "The amount is $29.99 — can you process that?",
    ]

    current_agent = triage
    for msg in messages:
        print(f"\nUser: {msg}")
        result = await Runner.run(
            current_agent, msg, session=session,
            session_id=sid, session_settings=settings,
        )
        current_agent = result.last_agent
        print(f"{current_agent.name}: {result.final_output}")

asyncio.run(support_conversation())

Key Patterns in This System

  1. Session continuity: Every agent in the chain sees the full conversation because they share the session_id.
  2. No context loss on handoff: When L1 escalates to L2, the senior agent sees everything L1 discussed with the user.
  3. Instructions reference history: Each agent is told to review the history and avoid redundant questions.
  4. Session limits: The SessionSettings(limit=50) prevents unbounded history growth.

Anti-Patterns to Avoid

Do not create separate sessions per agent. If each agent gets its own session_id, context is lost during handoffs. Always use one session_id per user conversation, regardless of how many agents participate.

Do not include agent-specific state in the session. Sessions store conversation items (user messages and assistant responses). If you need agent-specific metadata (internal routing decisions, confidence scores), store that in a separate data store keyed by session_id.

Do not assume history ordering. In concurrent multi-agent systems, items might be added by different agents simultaneously. Design your session backend to handle concurrent writes safely, and rely on item_order rather than timestamps.

Sources:

Share
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like