متعدد الوسائط: إدخال الفيديو

يمكن للوكيل في الوقت الفعلي أن يرى. إلى جانب دفق الصوت، يمكنك دفع إطارات الصور من كاميرا (أو شاشة) إلى النموذج، بحيث يمكن للمستخدم إظهار شيء للوكيل — منتج تالف للإرجاع، خطأ على الشاشة، مستند — بدلاً من وصفه.

الـ API

إحدى الطرق على الـ Runner، تعكس send_audio:

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

وهي متاحة أيضًا على المستوى الأدنى RealtimeRunner وعلى RealtimeSession مباشرةً. التطبيق الافتراضي للـ trait هو لا شيء (no-op)، لذا فإن الموفرين/النماذج التي لا تقبل المدخلات المرئية تتجاهل الإطارات ببساطة.

كيف يتعامل كل موفر مع الإطارات

تتعامل الواجهتان الخلفيتان مع الرؤية بشكل مختلف، وهذا يجب أن يحدد مدى تكرار إرسالك للإطارات:

مزودآليةوتيرة
Gemini Liveأجزاء وسائط realtimeInput مستمرةبثها — ~1-2 إطار في الثانية أمر طبيعي
OpenAI Realtimeجزء input_image على عنصر محادثةلقطات — تقييدها إلى ~1 كل بضع ثوانٍ

Gemini مصمم لـ الفيديو المستمر: تتدفق الإطارات كالصوت ويستدل النموذج على الصورة المتحركة. رؤية OpenAI في الوقت الفعلي هي صورة في السياق: يصبح كل إطار عنصر محادثة، لذا فإن إرسال العديد منها في الثانية يغرق السياق ويكلف أكثر. أرسل إلى OpenAI إطارًا عندما يكون مفيدًا (مثل قول المستخدم "انظر إلى هذا")، وليس في كل نبضة.

واجهات المستخدم المثال توضح ذلك:

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

التقاط الإطارات في المتصفح

التقط الكاميرا، ارسم <video> على لوحة قماشية، وأرسل إطارات JPEG عبر WebSocket الخاص بك (يقوم الجسر من جانب الخادم بإعادة توجيهها إلى 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) — الرؤية لا تحتاج إلى دقة كاملة، والإطارات الأصغر تعني زمن استجابة وتكلفة أقل.

المطالبة بالرؤية

أخبر الـ Agent أنه يستطيع الرؤية، بحيث يستخدم الكاميرا بشكل طبيعي:

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 يستدل الـ Agent على اللقطات الدورية.

التالي: حوار عاطفي ←