Claude Platform Docs
Managed AgentsDelegue trabalho ao seu agente

Pré-visualizar respostas com deltas de eventos

Renderize o texto de resposta do agente como uma pré-visualização ao vivo enquanto o modelo ainda o está gerando.

Por padrão, o texto de resposta do agente chega ao fluxo de eventos da sessão como eventos agent.message armazenados em buffer. Cada um é emitido somente depois que a requisição ao modelo que o produziu termina. Os "event deltas" (deltas de eventos) permitem que você renderize esse texto de forma incremental, como uma pré-visualização ao vivo, enquanto o modelo ainda o está gerando.

As pré-visualizações são um auxílio de exibição de melhor esforço, e o agent.message armazenado em buffer é sempre o registro oficial. Um cliente que ignora as pré-visualizações ainda recebe um fluxo completo e correto.

Ativar as pré-visualizações

As pré-visualizações são opcionais por conexão de fluxo. Adicione o parâmetro de consulta event_deltas[] ao fluxo que você está lendo e repita-o uma vez para cada tipo de evento que você deseja pré-visualizar. Os valores aceitos são agent.message e agent.thinking. Qualquer outro valor retorna um erro 400, assim como uma requisição com mais de 100 valores.

Ambos os endpoints de fluxo aceitam o parâmetro:

  • Fluxo no nível da sessão: GET /v1/sessions/{session_id}/events/stream
  • Fluxo de thread da sessão: GET /v1/sessions/{session_id}/threads/{thread_id}/stream

As pré-visualizações de um subagente aparecem no próprio fluxo de thread desse subagente.

[] é um padrão glob do shell, então coloque a URL entre aspas sempre que você construir a requisição em um shell. Os exemplos codificam os colchetes em porcentagem como %5B%5D, o que também funciona.

Eventos de pré-visualização

Quando um evento pré-visualizado começa, o stream emite um event_start contendo o tipo e o id do evento que está por vir:

{
  "type": "event_start",
  "event": {
    "type": "agent.message",
    "id": "sevt_01abc..."
  }
}

Para agent.message, o início é seguido por eventos event_delta contendo texto incremental. Cada delta identifica o evento que ele estende em event_id e o bloco de conteúdo que ele estende em delta.index:

{
  "type": "event_delta",
  "event_id": "sevt_01abc...",
  "delta": {
    "type": "content_delta",
    "index": 0,
    "content": {
      "type": "text",
      "text": "Here is the summary"
    }
  }
}

Para agent.thinking, apenas o event_start é emitido, como um sinal de que um bloco de pensamento começou. Nenhum evento event_delta vem em seguida. O evento agent.thinking armazenado em buffer que conclui a pré-visualização é um sinal de progresso e não contém nenhum conteúdo de pensamento.

Diferentemente dos eventos persistidos, event_start e event_delta não têm id nem processed_at próprios. O único identificador que eles carregam é o id do evento que pré-visualizam. Suas strings de tipo também são a exceção à convenção de nomenclatura {domain}.{action} dos eventos persistidos.

Acumular e reconciliar

Todo SDK que oferece suporte a deltas de eventos inclui um auxiliar acumulador que cuida do controle de index para você. O padrão manual desta seção funciona em todas as linguagens quando você precisa de um controle personalizado. Aplique-o aos tipos de eventos gerados.

No padrão manual, mantenha o texto de pré-visualização em um mapa temporário indexado por (event_id, index) e trate o evento armazenado em buffer como o registro. Reconcilie os dois por requisição ao modelo.

Um turno começa com um único evento session.status_running. Em um turno que é concluído normalmente, cada requisição ao modelo produz então estes eventos, nesta ordem:

  1. span.model_request_start
  2. event_start
  3. Os eventos event_delta
  4. O agent.message armazenado em buffer
  5. span.model_request_end (na aba Eventos de span)

Na transmissão, esta é a parte pré-visualizada dessa sequência, intercalada com os outros eventos armazenados em buffer da conexão:

event_start     {"event": {"type": "agent.message", "id": "sevt_01abc..."}}
event_delta     {"event_id": "sevt_01abc...", "delta": {"type": "content_delta", "index": 0, "content": {"type": "text", "text": "..."}}}
...
agent.message   {"id": "sevt_01abc...", "content": [...]}

A linha event_delta se repete uma vez por fragmento de texto. Processe cada evento à medida que ele chega:

  1. Em event_start, anote o id anunciado. Os identificadores sempre coincidem: event_start.event.id, cada event_delta.event_id e o id do agent.message armazenado em buffer são o mesmo valor.
  2. Em cada event_delta, anexe delta.content.text à entrada em (event_id, delta.index) e renderize o texto acumulado. O primeiro delta para um index cria essa entrada.
  3. Quando o agent.message armazenado em buffer chegar, associe-o pelo id, descarte a pré-visualização acumulada e renderize o conteúdo da mensagem no lugar dela.
  4. Em span.model_request_end, feche qualquer pré-visualização que não tenha sido reconciliada pelo seu evento armazenado em buffer. Nenhum outro delta chegará para ela. Se o turno apresentar erro ou for interrompido, o evento armazenado em buffer pode nunca chegar, mas span.model_request_end ainda chega.

O padrão depende de duas garantias:

  • Concatenar os deltas de uma pré-visualização na ordem de chegada, indexados por (event_id, index), resulta em um prefixo de content[index].text no evento armazenado em buffer. Não é necessariamente o texto inteiro, porque os deltas podem ser descartados sob carga.
  • Uma conexão emite no máximo um event_start por event_id, e o evento armazenado em buffer é a última coisa que essa conexão entrega para esse id.

Auxiliares acumuladores dos SDKs

O auxiliar de cada SDK cuida do controle de index. Os auxiliares de Go, Java, Ruby e C# também indexam a pré-visualização acumulada pelo id do evento. Com os auxiliares de Python, TypeScript e PHP, mantenha esse mapa você mesmo e incorpore cada delta à entrada do seu id.

Os exemplos a seguir ativam as pré-visualizações de agent.message e as reconciliam com o evento armazenado em buffer:

# Snapshots de prévia, indexados por id de evento. accumulate_managed_agents_event agrega cada
# event_start / event_delta em um snapshot de agent.message; o
# agent.message bufferizado o substitui.
previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}

# Habilite prévias de agent.message nesta conexão
with client.beta.sessions.events.stream(
    session.id, event_deltas=["agent.message"]
) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.message",
                "content": [{"type": "text", "text": "Describe the repo in one sentence."}],
            },
        ],
    )

    for event in stream:
        match event.type:
            case "event_start":
                snapshot = accumulate_managed_agents_event(None, event)
                if snapshot is not None:
                    previews[event.event.id] = snapshot
                print(f"event_start             {event.event.type} {event.event.id}")
            case "event_delta":
                preview = accumulate_managed_agents_event(previews.get(event.event_id), event)
                if preview is not None:
                    previews[event.event_id] = preview
                    text = "".join(block.text for block in preview.content)
                    print(f"event_delta             preview: {text!r}")
            case "agent.message":
                # O evento bufferizado é o registro: ele substitui e encerra a prévia
                preview = accumulate_managed_agents_event(previews.pop(event.id, None), event)
                text = "".join(block.text for block in preview.content)
                print(f"agent.message           {event.id} {text!r}")
            case "span.model_request_end":
                # Não virão mais deltas. Encerre qualquer prévia cujo
                # evento bufferizado nunca chegou.
                for event_id in previews:
                    print(f"span.model_request_end  closing preview for {event_id}")
                previews.clear()
            case "session.status_idle":
                break

Pré-visualizar eventos de threads de sessão

Em uma sessão multiagente, cada thread da sessão tem seu próprio fluxo de eventos. Ele aceita o mesmo parâmetro event_deltas[] com os mesmos valores.

Uma conexão pré-visualiza apenas a thread que está lendo. O fluxo no nível da sessão pré-visualiza a thread principal, e as pré-visualizações de uma thread filha nunca são replicadas nele. Para acompanhar o texto de um subagente enquanto o modelo o gera, abra o fluxo de thread desse subagente.

O caminho de um fluxo de thread termina em /threads/{thread_id}/stream. /events/stream existe apenas no nível da sessão, portanto não há um endpoint /threads/{thread_id}/events/stream.

event_start e event_delta têm o mesmo formato em um fluxo de thread e no fluxo no nível da sessão, e o padrão de acumular e reconciliar se aplica conforme descrito. Execute uma instância de acumulador por conexão de fluxo.

# Liste as threads da sessão e escolha uma filha: threads filhas têm parent_thread_id
# não nulo, e o parent_thread_id da thread primária é null.
child_thread = next(
    thread
    for thread in client.beta.sessions.threads.list(session.id)
    if thread.parent_thread_id is not None
)

# O stream da thread filha aceita o mesmo parâmetro event_deltas que o
# stream da sessão.
with client.beta.sessions.threads.events.stream(
    child_thread.id,
    session_id=session.id,
    event_deltas=["agent.message"],
) as stream:
    for event in stream:
        match event.type:
            case "event_delta":
                print(event.delta.content.text, end="")
            case "agent.message":
                # O evento bufferizado é o registro autoritativo; renderize seu conteúdo
                print()
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
                print()
            case "session.thread_status_idle":
                break

O loop de leitura termina em session.thread_status_idle, o evento emitido quando o turno da thread de sessão termina e a thread fica ociosa.

Limitações

  • Melhor esforço: Sob carga, o servidor pode descartar deltas de um evento. Quando isso acontece, você recebe um prefixo contíguo do texto e depois nenhum outro delta para esse evento. O agent.message armazenado em buffer ainda chega completo. Nunca trate uma pré-visualização acumulada como final.
  • Sem reprodução ao reconectar: Os deltas são entregues apenas à conexão que os ativou, enquanto ela estiver aberta. Isso se aplica igualmente ao fluxo no nível da sessão e a cada fluxo de thread da sessão. Uma conexão aberta depois que uma requisição ao modelo começou não recebe deltas para esse evento em andamento. Não há como solicitar novamente os deltas perdidos.
  • Uma thread, apenas texto: As pré-visualizações abrangem o texto do assistente na thread que a conexão está lendo. Uso de ferramentas, resultados de ferramentas e resultados de MCP nunca são pré-visualizados.
  • Nunca persistidos: event_start e event_delta existem apenas no fluxo ao vivo. Eles não aparecem no histórico de eventos da sessão (GET /v1/sessions/{session_id}/events) nem no histórico de eventos de nenhuma thread da sessão.

Solucionar problemas de pré-visualizações

Você vêO que significa
Um fluxo com eventos armazenados em buffer, mas sem event_start ou event_deltaA conexão que você está lendo não ativou as pré-visualizações, ou o turno nunca passou pela thread da qual você está fazendo streaming. event_deltas[] se aplica por conexão, não por sessão. Para descobrir qual thread foi executada, liste as threads da sessão (GET /v1/sessions/{session_id}/threads).
Um fluxo que cai durante uma pré-visualizaçãoOs deltas não são reproduzidos novamente. Siga o procedimento de reconexão: reabra o fluxo e liste o histórico de eventos. O histórico inclui todos os eventos armazenados em buffer emitidos enquanto você estava desconectado, incluindo o agent.message que sua pré-visualização estava aguardando.
Um 404 na URL do fluxoO caminho ou um ID está errado, ou a requisição não contém nenhum cabeçalho beta de managed-agents. Os endpoints de thread são restritos ao beta, então sem o cabeçalho eles não existem.
Um 400 mencionando event_deltasApenas agent.message e agent.thinking são aceitos.

Próximos passos

Envie eventos, faça streaming de respostas e interrompa ou redirecione sua sessão durante a execução.

Coordene vários agentes em uma única sessão.

Was this page helpful?