Mensajes del agente de Stream

Nota:

  • Los mensajes de agente de streaming solo se admiten en chats individuales.
  • Teams solo admite una respuesta de streaming simultánea por chat a la vez.
  • El streaming está disponible generalmente en la Web, el escritorio y móvil.

Puede transmitir mensajes de agente para entregar las respuestas de un agente al usuario como pequeñas actualizaciones mientras se genera la respuesta completa para mejorar la experiencia del usuario. A menudo, los agentes tardan mucho tiempo en generar respuestas sin actualizar la interfaz de usuario, lo que da lugar a una experiencia menos atractiva.

Cuando los usuarios observan que el agente procesa su solicitud en tiempo real, puede aumentar su satisfacción y confianza. Esta capacidad de respuesta y transparencia percibidas mejora la participación del usuario y disminuye el abandono de la conversación con el agente.

Experiencia del usuario de mensajes de Stream

Los mensajes del agente de streaming tienen dos tipos de actualizaciones:

  • Actualizaciones informativas: las actualizaciones informativas aparecen como una barra de progreso azul en la parte inferior del chat. Informa al usuario sobre las acciones en curso del agente mientras se genera una respuesta.

    Captura de pantalla que muestra las actualizaciones informativas de streaming de los agentes.

    Los mensajes informativos no deben tener más de 1 kb o 1000 caracteres.

  • Streaming de respuesta: El streaming de respuesta se muestra como un indicador de escritura. Revela la respuesta del agente al usuario como pequeñas actualizaciones mientras se genera la respuesta completa.

    La captura de pantalla muestra la secuencia de respuestas de los agentes.

    • El botón Detener : el botón permite a los usuarios controlar las respuestas de transmisión deteniéndolas temprano. Está disponible de forma predeterminada durante el streaming, lo que permite a los usuarios refinar las indicaciones o enviar otras nuevas. Comprender cómo funciona el botón Detener transmisión puede ayudar a diseñar interfaces conversacionales más eficaces y fáciles de usar.

    • Transmisión de contenido: durante la transmisión, los mensajes del agente deben contener el contenido transmitido anteriormente.

      Por ejemplo: este es un ejemplo de respuesta de streaming aceptable.
      Un marrón
      Un murciélago marrón
      Un murciélago hindú salta por encima de la valla

      No ejemplo: este es un ejemplo de una respuesta de streaming que devolverá un error.
      Un marrón
      Hola,

      Para obtener más información sobre el error, consulte códigos de error.

Implementar el streaming con el SDK de Teams

Úselo Stream.Update para escribir actualizaciones informativas antes de comenzar el flujo de mensajes. Stream.Update Se puede llamar varias veces con diferente texto de actualización.

Se usa Stream.Emit para escribir un fragmento de contenido en la secuencia. Los fragmentos se representarán en el mensaje tan pronto como Teams los reciba. Después de la primera llamada a Stream.Emit, las actualizaciones informativas ya no se mostrarán y Stream.Update no tendrán ningún efecto.

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

Úselo stream.update para escribir actualizaciones informativas antes de comenzar el flujo de mensajes. stream.update Se puede llamar varias veces con diferente texto de actualización.

Se usa stream.emit para escribir un fragmento de contenido en la secuencia. Los fragmentos se representarán en el mensaje tan pronto como Teams los reciba. Después de la primera llamada a stream.emit, las actualizaciones informativas ya no se mostrarán y stream.update no tendrán ningún efecto.

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!"
});

Úselo stream.update para escribir actualizaciones informativas antes de comenzar el flujo de mensajes. stream.update Se puede llamar varias veces con diferente texto de actualización.

Se usa stream.emit para escribir un fragmento de contenido en la secuencia. Los fragmentos se representarán en el mensaje tan pronto como Teams los reciba. Después de la primera llamada a stream.emit, las actualizaciones informativas ya no se mostrarán y stream.update no tendrán ningún efecto.

@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 obtener instrucciones sobre cómo dar formato a los mensajes transmitidos con Markdown extendido, incluidas las características y sintaxis admitidas, consulte Dar formato a los mensajes de agente.

Mensaje de Stream a través de la API de REST

Los mensajes del agente se pueden transmitir a través de la API REST. Los mensajes de streaming admiten texto enriquecido y citas. Los datos adjuntos, la etiqueta de IA, el botón de comentarios y las etiquetas de confidencialidad solo están disponibles para el mensaje de streaming final. Para obtener más información, consulte datos adjuntos y mensajes de agente con contenido generado por IA.

Cuando el agente invoque el streaming a través de la API REST, asegúrese de llamar a la siguiente API de streaming solo después de recibir una respuesta correcta de la llamada API inicial. Si el agente usa SDK, compruebe que recibe un objeto de respuesta nulo del método de actividad de envío para confirmar que la llamada anterior se transmitió correctamente.

Cuando el agente llama a la API de streaming demasiado rápido, puedes encontrar problemas y la experiencia de streaming se puede interrumpir. Recomendamos que el agente transmita un mensaje a la vez para asegurarse de que llama a la API de transmisión a un ritmo constante. Si no es así, es posible que se limite la solicitud. Almacene en búfer los tokens del modelo durante 1,5 a dos segundos para garantizar un proceso de streaming sin problemas.

Estas son las propiedades de los mensajes de agente de streaming:

Propiedad Obligatorio Descripción
type ✔️ Los valores admitidos son o typing .message
typing• : Úselo al transmitir el mensaje.
message• : Utilízalo para el mensaje final transmitido.
text ✔️ El contenido del mensaje que se va a transmitir.
entities.type ✔️ Debe ser streamInfo
entities.streamId ✔️ streamId Desde la solicitud de streaming inicial, inicia el streaming.
entities.streamType Tipos de actualizaciones de streaming. Los valores admitidos son informative, streamingo final. El valor predeterminado es streaming. final solo se usa en el mensaje final.
entities.streamSequence ✔️ Entero incremental para cada solicitud.

Nota:

Estos son los requisitos para usar streamSequence las API de REST:

  • El primero debe ser el número '1'.
  • Los números posteriores (excepto el final) deben ser un entero creciente monótono (por ejemplo, 1-2-3>>).
  • Para el mensaje final, streamSequence no debe establecerse.

Para habilitar el streaming en agentes, siga estos pasos:

  1. Iniciar transmisión
  2. Continuar streaming
  3. Streaming final

Iniciar transmisión

El agente puede enviar un mensaje informativo o de streaming como comunicación inicial. La respuesta incluye el streamId, que es importante para ejecutar llamadas posteriores.

El agente puede enviar varias actualizaciones informativas mientras procesa la solicitud del usuario, como escanear documentos, resumir contenido y encontrar elementos de trabajo relevantes. Puede enviar estas actualizaciones antes de que el agente genere su respuesta final al usuario.


//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

La siguiente imagen es un ejemplo de la transmisión de inicio:

La captura de pantalla muestra el inicio de la transmisión.

Continuar streaming

Use lo streamId que ha recibido de la solicitud inicial para enviar mensajes informativos o de streaming. Puede empezar con actualizaciones informativas y luego cambiar al streaming de respuestas cuando la respuesta final esté lista.

Empezar con actualizaciones informativas

A medida que el agente genera una respuesta, envíe actualizaciones informativas al usuario, como escanear documentos, resumir contenido y encontrar elementos de trabajo relevantes. Asegúrese de realizar llamadas posteriores solo después de que el agente reciba una respuesta correcta de las llamadas 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 { }

La imagen siguiente es un ejemplo de un agente que proporciona actualizaciones informativas:

Captura de pantalla que muestra las actualizaciones informativas del streaming.

Cambiar al streaming de respuesta

Cuando el agente esté listo para generar su mensaje final para el usuario, pase de proporcionar actualizaciones informativas a la transmisión de respuesta. Para cada actualización de streaming de respuesta, el contenido del mensaje debe ser la versión más reciente del mensaje final. Esto significa que el agente debe incorporar los nuevos tokens generados por los modelos de lenguaje grande (LLM). Anexe estos tokens a la versión anterior del mensaje y, a continuación, envíelos al usuario.

El límite es de 1 solicitud por segundo. Debe asegurarse de que el agente envía la solicitud dentro de este límite. El agente puede enviar solicitudes a un ritmo más lento, según sea necesario.


// 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{ }

La imagen siguiente es un ejemplo de un agente que proporciona actualizaciones en fragmentos:

La captura de pantalla muestra la secuencia de respuestas.

Transmisión final

Una vez que su agente termine de generar su mensaje, envíe la señal de transmisión final junto con el mensaje final. Para el mensaje final, el of activity es message.type Aquí, el agente establece los campos permitidos para la actividad de mensajes normal, pero final es el ú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{ }

La siguiente imagen es un ejemplo de la respuesta final del agente:

La captura de pantalla muestra el mensaje final transmitido.

Detener la respuesta del agente de streaming

El botón permite a los usuarios controlar las respuestas de streaming. El botón Detener está disponible de forma predeterminada durante el streaming, lo que permite a los usuarios detener una respuesta de forma anticipada. Los usuarios pueden interrumpir el streaming de mensajes y refinar sus indicaciones o enviar otras nuevas. Mejora la gestión de conversaciones con agentes para mejorar la experiencia del usuario.

Después de que un usuario detenga la generación del mensaje:

  • Los agentes tratan las respuestas detenidas como incompletas o descartadas en la conversación.

  • Los agentes no pueden cambiar el contenido ya transmitido.

  • El siguiente error se genera si un agente continúa transmitiendo en un mensaje que es detenido por un usuario:

    Detalles del error Descripción
    Código de estado HTTP 403
    Código de error ContentStreamNotAllowed
    Mensaje de error El usuario ha cancelado la transmisión de contenido.
    Descripción El usuario detuvo el streaming.

Códigos de respuesta

Los siguientes son los códigos de éxito y error:

Códigos de éxito

Código de estado HTTP Valor devuelto Descripción
201 streamId, es lo mismo que activityId tal como {"id":"1728640934763"} El agente devuelve este valor después de enviar la solicitud de streaming inicial.
Para cualquier solicitud de streaming posterior, se streamId requiere.
202 {} Código de éxito para las solicitudes de streaming posteriores.

Códigos de error

Código de estado HTTP Código de error Mensaje de error Descripción
202 ContentStreamSequenceOrderPreConditionFailed PreCondition failed exception when processing streaming activity. Es posible que pocas solicitudes de streaming lleguen fuera de secuencia y se descarten. La solicitud de streaming más reciente, determinada por streamSequence, se usa cuando las solicitudes se reciben de forma desordenada. Asegúrese de enviar cada solicitud de manera secuencial.
400 BadRequest Según el escenario, pueden aparecer varios mensajes de error, como Start streaming activities should include text La carga útil entrante no se adhiere a los valores necesarios ni los contiene.
403 ContentStreamNotAllowed Content stream is not allowed La función de API de streaming no está permitida para el usuario o el agente.
403 ContentStreamNotAllowed Content stream is not allowed on an already completed streamed message Un agente no puede transmitir continuamente en un mensaje que ya se ha transmitido y completado.
403 ContentStreamNotAllowed Content stream finished due to exceeded streaming time. El agente no pudo completar el proceso de streaming dentro del límite de tiempo estricto de dos minutos.
403 ContentStreamNotAllowed Message size too large El agente ha enviado un mensaje que supera la restricción de tamaño de mensaje actual.
403 ContentStreamNotAllowed Content stream was canceled by user El usuario detuvo el streaming.
403 ContentStreamNotAllowed Request streamed content should contain the previously streamed content El contenido entrante del mensaje de secuencia no contiene lo que ya se ha transmitido.
429 ND API calls quota exceeded El número de mensajes transmitidos por el agente ha superado la cuota.

Ejemplo de código

Ejemplo de nombre Descripción Node.js C# Python
Ejemplo de agente de streaming de Teams Esta aplicación de ejemplo se puede usar para escenarios de streaming en Teams con Azure Open AI y Bot Framework v4 para el ámbito personal. ND View ND
Agente de streaming conversacional Agente de streaming conversacional con SDK de Teams. View View Ver

Consulte también