SPB Git

Repository Public

responses-multi-agent.md 32.9 KB 896 lines markdown

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 execution174175![HTTP function call execution across the application, Responses API root, and three subagents.](https://developers.openai.com/images/api/multi-agent/multi-agent-1.png)176177#### WebSocket function call execution178179![WebSocket function call execution across the application, Responses API root, and three subagents.](https://developers.openai.com/images/api/multi-agent/multi-agent-2.png)180181### 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)
Files main
Menu

Theme