The OpenAI Agents SDK
In Chapter 4 you built the agent loop by hand to understand it. The OpenAI Agents SDK is the batteries-included version — a lightweight framework that runs the loop, tool calls, handoffs between agents, and guardrails for you. This chapter shows what it gives you, when to use it over the raw loop, and the minimal code to run one.
Learning objectives
- Explain what the Agents SDK adds over the hand-written loop.
- Install it and run a single agent with
Agent+Runner. - Give an agent tools and understand handoffs and guardrails.
- Decide between the SDK and the raw loop for a given need.
OPENAI_API_KEY) + pip install openai-agents (a separate package from openai).1 · What the Agents SDK is essential
You already know what an agent is — a loop that calls the model, runs the tools it asks for, feeds results back, and repeats. You built that by hand in Ch 4 precisely so the frameworks would stop being mysterious. The OpenAI Agents SDK (the openai-agents package) is OpenAI's official framework that runs that loop for you, plus the production concerns that cluster around it: multiple agents handing off to each other, input/output guardrails, session memory, and tracing — the things you'd otherwise hand-roll.
The framing to keep: the SDK is a convenience layer over the same primitive. It's described as "a lightweight yet powerful framework for building multi-agent workflows," and it's provider-agnostic (it works over the Responses API and Chat Completions, and even other models). It doesn't replace what you learned — it automates it. Knowing the hand-written loop is exactly what lets you use the SDK well, because you understand what it's doing under the hood.
The common mistake cuts both ways. Beginners reach for a framework first and never understand the loop, so they're lost when it misbehaves. Veterans refuse frameworks on principle and hand-roll multi-agent orchestration, handoffs, and tracing that the SDK gives for free. The right instinct: understand the loop (Ch 4), then let the SDK handle the orchestration boilerplate once your needs grow past a single simple loop.
Agent (instructions + tools); the Runner executes the full loop — model calls, tool calls, handoffs, guardrails — and returns final_output. It's the Ch 4 loop, automated.
- The blue box is the
Agent— a declarative bundle of instructions, tools, and optional handoffs. - The middle box is the
Runner— it executes the loop you wrote by hand in Ch 4, including tool dispatch and guardrails. - The green box is
result.final_output— the finished answer after the loop terminates.
In short: you describe the agent; the Runner runs the loop. Everything you learned about that loop still applies — it's just automated.
2 · Install & run one agent essential
The minimal program: install the package, define an Agent, run it with Runner, read final_output.
terminalpip install openai-agents
hello_agent.pyfrom agents import Agent, Runner
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant. Be concise.",
)
result = Runner.run_sync(agent, "Write a haiku about recursion.")
print(result.final_output)
from agents import Agent, Runner— the package installs asopenai-agentsbut imports asagents.Agent(name=…, instructions=…)declares the agent — its persona and rules, like the system prompt in a raw call.Runner.run_sync(agent, "...")runs the whole loop synchronously and returns a result;result.final_outputis the answer. (There's an asyncRunner.run(...)too.)
Try this: compare this five-line program to the hand-written loop in Ch 4 — same behavior, none of the loop bookkeeping. That's the convenience the SDK buys.
3 · Tools, handoffs & guardrails intermediate
The SDK's three headline features map onto things you'd otherwise build by hand. Tools: decorate a Python function and hand it to the agent — the SDK runs the function-call loop for you (no manual function_call/function_call_output plumbing). Handoffs: one agent can delegate to another specialist agent (a triage agent routing to a billing agent), which is multi-agent orchestration as a first-class feature. Guardrails: input/output validators that run alongside the agent and can block or correct unsafe content.
agent_with_tool.pyfrom agents import Agent, Runner, function_tool
@function_tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"18°C and cloudy in {city}"
agent = Agent(
name="Weather bot",
instructions="Answer weather questions using the tool.",
tools=[get_weather], # the SDK runs the tool loop for you
)
result = Runner.run_sync(agent, "What's the weather in Oslo?")
print(result.final_output)
@function_toolturns a plain typed Python function into a tool — the SDK reads its signature and docstring to build the schema the model needs.tools=[get_weather]registers it; when the model calls it, the SDK runs the function and feeds the result back automatically — the loop you wrote by hand in Ch 4 and ox2, now handled.- Add more agents and pass them as
handoffs=[…]to let one agent delegate; addinput_guardrails/output_guardrailsto validate around the run.
Try this: define a second agent and give the first one handoffs=[second] — ask a question outside the first's domain and watch it delegate. That's multi-agent orchestration in two lines.
4 · SDK vs the hand-written loop advanced
Use the raw loop (ox2 / Ch 4) when you want full control, minimal dependencies, or you're learning — a single agent with two tools doesn't need a framework. Reach for the Agents SDK when the orchestration grows: multiple agents handing off, guardrails you'd otherwise hand-roll, built-in tracing/sessions, and you'd rather not maintain loop plumbing. The decisive question is how much orchestration you have — one simple loop → raw; a web of agents, tools, and guardrails → SDK.
| Use… | When |
|---|---|
| Hand-written loop (Ch 4 / ox2) | single agent, full control, minimal deps, or learning |
| Agents SDK | multi-agent handoffs, guardrails, tracing/sessions — orchestration at scale |
5 · Tech-lead — frameworks as a dependency choice tech-lead
Adopting an agent framework is a dependency and lock-in decision, not just a convenience. The upside is real — handoffs, guardrails, and tracing you don't maintain. The cost is a dependency that evolves on its own schedule and a layer of abstraction between you and the API. The lead-level stance: adopt the SDK when your orchestration genuinely exceeds a simple loop, keep your tool functions plain (so they're reusable outside the framework), and make sure the team understands the underlying loop (Ch 4) so a framework bug is debuggable, not magic. The Agents SDK being provider-agnostic also softens lock-in — the orchestration isn't welded to one model vendor.
🪜 Practice ladder beginner → industry
- Beginner: run Lab OP7.1 and read
final_output. - Easy: change the agent's
instructionsand see the behavior shift. - Core: add the
@function_toolfrom Lab OP7.2 and confirm the SDK runs the tool loop. - Stretch: define a second agent and wire a
handoffsdelegation between them. - Hard: rebuild your Ch 4 hand-written agent as an Agents-SDK agent and compare the code.
- Industry: write the adopt-or-not decision doc for one real agent, weighing control vs orchestration and lock-in.
✓ Checkpoint — you can move on when you can…
- Explain what the Agents SDK automates over the raw loop.
- Run a single agent with
Agent+Runner. - Add a tool with
@function_tooland describe handoffs/guardrails. - Choose between the SDK and the hand-written loop.
Knowledge check check yourself
What does the OpenAI Agents SDK add over the hand-written agent loop, and how do you run a single agent?
Show answer
openai-agents package) runs the agent loop for you and adds multi-agent handoffs, input/output guardrails, sessions, and tracing — the orchestration you'd otherwise hand-roll. It's provider-agnostic. To run one agent: from agents import Agent, Runner; define Agent(name=…, instructions=…); call Runner.run_sync(agent, "...") and read result.final_output.When should you use the Agents SDK versus the hand-written loop from Chapter 4?