Phase 14 · Lesson 16 of 54

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_parallel vs 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

  1. Agent. LLM + instructions + tools + handoffs.
  2. Handoff. Delegation to another agent. Represented to the model as a tool named transfer_to_<agent_name>.
  3. Guardrail. Validation on input (first agent only), output (last agent only), or tool invocation (per function tool).
  4. Session. Automatic conversation history across turns.
  5. 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:

  1. Copy the conversation context (or collapse it via nest_handoff_history beta).
  2. Initialize the target agent with its instructions.
  3. 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).
  • Runner with 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

  1. Add a handoff hop counter: refuse after N transfers. Trace the behavior.
  2. Implement nest_handoff_history as an option — collapse prior messages into one summary before transferring.
  3. Write a blocking output guardrail. Compare latency on prompts that would trip it vs ones that pass.
  4. Wire add_trace_processor to a JSON logger. What shape does it emit per span?
  5. 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

Check yourself

Quick quiz

  1. What are the five primitives of the OpenAI Agents SDK?

    1. Plan, Worker, Solver, Evaluator, Reflector
    2. Tool, Prompt, Model, Memory, Trace
    3. Agent, Handoff, Guardrail, Session, Tracing
    4. Node, Edge, Reducer, Checkpointer, Subgraph
    Show the answer

    C. Agent, Handoff, Guardrail, Session, Tracing The SDK ships these five primitives.

  2. How does the model see a handoff?

    1. As a special token
    2. As a system message
    3. As a custom HTTP endpoint
    4. 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.

  3. Which three guardrail types does the SDK ship?

    1. Hard, soft, and best-effort guardrails
    2. Pre, post, and inline guardrails
    3. Input, output, and tool guardrails
    4. 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.

  4. What is the difference between parallel and blocking guardrails?

    1. Parallel runs alongside the main LLM (lower latency, wastes tokens on trip); blocking runs first (no wasted tokens on trip)
    2. Blocking only works on output
    3. Parallel costs more money always
    4. 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.

  5. How is tracing enabled in the SDK?

    1. Only on the hosted dashboard
    2. Off by default; enable per agent
    3. Only via OpenTelemetry collector
    4. 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.

  6. What is handoff drift and how does the lesson recommend mitigating it?

    1. Agent A hands off to B which hands back to A in a loop; add a hop counter
    2. Sessions overflow; archive old ones
    3. Tracing falls behind; reduce span volume
    4. 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.

  7. Why are built-in tools a guardrail gap?

    1. They do not support handoffs
    2. Tool guardrails only fire on function tools; built-in tools (file reader, web fetch) need separate policy
    3. They cannot be traced
    4. 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.

Next lessonThe Harness as a Library — Subagents and Session StorePrevious: Role-Based Agent Teams — Roles, Tasks, Processes

Lessons from AI Engineering from Scratch by Rohit Ghumare and contributors, MIT license. Notes for owners by Lozo. License

Next step

Rather have it built for you?

Reading is optional. Tell me what's stuck and I'll build it into the business you already run.

  • A real conversation, not a pitch
  • You keep your accounts
  • Nothing sends without your yes