You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/agents.md
+37-10Lines changed: 37 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,43 @@
1
1
# Agents
2
2
3
-
Agents are the core building block in your apps. An agent is a large language model (LLM), configured with instructionsand tools.
3
+
Agents are the core building block in your apps. An agent is a large language model (LLM) configured with instructions, tools, and optional runtime behavior such as handoffs, guardrails, and structured outputs.
4
4
5
-
## Basic configuration
5
+
Use this page when you want to define or customize a single agent. If you are deciding how multiple agents should collaborate, read [Agent orchestration](multi_agent.md).
6
+
7
+
## Choose the next guide
8
+
9
+
Use this page as the hub for agent definition. Jump to the adjacent guide that matches the next decision you need to make.
6
10
7
-
The most common properties of an agent you'll configure are:
11
+
| If you want to... | Read next |
12
+
| --- | --- |
13
+
| Choose a model or provider setup |[Models](models/index.md)|
14
+
| Add capabilities to the agent |[Tools](tools.md)|
15
+
| Decide between manager-style orchestration and handoffs |[Agent orchestration](multi_agent.md)|
| Run turns, stream events, or manage conversation state |[Running agents](running_agents.md)|
18
+
| Inspect final output, run items, or resumable state |[Results](results.md)|
19
+
| Share local dependencies and runtime state |[Context management](context.md)|
8
20
9
-
-`name`: A required string that identifies your agent.
10
-
-`instructions`: also known as a developer message or system prompt.
11
-
-`model`: which LLM to use, and optional `model_settings` to configure model tuning parameters like temperature, top_p, etc.
12
-
-`prompt`: Reference a prompt template by id (and variables) when using OpenAI's Responses API.
13
-
-`tools`: Tools that the agent can use to achieve its tasks.
14
-
-`mcp_servers`: MCP servers that provide tools to the agent. See the [MCP guide](mcp.md).
15
-
-`reset_tool_choice`: Whether to reset `tool_choice` after a tool call (default: `True`) to avoid tool-use loops. See [Forcing tool use](#forcing-tool-use).
21
+
## Basic configuration
22
+
23
+
The most common properties of an agent are:
24
+
25
+
| Property | Required | Description |
26
+
| --- | --- | --- |
27
+
|`name`| yes | Human-readable agent name. |
28
+
|`instructions`| yes | System prompt or dynamic instructions callback. See [Dynamic instructions](#dynamic-instructions). |
29
+
|`prompt`| no | OpenAI Responses API prompt configuration. Accepts a static prompt object or a function. See [Prompt templates](#prompt-templates). |
30
+
|`handoff_description`| no | Short description exposed when this agent is offered as a handoff target. |
31
+
|`handoffs`| no | Delegate the conversation to specialist agents. See [handoffs](handoffs.md). |
32
+
|`model`| no | Which LLM to use. See [Models](models/index.md). |
33
+
|`model_settings`| no | Model tuning parameters such as `temperature`, `top_p`, and `tool_choice`. |
34
+
|`tools`| no | Tools the agent can call. See [Tools](tools.md). |
35
+
|`mcp_servers`| no | MCP-backed tools for the agent. See the [MCP guide](mcp.md). |
36
+
|`input_guardrails`| no | Guardrails that run on the first user input for this agent chain. See [Guardrails](guardrails.md). |
37
+
|`output_guardrails`| no | Guardrails that run on the final output for this agent. See [Guardrails](guardrails.md). |
38
+
|`output_type`| no | Structured output type instead of plain text. See [Output types](#output-types). |
39
+
|`tool_use_behavior`| no | Control whether tool results loop back to the model or end the run. See [Tool use behavior](#tool-use-behavior). |
40
+
|`reset_tool_choice`| no | Reset `tool_choice` after a tool call (default: `True`) to avoid tool-use loops. See [Forcing tool use](#forcing-tool-use). |
16
41
17
42
```python
18
43
from agents import Agent, ModelSettings, function_tool
@@ -93,6 +118,8 @@ result = await Runner.run(
93
118
94
119
Agents are generic on their `context` type. Context is a dependency-injection tool: it's an object you create and pass to `Runner.run()`, that is passed to every agent, tool, handoff etc, and it serves as a grab bag of dependencies and state for the agent run. You can provide any Python object as the context.
95
120
121
+
Read the [context guide](context.md) for the full `RunContextWrapper` surface, shared usage tracking, nested `tool_input`, and serialization caveats.
Copy file name to clipboardExpand all lines: docs/context.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,23 @@ You can use the context for things like:
25
25
26
26
The context object is **not** sent to the LLM. It is purely a local object that you can read from, write to and call methods on it.
27
27
28
+
Within a single run, derived wrappers share the same underlying app context, approval state, and usage tracking. Nested [`Agent.as_tool()`][agents.agent.Agent.as_tool] runs may attach a different `tool_input`, but they do not get an isolated copy of your app state by default.
29
+
30
+
### What `RunContextWrapper` exposes
31
+
32
+
[`RunContextWrapper`][agents.run_context.RunContextWrapper] is a wrapper around your app-defined context object. In practice you will most often use:
33
+
34
+
-[`wrapper.context`][agents.run_context.RunContextWrapper.context] for your own mutable app state and dependencies.
35
+
-[`wrapper.usage`][agents.run_context.RunContextWrapper.usage] for aggregated request and token usage across the current run.
36
+
-[`wrapper.tool_input`][agents.run_context.RunContextWrapper.tool_input] for structured input when the current run is executing inside [`Agent.as_tool()`][agents.agent.Agent.as_tool].
37
+
-[`wrapper.approve_tool(...)`][agents.run_context.RunContextWrapper.approve_tool] / [`wrapper.reject_tool(...)`][agents.run_context.RunContextWrapper.reject_tool] when you need to update approval state programmatically.
38
+
39
+
Only `wrapper.context` is your app-defined object. The other fields are runtime metadata managed by the SDK.
40
+
41
+
If you later serialize a [`RunState`][agents.run_state.RunState] for human-in-the-loop or durable job workflows, that runtime metadata is saved with the state. Avoid putting secrets in [`RunContextWrapper.context`][agents.run_context.RunContextWrapper.context] if you intend to persist or transmit serialized state.
42
+
43
+
Conversation state is a separate concern. Use `result.to_input_list()`, `session`, `conversation_id`, or `previous_response_id` depending on how you want to carry turns forward. See [results](results.md), [running agents](running_agents.md), and [sessions](sessions/index.md) for that decision.
44
+
28
45
```python
29
46
import asyncio
30
47
from dataclasses import dataclass
@@ -109,7 +126,7 @@ plus additional fields specific to the current tool call:
109
126
-`tool_arguments` – the raw argument string passed to the tool
110
127
111
128
Use `ToolContext` when you need tool-level metadata during execution.
112
-
For general context sharing between agents and tools, `RunContextWrapper` remains sufficient.
129
+
For general context sharing between agents and tools, `RunContextWrapper` remains sufficient. Because `ToolContext` extends `RunContextWrapper`, it can also expose `.tool_input` when a nested `Agent.as_tool()` run supplied structured input.
Copy file name to clipboardExpand all lines: docs/guardrails.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,16 @@ There are two kinds of guardrails:
7
7
1. Input guardrails run on the initial user input
8
8
2. Output guardrails run on the final agent output
9
9
10
+
## Workflow boundaries
11
+
12
+
Guardrails are attached to agents and tools, but they do not all run at the same points in a workflow:
13
+
14
+
-**Input guardrails** run only for the first agent in the chain.
15
+
-**Output guardrails** run only for the agent that produces the final output.
16
+
-**Tool guardrails** run on every custom function-tool invocation, with input guardrails before execution and output guardrails after execution.
17
+
18
+
If you need checks around each custom function-tool call in a workflow that includes managers, handoffs, or delegated specialists, use tool guardrails instead of relying only on agent-level input/output guardrails.
19
+
10
20
## Input guardrails
11
21
12
22
Input guardrails run in 3 steps:
@@ -47,7 +57,7 @@ Tool guardrails wrap **function tools** and let you validate or block tool calls
47
57
48
58
- Input tool guardrails run before the tool executes and can skip the call, replace the output with a message, or raise a tripwire.
49
59
- Output tool guardrails run after the tool executes and can replace the output or raise a tripwire.
50
-
- Tool guardrails apply only to function tools created with [`function_tool`][agents.function_tool]; hosted tools (`WebSearchTool`, `FileSearchTool`, `HostedMCPTool`, `CodeInterpreterTool`, `ImageGenerationTool`) and built-in execution tools (`ComputerTool`, `ShellTool`, `ApplyPatchTool`, `LocalShellTool`) do not use this guardrail pipeline.
60
+
- Tool guardrails apply only to function tools created with [`function_tool`][agents.tool.function_tool]. Handoffs run through the SDK's handoff pipeline rather than the normal function-tool pipeline, so tool guardrails do not apply to the handoff call itself. Hosted tools (`WebSearchTool`, `FileSearchTool`, `HostedMCPTool`, `CodeInterpreterTool`, `ImageGenerationTool`) and built-in execution tools (`ComputerTool`, `ShellTool`, `ApplyPatchTool`, `LocalShellTool`) also do not use this guardrail pipeline, and [`Agent.as_tool()`][agents.agent.Agent.as_tool] does not currently expose tool-guardrail options directly.
Copy file name to clipboardExpand all lines: docs/handoffs.md
+34-1Lines changed: 34 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,11 +36,13 @@ The [`handoff()`][agents.handoffs.handoff] function lets you customize things.
36
36
-`tool_name_override`: By default, the `Handoff.default_tool_name()` function is used, which resolves to `transfer_to_<agent_name>`. You can override this.
37
37
-`tool_description_override`: Override the default tool description from `Handoff.default_tool_description()`
38
38
-`on_handoff`: A callback function executed when the handoff is invoked. This is useful for things like kicking off some data fetching as soon as you know a handoff is being invoked. This function receives the agent context, and can optionally also receive LLM generated input. The input data is controlled by the `input_type` param.
39
-
-`input_type`: The type of input expected by the handoff (optional).
39
+
-`input_type`: The schema for the handoff tool-call arguments. When set, the parsed payload is passed to `on_handoff`.
40
40
-`input_filter`: This lets you filter the input received by the next agent. See below for more.
41
41
-`is_enabled`: Whether the handoff is enabled. This can be a boolean or a function that returns a boolean, allowing you to dynamically enable or disable the handoff at runtime.
42
42
-`nest_handoff_history`: Optional per-call override for the RunConfig-level `nest_handoff_history` setting. If `None`, the value defined in the active run configuration is used instead.
43
43
44
+
The [`handoff()`][agents.handoffs.handoff] helper always transfers control to the specific `agent` you passed in. If you have multiple possible destinations, register one handoff per destination and let the model choose among them. Use a custom [`Handoff`][agents.handoffs.Handoff] only when your own handoff code must decide which agent to return at invocation time.
45
+
44
46
```python
45
47
from agents import Agent, handoff, RunContextWrapper
46
48
@@ -81,12 +83,43 @@ handoff_obj = handoff(
81
83
)
82
84
```
83
85
86
+
`input_type` describes the arguments for the handoff tool call itself. The SDK exposes that schema to the model as the handoff tool's `parameters`, validates the returned JSON locally, and passes the parsed value to `on_handoff`.
87
+
88
+
It does not replace the next agent's main input, and it does not choose a different destination. The [`handoff()`][agents.handoffs.handoff] helper still transfers to the specific agent you wrapped, and the receiving agent still sees the conversation history unless you change it with an [`input_filter`][agents.handoffs.Handoff.input_filter] or nested handoff history settings.
89
+
90
+
`input_type` is also separate from [`RunContextWrapper.context`][agents.run_context.RunContextWrapper.context]. Use `input_type` for metadata the model decides at handoff time, not for application state or dependencies you already have locally.
91
+
92
+
### When to use `input_type`
93
+
94
+
Use `input_type` when the handoff needs a small piece of model-generated metadata such as `reason`, `language`, `priority`, or `summary`. For example, a triage agent can hand off to a refund agent with `{ "reason": "duplicate_charge", "priority": "high" }`, and `on_handoff` can log or persist that metadata before the refund agent takes over.
95
+
96
+
Choose a different mechanism when the goal is different:
97
+
98
+
- Put existing application state and dependencies in [`RunContextWrapper.context`][agents.run_context.RunContextWrapper.context]. See the [context guide](context.md).
99
+
- Use [`input_filter`][agents.handoffs.Handoff.input_filter], [`RunConfig.nest_handoff_history`][agents.run.RunConfig.nest_handoff_history], or [`RunConfig.handoff_history_mapper`][agents.run.RunConfig.handoff_history_mapper] if you want to change what history the receiving agent sees.
100
+
- Register one handoff per destination if there are multiple possible specialists. `input_type` can add metadata to the chosen handoff, but it does not dispatch between destinations.
101
+
- If you want structured input for a nested specialist without transferring the conversation, prefer [`Agent.as_tool(parameters=...)`][agents.agent.Agent.as_tool]. See [tools](tools.md#structured-input-for-tool-agents).
102
+
84
103
## Input filters
85
104
86
105
When a handoff occurs, it's as though the new agent takes over the conversation, and gets to see the entire previous conversation history. If you want to change this, you can set an [`input_filter`][agents.handoffs.Handoff.input_filter]. An input filter is a function that receives the existing input via a [`HandoffInputData`][agents.handoffs.HandoffInputData], and must return a new `HandoffInputData`.
-`input_history`: the input history before `Runner.run(...)` started.
110
+
-`pre_handoff_items`: items generated before the agent turn where the handoff was invoked.
111
+
-`new_items`: items generated during the current turn, including the handoff call and handoff output items.
112
+
-`input_items`: optional items to forward to the next agent instead of `new_items`, allowing you to filter model input while keeping `new_items` intact for session history.
113
+
-`run_context`: the active [`RunContextWrapper`][agents.run_context.RunContextWrapper] at the time the handoff was invoked.
114
+
88
115
Nested handoffs are available as an opt-in beta and are disabled by default while we stabilize them. When you enable [`RunConfig.nest_handoff_history`][agents.run.RunConfig.nest_handoff_history], the runner collapses the prior transcript into a single assistant summary message and wraps it in a `<CONVERSATION HISTORY>` block that keeps appending new turns when multiple handoffs happen during the same run. You can provide your own mapping function via [`RunConfig.handoff_history_mapper`][agents.run.RunConfig.handoff_history_mapper] to replace the generated message without writing a full `input_filter`. The opt-in only applies when neither the handoff nor the run supplies an explicit `input_filter`, so existing code that already customizes the payload (including the examples in this repository) keeps its current behavior without changes. You can override the nesting behaviour for a single handoff by passing `nest_handoff_history=True` or `False` to [`handoff(...)`][agents.handoffs.handoff], which sets [`Handoff.nest_handoff_history`][agents.handoffs.Handoff.nest_handoff_history]. If you just need to change the wrapper text for the generated summary, call [`set_conversation_history_wrappers`][agents.handoffs.set_conversation_history_wrappers] (and optionally [`reset_conversation_history_wrappers`][agents.handoffs.reset_conversation_history_wrappers]) before running your agents.
89
116
117
+
If both the handoff and the active [`RunConfig.handoff_input_filter`][agents.run.RunConfig.handoff_input_filter] define a filter, the per-handoff [`input_filter`][agents.handoffs.Handoff.input_filter] takes precedence for that specific handoff.
118
+
119
+
!!! note
120
+
121
+
Handoffs stay within a single run. Input guardrails still apply only to the first agent in the chain, and output guardrails only to the agent that produces the final output. Use tool guardrails when you need checks around each custom function-tool call inside the workflow.
122
+
90
123
There are some common patterns (for example removing all tool calls from the history), which are implemented for you in [`agents.extensions.handoff_filters`][]
0 commit comments