البث في الاتجاهين باستخدام واجهة برمجة التطبيقات Gemini Live API


تتيح Gemini Live API التفاعل ثنائي الاتجاه مع Gemini باستخدام النص والصوت وبزمن استجابة منخفض. باستخدام Live API، يمكنك تزويد المستخدمين النهائيين بتجربة محادثات صوتية طبيعية تشبه المحادثات بين البشر، مع إمكانية مقاطعة ردود النموذج باستخدام أوامر نصية أو صوتية. يمكن للنموذج معالجة النصوص والمقاطع الصوتية (سيتم توفير الفيديو قريبًا!)، ويمكنه تقديم مخرجات نصية وصوتية.

يمكنك إنشاء نماذج أولية باستخدام الطلبات وLive API في Vertex AI Studio.

Live API هي واجهة برمجة تطبيقات ذات حالة تنشئ اتصال WebSocket لإنشاء جلسة بين العميل وخادم Gemini. للحصول على التفاصيل، راجِع المستندات المرجعية الخاصة بـ Live API.

قبل البدء

لا تتوفّر إلا عند استخدام Vertex AI Gemini API كموفّر لواجهة برمجة التطبيقات.

إذا لم يسبق لك إجراء ذلك، أكمل دليل بدء الاستخدام الذي يوضّح كيفية إعداد مشروعك على Firebase وربط تطبيقك بـ Firebase وإضافة حزمة تطوير البرامج (SDK) وتهيئة خدمة الخلفية الخاصة بـ Vertex AI Gemini API وإنشاء مثيل LiveModel.

الطُرز التي تتيح هذه الإمكانية

تتوافق السمة Live API مع gemini-2.0-flash-live-preview-04-09 فقط (وليس gemini-2.0-flash).

يُرجى العِلم أيضًا أنّ السمة gemini-2.0-flash-live-preview-04-09 لا تتوفّر إلا في الموقع الجغرافي us-central1.

استخدام الميزات العادية في Live API

يوضّح هذا القسم كيفية استخدام الميزات العادية في Live API، وتحديدًا لبث أنواع مختلفة من المدخلات والمخرجات:

إنشاء نص متدفّق من إدخال نص متدفّق

قبل تجربة هذا النموذج، أكمل القسم قبل البدء من هذا الدليل لإعداد مشروعك وتطبيقك.
في هذا القسم، ستنقر أيضًا على زر لمقدّم الخدمة الذي اخترته Gemini API حتى يظهر لك محتوى خاص بمقدّم الخدمة في هذه الصفحة.

يمكنك إرسال مدخلات نصية متدفقة وتلقّي مخرجات نصية متدفقة. احرص على إنشاء مثيل liveModel وضبط طريقة الرد على Text.

Swift

لا تتوافق Live API مع تطبيقات منصة Apple بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
val model = Firebase.ai(backend = GenerativeBackend.vertexAI(location = "us-central1")).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.TEXT 
   }
)

val session = model.connect()

// Provide a text prompt
val text = "tell a short story"

session.send(text)

var outputText = ""
session.receive().collect {
    if(it.status == Status.TURN_COMPLETE) {
        // Optional: if you don't require to send more requests.
        session.stopReceiving();
    }
    outputText = outputText + it.text
}

// Output received from the server.
println(outputText)

Java

ExecutorService executor = Executors.newFixedThreadPool(1);
// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI("us-central1")).liveModel(
        "gemini-2.0-flash-live-preview-04-09",
        // Configure the model to respond with text
        new LiveGenerationConfig.Builder()
                .setResponseModalities(ResponseModality.TEXT)
                .build()
);
LiveModelFutures model = LiveModelFutures.from(lm);
ListenableFuture<LiveSession> sessionFuture =  model.connect();
class LiveContentResponseSubscriber implements Subscriber<LiveContentResponse> {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE); // Request an unlimited number of items
    }
    @Override
    public void onNext(LiveContentResponse liveContentResponse) {
       // Handle the response from the server.
	System.out.println(liveContentResponse.getText());
    }
    @Override
    public void onError(Throwable t) {
        System.err.println("Error: " + t.getMessage());
    }
    @Override
    public void onComplete() {
        System.out.println("Done receiving messages!");
    }
}
Futures.addCallback(sessionFuture, new FutureCallback<LiveSession>() {
    @Override
    public void onSuccess(LiveSession ses) {
	  LiveSessionFutures session = LiveSessionFutures.from(ses);
        // Provide a text prompt
        String text = "tell me a short story?";
        session.send(text);
        Publisher<LiveContentResponse> publisher = session.receive();
        publisher.subscribe(new LiveContentResponseSubscriber());
    }
    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

Web

لا تتوافق Live API مع تطبيقات الويب بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Dart

import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

late LiveModelSession _session;

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
final model = FirebaseAI.vertexAI(location: 'us-central1').liveModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
  // Configure the model to respond with text
  config: LiveGenerationConfig(responseModalities: [ResponseModality.text]),
);

_session = await model.connect();

// Provide a text prompt
final prompt = Content.text('tell a short story');
await _session.send(input: prompt, turnComplete: true);

// In a separate thread, receive the response
await for (final message in _session.receive()) {
   // Process the received message 
}

Unity

using Firebase;
using Firebase.AI;

async Task SendTextReceiveText() {
  // Initialize the Vertex AI Gemini API backend service
  // Set the location to `us-central1` (the flash-live model is only supported in that location)
  // Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI(location: "us-central1")).GetLiveModel(
    modelName: "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    liveGenerationConfig: new LiveGenerationConfig(
        responseModalities: new[] { ResponseModality.Text })
  );

  LiveSession session = await model.ConnectAsync();

  // Provide a text prompt
  var prompt = ModelContent.Text("tell a short story");
  await session.SendAsync(content: prompt, turnComplete: true);

  // Receive the response
  await foreach (var message in session.ReceiveAsync()) {
    // Process the received message
    if (!string.IsNullOrEmpty(message.Text)) {
      UnityEngine.Debug.Log("Received message: " + message.Text);
    }
  }
}

إنشاء محتوى صوتي يتم بثه من محتوى صوتي يتم بثه

قبل تجربة هذا النموذج، أكمل القسم قبل البدء من هذا الدليل لإعداد مشروعك وتطبيقك.
في هذا القسم، ستنقر أيضًا على زر لمقدّم الخدمة الذي اخترته Gemini API حتى يظهر لك محتوى خاص بمقدّم الخدمة في هذه الصفحة.

يمكنك إرسال إدخال صوتي يتم بثه واستلام إخراج صوتي يتم بثه. احرص على إنشاء مثيل LiveModel وضبط طريقة الرد على Audio.

تعرَّف على كيفية ضبط صوت الرد وتخصيصه (لاحقًا في هذه الصفحة).

Swift

لا تتوافق Live API مع تطبيقات منصة Apple بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
val model = Firebase.ai(backend = GenerativeBackend.vertexAI(location = "us-central1")).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with text
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO 
   }
)

val session = model.connect()

// This is the recommended way.
// However, you can create your own recorder and handle the stream.
session.startAudioConversation()

Java

ExecutorService executor = Executors.newFixedThreadPool(1);
// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI("us-central1")).liveModel(
        "gemini-2.0-flash-live-preview-04-09",
        // Configure the model to respond with text
        new LiveGenerationConfig.Builder()
                .setResponseModalities(ResponseModality.TEXT)
                .build()
);
LiveModelFutures model = LiveModelFutures.from(lm);
ListenableFuture<LiveSession> sessionFuture =  model.connect();

Futures.addCallback(sessionFuture, new FutureCallback<LiveSession>() {
    @Override
    public void onSuccess(LiveSession ses) {
	 LiveSessionFutures session = LiveSessionFutures.from(ses);
        session.startAudioConversation();
    }
    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

Web

لا تتوافق Live API مع تطبيقات الويب بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Dart

import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:your_audio_recorder_package/your_audio_recorder_package.dart';

late LiveModelSession _session;
final _audioRecorder = YourAudioRecorder();

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize the Vertex AI Gemini API backend service
// Set the location to `us-central1` (the flash-live model is only supported in that location)
// Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
final model = FirebaseAI.vertexAI(location: 'us-central1').liveModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
   // Configure the model to respond with audio
   config: LiveGenerationConfig(responseModalities: [ResponseModality.audio]),
);

_session = await model.connect();

final audioRecordStream = _audioRecorder.startRecordingStream();
// Map the Uint8List stream to InlineDataPart stream
final mediaChunkStream = audioRecordStream.map((data) {
  return InlineDataPart('audio/pcm', data);
});
await _session.startMediaStream(mediaChunkStream);

// In a separate thread, receive the audio response from the model
await for (final message in _session.receive()) {
   // Process the received message 
}

Unity

using Firebase;
using Firebase.AI;

async Task SendTextReceiveAudio() {
  // Initialize the Vertex AI Gemini API backend service
  // Set the location to `us-central1` (the flash-live model is only supported in that location)
  // Create a `LiveModel` instance with the flash-live model (only model that supports the Live API)
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI(location: "us-central1")).GetLiveModel(
    modelName: "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to respond with audio
    liveGenerationConfig: new LiveGenerationConfig(
        responseModalities: new[] { ResponseModality.Audio })
  );

  LiveSession session = await model.ConnectAsync();

  // Start a coroutine to send audio from the Microphone
  var recordingCoroutine = StartCoroutine(SendAudio(session));

  // Start receiving the response
  await ReceiveAudio(session);
}

IEnumerator SendAudio(LiveSession liveSession) {
  string microphoneDeviceName = null;
  int recordingFrequency = 16000;
  int recordingBufferSeconds = 2;

  var recordingClip = Microphone.Start(microphoneDeviceName, true,
                                       recordingBufferSeconds, recordingFrequency);

  int lastSamplePosition = 0;
  while (true) {
    if (!Microphone.IsRecording(microphoneDeviceName)) {
      yield break;
    }

    int currentSamplePosition = Microphone.GetPosition(microphoneDeviceName);

    if (currentSamplePosition != lastSamplePosition) {
      // The Microphone uses a circular buffer, so we need to check if the
      // current position wrapped around to the beginning, and handle it
      // accordingly.
      int sampleCount;
      if (currentSamplePosition > lastSamplePosition) {
        sampleCount = currentSamplePosition - lastSamplePosition;
      } else {
        sampleCount = recordingClip.samples - lastSamplePosition + currentSamplePosition;
      }

      if (sampleCount > 0) {
        // Get the audio chunk
        float[] samples = new float[sampleCount];
        recordingClip.GetData(samples, lastSamplePosition);

        // Send the data, discarding the resulting Task to avoid the warning
        _ = liveSession.SendAudioAsync(samples);

        lastSamplePosition = currentSamplePosition;
      }
    }

    // Wait for a short delay before reading the next sample from the Microphone
    const float MicrophoneReadDelay = 0.5f;
    yield return new WaitForSeconds(MicrophoneReadDelay);
  }
}

Queue audioBuffer = new();

async Task ReceiveAudio(LiveSession liveSession) {
  int sampleRate = 24000;
  int channelCount = 1;

  // Create a looping AudioClip to fill with the received audio data
  int bufferSamples = (int)(sampleRate * channelCount);
  AudioClip clip = AudioClip.Create("StreamingPCM", bufferSamples, channelCount,
                                    sampleRate, true, OnAudioRead);

  // Attach the clip to an AudioSource and start playing it
  AudioSource audioSource = GetComponent();
  audioSource.clip = clip;
  audioSource.loop = true;
  audioSource.Play();

  // Start receiving the response
  await foreach (var message in liveSession.ReceiveAsync()) {
    // Process the received message
    foreach (float[] pcmData in message.AudioAsFloat) {
      lock (audioBuffer) {
        foreach (float sample in pcmData) {
          audioBuffer.Enqueue(sample);
        }
      }
    }
  }
}

// This method is called by the AudioClip to load audio data.
private void OnAudioRead(float[] data) {
  int samplesToProvide = data.Length;
  int samplesProvided = 0;

  lock(audioBuffer) {
    while (samplesProvided < samplesToProvide && audioBuffer.Count > 0) {
      data[samplesProvided] = audioBuffer.Dequeue();
      samplesProvided++;
    }
  }

  while (samplesProvided < samplesToProvide) {
    data[samplesProvided] = 0.0f;
    samplesProvided++;
  }
}



إنشاء تجارب أكثر جاذبية وتفاعلية

يوضّح هذا القسم كيفية إنشاء ميزات أكثر جاذبية أو تفاعلية في Live API وإدارتها.

تغيير صوت الرد

يستخدم Live API Chirp 3 لتقديم ردود صوتية مركّبة. عند استخدام Firebase AI Logic، يمكنك إرسال رسائل صوتية بمجموعة متنوعة من اللغات وبجودة صوت عالية. للاطّلاع على قائمة كاملة وعروض توضيحية لكل صوت، يُرجى الانتقال إلى Chirp 3: أصوات عالية الدقة.

لتحديد صوت، اضبط اسم الصوت ضمن الكائن speechConfig كجزء من إعداد النموذج. إذا لم تحدّد صوتًا، سيكون الصوت التلقائي Puck.

Swift

لا تتوافق Live API مع تطبيقات منصة Apple بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Kotlin

// ...

val model = Firebase.ai(backend = GenerativeBackend.vertexAI()).liveModel(
    modelName = "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to use a specific voice for its audio response
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO
        speechConfig = SpeechConfig(voice = Voices.FENRIR)
    }
)

// ...

Java

// ...

LiveModel model = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).liveModel(
    "gemini-2.0-flash-live-preview-04-09",
    // Configure the model to use a specific voice for its audio response
    new LiveGenerationConfig.Builder()
        .setResponseModalities(ResponseModality.AUDIO)
        .setSpeechConfig(new SpeechConfig(Voices.FENRIR))
        .build()
);

// ...

Web

لا تتوافق Live API مع تطبيقات الويب بعد، ولكن يمكنك التحقّق مرة أخرى قريبًا.

Dart

// ...

final model = FirebaseAI.vertexAI().liveGenerativeModel(
  model: 'gemini-2.0-flash-live-preview-04-09',
  // Configure the model to use a specific voice for its audio response
  config: LiveGenerationConfig(
    responseModality: ResponseModality.audio,
    speechConfig: SpeechConfig(voiceName: 'Fenrir'),
  ),
);

// ...

Unity

var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).GetLiveModel(
  modelName: "gemini-2.0-flash-live-preview-04-09",
  liveGenerationConfig: new LiveGenerationConfig(
    responseModalities: new[] { ResponseModality.Audio },
    speechConfig: SpeechConfig.UsePrebuiltVoice("Fenrir"),
);

للحصول على أفضل النتائج عند تقديم طلبات إلى النموذج ومطالبته بالرد بلغة غير الإنجليزية، يجب تضمين ما يلي كجزء من تعليمات النظام:

RESPOND IN LANGUAGE. YOU MUST RESPOND UNMISTAKABLY IN LANGUAGE.

الحفاظ على السياق في جميع الجلسات والطلبات

يمكنك استخدام بنية محادثة للحفاظ على السياق في جميع الجلسات والطلبات. يُرجى العِلم أنّ هذه الميزة لا تعمل إلا مع إدخال النص وإخراجه.

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

التعامل مع المقاطعات

لا يتيح Firebase AI Logic بعد التعامل مع المقاطعات. يرجى معاودة التحقق بعد قليل.

استخدام ميزة "استدعاء الدوال" (الأدوات)

يمكنك تحديد أدوات، مثل الدوال المتاحة، لاستخدامها مع Live API تمامًا كما يمكنك استخدام طرق إنشاء المحتوى العادية. يوضّح هذا القسم بعض التفاصيل الدقيقة عند استخدام Live API مع ميزة "استدعاء الدوال". للحصول على وصف كامل وأمثلة حول ميزة &quot;استدعاء الدوال&quot;، يمكنك الاطّلاع على دليل ميزة &quot;استدعاء الدوال&quot;.

من خلال طلب واحد، يمكن للنموذج إنشاء طلبات متعددة للدوال والرمز البرمجي اللازم لربط مخرجاتها. يتم تنفيذ هذه الرموز في بيئة وضع الحماية، ما يؤدي إلى إنشاء رسائل BidiGenerateContentToolCall لاحقة. يتم إيقاف التنفيذ مؤقتًا إلى أن تتوفّر نتائج كل استدعاء دالة، ما يضمن المعالجة التسلسلية.

بالإضافة إلى ذلك، يكون استخدام Live API مع ميزة "طلب تنفيذ وظيفة" فعّالاً بشكل خاص لأنّ النموذج يمكنه طلب معلومات متابعة أو توضيحية من المستخدم. على سبيل المثال، إذا لم يتوفّر لدى النموذج معلومات كافية لتقديم قيمة مَعلمة إلى دالة يريد استدعاءها، يمكن للنموذج أن يطلب من المستخدم تقديم المزيد من المعلومات أو توضيحها.

يجب أن يردّ العميل بالرمز BidiGenerateContentToolResponse.



القيود والمتطلبات

يُرجى مراعاة القيود والمتطلبات التالية الخاصة بـ Live API.

النسخ

Firebase AI Logic لا تتيح بعد نصوص التسجيلات. يرجى معاودة التحقق بعد قليل.

اللغات

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

يتوافق Live API مع تنسيقات الصوت التالية:

  • تنسيق الصوت المُدخَل: صوت PCM خام بمعدل 16 بت عند 16 كيلوهرتز بنظام الترتيب من الأصغر إلى الأكبر
  • تنسيق إخراج الصوت: صوت PCM خام 16 بت بترتيب وحدات البايت الأصغر أولاً بمعدل 24 كيلوهرتز

حدود معدّل الاستخدام

تنطبق حدود معدّل الاستخدام التالية:

  • ‫10 جلسات متزامنة لكل مشروع على Firebase
  • 4 ملايين رمز مميّز في الدقيقة

مدة الجلسة

المدة التلقائية للجلسة هي 30 دقيقة. عندما تتجاوز مدة الجلسة الحد الأقصى، يتم إنهاء الاتصال.

يخضع النموذج أيضًا لقيود حجم السياق. قد يؤدي إرسال أجزاء كبيرة من الإدخال إلى إنهاء الجلسة قبل الأوان.

رصد النشاط الصوتي (VAD)

يُجري النموذج تلقائيًا عملية رصد النشاط الصوتي (VAD) على دفق مستمر من الإدخال الصوتي. يتم تفعيل ميزة "التعرّف على النشاط الحيوي" تلقائيًا.

احتساب الرموز المميزة

لا يمكنك استخدام واجهة برمجة التطبيقات CountTokens مع Live API.


تقديم ملاحظات حول تجربتك مع Firebase AI Logic