Multimodal: Video-Eingabe
Ein Echtzeit-Agent kann sehen. Neben dem Audio-Stream können Sie Bild-Frames von einer Kamera (oder einem Bildschirm) an das Modell senden, sodass der Benutzer dem Agenten etwas zeigen kann – ein beschädigtes Produkt für eine Rücksendung, einen Fehler auf einem Bildschirm, ein Dokument – anstatt es zu beschreiben.
Die API
Eine Methode auf dem Runner, die send_audio widerspiegelt:
runner.send_video_frame("image/jpeg", &base64_jpeg).await?;
Sie ist auch auf dem niedrigeren Level RealtimeRunner und auf RealtimeSession direkt verfügbar. Die Standard-Trait-Implementierung ist ein No-Op, sodass Anbieter/Modelle, die keine visuelle Eingabe akzeptieren, Frames einfach ignorieren.
Wie jeder Anbieter Frames verarbeitet
Die beiden Backends behandeln die Vision unterschiedlich, und das sollte beeinflussen, wie oft Sie Frames senden:
| Anbieter | Mechanismus | Kadenz |
|---|---|---|
| Gemini Live | Kontinuierliche realtimeInput Medien-Chunks | Streamen Sie diese — ~1–2 fps ist natürlich |
| OpenAI Realtime | Ein input_image Teil eines Konversationselements | Snapshots — auf ~1 alle paar Sekunden drosseln |
Gemini ist für kontinuierliches Video ausgelegt: Frames fließen wie Audio und das Modell schließt über das sich bewegende Bild. OpenAIs Echtzeit-Vision ist Bild-im-Kontext: jeder Frame wird zu einem Konversationselement, sodass das Senden vieler pro Sekunde den Kontext überflutet und mehr kostet. Senden Sie OpenAI einen Frame, wenn es nützlich ist (z.B. wenn der Benutzer sagte "schau dir das an"), nicht bei jedem Tick.
Die Beispiel-UIs kodieren dies:
const intervalMs = provider === 'gemini' ? 700 : 2500; // ~1.4 fps vs ~0.4 fps
Frames in einem Browser erfassen
Nimm die Kamera, zeichne den <video> auf eine Leinwand und sende JPEG-Frames über dein WebSocket (die server-seitige Brücke leitet sie an send_video_frame weiter):
const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 } });
video.srcObject = stream;
const canvas = document.createElement('canvas');
setInterval(() => {
if (ws.readyState !== WebSocket.OPEN) return;
canvas.width = 640; canvas.height = 480;
canvas.getContext('2d').drawImage(video, 0, 0, 640, 480);
const data = canvas.toDataURL('image/jpeg', 0.6).split(',')[1]; // strip data: prefix
ws.send(JSON.stringify({ type: 'video_frame', mime: 'image/jpeg', data }));
}, intervalMs);
Auf dem Server an das Modell weiterleiten:
ClientMsg::VideoFrame { mime, data } => {
let _ = runner.send_video_frame(&mime, &data).await; // non-fatal on error
}
Halte Frames bescheiden (640×480, JPEG-Qualität ~0.6) — für die Bilderkennung ist keine volle Auflösung erforderlich, und kleinere Frames bedeuten geringere Latenz und Kosten.
Prompts für die Bilderkennung
Sag dem Agenten, dass er sehen kann, damit er die Kamera natürlich nutzt:
You can hear the customer and SEE what they show their camera. When they show
you an item (e.g. a damaged product for a return), briefly describe what you see
and use it to help resolve the issue.
Ausprobieren
Das customer_service-Beispiel hat ein Kamera-Panel: starte die Kamera, halte ein Objekt hoch und sage "Ich möchte dies zurückgeben — kannst du es sehen?". Es funktioniert am besten mit Gemini (kontinuierliches Video); bei OpenAI argumentiert der Agent über die periodischen Schnappschüsse.
Weiter: Affektiver Dialog →