Skip to content
,

OpenAI Agents SDK Python Guide (2026): Install, Tools, Handoffs, Guardrails and Tracing

7–11 minutes
Uneasy woman on a rooftop with a city skyline at dusk, OpenAI logo, hook Agents SDK 0.24 Python guide

The OpenAI Agents SDK is OpenAI’s official Python framework for building AI agents. The current release is openai-agents 0.24.0, published on PyPI on October 15, 2026.

This guide walks you through install, your first agent, tools, handoffs, guardrails, sessions and tracing, all on the Responses API with current GPT-6 and GPT-5.6 model IDs.

TLDR

  • Install: pip install openai-agents (Python 3.10 or newer). Latest version is 0.24.0.
  • Core pieces: Agent, Runner, tools, handoffs, guardrails, sessions and tracing.
  • Default model: gpt-5.6-luna if you set none. Pick gpt-6.1-sol or gpt-6-astra for harder work.
  • API: the SDK uses the Responses API by default. Chat Completions is optional.
  • Tracing: on by default, viewable in the OpenAI dashboard.

What is the OpenAI Agents SDK?

The Agents SDK is a small, open source library from OpenAI. It gives you a few building blocks and a loop that runs the model, calls tools and passes work between agents until the job is done.

Concept What it does
Agent A model with instructions, tools, guardrails and handoffs
Runner Runs the agent loop and returns a result
Tools Python functions, hosted tools and MCP servers
Handoffs Pass the conversation to a specialist agent
Guardrails Input and output checks that can stop a run
Sessions Keep conversation history across runs
Tracing Records every step so you can debug

It also supports realtime voice agents, sandbox agents for long tasks in a container, and human-in-the-loop approvals. A JavaScript version exists as a separate package.

How to install the Agents SDK

  1. Check Python. You need Python 3.10 or newer. Run python3 --version.
  2. Create a virtual environment. Run python3 -m venv .venv, then activate it with source .venv/bin/activate (macOS and Linux) or .venv\Scripts\activate (Windows).
  3. Install the package. Run pip install openai-agents. With uv, run uv add openai-agents.
  4. Add extras if needed. Use pip install 'openai-agents[voice]' for voice or pip install 'openai-agents[redis]' for Redis sessions.
  5. Set your API key. Run export OPENAI_API_KEY=sk-... on macOS and Linux, or setx OPENAI_API_KEY "sk-..." on Windows.
  6. Confirm the version. Run pip show openai-agents. It should show 0.24.0 or newer.

Warning: Never paste your API key into code you commit. Keep it in an environment variable or a .env file listed in .gitignore.

New to the OpenAI API itself? Start with my OpenAI API Python tutorial, then come back.

Your first agent

Save this as hello.py and run python hello.py.

import asyncio
from agents import Agent, Runner

agent = Agent(
    name="History Tutor",
    instructions="You answer history questions clearly and concisely.",
)

async def main():
    result = await Runner.run(agent, "When did the Roman Empire fall?")
    print(result.final_output)

if __name__ == "__main__":
    asyncio.run(main())

Three run methods are available:

  • Runner.run(): async, the one you will use most.
  • Runner.run_sync(): a blocking version for quick scripts.
  • Runner.run_streamed(): streams events as they happen, good for chat UIs.

By default a run stops after 10 turns. Raise it with max_turns if your agent needs many tool calls.

Choosing a model

If you do not set a model, the SDK uses gpt-5.6-luna with low verbosity. That is cheap and fast, but not the smartest choice for hard tasks.

Model ID Best for
gpt-6-astra Most capable, complex reasoning and coding
gpt-6.1-sol Near-Astra quality at lower cost
gpt-6.1-terra Fast, visual reasoning and computer use
gpt-6-luna High-volume, cost-sensitive tasks
gpt-5.6-luna SDK default when no model is set

Three ways to set the model

  • Per agent: Agent(name="Helper", model="gpt-6.1-sol").
  • Per run: RunConfig(model="gpt-6.1-sol") for agents without their own model.
  • Globally: set the OPENAI_DEFAULT_MODEL environment variable.

Tune reasoning with ModelSettings:

from agents import Agent, ModelSettings
from openai.types.shared import Reasoning

agent = Agent(
    name="Planner",
    model="gpt-6.1-sol",
    model_settings=ModelSettings(reasoning=Reasoning(effort="high")),
)

Note: The SDK talks to the Responses API by default. If you need Chat Completions, for example with another provider, call set_default_openai_api("chat_completions"). Check token costs in my OpenAI API pricing guide.

Adding tools

Function tools

Any Python function becomes a tool with the @function_tool decorator. The SDK reads the type hints and docstring to build the schema. In 0.24.0, @tool from agents.decorators is an alias for the same thing.

from agents import Agent, Runner, function_tool

@function_tool
def get_weather(city: str) -> str:
    """Return the weather for a city."""
    return f"It is sunny in {city}."

agent = Agent(
    name="Weather Bot",
    instructions="Use get_weather when asked about weather.",
    tools=[get_weather],
)

result = Runner.run_sync(agent, "What is the weather in Delhi?")
print(result.final_output)

Hosted tools

These run on OpenAI’s side with the Responses API:

  • WebSearchTool: searches the web.
  • FileSearchTool: searches your OpenAI vector stores.
  • CodeInterpreterTool: runs code in a sandbox.
  • ImageGenerationTool: creates images from a prompt.
  • HostedMCPTool: exposes a remote MCP server’s tools.
  • ToolSearchTool: loads deferred tools only when needed.

Local MCP servers

You can also plug in any MCP server. Here is a filesystem server run with npx:

from agents import Agent, Runner
from agents.mcp import MCPServerStdio

async def main():
    async with MCPServerStdio(
        params={"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"]}
    ) as server:
        agent = Agent(name="Files", instructions="Answer using the files.", mcp_servers=[server])
        result = await Runner.run(agent, "List the files in docs.")
        print(result.final_output)

Want to write your own server? See how to build an MCP server in Python.

Handoffs and agents as tools

There are two ways to make agents work together.

  • Handoffs: a triage agent passes the whole conversation to a specialist, who then answers.
  • Agents as tools: a manager agent calls a specialist like a function and keeps control.
from agents import Agent, Runner

history_tutor = Agent(
    name="History Tutor",
    handoff_description="Specialist for history questions",
    instructions="You answer history questions clearly.",
)
math_tutor = Agent(
    name="Math Tutor",
    handoff_description="Specialist for math questions",
    instructions="Explain math step by step.",
)
triage = Agent(
    name="Triage",
    instructions="Route each question to the right tutor.",
    handoffs=[history_tutor, math_tutor],
)

result = Runner.run_sync(triage, "What is 12 squared?")
print(result.final_output)
print("Answered by:", result.last_agent.name)

For the agents-as-tools pattern, call math_tutor.as_tool(tool_name="math", tool_description="Solve math") and add it to the manager’s tools list.

Tip: Write a clear handoff_description for each specialist. The triage agent picks a handoff based on that text, so vague descriptions cause wrong routing.

Guardrails

Guardrails run checks next to your agent. If a check trips, the run stops with an exception, so you avoid paying for a big model on a bad request.

from pydantic import BaseModel
from agents import (Agent, Runner, GuardrailFunctionOutput,
    InputGuardrailTripwireTriggered, input_guardrail)

class HomeworkCheck(BaseModel):
    is_homework: bool
    reasoning: str

checker = Agent(
    name="Checker",
    instructions="Decide if the user wants homework done for them.",
    output_type=HomeworkCheck,
    model="gpt-6-luna",
)

@input_guardrail
async def homework_guardrail(ctx, agent, input):
    result = await Runner.run(checker, input, context=ctx.context)
    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=result.final_output.is_homework,
    )

tutor = Agent(
    name="Tutor",
    instructions="Help students learn. Do not just give answers.",
    input_guardrails=[homework_guardrail],
)

try:
    Runner.run_sync(tutor, "Solve my homework: 2x + 3 = 11")
except InputGuardrailTripwireTriggered:
    print("Blocked by guardrail")
  • Input guardrails: check the user’s message before or while the agent runs.
  • Output guardrails: check the final answer with @output_guardrail.
  • Tool guardrails: check tool inputs and outputs with @tool_input_guardrail and @tool_output_guardrail.

Sessions and memory

Without a session, each run starts fresh. A session stores the history for you, so follow-up questions work.

from agents import Agent, Runner, SQLiteSession

agent = Agent(name="Helper", instructions="Reply briefly.")
session = SQLiteSession("user_123")

Runner.run_sync(agent, "My name is Priya.", session=session)
result = Runner.run_sync(agent, "What is my name?", session=session)
print(result.final_output)

SQLiteSession keeps history in memory by default, or in a file if you pass a path. For production, the Redis extra gives you a shared store.

Tracing and debugging

Tracing is on by default. Every run records model calls, tool calls, handoffs and guardrails, and you can view them in the Traces section of the OpenAI dashboard.

  • Group runs: wrap related runs in with trace("Support flow"): to see them as one trace.
  • Turn it off: set OPENAI_AGENTS_DISABLE_TRACING=1 or call set_tracing_disabled(True).
  • Hide sensitive data: set OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA to false to leave inputs and outputs out of traces.
  • Zero data retention: tracing is not available for organizations under a ZDR policy.

What changed in recent releases

The SDK moves fast, so pin a version in production. Here are the last few releases from PyPI and GitHub.

Version Date Notes
0.22.0 Aug 19, 2026 Failed or incomplete Responses now raise ModelBehaviorError. Pass organization and project on the AsyncOpenAI client, not alongside it.
0.23.1 Oct 2, 2026 Maintenance release
0.24.0 Oct 15, 2026 MCP annotations exposed on converted tools, run-wide tool error formatting. Older SDKs cannot read new RunState snapshots.

Version 0.24.0 still needs Python 3.10 or newer and the openai package version 3.

If you are comparing frameworks, my Claude Agent SDK guide covers Anthropic’s equivalent.

Troubleshooting: Common Problems and Fixes

  • ModuleNotFoundError: agents: you installed into a different Python. Activate your venv and reinstall openai-agents. Note the import name is agents.
  • Authentication error: OPENAI_API_KEY is not set in this shell. Export it again or load a .env file.
  • MaxTurnsExceeded: the agent looped too long. Raise max_turns or make tool results clearer.
  • Hosted tools fail: they need the Responses API. Do not switch to Chat Completions if you use them.
  • Wrong agent answers: improve each handoff_description and the triage instructions.
  • Rate limit or 429 errors: slow down parallel runs and check your usage tier.
  • run_sync fails in Jupyter: notebooks already run an event loop, so use await Runner.run(...) instead.

Frequently Asked Questions

What is the latest version of the OpenAI Agents SDK?

The latest on PyPI is openai-agents 0.24.0, released on October 15, 2026.

Which model does the Agents SDK use by default?

It uses gpt-5.6-luna when you do not set a model. You can change it per agent, per run or with OPENAI_DEFAULT_MODEL.

Does the Agents SDK use the Responses API?

Yes. The Responses API is the default and recommended path. Chat Completions is available as an option.

Is the OpenAI Agents SDK free?

The SDK is free and open source. You pay only for the API calls your agents make.

Can I use non-OpenAI models?

Yes. The SDK can use other providers through Chat Completions compatible endpoints and extensions such as LiteLLM.

What is the difference between a handoff and an agent as a tool?

A handoff passes the conversation to another agent, which then answers. An agent as a tool is called by a manager agent, which keeps control and writes the final reply.

How do I turn off tracing?

Set OPENAI_AGENTS_DISABLE_TRACING=1 or call set_tracing_disabled(True) at startup.

Sources

Free weekly email

Get new AI guides every week

One short weekly email with our newest local AI, ComfyUI and AI tool guides. No spam, no pop-ups, just the good stuff.

Free. Unsubscribe anytime in one click. We only use your email to send this newsletter. See our privacy policy.

Uneasy woman on a rooftop with a city skyline at dusk, OpenAI logo, hook Agents SDK 0.24 Python guide