Stream von Agent-Nachrichten

Hinweis

  • Streaming-Agent-Nachrichten werden nur in Einzelchats unterstützt.
  • Teams unterstützt jeweils nur eine gleichzeitige Streamingantwort pro Chat.
  • Streaming ist generell im Web, auf dem Desktop und auf Mobilgeräten verfügbar.

Sie können Agent-Nachrichten streamen, um die Antworten eines Agents in Form kleiner Updates an den Benutzer zu übermitteln, während die vollständige Antwort generiert wird, um die Benutzererfahrung zu verbessern. Oft brauchen Agenten sehr lange, um Antworten zu generieren, ohne die Benutzeroberfläche zu aktualisieren, was zu einer weniger ansprechenden Erfahrung führt.

Wenn Benutzer beobachten, wie der Agent ihre Anfrage in Echtzeit bearbeitet, kann dies ihre Zufriedenheit und ihr Vertrauen erhöhen. Diese wahrgenommene Reaktionsfähigkeit und Transparenz verbessert die Benutzerbindung und verringert den Gesprächsabbruch mit dem Agenten.

Benutzeroberfläche für Stream-Nachrichten

Für Streaming-Agent-Nachrichten gibt es zwei Arten von Updates:

  • Informative Updates: Informative Updates werden als blaue Statusanzeige am unteren Rand des Chats angezeigt. Er informiert den Benutzer über die laufenden Aktionen des Agents, während eine Antwort generiert wird.

    Der Screenshot zeigt den Agents informative Updates für das Streaming.

    Informationsnachrichten dürfen nicht länger als 1 KB oder 1000 Zeichen sein.

  • Antwortstreaming: Antwortstreaming wird als Eingabeindikator angezeigt. Es zeigt die Antwort des Agenten an den Benutzer in Form kleiner Aktualisierungen an, während die vollständige Antwort generiert wird.

    Der Screenshot zeigt das Antwortstreaming des Agents.

    • Die Schaltfläche "Stopp ": Mit dieser Schaltfläche können Benutzer Streamingantworten steuern, indem sie diese frühzeitig beenden. Es ist standardmäßig während des Streamings verfügbar, sodass Benutzer Eingabeaufforderungen verfeinern oder neue senden können. Wenn Sie verstehen, wie die Schaltfläche "Streaming beenden" funktioniert, können Sie effektivere und benutzerfreundlichere Unterhaltungsoberflächen entwerfen.

    • Streaming-Inhalte: Während des Streamings müssen die Agent-Nachrichten den zuvor gestreamten Inhalt enthalten.

      Beispiel: Dies ist ein Beispiel für eine akzeptable Streamingantwort.
      A Brown
      Ein brauner Fuchs
      Ein brauner Fuchs springt über den Zaun

      Nicht-Beispiel: Dies ist ein Beispiel für eine Streaming-Antwort, die einen Fehler zurückgibt.
      A Brown
      Hallo

      Weitere Informationen zu diesem Fehler finden Sie unter Fehlercodes.

Implementieren von Streaming mit Teams SDK

Wird verwendet Stream.Update , um informative Updates zu schreiben, bevor Sie mit dem Nachrichtenstrom beginnen. Stream.Update kann mehrfach mit unterschiedlichem Updatetext aufgerufen werden.

Wird verwendet Stream.Emit , um einen Inhaltsblock in den Stream zu schreiben. Chunks werden in der Nachricht gerendert, sobald sie von Teams empfangen werden. Nach dem ersten Aufruf von Stream.Emitwerden informative Aktualisierungen nicht mehr angezeigt und Stream.Update haben keine Auswirkungen.

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

Wird verwendet stream.update , um informative Updates zu schreiben, bevor Sie mit dem Nachrichtenstrom beginnen. stream.update kann mehrfach mit unterschiedlichem Updatetext aufgerufen werden.

Wird verwendet stream.emit , um einen Inhaltsblock in den Stream zu schreiben. Chunks werden in der Nachricht gerendert, sobald sie von Teams empfangen werden. Nach dem ersten Aufruf von stream.emitwerden informative Aktualisierungen nicht mehr angezeigt und stream.update haben keine Auswirkungen.

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

Wird verwendet stream.update , um informative Updates zu schreiben, bevor Sie mit dem Nachrichtenstrom beginnen. stream.update kann mehrfach mit unterschiedlichem Updatetext aufgerufen werden.

Wird verwendet stream.emit , um einen Inhaltsblock in den Stream zu schreiben. Chunks werden in der Nachricht gerendert, sobald sie von Teams empfangen werden. Nach dem ersten Aufruf von stream.emitwerden informative Aktualisierungen nicht mehr angezeigt und stream.update haben keine Auswirkungen.

@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)

Anleitungen zum Formatieren von gestreamten Nachrichten mit erweitertem Markdown, einschließlich unterstützter Features und Syntax, finden Sie unter Formatieren Ihrer Agent-Nachrichten.

Stream Nachricht über REST-API

Agent-Nachrichten können über die REST-API gestreamt werden. Streamingnachrichten unterstützen Rich-Text und Zitate. Anlagen-, KI-Bezeichnungs-, Feedbackschaltfläche und Vertraulichkeitsbezeichnungen sind nur für die endgültige Streamingnachricht verfügbar. Weitere Informationen finden Sie unter Anlagen und Agent-Nachrichten mit KI-generiertem Inhalt.

Wenn Ihr Agent das Streaming über die REST-API aufruft, stellen Sie sicher, dass Sie die nächste Streaming-API erst nach Erhalt einer erfolgreichen Antwort vom ersten API-Aufruf aufrufen. Wenn Ihr Agent SDK verwendet, stellen Sie sicher, dass Sie ein Null-Antwortobjekt von der Sendeaktivitätsmethode erhalten, um zu bestätigen, dass der vorherige Aufruf erfolgreich übertragen wurde.

Wenn Ihr Agent die Streaming-API zu schnell aufruft, können Probleme auftreten, und das Streamingerlebnis kann unterbrochen werden. Es wird empfohlen, dass Ihr Agent jeweils eine Nachricht streamt, um sicherzustellen, dass er die Streaming-API in einem konsistenten Tempo aufruft. Wenn dies nicht der Fall ist, wird die Anforderung möglicherweise gedrosselt. Puffern Sie die Token 1,5 bis zwei Sekunden lang aus dem Modell, um einen reibungslosen Streamingprozess sicherzustellen.

Im Folgenden finden Sie die Eigenschaften für Streaming-Agent-Nachrichten:

Eigenschaft Erforderlich Beschreibung
type ✔️ Unterstützte Werte sind entweder typing oder message.
typing: Wird beim Streamen der Nachricht verwendet.
message: Wird für die endgültige gestreamte Nachricht verwendet.
text ✔️ Der Inhalt der Nachricht, die gestreamt werden soll.
entities.type ✔️ Muss streamInfo sein.
entities.streamId ✔️ streamIdBeginnen Sie bei der ersten Streaminganforderung mit dem Streaming.
entities.streamType Typ der Streamingupdates. Unterstützte Werte sind entweder informative, streaming, oder final. Der Standardwert ist streaming. final wird nur in der endgültigen Nachricht verwendet.
entities.streamSequence ✔️ Inkrementelle ganze Zahl für jede Anforderung.

Hinweis

Hier sind die Anforderungen für die Verwendung streamSequence für REST-APIs:

  • Der erste muss die Nummer "1" sein.
  • Nachfolgende Zahlen (mit Ausnahme der Endzahlen) müssen eine monoton aufsteigende ganze Zahl sein (z. B. 1-2-3>>).
  • Für die endgültige Meldung streamSequence darf nicht festgelegt werden.

Gehen Sie folgendermaßen vor, um Streaming in Agents zu aktivieren:

  1. Streaming starten
  2. Streaming fortsetzen
  3. Endgültiges Streaming

Streaming starten

Der Agent kann entweder eine informative oder eine Streamingnachricht als erste Kommunikation senden. Die Antwort enthält das streamId, das für die Ausführung nachfolgender Aufrufe wichtig ist.

Ihr Agent kann mehrere informative Updates senden, während die Anfrage des Benutzers bearbeitet wird, z. B. Dokumente durchsuchen, Inhalt zusammenfassen und relevante Arbeitselemente finden. Sie können diese Updates senden, bevor Ihr Agent seine endgültige Antwort an den Benutzer generiert.


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

Die folgende Abbildung ist ein Beispiel für das Starten von Streaming:

Screenshot: Streaming starten.

Streaming fortsetzen

Verwenden Sie die streamId Nachrichten, die Sie von der ersten Anforderung erhalten haben, um entweder informative oder Streamingnachrichten zu senden. Sie können mit informativen Updates beginnen und später zum Antwortstreaming wechseln, wenn die endgültige Antwort fertig ist.

Starten Sie mit informativen Updates

Wenn Ihr Agent eine Antwort generiert, senden Sie informative Updates an den Benutzer, z. B. Durchsuchen von Dokumenten, Zusammenfassen von Inhalten und Gefundene relevante Arbeitselemente. Stellen Sie sicher, dass Sie nachfolgende Anrufe erst tätigen, nachdem der Agent eine erfolgreiche Antwort von den vorherigen Anrufen erhalten hat.


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

Die folgende Abbildung zeigt ein Beispiel für einen Agent, der informative Updates bereitstellt:

Screenshot: Informative Updates zum Streaming.

Zum Antwortstreaming wechseln

Wenn Ihr Agent bereit ist, die endgültige Nachricht für den Benutzer zu generieren, wechseln Sie von der Bereitstellung informativer Updates zum Antwortstreaming. Für jedes Antwortstreamingupdate sollte der Nachrichteninhalt die neueste Version der endgültigen Nachricht sein. Dies bedeutet, dass Ihr Agent alle neuen Token integrieren sollte, die von den LLMs (Large Language Models) generiert werden. Fügen Sie diese Token an die vorherige Nachrichtenversion an, und senden Sie sie dann an den Benutzer.

Der Drosselungsgrenzwert beträgt 1 Anforderung pro Sekunde. Sie müssen sicherstellen, dass der Agent die Anforderung innerhalb dieses Limits sendet. Der Agent kann Anforderungen je nach Bedarf mit einer langsameren Geschwindigkeit senden.


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

Die folgende Abbildung zeigt ein Beispiel für einen Agent, der Updates in Abschnitten bereitstellt:

Screenshot: Antwortstreaming.

Final Streaming

Nachdem der Agent die Generierung seiner Nachricht abgeschlossen hat, senden Sie das Streaming-Endsignal zusammen mit der endgültigen Nachricht. Für die letzte Meldung ist der type of activity .message Hier legt der Agent alle Felder fest, die für die reguläre Nachrichtenaktivität zulässig sind, aber final der einzige zulässige Wert für streamTypeist.


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

Die folgende Abbildung zeigt ein Beispiel für die endgültige Antwort des Agents:

Der Screenshot zeigt die endgültige gestreamte Nachricht.

Streaming-Agent-Antwort beenden

Mit der Schaltfläche können Benutzer Streamingantworten steuern. Die Schaltfläche "Stopp" ist während des Streamings standardmäßig verfügbar, sodass Benutzer eine Antwort frühzeitig beenden können. Benutzer können das Nachrichtenstreaming unterbrechen und ihre Eingabeaufforderungen verfeinern oder neue senden. Es verbessert das Konversationsmanagement mit Agenten für eine bessere Benutzererfahrung.

Nachdem ein Benutzer die Nachrichtengenerierung beendet hat:

  • Agents behandeln gestoppte Antworten als unvollständig oder in der Unterhaltung verworfen.

  • Die Mitarbeiter können den bereits gestreamten Inhalt nicht ändern.

  • Der folgende Fehler wird generiert, wenn ein Agent das Streaming auf eine Nachricht fortsetzt, die von einem Benutzer beendet wird:

    Fehlerdetails Beschreibung
    HTTP-Statuscode 403
    Fehlercode ContentStreamNotAllowed
    Fehlermeldung Der Inhaltsdatenstrom wurde vom Benutzer abgebrochen.
    Beschreibung Das Streaming wurde vom Benutzer beendet.

Antwortcodes

Die Erfolgs- und Fehlercodes folgen:

Erfolgscodes

HTTP-Statuscode Rückgabewert Beschreibung
201 streamId, dies ist dasselbe wie activityId{"id":"1728640934763"} Der Agent gibt diesen Wert zurück, nachdem die anfängliche Streaminganforderung gesendet wurde.
Für alle nachfolgenden Streaminganforderungen ist die streamId erforderlich.
202 {} Erfolgscode für alle nachfolgenden Streaminganforderungen.

Fehlercodes

HTTP-Statuscode Fehlercode Fehlermeldung Beschreibung
202 ContentStreamSequenceOrderPreConditionFailed PreCondition failed exception when processing streaming activity. Nur wenige Streaminganforderungen kommen möglicherweise nicht in der richtigen Reihenfolge an und werden verworfen. Die neueste Streaminganforderung, bestimmt durch streamSequence, wird verwendet, wenn Anforderungen ungeordnet empfangen werden. Stellen Sie sicher, dass jede Anforderung der Reihe nach gesendet wird.
400 BadRequest Je nach Szenario können verschiedene Fehlermeldungen angezeigt werden, z. B. Start streaming activities should include text Die eingehende Nutzlast hält sich nicht an die erforderlichen Werte oder enthält sie nicht.
403 ContentStreamNotAllowed Content stream is not allowed Das Streaming-API-Feature ist für den Benutzer oder Agent nicht zulässig.
403 ContentStreamNotAllowed Content stream is not allowed on an already completed streamed message Ein Agent kann nicht kontinuierlich auf eine Nachricht streamen, die bereits gestreamt und abgeschlossen wurde.
403 ContentStreamNotAllowed Content stream finished due to exceeded streaming time. Der Agent konnte den Streaming-Vorgang nicht innerhalb des strengen Zeitlimits von zwei Minuten abschließen.
403 ContentStreamNotAllowed Message size too large Der Agent hat eine Nachricht gesendet, die die aktuelle Größenbeschränkung für Nachrichten überschreitet.
403 ContentStreamNotAllowed Content stream was canceled by user Das Streaming wurde vom Benutzer beendet.
403 ContentStreamNotAllowed Request streamed content should contain the previously streamed content Der eingehende Inhalt für die Streamnachricht enthält nicht, was bereits gestreamt wurde.
429 API calls quota exceeded Die Anzahl der vom Agent gestreamten Nachrichten hat das Kontingent überschritten.

Codebeispiel

Beispielname Beschreibung Node.js C# Python
Beispiel für Teams-Streaming-Agent Diese Beispiel-App kann für Streamingszenarien in Teams verwendet werden, die Azure Open AI und Bot Framework v4 für den persönlichen Bereich verwenden. View
Agent für Unterhaltungsstreaming Dies ist ein Unterhaltungsstreaming-Agent mit Teams SDK. View View Anzeigen

Siehe auch