دليل إمكانات Live API

هذا دليل شامل يتناول الإمكانات وعمليات الإعداد المتاحة من خلال Live API. يمكنك الاطّلاع على صفحة البدء باستخدام Live API للحصول على نظرة عامة ورمز نموذجي لحالات الاستخدام الشائعة.

قبل البدء

  • التعرّف على المفاهيم الأساسية: إذا لم يسبق لك ذلك، ننصحك بقراءة صفحة البدء باستخدام Live API أولاً. سيساعدك هذا الدليل في التعرّف على المبادئ الأساسية لـ Live API وطريقة عملها ومختلف طرق التنفيذ.
  • تجربة Live API في AI Studio: قد يكون من المفيد تجربة Live API في Google AI Studio قبل البدء في إنشاء التطبيقات. لاستخدام Live API في Google AI Studio، انقر على البث المباشر (Stream).

مقارنة النماذج

يلخّص الجدول التالي الاختلافات الرئيسية بين Gemini 3.1 Flash Live Preview وGemini 2.5 Flash Live Preview:

الميزة معاينة مباشرة في Gemini 3.1 Flash ‫Gemini 2.5 Flash Live Preview
التفكير تستخدم thinkingLevel للتحكّم في عمق التفكير من خلال إعدادات مثل minimal وlow وmedium وhigh. القيمة التلقائية هي minimal لتحسين السرعة. اطّلِع على مستويات التفكير والميزانيات. يتم استخدام thinkingBudget لضبط عدد الرموز المميزة للتفكير. تكون ميزة "التفكير الديناميكي" مفعَّلة تلقائيًا. اضبط thinkingBudget على 0 لإيقافها. اطّلِع على مستويات التفكير والميزانيات.
تلقّي الردّ يمكن أن يحتوي حدث خادم واحد على أجزاء متعدّدة من المحتوى في الوقت نفسه (على سبيل المثال، inlineData والنص). احرص على أن يعالج الرمز البرمجي جميع الأجزاء في كل حدث لتجنُّب فقدان المحتوى. يحتوي كل حدث خادم على جزء واحد فقط من المحتوى. يتم تسليم الأجزاء في أحداث منفصلة.
محتوى العميل لا تتوفّر send_client_content إلا لإنشاء سجلّ السياق الأوّلي (يتطلّب ضبط initial_history_in_client_content في إعدادات الجلسة). لإرسال إشعارات نصية أثناء المحادثة، استخدِم send_realtime_input بدلاً من ذلك. يتوفّر send_client_content طوال المحادثة لإرسال تحديثات المحتوى التدريجية وتحديد السياق.
تفعيل التغطية القيمة التلقائية هي TURN_INCLUDES_AUDIO_ACTIVITY_AND_ALL_VIDEO. يتضمّن دور النموذج النشاط الصوتي الذي تم رصده وجميع لقطات الفيديو. القيمة التلقائية هي TURN_INCLUDES_ONLY_ACTIVITY. يتضمّن دور النموذج النشاط الذي تم رصده فقط.
التعرّف المخصّص على النشاط الصوتي (activity_start/activity_end) متاح أوقِف ميزة "التعرّف التلقائي على النشاط الصوتي" وأرسِل الرسالتَين activityStart وactivityEnd يدويًا للتحكّم في حدود الأدوار. متاح أوقِف ميزة "التعرّف التلقائي على النشاط الصوتي" وأرسِل الرسالتَين activityStart وactivityEnd يدويًا للتحكّم في حدود الدور.
إعداد ميزة "التعرّف على النشاط المرئي والصوتي" تلقائيًا متاح اضبط المَعلمات، مثل start_of_speech_sensitivity وend_of_speech_sensitivity وprefix_padding_ms وsilence_duration_ms. متاح اضبط المَعلمات، مثل start_of_speech_sensitivity وend_of_speech_sensitivity وprefix_padding_ms وsilence_duration_ms.
استدعاء الدالة غير المتزامن (behavior: NON_BLOCKING) غير متاح لا يمكن استدعاء الدوال إلا بشكل تسلسلي. لن يبدأ النموذج في الردّ إلى أن ترسل ردّ الأداة. متاح اضبط قيمة behavior على NON_BLOCKING في تعريف الدالة للسماح للنموذج بمواصلة التفاعل أثناء تشغيل الدالة. التحكّم في طريقة تعامل النموذج مع الردود باستخدام المَعلمة scheduling (INTERRUPT أو WHEN_IDLE أو SILENT)
التحكّم الاستباقي بالصوت غير متاح متاح عند تفعيل هذه الميزة، يمكن للنموذج أن يقرّر بشكل استباقي عدم الردّ إذا كان المحتوى المُدخَل غير ذي صلة. اضبط قيمة proactive_audio على true في إعدادات proactivity (يتطلّب ذلك v1beta).
الحوار التفاعلي العاطفي غير متاح متاح يعدّل النموذج أسلوب الردّ ليتطابق مع أسلوب التعبير والنبرة في الإدخال. اضبط قيمة enable_affective_dialog على true في إعدادات الجلسة (يتطلّب ذلك v1beta).

للانتقال من Gemini 2.5 Flash Live إلى Gemini 3.1 Flash Live، يُرجى الاطّلاع على دليل نقل البيانات.

إنشاء اتصال

يوضّح المثال التالي كيفية إنشاء اتصال باستخدام مفتاح واجهة برمجة التطبيقات:

Python

import asyncio
from google import genai

client = genai.Client()

model = "gemini-3.1-flash-live-preview"
config = {"response_modalities": ["AUDIO"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        print("Session started")
        # Send content...

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-3.1-flash-live-preview';
const config = { responseModalities: [Modality.AUDIO] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        console.debug(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  console.debug("Session started");
  // Send content...

  session.close();
}

main();

طُرق التفاعل

تقدّم الأقسام التالية أمثلة وسياقًا داعمًا لمختلف أساليب الإدخال والإخراج المتاحة في Live API.

إرسال الصوت

يجب إرسال الصوت كبيانات PCM أولية (صوت PCM أولي 16 بت، 16 كيلوهرتز، ترتيب البايتات الصغير).

Python

# Assuming 'chunk' is your raw PCM audio bytes
await session.send_realtime_input(
    audio=types.Blob(
        data=chunk,
        mime_type="audio/pcm;rate=16000"
    )
)

JavaScript

// Assuming 'chunk' is a Buffer of raw PCM audio
session.sendRealtimeInput({
  audio: {
    data: chunk.toString('base64'),
    mimeType: 'audio/pcm;rate=16000'
  }
});

تنسيقات الصوت

تكون البيانات الصوتية في Live API دائمًا بتنسيق PCM الأولي ذي الترتيب البايتي الصغير، وبدقة 16 بت. يستخدم مصدر إخراج الصوت دائمًا معدّل بيانات يبلغ 24 كيلوهرتز. يكون معدّل البيانات في الملف الصوتي 16 كيلو هرتز بشكل تلقائي، ولكن ستعيد Live API أخذ عينات إذا لزم الأمر، ما يتيح إرسال أي معدّل بيانات في الملف الصوتي. لتحديد معدّل أخذ العينات من الصوت المُدخَل، اضبط نوع MIME لكل Blob يحتوي على صوت على قيمة مثل audio/pcm;rate=16000.

استلام الصوت

يتم تلقّي الردود الصوتية من النموذج على شكل أجزاء من البيانات.

Python

async for response in session.receive():
    if response.server_content and response.server_content.model_turn:
        for part in response.server_content.model_turn.parts:
            if part.inline_data:
                audio_data = part.inline_data.data
                # Process or play the audio data

JavaScript

// Inside the onmessage callback
const content = response.serverContent;
if (content?.modelTurn?.parts) {
  for (const part of content.modelTurn.parts) {
    if (part.inlineData) {
      const audioData = part.inlineData.data;
      // Process or play audioData (base64 encoded string)
    }
  }
}

جارٍ إرسال الرسالة النصية

يمكن إرسال النص باستخدام send_realtime_input (Python) أو sendRealtimeInput (JavaScript).

Python

await session.send_realtime_input(text="Hello, how are you?")

JavaScript

session.sendRealtimeInput({
  text: 'Hello, how are you?'
});

إرسال الفيديو

يتم إرسال إطارات الفيديو كصور فردية (مثل JPEG أو PNG) بعدد اللقطات في الثانية محدّد (إطار واحد في الثانية كحد أقصى).

Python

# Assuming 'frame' is your JPEG-encoded image bytes
await session.send_realtime_input(
    video=types.Blob(
        data=frame,
        mime_type="image/jpeg"
    )
)

JavaScript

// Assuming 'frame' is a Buffer of JPEG-encoded image data
session.sendRealtimeInput({
  video: {
    data: frame.toString('base64'),
    mimeType: 'image/jpeg'
  }
});

تعديلات المحتوى التدريجية

استخدِم التعديلات المتزايدة لإرسال النص المُدخَل أو إنشاء سياق الجلسة أو استعادة سياق الجلسة. بالنسبة إلى السياقات القصيرة، يمكنك إرسال تفاعلات اتّجاهات مفصّلة لتمثيل التسلسل الدقيق للأحداث:

Python

turns = [
    {"role": "user", "parts": [{"text": "What is the capital of France?"}]},
    {"role": "model", "parts": [{"text": "Paris"}]},
]

await session.send_client_content(turns=turns, turn_complete=False)

turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]

await session.send_client_content(turns=turns, turn_complete=True)

JavaScript

let inputTurns = [
  { "role": "user", "parts": [{ "text": "What is the capital of France?" }] },
  { "role": "model", "parts": [{ "text": "Paris" }] },
]

session.sendClientContent({ turns: inputTurns, turnComplete: false })

inputTurns = [{ "role": "user", "parts": [{ "text": "What is the capital of Germany?" }] }]

session.sendClientContent({ turns: inputTurns, turnComplete: true })

بالنسبة إلى السياقات الأطول، ننصحك بتقديم ملخّص لرسالة واحدة لإتاحة مساحة أكبر في قدرة الاستيعاب للتفاعلات اللاحقة. راجِع استئناف الجلسة للتعرّف على طريقة أخرى لتحميل سياق الجلسة.

النصوص المُحوَّلة من مقاطع صوتية

بالإضافة إلى ردّ النموذج، يمكنك أيضًا تلقّي نصوص لكل من مصدر إخراج الصوت والمدخل الصوتي.

لتفعيل تحويل الصوت الذي ينتجه النموذج إلى نص، أرسِل output_audio_transcription في إعدادات الإعداد. يتم استنتاج لغة تحويل الصوت إلى نص من ردّ النموذج.

Python

import asyncio
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-3.1-flash-live-preview"

config = {
    "response_modalities": ["AUDIO"],
    "output_audio_transcription": {}
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello? Gemini are you there?"

        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.server_content.model_turn:
                print("Model turn:", response.server_content.model_turn)
            if response.server_content.output_transcription:
                print("Transcript:", response.server_content.output_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-3.1-flash-live-preview';

const config = {
  responseModalities: [Modality.AUDIO],
  outputAudioTranscription: {}
};

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.outputTranscription) {
      console.debug('Received output transcription: %s\n', turn.serverContent.outputTranscription.text);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}