Repository Public
1# Multi-agent23> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.45## Overview67Multi-agent lets a model spin up and coordinate subagents in parallel, synthesizing their work to provide a final response. This is especially effective for applications with complex tasks that benefit from parallel work delegation, such as codebase exploration, documentation, and implementation.89Multi-agent is available as a beta feature with all GPT-5.6 models. Check the model page before enabling Multi-agent in your application.1011## When to use Multi-agent1213Tasks can often be divided into independent sections of work that a single agent would complete sequentially, but multiple agents are able to tackle in parallel. Multi-agent enables a root agent to delegate to multiple subagents that complete work concurrently. This can provide multiple benefits:1415- **Parallel execution.** Independent research, analysis, or implementation tasks can proceed at the same time, which can lead to faster execution.16- **Focused context.** Each subagent receives a bounded task and maintains its own context, which reduces interference in context between unrelated lines of work and improves performance.17- **Model-directed coordination.** The root agent can create subagents, send them additional information, wait for results, and synthesize a final answer without requiring your application to implement orchestration.1819Multi-agent orchestration is most useful when a task can be divided into concrete, independent workstreams, such as:2021- Exploring separate parts of a large codebase22- Comparing multiple proposals, documents, or hypotheses23- Researching several sources in parallel24- Implementing independent components or writing independent test suites25- Investigating different possible causes of a failure in parallel26- Exploring separate approaches to a problem concurrently2728Note that adding subagents can increase token usage, and may not be as beneficial for tasks that depend on a single ordered chain of reasoning, require frequent writes to shared mutable state, or are already dominated by one slow external operation.2930| Use Multi-agent when | Prefer one agent when |31| ------------------------------------------------- | ----------------------------------------------------- |32| Work can be split into independent, bounded tasks | Each step depends directly on the previous step |33| Separate context improves focus | The task is small enough to complete in one short run |34| Parallel exploration can reduce wall-clock time | Agents would contend over the same mutable resource |35| Comparing independent findings improves coverage | You require a fixed, deterministic execution graph |3637## Quickstart3839The Python and JavaScript examples use the beta Responses SDK. For HTTP40 requests, use `client.beta.responses` and pass `responses_multi_agent=v1` in41 the `betas` argument. For raw HTTP requests and WebSocket connections, pass42 `OpenAI-Beta: responses_multi_agent=v1` in the request or connection headers.43 Item schemas may change while Multi-agent is in beta.4445Enable Multi-agent in your Responses API request with `multi_agent.enabled`. When `multi_agent.enabled` is `true`, the root agent becomes eligible to spawn a tree of subagents. The subagents share the request’s model and available tools, while agents coordinate through collaboration primitives such as spawning, messaging, and waiting (see [How Multi-agent works](#how-multi-agent-works)). The root agent is responsible for synthesizing subagent responses and providing the final response.4647Review a pull request with subagents4849```javascript50import OpenAI from "openai";5152const client = new OpenAI();5354async function reviewPullRequest(diff) {55 const response = await client.beta.responses.create({56 model: "gpt-5.6-sol",57 input:58 "Review the pull-request diff below with three agents: one for " +59 "correctness, one for security, and one for missing tests. " +60 "Reconcile duplicate or conflicting findings, then return a " +61 "prioritized review with file and line references.\n\n" +62 `<diff>\n${diff}\n</diff>`,63 multi_agent: {64 enabled: true,65 max_concurrent_subagents: 3,66 },67 betas: ["responses_multi_agent=v1"],68 });6970 return response.output71 .flatMap((item) =>72 item.type === "message" &&73 item.agent?.agent_name === "/root" &&74 item.phase === "final_answer"75 ? item.content76 : []77 )78 .filter((part) => part.type === "output_text")79 .map((part) => part.text)80 .join("");81}82```8384```python85from openai import OpenAI8687client = OpenAI()888990def review_pull_request(diff: str) -> str:91 response = client.beta.responses.create(92 model="gpt-5.6-sol",93 input=(94 "Review the pull-request diff below with three agents: one for "95 "correctness, one for security, and one for missing tests. "96 "Reconcile duplicate or conflicting findings, then return a "97 "prioritized review with file and line references.\n\n"98 f"<diff>\n{diff}\n</diff>"99 ),100 multi_agent={101 "enabled": True,102 "max_concurrent_subagents": 3,103 },104 betas=["responses_multi_agent=v1"],105 )106107 return "".join(108 part.text109 for item in response.output110 if (111 item.type == "message"112 and item.agent is not None113 and item.agent.agent_name == "/root"114 and item.phase == "final_answer"115 )116 for part in item.content117 if part.type == "output_text"118 )119```120121122`max_concurrent_subagents` sets the maximum number of subagents that can be active simultaneously across the entire agent tree. It includes all descendants—children, grandchildren, and deeper subagents—but excludes the root agent.123124The API does not impose a fixed upper bound on this setting. The default is `3`, which is recommended for most workloads. Multi-agent runs also have no fixed limit on tree depth or the total number of subagents created during a run.125126Add a developer message to tune when the root model should spawn subagents. This developer message is additive to the instructions injected for the root agent and subagents.127128Examples of developer messages include:129130- “Do not spawn subagents unless the user explicitly asks for subagents, delegation, or parallel agent work.”131- “Proactive Multi-agent delegation is active. Use subagents when parallel work would materially improve speed or quality.”132133## How Multi-agent works134135The Responses API provides the root and subagent models with hosted orchestration actions and instructions for using them. The root agent is named `/root`. Spawned subagents use hierarchical paths such as:136137```text138/root139├── /root/researcher140├── /root/reviewer141└── /root/reviewer/tester142```143144Multi-agent imposes no fixed limit on the total number of subagents or tree depth. For most tasks, use the default `max_concurrent_subagents` value of `3`. This setting limits the number of active subagent turns across the entire tree, including children and deeper descendants.145146When Multi-agent mode is enabled, the Responses API provides six hosted collaboration actions. You may see these as `multi_agent_call` items. Your application should not execute these or submit outputs for them.147148| Action | Purpose |149| ----------------- | ------------------------------------------------------------------------------ |150| `spawn_agent` | Create a subagent and assign its initial task. |151| `send_message` | Queue a message for an existing agent without starting a new turn. |152| `followup_task` | Assign more work to an existing non-root agent and start or resume its turn. |153| `wait_agent` | Wait for an update in the calling agent's mailbox. |154| `interrupt_agent` | Interrupt another agent's active turn without deleting its context. |155| `list_agents` | Return the current agent tree, statuses, and each agent's `last_task_message`. |156157Handling developer-defined tool calls works in the same way as without Multi-agent enabled. Any agent in the tree may emit a `function_call`. Your application must execute the call and submit a matching `function_call_output`.158159Note that all agents in the tree have access to the tools configured in the API request’s model call.160161## Using Multi-agent in Responses API162163### HTTP vs. WebSocket performance164165HTTP and WebSocket support the same Multi-agent capabilities, but WebSocket is recommended for tool-heavy or long-running workflows. Its persistent connection lets your application return function outputs as they become available, reducing continuation overhead and allowing agents to spend less time waiting.166167With HTTP, the response completes once every active agent has either finished or paused to wait for a client-executed function call. Your application then executes all outstanding function calls and submits their outputs in a new Responses API request, allowing the paused agents to resume.168169With WebSocket, your application can inject each function output into the response as soon as it becomes available, without waiting for the active response to complete. The waiting agent can resume immediately while other agents continue working. This reduces coordination delays and avoids extra request round trips when agents finish or request tools at different times.170171HTTP may be sufficient for workflows that require calling multiple hosted tools, such as parallel web searches, or one-request workflows with few function calls. For most Multi-agent workflows, WebSocket is likely to provide lower latency and better end-to-end performance.172173#### HTTP function call execution174175176177#### WebSocket function call execution178179180181### HTTP182183These examples require beta SDK builds that expose the beta Responses API. For HTTP streaming, call `client.beta.responses.create` and pass `responses_multi_agent=v1` with the `betas` argument; this enables beta types and autocomplete. In Python, import beta response item types from `openai.types.beta` when adding type annotations.184185Example client-side code:186187Handle HTTP streaming tool calls188189```javascript190import OpenAI from "openai";191192const client = new OpenAI();193const ROOT = "/root";194const proposals = {195 alpha: { estimated_weeks: 6, risk: "medium" },196 beta: { estimated_weeks: 8, risk: "low" },197};198199const tools = [200 {201 type: "function",202 name: "get_proposal",203 description:204 "Return details for a proposal that the agents should compare.",205 parameters: {206 type: "object",207 properties: {208 proposal: {209 type: "string",210 enum: ["alpha", "beta"],211 },212 },213 required: ["proposal"],214 additionalProperties: false,215 },216 strict: true,217 },218];219220const history = [221 {222 role: "user",223 content: "Compare proposal alpha and proposal beta.",224 },225];226227function agentName(item) {228 return item.agent?.agent_name ?? ROOT;229}230231function processToolCall(name, argumentsJson) {232 if (name !== "get_proposal") {233 throw new Error(`Unknown tool: ${name}`);234 }235 const { proposal } = JSON.parse(argumentsJson);236237 return JSON.stringify(proposals[proposal]);238}239240while (true) {241 const outputItems = [];242 const pendingCalls = [];243 const itemAgents = new Map();244245 const stream = await client.beta.responses.create({246 model: "gpt-5.6-sol",247 // Beta output items can be replayed as input on the next request.248 input: history,249 tools,250 store: false,251 multi_agent: {252 enabled: true,253 max_concurrent_subagents: 3,254 },255 stream: true,256 betas: ["responses_multi_agent=v1"],257 });258259 for await (const event of stream) {260 if (event.type === "response.output_item.added") {261 itemAgents.set(event.output_index, agentName(event.item));262 } else if (event.type === "response.output_text.delta") {263 const agent = itemAgents.get(event.output_index) ?? ROOT;264 const destination = agent === ROOT ? process.stdout : process.stderr;265 destination.write(266 agent === ROOT ? event.delta : `[${agent}] ${event.delta}`267 );268 } else if (event.type === "response.output_item.done") {269 outputItems.push(event.item);270 if (event.item.type === "function_call") {271 pendingCalls.push(event.item);272 }273 } else if (event.type === "response.completed") {274 console.error("\nUsage:", event.response.usage);275 break;276 } else if (277 event.type === "error" ||278 event.type === "response.failed" ||279 event.type === "response.incomplete"280 ) {281 throw new Error(JSON.stringify(event));282 }283 }284285 history.push(...outputItems);286 for (const call of pendingCalls) {287 history.push({288 type: "function_call_output",289 call_id: call.call_id,290 output: processToolCall(call.name, call.arguments),291 });292 }293294 if (pendingCalls.length === 0) break;295}296```297298```python299from __future__ import annotations300301import json302import sys303304from openai import OpenAI305from openai.types.beta import BetaResponseOutputItem306307client = OpenAI()308ROOT = "/root"309PROPOSALS = {310 "alpha": {"estimated_weeks": 6, "risk": "medium"},311 "beta": {"estimated_weeks": 8, "risk": "low"},312}313tools = [314 {315 "type": "function",316 "name": "get_proposal",317 "description": "Return details for a proposal that the agents should compare.",318 "parameters": {319 "type": "object",320 "properties": {321 "proposal": {322 "type": "string",323 "enum": ["alpha", "beta"],324 }325 },326 "required": ["proposal"],327 "additionalProperties": False,328 },329 "strict": True,330 }331]332history = [333 {334 "role": "user",335 "content": "Compare proposal alpha and proposal beta.",336 }337]338339340def agent_name(item: BetaResponseOutputItem) -> str:341 return item.agent.agent_name if item.agent else ROOT342343344def render_to_user(delta: str) -> None:345 print(delta, end="", flush=True)346347348def log_subagent_text(agent: str, delta: str) -> None:349 print(f"[{agent}] {delta}", end="", file=sys.stderr, flush=True)350351352def process_tool_call(name: str, arguments: str) -> str:353 if name != "get_proposal":354 raise ValueError(f"Unknown tool: {name}")355 parsed_arguments = json.loads(arguments)356 return json.dumps(PROPOSALS[parsed_arguments["proposal"]])357358359while True:360 output_items = []361 pending_calls = []362 item_agents: dict[int, str] = {}363364 stream = client.beta.responses.create(365 model="gpt-5.6-sol",366 input=history,367 tools=tools,368 store=False,369 multi_agent={370 "enabled": True,371 "max_concurrent_subagents": 3,372 },373 stream=True,374 betas=["responses_multi_agent=v1"],375 )376 for event in stream:377 if event.type == "response.output_item.added":378 item_agents[event.output_index] = agent_name(event.item)379 elif event.type == "response.output_text.delta":380 agent = item_agents.get(event.output_index, ROOT)381 if agent == ROOT:382 render_to_user(event.delta)383 else:384 log_subagent_text(agent, event.delta)385 elif event.type == "response.output_item.done":386 output_items.append(event.item)387 if event.item.type == "function_call":388 # Handle function calls from both the root agent and subagents.389 pending_calls.append(event.item)390 elif event.type == "response.completed":391 print(f"\nUsage: {event.response.usage}", file=sys.stderr)392 break393 elif event.type in {394 "error",395 "response.failed",396 "response.incomplete",397 }:398 raise RuntimeError(event)399400 history.extend(output_items)401402 for call in pending_calls:403 history.append(404 {405 "type": "function_call_output",406 "call_id": call.call_id,407 "output": process_tool_call(call.name, call.arguments),408 }409 )410411 if not pending_calls:412 break413```414415416If one or more agents call developer-defined functions, execute every pending call and create a continuation request containing their outputs.417418### WebSocket419420In WebSocket mode, when an agent calls a developer-defined function, execute the function in your application and send its result to the active response with a `response.inject` event. The waiting agent can then resume without waiting for the entire Multi-agent response to complete.421422```json423{424 "type": "response.inject",425 "response_id": "resp_123",426 "input": [427 {428 "type": "function_call_output",429 "call_id": "call_123",430 "output": "{\"temperature\":72}"431 }432 ]433}434```435436For a valid `response.inject` request, the server replies with one of two events:437438- `response.inject.created`: the input was validated and accepted for injection439- `response.inject.failed`: the input was not injected; inspect `error.code`440441```json442{443 "type": "response.inject.created",444 "sequence_number": 42,445 "response_id": "resp_123"446}447```448449```json450{451 "type": "response.inject.failed",452 "sequence_number": 43,453 "response_id": "resp_123",454 "input": [455 {456 "type": "function_call_output",457 "call_id": "call_123",458 "output": "{\"temperature\":72}"459 }460 ],461 "error": {462 "code": "response_already_completed",463 "message": "Response 'resp_123' has already completed."464 }465}466```467468If a request doesn't conform to the `response.inject` schema, the server sends a generic error with status `400` and closes the WebSocket connection. Fix the request and open a new WebSocket connection before sending another event.469470The Python beta SDK exposes WebSocket mode through `client.beta.responses.connect`. The TypeScript beta SDK exposes it through `ResponsesWS`. Pass `OpenAI-Beta: responses_multi_agent=v1` in the connection headers; unlike HTTP streaming, the WebSocket connectors do not yet accept the `betas` argument.471472Save the response ID from the `response.created` event and include it in every `response.inject` event you send for that response. After sending an injection item, continue reading from the WebSocket until the response has completed and every injection has produced either a `response.inject.created` or `response.inject.failed` event.473474Inject tool outputs over WebSocket475476```javascript477import OpenAI from "openai";478479import { ResponsesWS } from "openai/resources/beta/responses/ws";480481const client = new OpenAI();482const proposals = {483 alpha: { estimated_weeks: 6, risk: "medium" },484 beta: { estimated_weeks: 8, risk: "low" },485};486const tools = [487 {488 type: "function",489 name: "get_proposal",490 description:491 "Return details for a proposal that the agents should compare.",492 parameters: {493 type: "object",494 properties: {495 proposal: {496 type: "string",497 enum: ["alpha", "beta"],498 },499 },500 required: ["proposal"],501 additionalProperties: false,502 },503 strict: true,504 },505];506507function processToolCall(name, argumentsJson) {508 if (name !== "get_proposal") {509 throw new Error(`Unknown tool: ${name}`);510 }511 const { proposal } = JSON.parse(argumentsJson);512513 return JSON.stringify(proposals[proposal]);514}515516async function runMultiAgent(ws) {517 let previousResponseId;518 let pendingInput = [519 { role: "user", content: process.argv.slice(2).join(" ") },520 ];521522 while (pendingInput.length > 0) {523 ws.send({524 type: "response.create",525 model: "gpt-5.6-sol",526 store: true,527 multi_agent: {528 enabled: true,529 max_concurrent_subagents: 3,530 },531 tools,532 input: pendingInput,533 previous_response_id: previousResponseId,534 });535536 const nextInput = [];537 let completedResponseId;538 let responseId;539 let pendingInjections = 0;540541 for await (const message of ws) {542 if (message.type === "error") throw message.error;543 if (message.type !== "message") continue;544545 const event = message.message;546 if (event.type === "response.created") {547 responseId = event.response.id;548 } else if (549 event.type === "response.output_item.done" &&550 event.item.type === "function_call"551 ) {552 if (!responseId) {553 throw new Error("Received a function call before response.created");554 }555 pendingInjections += 1;556 ws.send({557 type: "response.inject",558 response_id: responseId,559 input: [560 {561 type: "function_call_output",562 call_id: event.item.call_id,563 output: processToolCall(event.item.name, event.item.arguments),564 },565 ],566 });567 } else if (event.type === "response.inject.created") {568 pendingInjections -= 1;569 } else if (event.type === "response.inject.failed") {570 pendingInjections -= 1;571 if (event.error.code !== "response_already_completed") {572 throw new Error(JSON.stringify(event.error));573 }574 nextInput.push(...event.input);575 } else if (event.type === "response.completed") {576 completedResponseId = event.response.id;577 } else if (578 event.type === "error" ||579 event.type === "response.failed" ||580 event.type === "response.incomplete"581 ) {582 throw new Error(JSON.stringify(event));583 }584585 if (completedResponseId && pendingInjections === 0) break;586 }587588 if (!completedResponseId) {589 throw new Error("Connection ended before response.completed");590 }591 if (nextInput.length === 0) return;592593 previousResponseId = completedResponseId;594 pendingInput = nextInput;595 }596}597598const ws = new ResponsesWS(client, {599 headers: { "OpenAI-Beta": "responses_multi_agent=v1" },600});601602try {603 await runMultiAgent(ws);604} finally {605 ws.close();606}607```608609```python610from __future__ import annotations611612import json613614from openai import OpenAI615616client = OpenAI()617PROPOSALS = {618 "alpha": {"estimated_weeks": 6, "risk": "medium"},619 "beta": {"estimated_weeks": 8, "risk": "low"},620}621tools = [622 {623 "type": "function",624 "name": "get_proposal",625 "description": "Return details for a proposal that the agents should compare.",626 "parameters": {627 "type": "object",628 "properties": {629 "proposal": {630 "type": "string",631 "enum": ["alpha", "beta"],632 }633 },634 "required": ["proposal"],635 "additionalProperties": False,636 },637 "strict": True,638 }639]640641642def process_tool_call(name: str, arguments: str) -> str:643 if name != "get_proposal":644 raise ValueError(f"Unknown tool: {name}")645 parsed_arguments = json.loads(arguments)646 return json.dumps(PROPOSALS[parsed_arguments["proposal"]])647648649def run_multi_agent(connection):650 previous_response_id: str | None = None651 pending_input: list[dict[str, object]] = [{"role": "user", "content": input()}]652653 while pending_input:654 request = {655 "type": "response.create",656 "model": "gpt-5.6-sol",657 "store": True,658 "multi_agent": {"enabled": True},659 "tools": tools,660 "input": pending_input,661 }662 if previous_response_id is not None:663 request["previous_response_id"] = previous_response_id664665 connection.send(request)666667 next_input: list[dict[str, object]] = []668 completed_response = None669 response_id: str | None = None670 pending_injections = 0671672 for event in connection:673 event_type = event.type674675 if event_type == "response.created":676 response_id = event.response.id677678 elif event_type == "response.output_item.done":679 item = event.item680681 if item.type == "function_call":682 if response_id is None:683 raise RuntimeError(684 "Received a function call before response.created"685 )686687 output = {688 "type": "function_call_output",689 "call_id": item.call_id,690 "output": process_tool_call(item.name, item.arguments),691 }692 pending_injections += 1693694 connection.send(695 {696 "type": "response.inject",697 "response_id": response_id,698 "input": [output],699 }700 )701702 elif event_type == "response.inject.created":703 pending_injections -= 1704705 elif event_type == "response.inject.failed":706 pending_injections -= 1707708 if event.error.code != "response_already_completed":709 raise RuntimeError(event.error)710711 next_input.extend(item.model_dump(mode="json") for item in event.input)712713 elif event_type == "response.completed":714 completed_response = event.response715716 elif event_type in {717 "error",718 "response.failed",719 "response.incomplete",720 }:721 raise RuntimeError(event)722723 if completed_response is not None and pending_injections == 0:724 break725726 if completed_response is None:727 raise RuntimeError("Connection ended before response.completed")728729 if not next_input:730 return completed_response731732 previous_response_id = completed_response.id733 pending_input = next_input734735736with client.beta.responses.connect(737 extra_headers={"OpenAI-Beta": "responses_multi_agent=v1"},738) as connection:739 run_multi_agent(connection)740```741742743After sending a `response.inject` event, keep reading from the WebSocket and handle the acknowledgement:744745- **`response.inject.created`**: The function output was added to the active response. Continue reading events for that response.746- **`response.inject.failed` with `response_already_completed`**: The response completed before the function output could be added. Take the `input` returned in the failure event and send it in a new `response.create` request that continues from the completed response.747- **`response.inject.failed` with `response_not_found`**: The server could not find the response identified by `response_id`. Verify that you are using the ID received from `response.created`.748749A single Multi-agent run may span multiple Responses API requests. Over HTTP, when an agent calls a developer-defined function, your application executes the function and submits its output in a new `response.create` call. Over WebSocket, your application instead injects the function output into the active response.750751## New Multi-agent output items752753Multi-agent responses can include three additional output item types:754755- `multi_agent_call`: records a hosted Multi-agent action, such as `spawn_agent`.756- `multi_agent_call_output`: contains the result from execution of a hosted action.757- `agent_message`: carries an encrypted message from one agent to another.758759The `call_id` field links each `multi_agent_call` to its corresponding `multi_agent_call_output`.760761Each item also includes an `agent` attribute. For an `agent_message`, `agent.agent_name` identifies the recipient agent. Use `author` and `recipient` to trace the message direction.762763When your application receives a `multi_agent_call`, do not execute it as a function call or send back a result. The Responses API executes the hosted action and returns the corresponding `multi_agent_call_output`. Preserve both items if your application needs them for replay or tracing.764765```json766[767 {768 "type": "multi_agent_call",769 "id": "mac_123",770 "call_id": "call_spawn_a",771 "action": "spawn_agent",772 "arguments": "{\"task_name\":\"agent_a\",\"fork_turns\":\"all\",\"message\":\"enc_...\"}",773 "agent": { "agent_name": "/root" }774 },775 {776 "type": "multi_agent_call_output",777 "id": "maco_123",778 "call_id": "call_spawn_a",779 "action": "spawn_agent",780 "output": [781 {782 "type": "output_text",783 "text": "{\"task_name\":\"/root/agent_a\"}",784 "annotations": [],785 "logprobs": []786 }787 ],788 "agent": { "agent_name": "/root" }789 },790 {791 "type": "agent_message",792 "id": "amsg_123",793 "author": "/root/agent_a",794 "recipient": "/root",795 "content": [796 {797 "type": "encrypted_content",798 "encrypted_content": "enc_..."799 }800 ],801 "agent": { "agent_name": "/root" }802 }803]804```805806Agent-attributed SSE events include a top-level `agent` attribute. For an `agent_message` event, `agent.agent_name` identifies the recipient agent. Response lifecycle events such as `response.created` and `response.completed` describe the overall response rather than an individual agent, so they do not include an `agent` attribute.807808```json809{810 "type": "response.output_item.done",811 "agent": { "agent_name": "/root" },812 "item": {813 "type": "agent_message",814 "id": "amsg_123",815 "author": "/root/agent_a",816 "recipient": "/root",817 "content": [818 {819 "type": "encrypted_content",820 "encrypted_content": "enc_..."821 }822 ],823 "agent": { "agent_name": "/root" }824 }825}826```827828## Limitations8298301. Compaction:831 1. The `/responses/compact` endpoint is not supported when Multi-agent is enabled.832 2. When `multi_agent.enabled` is set to `true`, automatic server-side compaction is enabled implicitly, even if the request does not configure `context_management`. Compaction is applied independently to the root agent and each subagent, preserving their separate contexts. Users can still override `compact_threshold` by setting an explicit `context_management.compact_threshold` in the request.8332. `reasoning.summary` is not supported when Multi-agent is enabled.8343. `max_tool_calls` is not supported when Multi-agent is enabled.8354. `max_concurrent_subagents` defaults to `3`, which is the recommended setting.836837## Prompt guidance838839When Multi-agent is enabled, our systems automatically append these instructions to the root agent and subagents as a new developer message. You cannot edit or remove these instructions, but you should frame your developer instructions as additive to these automatically injected instructions.840841### Root agent842843````text844You are `/root`, the primary agent in a team of agents collaborating to fulfill the user's goals.845846At the start of your turn, you are the active agent.847You can spawn sub-agents to handle subtasks, and those sub-agents can spawn their own sub-agents.848All agents in the team, including the agents that you can assign tasks to, are equally intelligent and capable, and have access to the same set of tools.849850You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent without triggering a turn.851Child agents can also spawn their own sub-agents.852You can decide how much context you want to propagate to your sub-agents with the `fork_turns` parameter.853854You will receive messages in the form:855```856Message Type: MESSAGE | FINAL_ANSWER857Task name: <recipient>858Sender: <author>859Payload:860<payload text>861```862They may be addressed as to=/root863864There are {max_concurrent_subagents + 1} available concurrency slots, meaning that up to {max_concurrent_subagents + 1} agents can be active at once, including you.865````866867### Subagent868869````text870You are an agent in a team of agents collaborating to complete a task.871872You can spawn sub-agents to handle subtasks, and those sub-agents can spawn their own sub-agents. All agents in the team, including the agents that you can assign tasks to, are equally intelligent and capable, and have access to the same set of tools.873874You can use `spawn_agent` to create a new agent, `followup_task` to give an existing agent a new task and trigger a turn, and `send_message` to pass a message to a running agent.875Child agents can also spawn their own sub-agents.876877When you provide a response in the final channel, that content is immediately delivered back to your parent agent.878879You will receive messages in the form:880```881Message Type: NEW_TASK | MESSAGE | FINAL_ANSWER882Task name: <recipient>883Sender: <author>884Payload:885<payload text>886```887You may also see them addressed as to=/root/..., which indicates your identity is /root/...888889There are {max_concurrent_subagents + 1} available concurrency slots, meaning that up to {max_concurrent_subagents + 1} agents can be active at once, including you.890````891892## Related guides893894- [Function calling](https://developers.openai.com/api/docs/guides/function-calling)895- [WebSocket mode](https://developers.openai.com/api/docs/guides/websocket-mode)896- [Compaction](https://developers.openai.com/api/docs/guides/compaction)