|
| 1 | +# OpenAI Agents SDK |
| 2 | + |
| 3 | +The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows. |
| 4 | + |
| 5 | +<img src="https://cdn.openai.com/API/docs/images/orchestration.png" alt="Image of the Agents Tracing UI" style="max-height: 803px;"> |
| 6 | + |
| 7 | +### Core concepts: |
| 8 | + |
| 9 | +1. [**Agents**](https://openai.github.io/openai-agents-python/agents): LLMs configured with instructions, tools, guardrails, and handoffs |
| 10 | +2. [**Handoffs**](https://openai.github.io/openai-agents-python/handoffs/): Allow agents to transfer control to other agents for specific tasks |
| 11 | +3. [**Guardrails**](https://openai.github.io/openai-agents-python/guardrails/): Configurable safety checks for input and output validation |
| 12 | +4. [**Tracing**](https://openai.github.io/openai-agents-python/tracing/): Built-in tracking of agent runs, allowing you to view, debug and optimize your workflows |
| 13 | + |
| 14 | +Explore the [examples](examples) directory to see the SDK in action, and read our [documentation](https://openai.github.io/openai-agents-python/) for more details. |
| 15 | + |
| 16 | +Notably, our SDK [is compatible](https://openai.github.io/openai-agents-python/models/) with any model providers that support the OpenAI Chat Completions API format. |
| 17 | + |
| 18 | +## Get started |
| 19 | + |
| 20 | +1. Set up your Python environment |
| 21 | + |
| 22 | +``` |
| 23 | +python -m venv env |
| 24 | +.\env\Scripts\activate |
| 25 | +
|
| 26 | +
|
| 27 | +2. Install Agents SDK |
| 28 | +
|
| 29 | +``` |
| 30 | +pip install openai-agents |
| 31 | +``` |
| 32 | +
|
| 33 | +## Hello world example |
| 34 | +
|
| 35 | +```python |
| 36 | +from agents import Agent, Runner |
| 37 | +
|
| 38 | +agent = Agent(name="Assistant", instructions="You are a helpful assistant") |
| 39 | +
|
| 40 | +result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") |
| 41 | +print(result.final_output) |
| 42 | +
|
| 43 | +# Code within the code, |
| 44 | +# Functions calling themselves, |
| 45 | +# Infinite loop's dance. |
| 46 | +``` |
| 47 | + |
| 48 | +(_If running this, ensure you set the `OPENAI_API_KEY` environment variable_) |
| 49 | + |
| 50 | +(_For Jupyter notebook users, see [hello_world_jupyter.py](examples/basic/hello_world_jupyter.py)_) |
| 51 | + |
| 52 | +## Handoffs example |
| 53 | + |
| 54 | +```python |
| 55 | +from agents import Agent, Runner |
| 56 | +import asyncio |
| 57 | + |
| 58 | +spanish_agent = Agent( |
| 59 | + name="Spanish agent", |
| 60 | + instructions="You only speak Spanish.", |
| 61 | +) |
| 62 | + |
| 63 | +english_agent = Agent( |
| 64 | + name="English agent", |
| 65 | + instructions="You only speak English", |
| 66 | +) |
| 67 | + |
| 68 | +triage_agent = Agent( |
| 69 | + name="Triage agent", |
| 70 | + instructions="Handoff to the appropriate agent based on the language of the request.", |
| 71 | + handoffs=[spanish_agent, english_agent], |
| 72 | +) |
| 73 | + |
| 74 | + |
| 75 | +async def main(): |
| 76 | + result = await Runner.run(triage_agent, input="Hola, ¿cómo estás?") |
| 77 | + print(result.final_output) |
| 78 | + # ¡Hola! Estoy bien, gracias por preguntar. ¿Y tú, cómo estás? |
| 79 | + |
| 80 | + |
| 81 | +if __name__ == "__main__": |
| 82 | + asyncio.run(main()) |
| 83 | +``` |
| 84 | + |
| 85 | +## Functions example |
| 86 | + |
| 87 | +```python |
| 88 | +import asyncio |
| 89 | + |
| 90 | +from agents import Agent, Runner, function_tool |
| 91 | + |
| 92 | + |
| 93 | +@function_tool |
| 94 | +def get_weather(city: str) -> str: |
| 95 | + return f"The weather in {city} is sunny." |
| 96 | + |
| 97 | + |
| 98 | +agent = Agent( |
| 99 | + name="Hello world", |
| 100 | + instructions="You are a helpful agent.", |
| 101 | + tools=[get_weather], |
| 102 | +) |
| 103 | + |
| 104 | + |
| 105 | +async def main(): |
| 106 | + result = await Runner.run(agent, input="What's the weather in Tokyo?") |
| 107 | + print(result.final_output) |
| 108 | + # The weather in Tokyo is sunny. |
| 109 | + |
| 110 | + |
| 111 | +if __name__ == "__main__": |
| 112 | + asyncio.run(main()) |
| 113 | +``` |
| 114 | + |
| 115 | +## The agent loop |
| 116 | + |
| 117 | +When you call `Runner.run()`, we run a loop until we get a final output. |
| 118 | + |
| 119 | +1. We call the LLM, using the model and settings on the agent, and the message history. |
| 120 | +2. The LLM returns a response, which may include tool calls. |
| 121 | +3. If the response has a final output (see below for more on this), we return it and end the loop. |
| 122 | +4. If the response has a handoff, we set the agent to the new agent and go back to step 1. |
| 123 | +5. We process the tool calls (if any) and append the tool responses messages. Then we go to step 1. |
| 124 | + |
| 125 | +There is a `max_turns` parameter that you can use to limit the number of times the loop executes. |
| 126 | + |
| 127 | +### Final output |
| 128 | + |
| 129 | +Final output is the last thing the agent produces in the loop. |
| 130 | + |
| 131 | +1. If you set an `output_type` on the agent, the final output is when the LLM returns something of that type. We use [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) for this. |
| 132 | +2. If there's no `output_type` (i.e. plain text responses), then the first LLM response without any tool calls or handoffs is considered as the final output. |
| 133 | + |
| 134 | +As a result, the mental model for the agent loop is: |
| 135 | + |
| 136 | +1. If the current agent has an `output_type`, the loop runs until the agent produces structured output matching that type. |
| 137 | +2. If the current agent does not have an `output_type`, the loop runs until the current agent produces a message without any tool calls/handoffs. |
| 138 | + |
| 139 | +## Common agent patterns |
| 140 | + |
| 141 | +The Agents SDK is designed to be highly flexible, allowing you to model a wide range of LLM workflows including deterministic flows, iterative loops, and more. See examples in [`examples/agent_patterns`](examples/agent_patterns). |
| 142 | + |
| 143 | +## Tracing |
| 144 | + |
| 145 | +The Agents SDK automatically traces your agent runs, making it easy to track and debug the behavior of your agents. Tracing is extensible by design, supporting custom spans and a wide variety of external destinations, including [Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents), [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk), [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk), and [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent). For more details about how to customize or disable tracing, see [Tracing](http://openai.github.io/openai-agents-python/tracing). |
| 146 | + |
| 147 | +## Development (only needed if you need to edit the SDK/examples) |
| 148 | + |
| 149 | +0. Ensure you have [`uv`](https://docs.astral.sh/uv/) installed. |
| 150 | + |
| 151 | +```bash |
| 152 | +uv --version |
| 153 | +``` |
| 154 | + |
| 155 | +1. Install dependencies |
| 156 | + |
| 157 | +```bash |
| 158 | +make sync |
| 159 | +``` |
| 160 | + |
| 161 | +2. (After making changes) lint/test |
| 162 | + |
| 163 | +``` |
| 164 | +make tests # run tests |
| 165 | +make mypy # run typechecker |
| 166 | +make lint # run linter |
| 167 | +``` |
| 168 | + |
| 169 | +## Acknowledgements |
| 170 | + |
| 171 | +We'd like to acknowledge the excellent work of the open-source community, especially: |
| 172 | + |
| 173 | +- [Pydantic](https://docs.pydantic.dev/latest/) (data validation) and [PydanticAI](https://ai.pydantic.dev/) (advanced agent framework) |
| 174 | +- [MkDocs](https://github.com/squidfunk/mkdocs-material) |
| 175 | +- [Griffe](https://github.com/mkdocstrings/griffe) |
| 176 | +- [uv](https://github.com/astral-sh/uv) and [ruff](https://github.com/astral-sh/ruff) |
| 177 | + |
| 178 | +We're committed to continuing to build the Agents SDK as an open source framework so others in the community can expand on our approach. |
0 commit comments