Stream mensagens do agente

Observação

  • As mensagens do agente de streaming têm suporte apenas em chats individuais.
  • O Teams dá suporte a apenas uma resposta de streaming simultânea por chat por vez.
  • O streaming geralmente está disponível na Web, na área de trabalho e em dispositivos móveis.

Você pode transmitir mensagens do agente para entregar as respostas de um agente ao usuário como pequenas atualizações enquanto a resposta completa está sendo gerada para aprimorar a experiência do usuário. Muitas vezes, os agentes demoram muito para gerar respostas sem atualizar a interface do usuário, levando a uma experiência menos envolvente.

Quando os usuários observam o agente processando sua solicitação em tempo real, isso pode aumentar sua satisfação e confiança. Essa capacidade de resposta e transparência percebidas aumentam o envolvimento do usuário e diminuem o abandono da conversa com o agente.

Experiência do usuário de mensagens do Stream

As mensagens do agente de streaming têm dois tipos de atualizações:

  • Atualizações informativas: as atualizações informativas aparecem como uma barra de progresso azul na parte inferior do chat. Ele informa o usuário sobre as ações em andamento do agente enquanto uma resposta está sendo gerada.

    A captura de tela mostra as atualizações informativas do streaming dos agentes.

    As mensagens informativas não devem ter mais de 1 KB ou 1000 caracteres.

  • Streaming de resposta: o streaming de resposta é exibido como um indicador de digitação. Ele revela a resposta do agente ao usuário como pequenas atualizações enquanto a resposta completa está sendo gerada.

    A captura de tela mostra o streaming de respostas dos agentes.

    • O botão Parar : o botão permite que os usuários controlem as respostas de streaming interrompendo-as antecipadamente. Ele está disponível por padrão durante o streaming, permitindo que os usuários refinem os prompts ou enviem novos. Entender como o botão parar transmissão funciona pode ajudar a criar interfaces de conversação mais eficazes e amigáveis.

    • Conteúdo de streaming: Durante a transmissão, as mensagens do agente devem conter o conteúdo transmitido anteriormente.

      Por exemplo: este é um exemplo de resposta de streaming aceitável.
      Um marrom
      Uma raposa marrom
      Uma raposa marrom pula a cerca

      Não exemplo: este é um exemplo de uma resposta de streaming que retornará um erro.
      Um marrom
      Olá

      Para obter mais informações sobre o erro, consulte códigos de erro.

Implementar o streaming com o SDK do Teams

Use Stream.Update para gravar atualizações informativas antes de iniciar o fluxo de mensagens. Stream.Update Pode ser chamado várias vezes com texto de atualização diferente.

Use Stream.Emit para gravar uma parte do conteúdo no fluxo. As partes serão renderizadas na mensagem assim que forem recebidas pelas equipes. Após a primeira chamada para Stream.Emit, as atualizações informativas não serão mais exibidas e Stream.Update não terão efeito.

app.OnMessage(async (context, cancellationToken) =>
{   
   context.Stream.Update("Testing");
   await Task.Delay(1000);
   context.Stream.Emit("hello");
   context.Stream.Emit(", ");
   context.Stream.Emit("world!");
});

Use stream.update para gravar atualizações informativas antes de iniciar o fluxo de mensagens. stream.update Pode ser chamado várias vezes com texto de atualização diferente.

Use stream.emit para gravar uma parte do conteúdo no fluxo. As partes serão renderizadas na mensagem assim que forem recebidas pelas equipes. Após a primeira chamada para stream.emit, as atualizações informativas não serão mais exibidas e stream.update não terão efeito.

app.on('message', async ({ activity, stream }) => {
  stream.update("Thinking...");
  await new Promise(resolve => setTimeout(resolve, 1000))  
  stream.emit('hello');
  stream.emit(', ');
  stream.emit('world!');

  // result message: "hello, world!"
});

Use stream.update para gravar atualizações informativas antes de iniciar o fluxo de mensagens. stream.update Pode ser chamado várias vezes com texto de atualização diferente.

Use stream.emit para gravar uma parte do conteúdo no fluxo. As partes serão renderizadas na mensagem assim que forem recebidas pelas equipes. Após a primeira chamada para stream.emit, as atualizações informativas não serão mais exibidas e stream.update não terão efeito.

@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]):
    ctx.stream.update("Stream starting...")
    await asyncio.sleep(1)

    # Stream messages with delays using ctx.stream.emit
    for message in STREAM_MESSAGES:
        # Add some randomness to timing
        await asyncio.sleep(random())

        ctx.stream.emit(message)

Para obter orientação sobre como formatar mensagens transmitidas com Markdown estendido, incluindo recursos e sintaxe com suporte, consulte Formatar suas mensagens de agente.

Stream mensagem por meio da API REST

As mensagens do agente podem ser transmitidas por meio da API REST. As mensagens de streaming dão suporte a rich text e citação. Anexo, rótulo AI, botão de comentários e rótulos de confidencialidade estão disponíveis apenas para a mensagem de streaming final. Para obter mais informações, consulte Anexos e mensagens de agente com conteúdo gerado por IA.

Quando o agente invocar o streaming por meio da API REST, certifique-se de chamar a próxima API de streaming somente depois de receber uma resposta bem-sucedida da chamada inicial da API. Se o agente usar o SDK, verifique se você recebeu um objeto de resposta nulo do método de atividade de envio para confirmar se a chamada anterior foi transmitida com êxito.

Quando seu agente chama a API de streaming muito rapidamente, você pode encontrar problemas e a experiência de streaming pode ser interrompida. Recomendamos que seu agente transmita uma mensagem por vez para garantir que ele chame a API de streaming em um ritmo consistente. Caso contrário, a solicitação poderá ser limitada. Armazene os tokens em buffer do modelo por 1,5 a dois segundos para garantir um processo de streaming suave.

Veja a seguir as propriedades para mensagens do agente de streaming:

Propriedade Obrigatório Descrição
type ✔️ Os valores com suporte são ou typingmessage.
typing: Use ao transmitir a mensagem.
message: Use para a mensagem final transmitida.
text ✔️ O conteúdo da mensagem que será transmitida.
entities.type ✔️ Deve ser streamInfo
entities.streamId ✔️ streamId Na solicitação inicial de streaming, inicie o streaming.
entities.streamType Tipos de atualizações de streaming. Os valores com suporte são informative, streaming, ou final. O valor padrão é streaming. final é usada somente na mensagem final.
entities.streamSequence ✔️ Número inteiro incremental para cada solicitação.

Observação

Aqui estão os requisitos para uso streamSequence de APIs REST:

  • O primeiro deve ser o número '1'.
  • Os números subsequentes (exceto final) devem ser um número inteiro crescente monotônico (por exemplo, 1-2-3>>).
  • para a mensagem final, streamSequence não deve ser definida.

Para habilitar o streaming em agentes, siga estas etapas:

  1. Iniciar streaming
  2. Continuar transmissão
  3. Streaming final

Iniciar streaming

O agente pode enviar uma mensagem informativa ou de streaming como sua comunicação inicial. A resposta inclui o streamId, que é importante para executar chamadas subsequentes.

Seu agente pode enviar várias atualizações informativas enquanto processa a solicitação do usuário, como Verificação de documentos, Resumo de conteúdo e Itens de trabalho relevantes encontrados. Você pode enviar essas atualizações antes que seu agente gere sua resposta final ao usuário.


//Ex: An agent sends the first request with content & the content is informative loading message.

POST /conversations/<conversationId>/activities HTTP/1.1 
{
  "type": "typing",
  "serviceurl": "https://smba.trafficmanager.net/amer/",
  "channelId": "msteams",
  "from": {
    "id": "<botId>",
    "name": "<BotName>"
  },
  "conversation": {
    "conversationType": "personal",
    "id": "<conversationId>"
  },
  "recipient": {
    "id": "<recipientId>",
    "name": "<recipientName>",
    "aadObjectId": "<recipient aad objecID>"
  },
  "locale": "en-US",
  "text": "Searching through documents...", //(required) first informative loading message.
  "entities":[
    {
      "type": "streaminfo",
      "streamType": "informative", // informative or streaming; default= streaming.
      "streamSequence": 1 // (required) incremental integer; must be present for start and continue streaming request, but must not be set for final streaming request.
    }
  ],
}

201 created { "id": "a-0000l" } // return stream id

A imagem a seguir é um exemplo de iniciar streaming:

A captura de tela mostra iniciar transmissão.

Continuar transmissão

Use o streamId que você recebeu da solicitação inicial para enviar mensagens informativas ou de streaming. Você pode começar com atualizações informativas e, posteriormente , mudar para o streaming de resposta quando a resposta final estiver pronta.

Comece com atualizações informativas

À medida que o agente gera uma resposta, envie atualizações informativas para o usuário, como Verificação de documentos, Resumo de conteúdo e Itens de trabalho relevantes encontrados. Certifique-se de fazer chamadas subsequentes somente depois que o agente receber uma resposta bem-sucedida das chamadas anteriores.


// Ex: An agent sends the second request with content & the content is informative loading message.

POST /conversations/<conversationId>/activities HTTP/1.1 
{
  "type": "typing",
  "serviceurl": "https://smba.trafficmanager.net/amer/",
  "channelId": "msteams",
  "from": {
    "id": "<botId>",
    "name": "<BotName>"
  },
  "conversation": {
    "conversationType": "personal",
    "id" : "<conversationId>"
  },
  "recipient": {
    "id": "<recipientId>",
    "name": "<recipientName>",
    "aadObjectId": "<recipient aad objecID>"
  },
  "locale": "en -US",
  "text": "Searching through emails...", // (required) second informative loading message.
  "entities":[
    {
      "type": "streaminfo",
      "streamId": "a-0000l", // // (required) must be present for any subsequent request after the first chunk.
      "streamType": "informative", // informative or streaming; default= streaming.
      "streamSequence": 2 // (required) incremental integer; must be present for start and continue streaming request, but must not be set for final streaming request.
    }
  ],
} 
202 0K { }

A imagem a seguir é um exemplo de um agente que fornece atualizações informativas:

A captura de tela mostra as atualizações informativas do streaming.

Alternar para streaming de resposta

Depois que o agente estiver pronto para gerar sua mensagem final para o usuário, alterne do fornecimento de atualizações informativas para o streaming de respostas. Para cada atualização de streaming de resposta, o conteúdo da mensagem deve ser a versão mais recente da mensagem final. Isso significa que seu agente deve incorporar todos os novos tokens gerados pelos Large Language Models (LLMs). Acrescente esses tokens à versão anterior da mensagem e envie-os ao usuário.

O limite de limitação é de 1 solicitação por segundo. Você deve garantir que o agente envie a solicitação dentro desse limite. O agente pode enviar solicitações em uma taxa mais lenta, conforme necessário.


// Ex: An agent sends the third request with content & the content is actual streaming content.

POST /conversations/<conversationId>/activities HTTP/1.1
{
  "type": "typing",
  "serviceurl" : "https://smba.trafficmanager.net/amer/ ",
  "channelId": "msteams",
  "from": {
    "id": "<botId>",
    "name": "<BotName>"
  },
  "conversation": {
    "conversationType": "personal",
    "id" : "<conversationId>"
  },
  "recipient": {
    "id" : "<recipientId>",
    "name": "<recipientName>",
    "aadObjectId": "<recipient aad objecID>"
  },
  "locale": "en-US" ,
  "text": "A brown fox", // (required) first streaming content.
  "entities":[
    {
      "type": "streaminfo",
      "streamId": "a-0000l", // // (required) must be present for any subsequent request after the first chunk.
      "streamType": "streaming", // informative or streaming; default= streaming.
      "streamSequence": 3 // (required) incremental integer; must be present for start and continue streaming request, but must not be set for final streaming request.
    }
  ],
}
202 0K{ }


// Ex: An agent sends the fourth request with content & the content is actual streaming content.

POST /conversations/<conversationId>/activities HTTP/1.1
{
  "type": "typing",
  "serviceurl" : "https://smba.trafficmanager.net/amer/ ",
  "channelId": "msteams",
  "from": {
    "id": "<botId>",
    "name": "<BotName>"
  },
  "conversation": {
    "conversationType": "personal",
    "id" : "<conversationId>"
  },
  "recipient": {
    "id" : "<recipientId>",
    "name": "<recipientName>",
    "aadObjectId": "<recipient aad objecID>"
  },
  "locale": "en-US" ,
  "text": "A brown fox jumped over the fence", // (required) first streaming content.
  "entities":[
    {
      "type": "streaminfo",
      "streamId": "a-0000l", // // (required) must be present for any subsequent request after the first chunk.
      "streamType": "streaming", // informative or streaming; default= streaming.
      "streamSequence": 4 // (required) incremental integer; must be present for start and continue streaming request, but must not be set for final streaming request.
    }
  ],
}
202 0K{ }

A imagem a seguir é um exemplo de um agente que fornece atualizações em partes:

A captura de tela mostra o streaming de respostas.

Final Streaming

Depois que o agente concluir a geração da mensagem, envie o sinal de término do streaming junto com a mensagem final. Para a mensagem final, a type atividade de é message. Aqui, o agente define todos os campos permitidos para a atividade de mensagem regular, mas final é o único valor permitido para streamType.


// Ex: An agent sends the second request with content && the content is informative loading message.

POST /conversations/<conversationId>/activities HTTP/1.1
{
  "type": "message",
  "serviceurl" : "https://smba.trafficmanager.net/amer/ ",
  "channelId": "msteams",
  "from": {
    "id": "<botId>",
    "name": "<BotName>"
  },
  "conversation": {
    "conversationType": "personal",
    "id" : "<conversationId>"
  },
  "recipient": {
    "id" : "recipientId>",
    "name": "<recipientName>",
    "aadObjectId": "<recipient aad objecID>"
  },
  "locale": "en-US",
  "text": "A brown fox jumped over the fence.", // (required) first streaming content.
  "entities":[
    {
      "type": "streaminfo",
      "streamId": "a-0000l", // // (required) must be present for any subsequent request after the first chunk.
      "streamType": "final", // (required) final is only allowed for the last message of the streaming.
    }
  ],
  }
202 0K{ }

A imagem a seguir é um exemplo da resposta final do agente:

A captura de tela mostra a mensagem final transmitida.

Parar resposta do agente de streaming

O botão permite aos usuários controlar as respostas de streaming. O botão Parar está disponível por padrão durante o streaming, permitindo que os usuários interrompam uma resposta antecipadamente. Os usuários podem interromper o streaming da mensagem e refinar seus prompts ou enviar novos. Ele aprimora o gerenciamento de conversas com agentes para uma melhor experiência do usuário.

Depois que um usuário interromper a geração de mensagens:

  • Os agentes tratam as respostas interrompidas como incompletas ou descartadas na conversa.

  • Os agentes não podem alterar o conteúdo já transmitido.

  • O seguinte erro será gerado se um agente continuar a transmitir em uma mensagem interrompida por um usuário:

    Detalhes do erro Descrição
    Código de status HTTP 403
    Código de erro ContentStreamNotAllowed
    Mensagem de erro O fluxo de conteúdo foi cancelado pelo usuário.
    Descrição O streaming foi interrompido pelo usuário.

Códigos de resposta

A seguir estão os códigos de sucesso e erro:

Códigos de sucesso

Código de status HTTP Valor de retorno Descrição
201 streamId, é o mesmo que activityId{"id":"1728640934763"} O agente retorna esse valor após enviar a solicitação de streaming inicial.
Para todas as solicitações de streaming subsequentes, o streamId é obrigatório.
202 {} Código de sucesso para todas as solicitações de streaming subsequentes.

Códigos de erro

Código de status HTTP Código de erro Mensagem de erro Descrição
202 ContentStreamSequenceOrderPreConditionFailed PreCondition failed exception when processing streaming activity. Algumas solicitações de streaming podem chegar fora de sequência e ser descartadas. A solicitação de streaming mais recente, determinada por streamSequence, é usada quando as solicitações são recebidas de maneira desordenada. Certifique-se de enviar cada solicitação de forma sequencial.
400 BadRequest Dependendo do cenário, você pode encontrar várias mensagens de erro, como Start streaming activities should include text O conteúdo de entrada não adere nem contém os valores necessários.
403 ContentStreamNotAllowed Content stream is not allowed O recurso de API de streaming não é permitido para o usuário ou agente.
403 ContentStreamNotAllowed Content stream is not allowed on an already completed streamed message Um agente não pode transmitir continuamente em uma mensagem que já foi transmitida e concluída.
403 ContentStreamNotAllowed Content stream finished due to exceeded streaming time. O agente não conseguiu concluir o processo de streaming dentro do limite de tempo estrito de dois minutos.
403 ContentStreamNotAllowed Message size too large O agente enviou uma mensagem que excede a restrição de tamanho de mensagem atual.
403 ContentStreamNotAllowed Content stream was canceled by user O streaming foi interrompido pelo usuário.
403 ContentStreamNotAllowed Request streamed content should contain the previously streamed content O conteúdo de entrada da mensagem de fluxo não contém o que já foi transmitido.
429 NA API calls quota exceeded O número de mensagens transmitidas pelo agente excedeu a cota.

Exemplo de código

Nome do exemplo Descrição Node.js C# Python
Exemplo de agente de streaming do Teams Este aplicativo de exemplo pode ser usado para cenários de streaming no Teams usando o Azure Open AI e o Bot Framework v4 para escopo pessoal. NA View NA
Agente de streaming de conversa Este é um agente de streaming de conversa com SDK do Teams. View View Exibir

Confira também