For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal
Theme

Modo multiagente

Permita que o modelo crie subagentes para executar tarefas específicas em paralelo em uma requisição à API Responses.

Visão geral

No modo multiagente, o modelo pode criar e coordenar subagentes que trabalham em paralelo e reunir os resultados em uma resposta final. Esse modo é especialmente eficaz em aplicativos com tarefas complexas que se beneficiam da divisão do trabalho em paralelo, como explorar uma base de código, escrever documentação e implementar funcionalidades.

O modo multiagente está disponível em versão beta para o GPT-6.1 Sol e todos os modelos GPT-5.6. Consulte a página do modelo antes de ativar o modo multiagente no seu aplicativo.

Quando usar o modo multiagente

Muitas tarefas podem ser divididas em partes independentes que um único agente executaria em sequência, mas que vários agentes podem executar em paralelo. No modo multiagente, o agente raiz pode delegar essas partes a vários subagentes que trabalham ao mesmo tempo. Isso pode trazer algumas vantagens:

  • Execução paralela. Tarefas independentes de pesquisa, análise ou implementação podem ocorrer ao mesmo tempo, o que pode reduzir o tempo de execução.
  • Contexto específico para cada tarefa. Cada subagente recebe uma tarefa de escopo delimitado e mantém seu próprio contexto. Isso reduz a interferência entre frentes de trabalho distintas e melhora o desempenho.
  • Coordenação pelo modelo. O agente raiz pode criar subagentes, enviar informações adicionais, aguardar os resultados e reuni-los em uma resposta final sem que seu aplicativo precise implementar a orquestração.

A orquestração multiagente é mais útil quando a tarefa pode ser dividida em frentes de trabalho concretas e independentes, como:

  • Explorar partes distintas de uma base de código extensa
  • Comparar várias propostas, documentos ou hipóteses
  • Pesquisar em várias fontes em paralelo
  • Implementar componentes independentes ou escrever conjuntos de testes independentes
  • Investigar em paralelo diferentes causas possíveis de uma falha
  • Explorar ao mesmo tempo diferentes abordagens para um problema

Adicionar subagentes pode aumentar o uso de tokens. O benefício pode ser menor em tarefas que dependem de uma única sequência de raciocínio, exigem gravações frequentes em um estado mutável compartilhado ou já gastam a maior parte do tempo em uma única operação externa lenta.

Use o modo multiagente quando Prefira um único agente quando
O trabalho puder ser dividido em tarefas independentes de escopo delimitado Cada etapa depender diretamente da anterior
Manter os contextos separados ajudar cada agente a se concentrar na própria tarefa A tarefa for pequena o suficiente para ser concluída em uma única execução curta
A exploração em paralelo puder reduzir o tempo total de execução Os agentes precisarem disputar o acesso ao mesmo recurso mutável
Comparar resultados independentes ampliar a cobertura da análise Você precisar de um grafo de execução fixo e determinístico

Início rápido

Os exemplos em Python e JavaScript usam o SDK beta da API Responses. Para requisições HTTP, use client.beta.responses e passe responses_multi_agent=v1 no argumento betas. Para requisições HTTP diretas e conexões WebSocket, inclua OpenAI-Beta: responses_multi_agent=v1 nos cabeçalhos da requisição ou da conexão. Os schemas dos itens podem mudar enquanto o modo multiagente estiver em beta.

Ative o modo multiagente na requisição à API Responses com multi_agent.enabled. Quando multi_agent.enabled é true, o agente raiz pode criar uma árvore de subagentes. Os subagentes usam o mesmo modelo e as mesmas ferramentas disponíveis na requisição. Os agentes se coordenam por meio de operações básicas de colaboração, como criar subagentes, trocar mensagens e aguardar resultados (consulte Como funciona o modo multiagente). Cabe ao agente raiz sintetizar as respostas dos subagentes e fornecer a resposta final.

Revise um pull request com subagentes
from openai import OpenAI

client = OpenAI()


def review_pull_request(diff: str) -> str:
    response = client.beta.responses.create(
        model="gpt-6.1-sol",
        input=(
            "Review the pull-request diff below with three agents: one for "
            "correctness, one for security, and one for missing tests. "
            "Reconcile duplicate or conflicting findings, then return a "
            "prioritized review with file and line references.\n\n"
            f"<diff>\n{diff}\n</diff>"
        ),
        multi_agent={
            "enabled": True,
            "max_concurrent_subagents": 3,
        },
        betas=["responses_multi_agent=v1"],
    )

    return "".join(
        part.text
        for item in response.output
        if (
            item.type == "message"
            and item.agent is not None
            and item.agent.agent_name == "/root"
            and item.phase == "final_answer"
        )
        for part in item.content
        if part.type == "output_text"
    )

max_concurrent_subagents define o número máximo de subagentes que podem estar ativos ao mesmo tempo em toda a árvore de agentes. A contagem inclui todos os descendentes, dos filhos e netos aos subagentes em níveis mais profundos, mas exclui o agente raiz.

A API não impõe um limite superior fixo para essa configuração. O valor padrão é 3, recomendado para a maioria das cargas de trabalho. O modo multiagente também não impõe um limite fixo à profundidade da árvore nem ao número total de subagentes criados durante uma execução.

Adicione uma mensagem de desenvolvedor para definir com mais precisão quando o modelo do agente raiz deve criar subagentes. Essa mensagem complementa as instruções injetadas para o agente raiz e os subagentes.

Exemplos de mensagens de desenvolvedor:

  • “Só crie subagentes se o usuário pedir explicitamente o uso de subagentes, a delegação de tarefas ou o trabalho de agentes em paralelo.”
  • “A delegação proativa no modo multiagente está ativa. Use subagentes quando trabalhar em paralelo puder reduzir significativamente o tempo de execução ou melhorar significativamente a qualidade do resultado.”

Como funciona o modo multiagente

A API Responses disponibiliza ações de orquestração hospedadas aos modelos do agente raiz e dos subagentes, junto com instruções de uso. O agente raiz recebe o nome /root. Os subagentes criados usam caminhos hierárquicos como estes:

/root
├── /root/researcher
├── /root/reviewer
└── /root/reviewer/tester

O modo multiagente não impõe um limite fixo ao número total de subagentes nem à profundidade da árvore. Para a maioria das tarefas, use o valor padrão de max_concurrent_subagents, que é 3. Essa configuração limita o número de turnos de subagentes que podem estar ativos ao mesmo tempo em toda a árvore, incluindo os turnos dos filhos e dos descendentes em níveis mais profundos.

Quando o modo multiagente está ativo, a API Responses disponibiliza seis ações de colaboração hospedadas. Elas podem aparecer como itens multi_agent_call. Seu aplicativo não deve executar essas ações nem enviar saídas para elas.

Ação Finalidade
spawn_agent Cria um subagente e atribui a ele sua tarefa inicial.
send_message Coloca uma mensagem na fila de um agente existente sem iniciar um novo turno.
followup_task Atribui mais trabalho a um agente existente que não seja o agente raiz e inicia ou retoma seu turno.
wait_agent Aguarda uma atualização na caixa de entrada do agente que fez a chamada.
interrupt_agent Interrompe o turno ativo de outro agente sem excluir seu contexto.
list_agents Retorna a árvore atual de agentes, o status de cada um e seu last_task_message.

As chamadas de ferramentas definidas pelo desenvolvedor são tratadas da mesma forma que quando o modo multiagente está desativado. Qualquer agente da árvore pode emitir um item function_call. Seu aplicativo deve executar a chamada e enviar o function_call_output correspondente.

Todos os agentes da árvore têm acesso às ferramentas configuradas na chamada ao modelo da requisição à API.

Como usar o modo multiagente na API Responses

Desempenho com HTTP e WebSocket

HTTP e WebSocket oferecem os mesmos recursos no modo multiagente, mas recomendamos WebSocket para fluxos de trabalho demorados ou que fazem uso intensivo de ferramentas. A conexão persistente permite que seu aplicativo devolva as saídas das funções assim que estiverem disponíveis. Isso reduz o custo de retomar a execução e o tempo que os agentes passam esperando.

Com HTTP, a resposta é concluída quando cada agente ativo termina seu trabalho ou pausa para aguardar a execução de uma chamada de função pelo cliente. Seu aplicativo então executa todas as chamadas de função pendentes e envia as saídas em uma nova requisição à API Responses, permitindo que os agentes em pausa retomem o trabalho.

Com WebSocket, seu aplicativo pode injetar a saída de cada função na resposta assim que a saída estiver disponível, sem esperar que a resposta ativa seja concluída. O agente que aguardava a saída pode retomar o trabalho imediatamente enquanto os demais continuam trabalhando. Isso reduz os atrasos de coordenação e evita ciclos adicionais de requisição e resposta quando os agentes terminam suas tarefas ou solicitam ferramentas em momentos diferentes.

HTTP pode ser suficiente para fluxos de trabalho que exigem chamadas a várias ferramentas hospedadas, como pesquisas na Web em paralelo, ou que usam uma única requisição com poucas chamadas de função. Para a maioria dos fluxos de trabalho no modo multiagente, WebSocket tende a oferecer menor latência e melhor desempenho de ponta a ponta.

Execução de chamadas de função via HTTP

Execução de chamadas de função via HTTP envolvendo o aplicativo, o agente raiz da API Responses e três subagentes.

Execução de chamadas de função via WebSocket

Execução de chamadas de função via WebSocket envolvendo o aplicativo, o agente raiz da API Responses e três subagentes.

HTTP

Estes exemplos exigem versões beta dos SDKs que dão acesso à versão beta da API Responses. Para usar streaming via HTTP, chame client.beta.responses.create e passe responses_multi_agent=v1 no argumento betas. Isso habilita os tipos beta e o preenchimento automático. Em Python, ao adicionar anotações de tipo, importe os tipos beta dos itens de resposta de openai.types.beta.

Exemplo de código do cliente:

Trate chamadas de ferramentas no streaming via HTTP
from __future__ import annotations

import json
import sys

from openai import OpenAI
from openai.types.beta import BetaResponseOutputItem

client = OpenAI()
ROOT = "/root"
PROPOSALS = {
    "alpha": {"estimated_weeks": 6, "risk": "medium"},
    "beta": {"estimated_weeks": 8, "risk": "low"},
}
tools = [
    {
        "type": "function",
        "name": "get_proposal",
        "description": "Return details for a proposal that the agents should compare.",
        "parameters": {
            "type": "object",
            "properties": {
                "proposal": {
                    "type": "string",
                    "enum": ["alpha", "beta"],
                }
            },
            "required": ["proposal"],
            "additionalProperties": False,
        },
        "strict": True,
    }
]
history = [
    {
        "role": "user",
        "content": (
            "Use two subagents, one for proposal alpha and one for proposal beta. "
            "Have each call get_proposal, then compare their findings."
        ),
    }
]


def agent_name(item: BetaResponseOutputItem) -> str:
    return item.agent.agent_name if item.agent else ROOT


def render_to_user(delta: str) -> None:
    print(delta, end="", flush=True)


def log_subagent_text(agent: str, delta: str) -> None:
    print(f"[{agent}] {delta}", end="", file=sys.stderr, flush=True)


def process_tool_call(name: str, arguments: str) -> str:
    if name != "get_proposal":
        raise ValueError(f"Unknown tool: {name}")
    parsed_arguments = json.loads(arguments)
    return json.dumps(PROPOSALS[parsed_arguments["proposal"]])


while True:
    output_items = []
    pending_calls = []
    item_agents: dict[int, str] = {}

    stream = client.beta.responses.create(
        model="gpt-6.1-sol",
        input=history,
        tools=tools,
        store=False,
        multi_agent={
            "enabled": True,
            "max_concurrent_subagents": 3,
        },
        stream=True,
        betas=["responses_multi_agent=v1"],
    )
    for event in stream:
        if event.type == "response.output_item.added":
            item_agents[event.output_index] = agent_name(event.item)
        elif event.type == "response.output_text.delta":
            agent = item_agents.get(event.output_index, ROOT)
            if agent == ROOT:
                render_to_user(event.delta)
            else:
                log_subagent_text(agent, event.delta)
        elif event.type == "response.output_item.done":
            output_items.append(event.item)
            if event.item.type == "function_call":
                # Handle function calls from both the root agent and subagents.
                pending_calls.append(event.item)
        elif event.type == "response.completed":
            print(f"\nUsage: {event.response.usage}", file=sys.stderr)
            break
        elif event.type in {
            "error",
            "response.failed",
            "response.incomplete",
        }:
            raise RuntimeError(event)

    history.extend(output_items)

    for call in pending_calls:
        history.append(
            {
                "type": "function_call_output",
                "call_id": call.call_id,
                "output": process_tool_call(call.name, call.arguments),
            }
        )

    if not pending_calls:
        break

Se um ou mais agentes chamarem funções definidas pelo desenvolvedor, execute todas as chamadas pendentes e crie uma requisição de continuação com as respectivas saídas.

WebSocket

No modo WebSocket, quando um agente chamar uma função definida pelo desenvolvedor, execute a função no seu aplicativo e envie o resultado à resposta ativa em um evento response.inject. O agente que aguardava o resultado poderá retomar o trabalho sem esperar pela conclusão de toda a resposta do modo multiagente.

{
  "type": "response.inject",
  "response_id": "resp_123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_123",
      "output": "{\"temperature\":72}"
    }
  ]
}

Para uma requisição response.inject válida, o servidor responde com um de dois eventos:

  • response.inject.created: a entrada foi validada e aceita para injeção.
  • response.inject.failed: a entrada não foi injetada. Verifique error.code.
{
  "type": "response.inject.created",
  "sequence_number": 42,
  "response_id": "resp_123"
}
{
  "type": "response.inject.failed",
  "sequence_number": 43,
  "response_id": "resp_123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_123",
      "output": "{\"temperature\":72}"
    }
  ],
  "error": {
    "code": "response_already_completed",
    "message": "Response 'resp_123' has already completed."
  }
}

Se a requisição não seguir o schema de response.inject, o servidor enviará um erro genérico com o status 400 e encerrará a conexão WebSocket. Corrija a requisição e abra uma nova conexão WebSocket antes de enviar outro evento.

O SDK beta de Python disponibiliza o modo WebSocket por meio de client.beta.responses.connect. No SDK beta de TypeScript, use ResponsesWS. Inclua OpenAI-Beta: responses_multi_agent=v1 nos cabeçalhos da conexão. Diferentemente do streaming via HTTP, os conectores WebSocket ainda não aceitam o argumento betas.

Guarde o ID da resposta recebido no evento response.created e inclua esse ID em cada evento response.inject que enviar para essa resposta. Depois de enviar um item para injeção, continue lendo os eventos da conexão WebSocket até que a resposta seja concluída e cada injeção tenha gerado um evento response.inject.created ou response.inject.failed.

Injete saídas de ferramentas via WebSocket
from __future__ import annotations

import json

from openai import OpenAI

client = OpenAI()
PROPOSALS = {
    "alpha": {"estimated_weeks": 6, "risk": "medium"},
    "beta": {"estimated_weeks": 8, "risk": "low"},
}
tools = [
    {
        "type": "function",
        "name": "get_proposal",
        "description": "Return details for a proposal that the agents should compare.",
        "parameters": {
            "type": "object",
            "properties": {
                "proposal": {
                    "type": "string",
                    "enum": ["alpha", "beta"],
                }
            },
            "required": ["proposal"],
            "additionalProperties": False,
        },
        "strict": True,
    }
]


def process_tool_call(name: str, arguments: str) -> str:
    if name != "get_proposal":
        raise ValueError(f"Unknown tool: {name}")
    parsed_arguments = json.loads(arguments)
    return json.dumps(PROPOSALS[parsed_arguments["proposal"]])


def run_multi_agent(connection):
    previous_response_id: str | None = None
    pending_input: list[dict[str, object]] = [{"role": "user", "content": input()}]

    while pending_input:
        request = {
            "type": "response.create",
            "model": "gpt-6.1-sol",
            "store": True,
            "multi_agent": {"enabled": True},
            "tools": tools,
            "input": pending_input,
        }
        if previous_response_id is not None:
            request["previous_response_id"] = previous_response_id

        connection.send(request)

        next_input: list[dict[str, object]] = []
        completed_response = None
        response_id: str | None = None
        pending_injections = 0

        for event in connection:
            event_type = event.type

            if event_type == "response.created":
                response_id = event.response.id

            elif event_type == "response.output_item.done":
                item = event.item

                if item.type == "function_call":
                    if response_id is None:
                        raise RuntimeError(
                            "Received a function call before response.created"
                        )

                    output = {
                        "type": "function_call_output",
                        "call_id": item.call_id,
                        "output": process_tool_call(item.name, item.arguments),
                    }
                    pending_injections += 1

                    connection.send(
                        {
                            "type": "response.inject",
                            "response_id": response_id,
                            "input": [output],
                        }
                    )

            elif event_type == "response.inject.created":
                pending_injections -= 1

            elif event_type == "response.inject.failed":
                pending_injections -= 1

                if event.error.code != "response_already_completed":
                    raise RuntimeError(event.error)

                next_input.extend(item.model_dump(mode="json") for item in event.input)

            elif event_type == "response.completed":
                completed_response = event.response

            elif event_type in {
                "error",
                "response.failed",
                "response.incomplete",
            }:
                raise RuntimeError(event)

            if completed_response is not None and pending_injections == 0:
                break

        if completed_response is None:
            raise RuntimeError("Connection ended before response.completed")
        if pending_injections:
            raise RuntimeError("Connection ended with unacknowledged tool results")

        if not next_input:
            return completed_response

        previous_response_id = completed_response.id
        pending_input = next_input


with client.beta.responses.connect(
    extra_headers={"OpenAI-Beta": "responses_multi_agent=v1"},
) as connection:
    response = run_multi_agent(connection)
    print(
        "".join(
            part.text
            for item in response.output
            if (
                item.type == "message"
                and item.agent is not None
                and item.agent.agent_name == "/root"
                and item.phase == "final_answer"
            )
            for part in item.content
            if part.type == "output_text"
        )
    )

Depois de enviar um evento response.inject, continue lendo os eventos da conexão WebSocket e trate o retorno do servidor:

  • response.inject.created: a saída da função foi adicionada à resposta ativa. Continue lendo os eventos dessa resposta.
  • response.inject.failed com response_already_completed: a resposta foi concluída antes que a saída da função pudesse ser adicionada. Envie o input retornado no evento de falha em uma nova requisição response.create que dê continuidade à resposta concluída.
  • response.inject.failed com response_not_found: o servidor não encontrou a resposta identificada por response_id. Verifique se você está usando o ID recebido em response.created.

Uma única execução no modo multiagente pode envolver várias requisições à API Responses. Com HTTP, quando um agente chama uma função definida pelo desenvolvedor, seu aplicativo executa a função e envia a saída em uma nova chamada response.create. Com WebSocket, seu aplicativo injeta a saída da função diretamente na resposta ativa.

Novos itens de saída do modo multiagente

As respostas no modo multiagente podem incluir três tipos adicionais de itens de saída:

  • multi_agent_call: registra uma ação hospedada do modo multiagente, como spawn_agent.
  • multi_agent_call_output: contém o resultado da execução de uma ação hospedada.
  • agent_message: transporta uma mensagem criptografada de um agente para outro.

O campo call_id associa cada multi_agent_call ao multi_agent_call_output correspondente.

Cada item também inclui um atributo agent. Em um item agent_message, agent.agent_name identifica o agente destinatário. Use author e recipient para rastrear quem enviou e quem recebeu a mensagem.

Quando seu aplicativo receber um item multi_agent_call, não o execute como uma chamada de função nem envie um resultado de volta. A API Responses executa a ação hospedada e retorna o multi_agent_call_output correspondente. Preserve os dois itens se seu aplicativo precisar deles para reproduzir ou rastrear a execução.

[
  {
    "type": "multi_agent_call",
    "id": "mac_123",
    "call_id": "call_spawn_a",
    "action": "spawn_agent",
    "arguments": "{\"task_name\":\"agent_a\",\"fork_turns\":\"all\",\"message\":\"enc_...\"}",
    "agent": { "agent_name": "/root" }
  },
  {
    "type": "multi_agent_call_output",
    "id": "maco_123",
    "call_id": "call_spawn_a",
    "action": "spawn_agent",
    "output": [
      {
        "type": "output_text",
        "text": "{\"task_name\":\"/root/agent_a\"}",
        "annotations": [],
        "logprobs": []
      }
    ],
    "agent": { "agent_name": "/root" }
  },
  {
    "type": "agent_message",
    "id": "amsg_123",
    "author": "/root/agent_a",
    "recipient": "/root",
    "content": [
      {
        "type": "encrypted_content",
        "encrypted_content": "enc_..."
      }
    ],
    "agent": { "agent_name": "/root" }
  }
]

Os eventos SSE atribuídos a um agente incluem um atributo agent no nível superior. Em um evento agent_message, agent.agent_name identifica o agente destinatário. Eventos do ciclo de vida da resposta, como response.created e response.completed, descrevem a resposta como um todo. Por isso, não incluem um atributo agent.

{
  "type": "response.output_item.done",
  "agent": { "agent_name": "/root" },
  "item": {
    "type": "agent_message",
    "id": "amsg_123",
    "author": "/root/agent_a",
    "recipient": "/root",
    "content": [
      {
        "type": "encrypted_content",
        "encrypted_content": "enc_..."
      }
    ],
    "agent": { "agent_name": "/root" }
  }
}

Limitações

  1. Compactação:
    1. A API não oferece suporte ao endpoint /responses/compact quando o modo multiagente está ativo.
    2. Quando multi_agent.enabled é definido como true, a compactação automática no servidor é ativada implicitamente, mesmo que a requisição não configure context_management. O servidor aplica a compactação separadamente ao agente raiz e a cada subagente, preservando os contextos individuais. Você ainda pode substituir o valor de compact_threshold ao definir explicitamente context_management.compact_threshold na requisição.
  2. A API não oferece suporte a reasoning.summary quando o modo multiagente está ativo.
  3. A API não oferece suporte a max_tool_calls quando o modo multiagente está ativo.
  4. O valor padrão de max_concurrent_subagents é 3, que é a configuração recomendada.

Orientações para prompts

Quando o modo multiagente está ativo, nossos sistemas acrescentam automaticamente as instruções a seguir ao contexto do agente raiz e dos subagentes em uma nova mensagem de desenvolvedor. Você não pode editar nem remover essas instruções. Ao escrever suas instruções de desenvolvedor, formule-as de modo que complementem as instruções injetadas automaticamente.

Agente raiz

You are `/root`, the primary agent in a team of agents collaborating to fulfill the user's goals.

At the start of your turn, you are the active agent.
You 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.

You 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.
Child agents can also spawn their own sub-agents.
You can decide how much context you want to propagate to your sub-agents with the `fork_turns` parameter.

You will receive messages in the form:
```
Message Type: MESSAGE | FINAL_ANSWER
Task name: <recipient>
Sender: <author>
Payload:
<payload text>
```
They may be addressed as to=/root

There are {max_concurrent_subagents + 1} available concurrency slots, meaning that up to {max_concurrent_subagents + 1} agents can be active at once, including you.

Subagente

You are an agent in a team of agents collaborating to complete a task.

You 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.

You 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.
Child agents can also spawn their own sub-agents.

When you provide a response in the final channel, that content is immediately delivered back to your parent agent.

You will receive messages in the form:
```
Message Type: NEW_TASK | MESSAGE | FINAL_ANSWER
Task name: <recipient>
Sender: <author>
Payload:
<payload text>
```
You may also see them addressed as to=/root/..., which indicates your identity is /root/...

There are {max_concurrent_subagents + 1} available concurrency slots, meaning that up to {max_concurrent_subagents + 1} agents can be active at once, including you.

Guias relacionados