Truyền trực tuyến hai chiều bằng Gemini Live API


Gemini Live API cho phép tương tác bằng văn bản và giọng nói hai chiều có độ trễ thấp với Gemini. Khi sử dụng Live API, bạn có thể mang đến cho người dùng cuối trải nghiệm trò chuyện tự nhiên, giống như con người, với khả năng ngắt lời phản hồi của mô hình bằng lệnh văn bản hoặc lệnh thoại. Mô hình này có thể xử lý dữ liệu đầu vào là văn bản và âm thanh (video sắp ra mắt!) và có thể cung cấp dữ liệu đầu ra là văn bản và âm thanh.

Bạn có thể tạo nguyên mẫu bằng câu lệnh và Live API trong Vertex AI Studio.

Live API là một API có trạng thái tạo kết nối WebSocket để thiết lập phiên giữa ứng dụng và máy chủ Gemini. Để biết thông tin chi tiết, hãy xem tài liệu tham khảo về Live API.

Trước khi bắt đầu

Chỉ có sẵn khi bạn sử dụng Vertex AI Gemini API làm trình cung cấp API.

Nếu bạn chưa hoàn tất, hãy hoàn thành hướng dẫn bắt đầu sử dụng. Hướng dẫn này mô tả cách thiết lập dự án Firebase, kết nối ứng dụng với Firebase, thêm SDK, khởi chạy dịch vụ phụ trợ cho Vertex AI Gemini API và tạo một thực thể LiveModel.

Các mô hình hỗ trợ tính năng này

Live API chỉ được gemini-2.0-flash-live-preview-04-09 hỗ trợ (không phải gemini-2.0-flash).

Sử dụng các tính năng tiêu chuẩn của Live API

Phần này mô tả cách sử dụng các tính năng tiêu chuẩn của Live API, cụ thể là để truyền trực tuyến nhiều loại dữ liệu đầu vào và đầu ra:

Tạo văn bản truyền trực tuyến từ dữ liệu đầu vào văn bản truyền trực tuyến

Trước khi thử mẫu này, hãy hoàn tất phần Trước khi bắt đầu của hướng dẫn này để thiết lập dự án và ứng dụng.
Trong phần đó, bạn cũng sẽ nhấp vào nút của nhà cung cấp Gemini API mà bạn đã chọn để xem nội dung dành riêng cho nhà cung cấp trên trang này.

Bạn có thể gửi dữ liệu đầu vào văn bản được truyền trực tuyến và nhận dữ liệu đầu ra văn bản được truyền trực tuyến. Hãy nhớ tạo một thực thể liveModel và đặt chế độ phản hồi thành Text.

Swift

Live API hiện chưa được hỗ trợ cho các ứng dụng trên nền tảng Apple, nhưng hãy sớm quay lại nhé!

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Create a `LiveModel` instance with the model that supports the Live API
val model = Firebase.vertexAI.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
// Create a `LiveModel` instance with the model that supports the Live API
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).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 chưa được hỗ trợ cho ứng dụng Web, nhưng hãy sớm quay lại nhé!

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
// Create a `LiveModel` instance with the model that supports the Live API
final model = FirebaseAI.vertexAI().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
  // Create a `LiveModel` instance with the model that supports the Live API
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).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);
    }
  }
}

Tìm hiểu cách chọn một mô hình phù hợp với trường hợp sử dụng và ứng dụng của bạn.

Tạo âm thanh phát trực tuyến từ đầu vào âm thanh phát trực tuyến

Trước khi thử mẫu này, hãy hoàn tất phần Trước khi bắt đầu của hướng dẫn này để thiết lập dự án và ứng dụng.
Trong phần đó, bạn cũng sẽ nhấp vào nút của nhà cung cấp Gemini API mà bạn đã chọn để xem nội dung dành riêng cho nhà cung cấp trên trang này.

Bạn có thể gửi đầu vào âm thanh trực tuyến và nhận đầu ra âm thanh trực tuyến. Hãy nhớ tạo một thực thể LiveModel và đặt chế độ phản hồi thành Audio.

Tìm hiểu cách định cấu hình và tuỳ chỉnh giọng nói phản hồi (ở phần sau của trang này).

Swift

Live API hiện chưa được hỗ trợ cho các ứng dụng trên nền tảng Apple, nhưng hãy sớm quay lại nhé!

Kotlin

// Initialize the Vertex AI Gemini API backend service
// Create a `LiveModel` instance with the model that supports the Live API
val model = Firebase.vertexAI.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
// Create a `LiveModel` instance with the model that supports the Live API
LiveGenerativeModel lm = FirebaseAI.getInstance(GenerativeBackend.vertexAI()).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 chưa được hỗ trợ cho ứng dụng Web, nhưng hãy sớm quay lại nhé!

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
// Create a `LiveModel` instance with the model that supports the Live API
final model = FirebaseAI.vertexAI().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
  // Create a `LiveModel` instance with the model that supports the Live API
  var model = FirebaseAI.GetInstance(FirebaseAI.Backend.VertexAI()).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++;
  }
}

Tìm hiểu cách chọn một mô hình phù hợp với trường hợp sử dụng và ứng dụng của bạn.



Tạo trải nghiệm hấp dẫn và có tính tương tác hơn

Phần này mô tả cách tạo và quản lý các tính năng tương tác hoặc hấp dẫn hơn của Live API.

Thay đổi giọng nói phản hồi

Live API sử dụng Chirp 3 để hỗ trợ các câu trả lời bằng lời nói được tổng hợp. Khi sử dụng Firebase AI Logic, bạn có thể gửi âm thanh bằng 5 giọng nói HD và 31 ngôn ngữ.

Nếu bạn không chỉ định giọng nói, giá trị mặc định sẽ là Puck. Ngoài ra, bạn có thể định cấu hình mô hình để phản hồi bằng giọng nói bất kỳ trong số sau:

Aoede (nữ)
Charon (nam)
Fenrir (nam)
Kore (nữ)
Puck (nam)

Để xem bản minh hoạ về âm thanh của các giọng nói này và danh sách đầy đủ các ngôn ngữ có sẵn, hãy xem bài viết Chirp 3: Giọng nói HD.

Để chỉ định giọng nói, hãy đặt tên giọng nói trong đối tượng speechConfig như một phần của cấu hình mô hình:

Swift

Live API hiện chưa được hỗ trợ cho các ứng dụng trên nền tảng Apple, nhưng hãy sớm quay lại nhé!

Kotlin

// ...

val model = Firebase.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 = Firebase.getVertexAI().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 chưa được hỗ trợ cho ứng dụng Web, nhưng hãy sớm quay lại nhé!

Dart

// ...

final model = FirebaseVertexAI.instance.liveModel(
  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(voice: Voice.fenrir),
  ),
);

// ...

Unity

Snippets coming soon!

Để có kết quả tốt nhất khi nhắc và yêu cầu mô hình phản hồi bằng ngôn ngữ không phải tiếng Anh, hãy đưa nội dung sau vào hướng dẫn hệ thống:

RESPOND IN LANGUAGE. YOU MUST RESPOND UNMISTAKABLY IN LANGUAGE.

Duy trì ngữ cảnh trên các phiên và yêu cầu

Bạn có thể sử dụng cấu trúc trò chuyện để duy trì ngữ cảnh trên các phiên và yêu cầu. Xin lưu ý rằng tính năng này chỉ hoạt động đối với dữ liệu đầu vào và đầu ra dạng văn bản.

Phương pháp này phù hợp nhất với ngữ cảnh ngắn; bạn có thể gửi các lượt tương tác từng chặng để thể hiện trình tự chính xác của các sự kiện . Đối với ngữ cảnh dài hơn, bạn nên cung cấp một bản tóm tắt tin nhắn để giải phóng cửa sổ ngữ cảnh cho các lượt tương tác tiếp theo.

Xử lý các hoạt động gây gián đoạn

Firebase AI Logic chưa hỗ trợ việc xử lý các sự cố gián đoạn. Vui lòng kiểm tra lại sớm!

Sử dụng lệnh gọi hàm (công cụ)

Bạn có thể xác định các công cụ (chẳng hạn như các hàm có sẵn) để sử dụng với Live API giống như bạn có thể làm với các phương thức tạo nội dung tiêu chuẩn. Phần này mô tả một số điểm khác biệt khi sử dụng API Trực tiếp với lệnh gọi hàm. Để biết nội dung mô tả đầy đủ và ví dụ về cách gọi hàm, hãy xem hướng dẫn gọi hàm.

Từ một câu lệnh duy nhất, mô hình có thể tạo nhiều lệnh gọi hàm và mã cần thiết để tạo chuỗi đầu ra. Mã này thực thi trong môi trường hộp cát, tạo ra các thông báo BidiGenerateContentToolCall tiếp theo. Quá trình thực thi sẽ tạm dừng cho đến khi có kết quả của từng lệnh gọi hàm, đảm bảo quá trình xử lý tuần tự.

Ngoài ra, việc sử dụng Live API với lệnh gọi hàm đặc biệt hiệu quả vì mô hình có thể yêu cầu người dùng cung cấp thông tin tiếp theo hoặc làm rõ thông tin. Ví dụ: nếu không có đủ thông tin để cung cấp giá trị tham số cho một hàm mà mô hình muốn gọi, thì mô hình có thể yêu cầu người dùng cung cấp thêm hoặc làm rõ thông tin.

Ứng dụng sẽ phản hồi bằng BidiGenerateContentToolResponse.



Giới hạn và yêu cầu

Hãy lưu ý các giới hạn và yêu cầu sau đây của Live API.

Bản ghi âm

Firebase AI Logic chưa hỗ trợ bản chép lời. Vui lòng kiểm tra lại sớm!

Ngôn ngữ

Định dạng âm thanh

Live API hỗ trợ các định dạng âm thanh sau:

  • Định dạng âm thanh đầu vào: Âm thanh PCM thô 16 bit ở 16 kHz little-endian
  • Định dạng âm thanh đầu ra: Âm thanh PCM thô 16 bit ở 24 kHz little-endian

Giới hạn tốc độ

Các giới hạn tốc độ sau đây sẽ được áp dụng:

  • 10 phiên đồng thời cho mỗi dự án Firebase
  • 4 triệu mã thông báo mỗi phút

Thời lượng phiên

Thời lượng mặc định của một phiên là 30 phút. Khi thời lượng phiên vượt quá giới hạn, kết nối sẽ bị chấm dứt.

Mô hình cũng bị giới hạn bởi kích thước ngữ cảnh. Việc gửi các phần lớn dữ liệu đầu vào có thể dẫn đến việc kết thúc phiên sớm hơn.

Phát hiện hoạt động giọng nói (VAD)

Mô hình này tự động thực hiện tính năng phát hiện hoạt động giọng nói (VAD) trên luồng đầu vào âm thanh liên tục. VAD được bật theo mặc định.

Tính số mã thông báo

Bạn không thể sử dụng API CountTokens với Live API.


Gửi ý kiến phản hồi về trải nghiệm của bạn với Firebase AI Logic