Use this file to discover all available pages before exploring further.
The OpenAI Agents SDK is a lightweight Python library for building production-ready agents. It handles the agent loop, tool execution, handoffs between agents, and session memory — letting you focus on what your agents should do rather than how to orchestrate them. The SDK is built on the Responses API and integrates directly with OpenAI models, tracing, and evaluation tooling.
An Agent takes a name, instructions, and an optional list of tools. The Runner executes the agent loop synchronously or asynchronously.
from agents import Agent, Runneragent = Agent( name="AssistantAgent", instructions="You are a helpful assistant. Answer questions clearly and concisely.",)result = Runner.run_sync(agent, "What is the capital of Japan?")print(result.final_output)# Tokyo
Runner.run_sync is a convenience wrapper for non-async contexts. In production async code, use await Runner.run(agent, input) instead.
Tools are Python functions decorated with @function_tool. The SDK automatically generates the JSON schema from your function signature and docstring.
from agents import Agent, Runner, function_tool@function_tooldef get_stock_price(ticker: str) -> str: """Return the current stock price for a given ticker symbol.""" # Replace with a real market data API call prices = {"AAPL": "189.42", "GOOG": "175.10", "MSFT": "415.08"} return prices.get(ticker.upper(), "Price not found")agent = Agent( name="StockAgent", instructions="Help users look up stock prices. Use the get_stock_price tool.", tools=[get_stock_price],)result = Runner.run_sync(agent, "What's the price of Apple stock?")print(result.final_output)
The agent will call get_stock_price with the appropriate arguments and incorporate the result into its response automatically.
Handoffs let one agent transfer control to a specialized agent when appropriate. The receiving agent inherits the conversation context and continues from there.The dispute management example below shows a triage agent routing to either an acceptance agent or an investigator agent based on order fulfillment status:
from agents import Agent, Runner, handoffacceptance_agent = Agent( name="AcceptanceAgent", instructions=( "Handle clear-cut dispute cases where the company made an error. " "Accept the dispute and provide a concise, professional explanation." ),)investigator_agent = Agent( name="InvestigatorAgent", instructions=( "Investigate disputes by analyzing order records and communication history. " "Collect evidence before recommending any action." ),)triage_agent = Agent( name="TriageAgent", instructions=( "Determine whether a dispute should be accepted outright or requires investigation. " "If the order was not fulfilled, hand off to AcceptanceAgent. " "Otherwise hand off to InvestigatorAgent." ), handoffs=[acceptance_agent, investigator_agent],)result = Runner.run_sync( triage_agent, "Customer claims they never received order #8821.")print(result.final_output)
Handoff agents receive the full message history from the previous agent. You don’t need to manually pass context between them.
When a task has multiple independent subtasks, running specialized agents concurrently reduces total latency. Use asyncio.gather to fan out, then pass all outputs to a meta-agent to produce a final unified result.
import asynciofrom agents import Agent, Runner# Specialized agents for product review analysisfeatures_agent = Agent( name="FeaturesAgent", instructions="Extract the key product features from the review.",)pros_cons_agent = Agent( name="ProsConsAgent", instructions="List the pros and cons mentioned in the review.",)sentiment_agent = Agent( name="SentimentAgent", instructions="Summarize the overall user sentiment from the review.",)# Meta-agent combines all outputs into a final summarymeta_agent = Agent( name="MetaAgent", instructions=( "You are given summaries labeled Features, ProsCons, and Sentiment. " "Combine them into a concise executive summary with a 1-5 star rating for each area." ),)async def analyze_review(review_text: str) -> str: # Run all specialist agents concurrently results = await asyncio.gather( Runner.run(features_agent, review_text), Runner.run(pros_cons_agent, review_text), Runner.run(sentiment_agent, review_text), ) # Combine outputs and pass to the meta-agent combined = "\n".join([ f"### {r.last_agent.name}\n{r.final_output}" for r in results ]) final = await Runner.run(meta_agent, combined) return final.final_outputreview = "Battery life is excellent, but the screen dims too quickly in sunlight."print(asyncio.run(analyze_review(review)))
This fan-out / fan-in pattern is directly applicable to real-world scenarios like content moderation, customer-support triage, and document analysis.
The Session object manages conversation history across multiple turns so you don’t have to manually track previous_response_id or append messages yourself.
from agents import Agent, Runner, Sessionagent = Agent( name="SupportAgent", instructions=( "You are a customer support agent. Remember what the user has told you " "across the conversation and refer back to it when relevant." ),)async def multi_turn_conversation(): session = Session() turns = [ "My order #4412 hasn't arrived yet.", "I placed it about two weeks ago.", "What are my options for getting a refund?", ] for user_input in turns: result = await Runner.run(agent, user_input, session=session) print(f"User: {user_input}") print(f"Agent: {result.final_output}\n")asyncio.run(multi_turn_conversation())
For long-running conversations, uncurated history can overwhelm the context window. The Agents SDK supports two main strategies:
1
Trimming
Remove older messages from the history when approaching the context limit. The session keeps recent turns and discards earlier ones.
2
Compression
Summarize the conversation so far into a compact representation, replacing the raw message history with a summary. This preserves key facts while reducing token count.
Both strategies are configurable via the Session object and can be combined. See the session memory cookbook for a full walkthrough.
The Agents SDK integrates with OpenTelemetry-compatible tracing tools (such as Langfuse) to capture internal traces of every agent run. You can use these traces for:
Offline evaluation — batch-test your agent against a labeled dataset and score outputs
Online monitoring — watch costs, latency, and tool-call accuracy in real time
Debugging — inspect the exact sequence of model calls and tool executions when something goes wrong
from agents import Agent, Runner, set_tracing_export_api_key# Enable tracing to an OpenTelemetry-compatible backendset_tracing_export_api_key("your-langfuse-api-key")agent = Agent( name="EvaluatedAgent", instructions="Answer questions about OpenAI products.",)result = Runner.run_sync(agent, "What models does OpenAI offer?")print(result.final_output)# Traces are exported automatically