OpenAI Agents SDK: Handoffs, Guardrails, Tracing
OpenAI Agents SDK is the lightweight multi-agent framework built on the Responses API. Five primitives: Agent, Handoff, Guardrail, Session, Tracing. Handoffs are tools named transfer_to_<agent>. Guardrails trip on input or output. Tracing is on by default.
Lesson 16 of 54Learn + Build~75 minutesPython (stdlib)
Before this: Lesson 1 of Phase 14 (Agent Loop), lesson 6 of Phase 14 (Tool Use)
On this page
Learning Objectives
- Name the five primitives of the OpenAI Agents SDK.
- Explain handoffs: why they are modeled as tools, what name shape the model sees, and how context transfers.
- Distinguish input guardrails, output guardrails, and tool guardrails; explain
run_in_parallelvs blocking mode. - Implement a stdlib runtime with handoffs + guardrails + span-style tracing.
The Problem
Agents that cannot delegate cleanly end up stuffing everything into one prompt. Agents without guardrails ship PII, policy-violating output, or loop forever. OpenAI's SDK codifies the three primitives that make multi-agent work tractable.
The Concept
Five primitives
- Agent. LLM + instructions + tools + handoffs.
- Handoff. Delegation to another agent. Represented to the model as a tool named
transfer_to_<agent_name>. - Guardrail. Validation on input (first agent only), output (last agent only), or tool invocation (per function tool).
- Session. Automatic conversation history across turns.
- Tracing. Built-in spans for LLM generations, tool calls, handoffs, guardrails.
Handoffs as tools
The model sees transfer_to_billing_agent in its tool list. Calling it signals the runtime to:
- Copy the conversation context (or collapse it via
nest_handoff_historybeta). - Initialize the target agent with its instructions.
- Continue the run with the target agent.
This is the supervisor pattern (Lesson 13 / Lesson 28) productized.
Guardrails
Three flavors:
- Input guardrails. Run on the first agent's input. Reject unsafe or out-of-scope requests before any LLM call.
- Output guardrails. Run on the last agent's output. Catch PII leaks, policy violations, malformed responses.
- Tool guardrails. Run per-function-tool. Validate arguments, check permissions, audit execution.
Mode:
- Parallel (default). Guardrail LLM runs alongside the main LLM. Lower tail latency. If tripped, the main LLM's work is discarded (token waste).
- Blocking (
run_in_parallel=False). Guardrail LLM runs first. If tripped, no tokens wasted on the main call.
Tripwires raise InputGuardrailTripwireTriggered / OutputGuardrailTripwireTriggered.
Tracing
On by default. Every LLM generation, tool call, handoff, and guardrail emits a span. OPENAI_AGENTS_DISABLE_TRACING=1 opts out. add_trace_processor(processor) fans spans to your own backend alongside OpenAI's.
Sessions
Session stores conversation history in a backend (SQLite, Redis, custom). Runner.run(agent, input, session=session) auto-loads and appends.
Where this pattern goes wrong
- Handoff drift. Agent A hands off to Agent B which hands back to Agent A. Add a hop counter.
- Guardrail bypass. Tool guardrails only fire on function tools; built-in tools (file reader, web fetch) need separate policy.
- Over-tracing. Sensitive content in spans. Pair with OTel GenAI content-capture rules (Lesson 23) — store externally, reference by ID.
ae-agent-handoff
Build It
code/main.py implements the SDK shape in stdlib:
Agent,FunctionTool,Handoff(as a function tool with transfer semantics).Runnerwith input/output/tool guardrails, handoff dispatch, and hop counter.- A simple span emitter to show the trace shape.
- A triage agent that hands off to billing or support based on the user's query; guardrail trips on one input.
Run it:
python3 code/main.py
The trace shows two successful handoffs, one input guardrail trip, and a span tree mirroring what the real SDK emits.
Use It
- OpenAI Agents SDK for OpenAI-first products.
- Claude Agent SDK (Lesson 17) for Claude-first products.
- LangGraph (Lesson 13) when you want explicit state and durable resume.
- Custom when you need exact control (voice, multi-provider, federated deployments).
Ship It
outputs/skill-agents-sdk-scaffold.md scaffolds an Agents SDK app with a triage agent, handoffs, input/output/tool guardrails, session store, and a trace processor.
Exercises
- Add a handoff hop counter: refuse after N transfers. Trace the behavior.
- Implement
nest_handoff_historyas an option — collapse prior messages into one summary before transferring. - Write a blocking output guardrail. Compare latency on prompts that would trip it vs ones that pass.
- Wire
add_trace_processorto a JSON logger. What shape does it emit per span? - Read the SDK docs. Port your stdlib toy to
openai-agents-python. What did you model wrong?
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Agent | "LLM + instructions" | Agent type in the SDK; owns tools and handoffs |
| Handoff | "Transfer" | Tool the model calls to delegate to another agent |
| Guardrail | "Policy check" | Validation on input / output / tool invocation |
| Tripwire | "Guardrail trip" | Exception raised when guardrail rejects |
| Session | "History store" | Conversation memory persisted between runs |
| Tracing | "Spans" | Built-in observability over LLM + tool + handoff + guardrail |
| Blocking guardrail | "Sequential check" | Guardrail runs first; no token waste on trip |
| Parallel guardrail | "Concurrent check" | Guardrail runs alongside; lower latency, wastes tokens on trip |
Further Reading
- OpenAI Agents SDK docs — primitives, handoffs, guardrails, tracing
- Claude Agent SDK overview — Claude-flavored counterpart
- Anthropic, Building Effective Agents — when to reach for handoffs at all
- OpenTelemetry GenAI semantic conventions — the standard Agents SDK spans map to
Check yourself
Quick quiz
What are the five primitives of the OpenAI Agents SDK?
- Plan, Worker, Solver, Evaluator, Reflector
- Tool, Prompt, Model, Memory, Trace
- Agent, Handoff, Guardrail, Session, Tracing
- Node, Edge, Reducer, Checkpointer, Subgraph
Show the answer
C. Agent, Handoff, Guardrail, Session, Tracing The SDK ships these five primitives.
How does the model see a handoff?
- As a special token
- As a system message
- As a custom HTTP endpoint
- As a tool named transfer_to_<agent_name>
Show the answer
D. As a tool named transfer_to_<agent_name> Handoffs are exposed as tools with the transfer_to_<agent> name shape.
Which three guardrail types does the SDK ship?
- Hard, soft, and best-effort guardrails
- Pre, post, and inline guardrails
- Input, output, and tool guardrails
- Static, dynamic, and federated guardrails
Show the answer
C. Input, output, and tool guardrails Input (first agent), output (last agent), and tool (per function tool) guardrails.
What is the difference between parallel and blocking guardrails?
- Parallel runs alongside the main LLM (lower latency, wastes tokens on trip); blocking runs first (no wasted tokens on trip)
- Blocking only works on output
- Parallel costs more money always
- Blocking is asynchronous; parallel is synchronous
Show the answer
A. Parallel runs alongside the main LLM (lower latency, wastes tokens on trip); blocking runs first (no wasted tokens on trip) Parallel optimizes latency at the cost of wasted tokens when tripped; blocking saves tokens but adds latency.
How is tracing enabled in the SDK?
- Only on the hosted dashboard
- Off by default; enable per agent
- Only via OpenTelemetry collector
- On by default; OPENAI_AGENTS_DISABLE_TRACING=1 opts out
Show the answer
D. On by default; OPENAI_AGENTS_DISABLE_TRACING=1 opts out Spans for LLM, tool, handoff, and guardrail emit by default; an env var disables them.
What is handoff drift and how does the lesson recommend mitigating it?
- Agent A hands off to B which hands back to A in a loop; add a hop counter
- Sessions overflow; archive old ones
- Tracing falls behind; reduce span volume
- Guardrails desync; retrain
Show the answer
A. Agent A hands off to B which hands back to A in a loop; add a hop counter A hop counter caps transfer chains before they loop indefinitely.
Why are built-in tools a guardrail gap?
- They do not support handoffs
- Tool guardrails only fire on function tools; built-in tools (file reader, web fetch) need separate policy
- They cannot be traced
- They are slower than function tools
Show the answer
B. Tool guardrails only fire on function tools; built-in tools (file reader, web fetch) need separate policy Per-tool guardrails cover function tools; built-in tools require a separate policy layer.
Questions people ask
What is the OpenAI Agents SDK?
It is OpenAI's lightweight framework for building agents. Its core parts are agents, handoffs between agents, guardrails that check input and output, sessions for conversation history, and built-in tracing of each run.
What are guardrails in AI agents?
Guardrails are checks that run alongside the agent. An input guardrail can stop an abusive or off-topic request before the main model runs. An output guardrail can block a reply that leaks private data or breaks a policy.
Lessons from AI Engineering from Scratch by Rohit Ghumare and contributors, MIT license. Notes for owners by Lozo. License