멀티모달: 비디오 입력

실시간 에이전트는 볼 수 있습니다. 오디오 스트림과 함께 카메라(또는 화면)에서 이미지 프레임을 모델로 푸시할 수 있으므로, 사용자는 에이전트에게 무언가를 설명하는 대신 — 반품할 손상된 제품, 화면의 오류, 문서 등 — 보여줄 수 있습니다.

API

runner의 한 메서드로, send_audio를 미러링합니다:

runner.send_video_frame("image/jpeg", &base64_jpeg).await?;

이는 하위 수준의 RealtimeRunnerRealtimeSession에서도 직접 사용할 수 있습니다. 기본 트레이트 구현은 no-op이므로, 시각적 입력을 받지 않는 제공자/모델은 프레임을 단순히 무시합니다.

각 제공자가 프레임을 처리하는 방법

두 백엔드는 비전을 다르게 처리하며, 이는 프레임을 얼마나 자주 전송해야 하는지에 영향을 미칩니다:

제공자메커니즘주기
Gemini Live연속 realtimeInput 미디어 청크스트리밍 — ~1–2 fps가 자연스러움
OpenAI Realtime대화 항목의 input_image 부분스냅샷 — 몇 초마다 ~1개로 제한

Gemini는 연속 비디오를 위해 구축되었습니다: 프레임은 오디오처럼 흐르고 모델은 움직이는 그림을 추론합니다. OpenAI의 실시간 비전은 이미지-인-컨텍스트입니다: 각 프레임은 대화 항목이 되므로 초당 많은 프레임을 보내면 컨텍스트가 넘치고 비용이 더 많이 듭니다. 유용할 때 (예: 사용자가 "이것 좀 봐"라고 말했을 때) OpenAI에 프레임을 보내고, 매 틱마다 보내지 마세요.

예시 UI는 이를 인코딩합니다:

const intervalMs = provider === 'gemini' ? 700 : 2500;  // ~1.4 fps vs ~0.4 fps

브라우저에서 프레임 캡처

카메라를 잡고, <video>를 캔버스에 그리고, WebSocket를 통해 JPEG 프레임을 전송합니다 (서버 측 브리지send_video_frame로 전달합니다):

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

서버에서 모델로 전달합니다:

ClientMsg::VideoFrame { mime, data } => {
    let _ = runner.send_video_frame(&mime, &data).await;  // non-fatal on error
}

프레임을 적당하게 유지하세요 (640×480, JPEG 품질 ~0.6) — 비전은 전체 해상도가 필요하지 않으며, 더 작은 프레임은 더 낮은 지연 시간과 비용을 의미합니다.

비전을 위한 프롬프트 작성

에이전트에게 볼 수 있다고 알려주면 카메라를 자연스럽게 사용합니다:

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.

시도해보기

customer_service 예시에는 카메라 패널이 있습니다: 카메라를 시작하고, 물건을 들고 *"이것을 반품하고 싶습니다 — 보이시나요?"*라고 말해보세요. Gemini (연속 비디오)에서 가장 잘 작동하며; OpenAI에서는 에이전트가 주기적인 스냅샷을 추론합니다.

다음: 감성 대화 →