Claude Platform Docs
Managed AgentsOrquestração avançada

Threads de sessão

Liste, interrompa e arquive as threads de uma sessão multiagente, leia seus eventos e gerencie permissões de ferramentas entre elas.

Em uma sessão multiagente, cada agente trabalha em sua própria session thread (thread de sessão). Esta página aborda como listar, interromper e arquivar threads, os eventos que elas enviam e como as permissões de ferramentas funcionam entre elas. Uma execução de workflow também cria threads de sessão.

Thread principal e threads de sessão

O fluxo de eventos no nível da sessão (/v1/sessions/{session_id}/events/stream) é considerado a primary thread (thread principal), contendo uma visão condensada de toda a atividade em todas as threads. Você não vê a atividade completa dos subagentes, mas vê o início e o fim do trabalho deles, além de eventos bloqueantes, como solicitações de permissão de ferramentas.

As threads de sessão são onde você se aprofunda na atividade de um agente específico.

O status da sessão é uma agregação de toda a atividade dos agentes; se pelo menos uma thread estiver running, o status geral da sessão também será running. Uma execução de workflow em andamento também pode manter a sessão running, mesmo enquanto nenhuma de suas threads estiver trabalhando. Quando nenhuma thread está trabalhando e uma thread aguarda seu cliente, a sessão fica idle; consulte Saiba quando o trabalho está concluído.

Um orçamento de sessão é um limite único compartilhado entre todas as threads de uma sessão. À medida que o limite é atingido, as threads pausam de forma independente, e o custo de cada thread é calculado com base no próprio modelo servido da thread.

Listar threads

Liste todas as threads associadas a uma sessão da seguinte forma:

for thread in client.beta.sessions.threads.list(session.id):
    agent = thread.agent
    label = agent.type if agent.type == "advisor" else agent.name
    print(f"[{label}] {thread.status}")

A lista completa inclui a thread principal. parent_thread_id é null para a thread principal. Todas as outras threads são threads filhas. workflow_run_id é null, exceto nas threads de uma execução.

Para listar apenas threads com determinados status, adicione statuses[] à solicitação e repita-o para informar mais de um status, como em ?statuses[]=running&statuses[]=idle. Omita-o para retornar threads de todos os status.

Interromper uma thread de sessão

Envie user.interrupt com session_thread_id para parar uma thread específica. Omitir session_thread_id interrompe todas as threads não arquivadas da sessão, incluindo a principal. Em uma sessão com workflows dinâmicos, uma interrupção não encerra nenhuma execução, e uma interrupção que nomeia a thread de uma execução não para nada. Uma interrupção fecha as chamadas de ferramentas pendentes de outras threads filhas, mas não conte com ela para fechar as de uma thread de execução. Consulte Interromper uma sessão com execuções abertas.

client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)

Na thread de um subagente bloqueada em requires_action, a interrupção fecha cada chamada de ferramenta pendente com um resultado de ferramenta de erro ("Tool execution was interrupted before completion. Please retry.") e reemite session.thread_status_idle com stop_reason: end_turn diretamente; o modelo não é amostrado. Em uma thread filha ociosa com end_turn ou budget_reached, a interrupção não tem efeito. Uma interrupção que nomeia uma thread encerrada retorna um erro 400. Uma thread filha interrompida não envia ao agente da thread principal o relatório que envia quando um turno termina. Enquanto esse agente aguarda a thread filha, ele não inicia outro turno até que algo mais chegue até ele, como uma user.message ou o relatório de outra thread.

Arquivar uma thread de sessão

Opcionalmente, arquive uma thread de sessão quando ela tiver concluído seu trabalho. Arquivar uma thread libera seu lugar dentro do limite de 25 threads filhas. O servidor arquiva as threads de uma execução de workflow por conta própria. Você não precisa arquivá-las e não pode fazê-lo enquanto a execução estiver aberta.

archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)

O arquivamento só é bem-sucedido se a thread estiver idle. Uma thread parada em requires_action conta como ociosa e pode ser arquivada diretamente; apenas uma thread em execução precisa ser interrompida primeiro:

client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)
archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)

Eventos da thread principal

Estes eventos expõem a atividade multiagente na thread principal em /v1/sessions/{session_id}/events/stream. Os eventos de direção de mensagem são nomeados em relação à thread em cujo fluxo aparecem: agent.thread_message_received significa que uma mensagem chegou a esta thread vinda de outra thread, e agent.thread_message_sent significa que esta thread enviou uma. A tarefa que o agente da thread principal delega, por exemplo, chega ao fluxo da própria thread filha como um evento agent.thread_message_received.

TipoDescrição
session.thread_createdUma thread foi criada. Inclui session_thread_id e agent_name.
session.thread_status_runningUma thread iniciou atividade.
session.thread_status_idleO agente associado à thread está aguardando entrada. Inclui um stop_reason indicando por que o agente parou.
session.thread_status_terminatedUma thread foi encerrada e não aceita mais entradas, por exemplo, porque foi arquivada ou encontrou um erro irrecuperável. Uma thread de advisor também é encerrada quando sua consulta termina.
agent.thread_message_receivedNa thread principal, um subagente enviou ao agente da thread principal um relatório ou uma pergunta. Inclui from_session_thread_id, from_agent_name e content.
agent.thread_message_sentNa thread principal, o agente da thread principal enviou a um subagente uma tarefa ou mensagem de acompanhamento. Inclui to_session_thread_id, to_agent_name e content.

As consultas ao advisor emitem esses mesmos eventos de thread sob o nome reservado anthropic.advisor (como agent_name nos eventos de ciclo de vida da thread e from_agent_name na entrega do conselho); consulte Dar um advisor à sessão para ver a sequência.

As threads de uma execução de workflow aparecem no fluxo principal da seguinte forma:

  • Eventos de ciclo de vida: Cada thread de execução envia session.thread_created, com o workflow_run_id da execução, e seus eventos session.thread_status_running, session.thread_status_idle e session.thread_status_terminated.
  • Eventos de mensagem: O prompt de uma thread de execução, um evento agent.thread_message_received, permanece em seu próprio fluxo.
  • Eventos de execução: Eventos workflow_run.* também chegam a este fluxo; consulte Eventos de execução.
  • Chamadas de ferramentas que aguardam você: As chamadas de ferramentas de uma thread de execução que precisam do seu cliente são replicadas neste fluxo, como para qualquer thread filha. Consulte Permissões de ferramentas e ferramentas personalizadas.

Eventos de thread de sessão

Eventos críticos são encaminhados para a thread principal. No entanto, você ainda pode querer investigar o raciocínio e as chamadas de ferramentas de um agente específico. Para isso, faça streaming ou liste os eventos da thread de sessão associada.

Cada thread de sessão tem seu próprio fluxo de eventos em /v1/sessions/{session_id}/threads/{thread_id}/stream, e ele aceita o mesmo parâmetro event_deltas[] que o fluxo no nível da sessão, para que você possa pré-visualizar o texto de um subagente à medida que o modelo o gera. Uma conexão pré-visualiza apenas a thread que está lendo: as pré-visualizações de uma thread filha nunca aparecem no fluxo no nível da sessão, então, para acompanhar um subagente ao vivo, abra o fluxo da própria thread dele. Consulte Pré-visualizar eventos de threads de sessão para saber como ativar, acumular e reconciliar pré-visualizações.

Em uma execução de workflow, o servidor executa um workflow: um programa que o agente da thread principal escreve. Em cada uma das threads da execução, o primeiro agent.thread_message_received é o prompt que o workflow escreveu. Seu from_session_thread_id é o ID da thread principal, e ele não tem from_agent_name. A API não garante o texto do prompt, então não o analise. O evento session.thread_status_terminated da thread, no fluxo da thread principal, informa que a thread terminou. Nenhum evento registra o resultado que ela retornou ao workflow.

O fluxo de uma thread não reproduz eventos anteriores. Logo após session.thread_created, a lista de eventos da thread de uma execução pode estar vazia, porque o servidor grava o primeiro evento da thread depois dele. Portanto, abra primeiro o fluxo da thread, depois liste os eventos da thread e ignore cada evento recebido pelo fluxo cujo id a lista retornou.

with client.beta.sessions.threads.events.stream(
    thread.id,
    session_id=session.id,
) as stream:
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "session.thread_status_idle":
                break

Permissões de ferramentas e ferramentas personalizadas

Se um subagente precisar de algo do seu cliente, como permissão para executar uma chamada de ferramenta ou o resultado de uma ferramenta personalizada, o evento é replicado na thread principal com session_thread_id identificando a thread de sessão de origem. Uma chamada de ferramenta precisa da sua permissão sob always_ask, ou sob auto quando o servidor não chega a uma determinação.

{
  "type": "session.thread_status_idle",
  "id": "sevt_01ABC...",
  "session_thread_id": "sthr_01DEF...",
  "agent_name": "code-reviewer",
  "stop_reason": {
    "type": "requires_action",
    "event_ids": ["sevt_01XYZ..."]
  }
}

Envie user.tool_confirmation (com tool_use_id) ou user.custom_tool_result (com custom_tool_use_id); o servidor encaminha a resposta para a thread correta automaticamente. A resposta pode aparecer na thread principal e na thread do subagente com valores de id diferentes. Para associar as duas cópias, compare type e tool_use_id (ou custom_tool_use_id), não id.

A sessão fica idle somente quando nenhuma thread está running, então session.status_idle pode chegar muito depois da chamada de um subagente. Você não precisa esperar por ele: envie o user.custom_tool_result assim que o evento agent.custom_tool_use replicado chegar.

Sob auto, seus eventos user.message podem levar o servidor a permitir uma chamada que, de outra forma, ele negaria. Nada na thread de um subagente conta como sua intenção. Seu cliente não envia mensagens ali, e as mensagens que o agente da thread principal envia ao subagente não contam. Quando o servidor nega uma chamada sob auto, nada é replicado: o evento e o resultado de ferramenta de erro aparecem apenas no próprio fluxo da thread do subagente, e o subagente continua em execução.

O exemplo a seguir fica dentro do loop de eventos do manipulador de confirmação de ferramentas. Para cada ID em stop_reason.event_ids, ele envia um user.tool_confirmation que permite a chamada. O mesmo padrão se aplica a user.custom_tool_result.

for event_id in stop.event_ids:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.tool_confirmation",
                "tool_use_id": event_id,
                "result": "allow",
            }
        ],
    )

O padrão anterior responde às chamadas que um evento de ociosidade lista. No fluxo principal, o evento session.thread_status_idle de um subagente pode chegar antes dos eventos agent.tool_use ou agent.mcp_tool_use que seu stop_reason.event_ids lista. Um user.tool_confirmation para uma chamada cujo evento ainda não chegou pode retornar 400. Para evitar isso, responda a cada chamada cujo evaluated_permission seja ask quando o próprio evento dela chegar ao fluxo principal.

Was this page helpful?