WebSocket
Bidirektionale Kommunikation in Echtzeit für Chat-Anwendungen mit Streaming-Antworten und dauerhaften Sessions.
Auf dieser Seite
Einrichtung
Verbindung erstellen
Öffne den Agenten, klicke im Verbindungsflussdiagramm auf Add inbound connector, dann auf Create New Connector und wähle WebSocket.
WebSocket URL und Secret kopieren
Nach einem Klick auf Create öffnet sich der Detail-Drawer der Verbindung automatisch und zeigt unter Configuration die Zugangsdaten. Die Authentifizierung ist standardmäßig aktiviert; deaktiviere Require Authentication nur für einen bewusst nicht authentifizierten Endpoint. Bewege den Mauszeiger im Verbindungsflussdiagramm über die Verbindung und klicke auf das Augensymbol, um später auf die Zugangsdaten zuzugreifen.
Vom Client aus verbinden
Verwende die URL und übermittle bei aktivierter Authentifizierung das Secret über
?secret=, den HeaderX-Connic-Secretoder die erste JSON-Nachricht.
So funktioniert WebSocket
WebSocket-Verbindungen ermöglichen Full-Duplex-Kommunikation für Chats in Echtzeit. Anders als HTTP-Webhooks halten sie dauerhafte Verbindungen für bidirektionale Nachrichten. Das eignet sich für Chat-Anwendungen, Streaming-Antworten, Gespräche mit mehreren Nachrichten und interaktive Agenten.
- Streaming: Teilantworten während ihrer Generierung senden (Standard: aktiviert)
- Require Auth: Authentifizierung per Secret Key (Standard: aktiviert)
- Session Timeout: Schließt eine inaktive Verbindung nach 60 bis 86.400 Sekunden (Standard: 3.600)
- Max Messages: Limit pro Verbindung, 1 bis 10.000 (Standard: 100)
Verbindung herstellen
// Mit WebSocket verbinden
const ws = new WebSocket('<websocket-url>');
// Authentifizieren (standardmäßig erforderlich)
ws.onopen = () => {
ws.send(JSON.stringify({ secret: '<your-secret-key>' }));
};
// Verbindungsbestätigung verarbeiten
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'connected') {
console.log('Connector-Run-ID:', data.connector_run_id);
console.log('Agents:', data.agents);
}
};Die beim Verbindungsaufbau zurückgegebene connector_run_id identifiziert den Connector-Run, der diese Verbindung aufzeichnet.
Nachrichten senden
// Nachricht senden
ws.send(JSON.stringify({
type: 'message',
id: 'msg-001',
payload: {
message: 'Wie ist das Wetter heute?',
context: { location: 'New York' }
}
}));Das Feld id ist optional, hilft aber bei der Korrelation von Antworten.
Jede Verbindung verarbeitet eine Nachricht nach der anderen, in der Reihenfolge des Eingangs. Eine Nachricht, die während einer laufenden Antwort eintrifft, wartet und wird verarbeitet, sobald alle verknüpften Agenten geantwortet haben. Eine Antwort darf so lange dauern wie das Run-Timeout. Die Wartezeit auf eine Freigabe zählt nicht mit. Ein freigabepflichtiges Tool hält die Antwort daher an, bis jemand entscheidet, und spätere Nachrichten warten. Halte approval.timeout bei Chat-Agenten kurz.
Dateien senden
Füge der Payload ein files-Array hinzu, um Dokumente, Bilder oder Audio an ein multimodales Modell zu senden. Die Bytes jeder Datei sind Base64-kodiert:
// Nachricht mit Base64-kodierten Dateien senden
ws.send(JSON.stringify({
type: 'message',
id: 'msg-002',
payload: {
message: 'Fasse dieses Dokument zusammen',
files: [
{
name: 'invoice.pdf',
mime_type: 'application/pdf',
data: '<base64-bytes>',
size: 12456
}
]
}
}));connic nimmt bis zu 10 vollständige Dateien an; es gelten 10 MiB pro Datei und insgesamt 10 MiB. Ungültige optionale Dateien werden einzeln ausgelassen. Sobald eine Datei die Anzahl- oder Größenbegrenzung überschreitet, bleiben die angenommenen Dateien erhalten; diese Datei und alle folgenden werden ausgelassen.file_issues enthält die Auslassungen mit stabilen Codes, auch wenn Dateien das Budget der Input-Prüfung überschreiten. Der Run kann selbst ohne verbleibende optionale Dateien fortfahren. Unter Linked Agents lässt sich Files required aktivieren, wenn die Aufgabe bei jeder Auslassung oder bei fehlenden Dateien stoppen muss.
Dabei gilt dieselbe Konvention wie für Multipart-Webhook-Uploads: Jeder angenommene Eintrag unter files wird zu einem Binärteil des LLM-Inputs; der führende Textteil ist die Payload, aus der files entfernt wurde. Die Middleware kann die rohe Payload über context["payload"] prüfen und Binärteile in before() hinzufügen oder entfernen.
Streaming-Antworten
// Ereignisse einer Streaming-Antwort
{ "type": "ack", "id": "msg-001", "message_number": 1 }
{ "type": "stream_start", "id": "msg-001", "agent": "assistant" }
{ "type": "stream_chunk", "id": "msg-001", "agent": "assistant", "chunk": "Das Wetter in " }
{ "type": "stream_chunk", "id": "msg-001", "agent": "assistant", "chunk": "New York ist sonnig." }
{
"type": "stream_end",
"id": "msg-001",
"agent": "assistant",
"full_response": "Das Wetter in New York ist sonnig.",
"token_usage": { "input_tokens": 45, "output_tokens": 15, "total_tokens": 60 }
}Ereignistypen: ack (empfangen), stream_start, stream_chunk (Textfragment), stream_end (vollständig, einschließlich Token-Nutzung)
Agenten mit Output Guardrails antworten nach Abschluss des Runs immer mit einem einzigen stream_chunk: Es wird kein Textfragment gesendet, bevor die Guardrails die vollständige Antwort geprüft haben. Implementiere den Client anhand des dokumentierten Ereignisablaufs. Er darf keine feste Anzahl von Chunks voraussetzen.
Modus ohne Streaming
Wenn Streaming deaktiviert ist, wird die vollständige Antwort in einer einzigen Nachricht gesendet:
// Nicht gestreamte Antwort (bei deaktiviertem Streaming)
{ "type": "ack", "id": "msg-001", "message_number": 1 }
{
"type": "response",
"id": "msg-001",
"agent": "assistant",
"response": "Das Wetter in New York ist sonnig.",
"token_usage": { "input_tokens": 45, "output_tokens": 15, "total_tokens": 60 }
}Gesprächsverlauf
Jede Nachricht startet einen eigenen Agent-Run. Nachrichten teilen sich nur dann einen Gesprächsverlauf, wenn der Agent eine persistente Session hat. Setze session.key auf ein Payload-Feld, das das Gespräch identifiziert, etwa input.conversation_id, und sende dieses Feld mit jeder Nachricht. Ohne Key teilen sich alle Gespräche des Agenten eine Session.
session:
key: input.conversation_id
ttl: 86400Der Verlauf gehört zum Gespräch, nicht zur Verbindung. Eine neue Verbindung mit derselben conversation_id setzt ihn fort, und das Schließen der Verbindung beendet ihn nicht. Mit ttl laufen inaktive Sessions ab.
Python-Beispiel
import asyncio
import websockets
import json
async def chat():
uri = "<websocket-url>"
async with websockets.connect(uri) as ws:
# Authentifizieren
await ws.send(json.dumps({"secret": "<your-secret-key>"}))
response = await ws.recv()
print(f"Verbunden: {json.loads(response)}")
# Nachricht senden
await ws.send(json.dumps({"message": "Hallo!"}))
# Streaming-Antwort empfangen
while True:
msg = await ws.recv()
data = json.loads(msg)
if data["type"] == "stream_chunk":
print(data["chunk"], end="", flush=True)
elif data["type"] == "stream_end":
print(f"\nFertig! Tokens: {data['token_usage']}")
break
asyncio.run(chat())Installation mit pip install websockets
Verbindungsfunktionen
- Ping/Pong-Keepalive, ordnungsgemäßes Schließen, Session-Timeout und Nachrichtenlimits