Skip to main content

OpenAI Agents SDK — Multi-Agent Systems

[ ABORT TO HUD ]
SEQ. 1
SEQ. 2
SEQ. 3
SEQ. 4
SEQ. 5
SEQ. 6
SEQ. 7
SEQ. 8

OpenAI Agents SDK

👥 Multi-Agent Systems⏱ 15 min⭐ 100 BASE XP⌨ HANDS-ON LAB

Production Agent Framework from OpenAI

The OpenAI Agents SDK (open-source, Python) provides a lightweight, opinionated framework for building production agents with core primitives: Agents, Handoffs, Guardrails, and Tracing. In April 2026, it introduced Native Sandboxing (isolated filesystems and shell execution) and the Long-Horizon use for multi-step workflows. Unlike heavier frameworks, it embraces minimal abstraction - just enough structure to build reliable systems.

Core Primitives

PrimitivePurposeKey Concept
AgentA configured LLM with instructions, tools, and modelThe basic unit - wraps a system prompt + tool set
HandoffTransfer control from one agent to anotherTriage agent routes to specialized agents (billing, support, etc.)
GuardrailInput/output validation that runs in parallel with the agentCatches policy violations, PII leaks, or off-topic responses before they reach the user
TracingBuilt-in observability for every agent runAutomatic logging of LLM calls, tool executions, handoffs, and guardrail checks

Handoffs Pattern

The Handoffs pattern is the SDK's signature feature. A triage agent evaluates the user's request and hands off to a specialist agent with full context transfer:

from agents import Agent, handoff, Runner, function_tool

@function_tool
def lookup_invoice(invoice_id: str) -> str:
    """Fetch invoice status and total amount."""
    return f"Invoice {invoice_id}: $99.00 (paid)"

billing_agent = Agent(
    name="Billing Specialist",
    instructions="Handle billing inquiries. Access the billing database.",
    tools=[lookup_invoice, process_refund]
)

tech_agent = Agent(
    name="Technical Support",
    instructions="Debug technical issues. Access logs and documentation.",
    tools=[search_docs, check_status]
)

triage_agent = Agent(
    name="Triage",
    instructions="Route the customer to the right specialist.",
    handoffs=[handoff(billing_agent), handoff(tech_agent)]
)

# Agents-as-Tools: use an agent as a tool (returns result to caller)
triage_agent_v2 = Agent(
    name="Coordinator",
    tools=[
        billing_agent.as_tool(tool_name="billing_expert", tool_description="Handle billing and refund inquiries"),
        tech_agent.as_tool(tool_name="tech_expert", tool_description="Debug technical issues"),
    ]
)

result = await Runner.run(triage_agent, "I was double-charged")
# → Triage hands off to Billing Specialist automatically

Guardrails System

Guardrails run in parallel with the agent. If a guardrail trips, the agent's response is blocked before reaching the user:

  • Input Guardrails: Validate user messages (block jailbreaks, detect PII)
  • Output Guardrails: Validate agent responses (check for policy violations, hallucinated data)

Guardrails & Remote MCP Integration

from agents import Agent, Runner, InputGuardrail, OutputGuardrail, GuardrailFunctionOutput
from agents.mcp import MCPServerStreamableHttp

async def block_pii(ctx, agent, input_data) -> GuardrailFunctionOutput:
    tripped = "ssn:" in str(input_data).lower()
    return GuardrailFunctionOutput(tripwire_triggered=tripped, output_info="PII blocked")

async def check_output(ctx, agent, output) -> GuardrailFunctionOutput:
    tripped = "internal_secret" in str(output).lower()
    return GuardrailFunctionOutput(tripwire_triggered=tripped, output_info="Secret redacted")

async with MCPServerStreamableHttp(
    name="enterprise-mcp",
    params={"url": "https://mcp.example.com/mcp"},
) as mcp_server:
    secure_agent = Agent(
        name="Enterprise Support",
        model="gpt-6-astra",
        instructions="Resolve customer issues using verified MCP tools.",
        mcp_servers=[mcp_server],
        input_guardrails=[InputGuardrail(guardrail_function=block_pii)],
        output_guardrails=[OutputGuardrail(guardrail_function=check_output)],
    )
    result = await Runner.run(secure_agent, "Check ticket #402 status")

Handoffs vs Agents-as-Tools

PatternControl FlowBest For
HandoffControl transfers TO the new agent (caller loses control)Full delegation - "you handle this"
Agent-as-ToolCaller invokes agent, gets result backSub-task - "do this and report back"
💡 Key Insight: The Agents SDK is intentionally minimal. It doesn't try to be a graph engine or workflow orchestrator - it focuses on the agent-to-agent handoff pattern and built-in guardrails, making it ideal for customer-facing multi-agent support systems.
⌨ HANDS-ON LABRun Your First Agents SDK Agent
⭐ +150 XP

Minimal abstraction, maximum speed. Install the OpenAI Agents SDK, set your key, and execute a one-file agent with Runner.run_sync.

1Install the openai-agents package from PyPI.
2Export your OpenAI API key so the SDK can authenticate.
3Run a hello-world agent script (Agent + Runner.run_sync from the agents package).
lab-sandbox — simulated environment
INFINITY LAB SANDBOX v2.6 — simulated shell
Type the command for the current objective. Helpers: "hint", "solution", "clear".
$
OBJECTIVE 1 / 3 — type "hint" if stuck
SYNAPSE VERIFICATION
QUERY 1 // 3
What is the key difference between a 'Handoff' and 'Agent-as-Tool' in the OpenAI Agents SDK?
There is no difference
Handoff transfers full control to the new agent; Agent-as-Tool invokes the agent and returns the result to the caller
Agent-as-Tool is faster
Handoff only works with GPT-6 Astra