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.
- 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-lunaif you set none. Pickgpt-6.1-solorgpt-6-astrafor 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
- Check Python. You need Python 3.10 or newer. Run
python3 --version. - Create a virtual environment. Run
python3 -m venv .venv, then activate it withsource .venv/bin/activate(macOS and Linux) or.venv\Scripts\activate(Windows). - Install the package. Run
pip install openai-agents. With uv, runuv add openai-agents. - Add extras if needed. Use
pip install 'openai-agents[voice]'for voice orpip install 'openai-agents[redis]'for Redis sessions. - Set your API key. Run
export OPENAI_API_KEY=sk-...on macOS and Linux, orsetx OPENAI_API_KEY "sk-..."on Windows. - 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_MODELenvironment 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_guardrailand@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=1or callset_tracing_disabled(True). - Hide sensitive data: set
OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATAto 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 reinstallopenai-agents. Note the import name isagents.- Authentication error:
OPENAI_API_KEYis not set in this shell. Export it again or load a.envfile. MaxTurnsExceeded: the agent looped too long. Raisemax_turnsor 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_descriptionand the triage instructions. - Rate limit or 429 errors: slow down parallel runs and check your usage tier.
run_syncfails in Jupyter: notebooks already run an event loop, so useawait 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.



