OpenAI Agents SDK — Multi-Agent Systems
OpenAI Agents SDK
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
| Primitive | Purpose | Key Concept |
|---|---|---|
| Agent | A configured LLM with instructions, tools, and model | The basic unit - wraps a system prompt + tool set |
| Handoff | Transfer control from one agent to another | Triage agent routes to specialized agents (billing, support, etc.) |
| Guardrail | Input/output validation that runs in parallel with the agent | Catches policy violations, PII leaks, or off-topic responses before they reach the user |
| Tracing | Built-in observability for every agent run | Automatic 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
| Pattern | Control Flow | Best For |
|---|---|---|
| Handoff | Control transfers TO the new agent (caller loses control) | Full delegation - "you handle this" |
| Agent-as-Tool | Caller invokes agent, gets result back | Sub-task - "do this and report back" |
Minimal abstraction, maximum speed. Install the OpenAI Agents SDK, set your key, and execute a one-file agent with Runner.run_sync.