API Gemini Live

Для приложений, требующих поддержки голосовой связи в реальном времени с низкой задержкой, таких как чат-боты или агентское взаимодействие, API Gemini Live предоставляет оптимизированный способ потоковой передачи как входных, так и выходных данных для модели Gemini. Используя Firebase AI Logic, вы можете вызывать API Gemini Live напрямую из своего Android-приложения без необходимости интеграции с бэкэндом. В этом руководстве показано, как использовать API Gemini Live в вашем Android-приложении с Firebase AI Logic.

Начать

Прежде чем начать, убедитесь, что ваше приложение ориентировано на API уровня 23 или выше .

Если вы еще этого не сделали, создайте проект Firebase и подключите свое приложение к Firebase. Подробности см. в документации Firebase AI Logic .

Настройте свой Android-проект

Добавьте зависимость библиотеки Firebase AI Logic в файл build.gradle.kts или build.gradle на уровне приложения. Используйте Firebase Android BoM для управления версиями библиотек.

dependencies {
  // Import the Firebase BoM
  implementation(platform("com.google.firebase:firebase-bom:34.6.0"))
  // Add the dependency for the Firebase AI Logic library
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation("com.google.firebase:firebase-ai")
}

После добавления зависимости синхронизируйте свой Android-проект с Gradle.

Интегрируйте Firebase AI Logic и инициализируйте генеративную модель.

Добавьте разрешение RECORD_AUDIO в файл AndroidManifest.xml вашего приложения:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

Инициализируйте бэкэнд-сервис Gemini Developer API и получите доступ к LiveModel . Используйте модель, поддерживающую Live API, например gemini-2.5-flash-native-audio-preview-09-2025 . Список доступных моделей см. в документации Firebase.

Чтобы указать голос, задайте его имя в объекте speechConfig в рамках конфигурации модели . Если вы не укажете голос, по умолчанию будет использоваться Puck .

Котлин

// Initialize the `LiveModel`
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
       modelName = "gemini-2.5-flash-native-audio-preview-09-2025",
       generationConfig = liveGenerationConfig {
          responseModality = ResponseModality.AUDIO
          speechConfig = SpeechConfig(voice = Voice("FENRIR"))
       })

Java

// Initialize the `LiveModel`
LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-2.5-flash-native-audio-preview-09-2025",
              new LiveGenerationConfig.Builder()
                     .setResponseModality(ResponseModality.AUDIO)
                     .setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
              ).build(),
        null,
        null
);

При желании вы можете определить роль или образ, который будет играть модель, задав соответствующую системную инструкцию:

Котлин

val systemInstruction = content {
            text("You are a helpful assistant, you main role is [...]")}

val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
       modelName = "gemini-2.5-flash-native-audio-preview-09-2025",
       generationConfig = liveGenerationConfig {
          responseModality = ResponseModality.AUDIO
          speechConfig = SpeechConfig(voice= Voice("FENRIR"))
       },
       systemInstruction = systemInstruction,
)

Java

Content systemInstruction = new Content.Builder()
       .addText("You are a helpful assistant, you main role is [...]")
       .build();

LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-2.5-flash-native-audio-preview-09-2025",
              new LiveGenerationConfig.Builder()
                     .setResponseModality(ResponseModality.AUDIO)
                     .setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
              ).build(),
        tools, // null if you don't want to use function calling
        systemInstruction
);

Вы можете дополнительно специализировать диалог с моделью, используя системные инструкции для предоставления контекста, специфичного для вашего приложения (например, истории активности пользователя в приложении).

Инициализация сессии Live API

После создания экземпляра LiveModel вызовите model.connect() , чтобы создать объект LiveSession и установить постоянное соединение с моделью с потоковой передачей данных с низкой задержкой. LiveSession позволяет взаимодействовать с моделью, запуская и останавливая голосовую сессию, а также отправляя и получая текст.

Затем вы можете вызвать startAudioConversation() , чтобы начать разговор с моделью:

Котлин

val session = model.connect()
session.startAudioConversation()

Java

LiveModelFutures model = LiveModelFutures.from(liveModel);
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);

В процессе взаимодействия с моделью обратите внимание на то, что она не обрабатывает прерывания. Кроме того, Live API является двунаправленным , поэтому для отправки и получения контента используется одно и то же соединение.

Вы также можете использовать API Gemini Live для генерации звука из различных источников входного сигнала:

Вызов функции: подключите API Gemini Live к вашему приложению.

Более того, вы можете разрешить модели напрямую взаимодействовать с логикой вашего приложения, используя вызовы функций.

Вызов функций (или вызов инструментов) — это особенность генеративного ИИ, позволяющая модели вызывать функции по собственной инициативе для выполнения действий. Если функция имеет выходные данные, модель добавляет их в свой контекст и использует для последующих поколений.

Диаграмма, иллюстрирующая, как API Gemini Live позволяет модели интерпретировать запрос пользователя, запуская предопределенную функцию с соответствующими аргументами в приложении Android, которое затем получает подтверждающий ответ от модели.
Рисунок 1: Диаграмма, иллюстрирующая, как API Gemini Live позволяет модели интерпретировать запрос пользователя, запуская предопределенную функцию с соответствующими аргументами в приложении Android, которое затем получает подтверждающий ответ от модели.

Чтобы реализовать вызов функций в вашем приложении, начните с создания объекта FunctionDeclaration для каждой функции, которую вы хотите предоставить модели.

Например, чтобы предоставить Gemini доступ к функции addList , которая добавляет строку к списку строк, начните с создания переменной FunctionDeclaration с именем и кратким описанием функции и ее параметра на простом английском языке:

Котлин

val itemList = mutableListOf<String>()

fun addList(item: String){
   itemList.add(item)
}

val addListFunctionDeclaration = FunctionDeclaration(
        name = "addList",
        description = "Function adding an item the list",
        parameters = mapOf("item" to Schema.string("A short string
            describing the item to add to the list"))
        )

Java

HashMap<String, Schema> addListParams = new HashMap<String, Schema>(1);

addListParams.put("item", Schema.str("A short string describing the item to add to the list"));
addListParams.put("item", Schema.str("A short string describing the item to add to the list"));

FunctionDeclaration addListFunctionDeclaration = new FunctionDeclaration(
    "addList",
    "Function adding an item the list",
    addListParams,
    Collections.emptyList()
);

Затем передайте это FunctionDeclaration в качестве Tool модели при ее создании экземпляра:

Котлин

val addListTool = Tool.functionDeclarations(listOf(addListFunctionDeclaration))

val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
       modelName = "gemini-2.5-flash-native-audio-preview-09-2025",
       generationConfig = liveGenerationConfig {
          responseModality = ResponseModality.AUDIO
          speechConfig = SpeechConfig(voice= Voice("FENRIR"))
       },
       systemInstruction = systemInstruction,
       tools = listOf(addListTool)
)

Java

LiveGenerativeModel model = FirebaseAI.getInstance(
    GenerativeBackend.googleAI()).liveModel(
        "gemini-2.5-flash-native-audio-preview-09-2025",
  new LiveGenerationConfig.Builder()
        .setResponseModalities(ResponseModality.AUDIO)
        .setSpeechConfig(new SpeechConfig(new Voice("FENRIR")))
        .build(),
  List.of(Tool.functionDeclarations(List.of(addListFunctionDeclaration))),
               null,
               systemInstruction
        );

Наконец, реализуйте функцию-обработчик для обработки вызова инструмента, выполняемого моделью, и передачи ей ответа. Эта функция-обработчик, предоставляемая LiveSession при вызове startAudioConversation , принимает параметр FunctionCallPart и возвращает FunctionResponsePart :

Котлин

session.startAudioConversation(::functionCallHandler)

// ...

fun functionCallHandler(functionCall: FunctionCallPart): FunctionResponsePart {
    return when (functionCall.name) {
        "addList" -> {
            // Extract function parameter from functionCallPart
            val itemName = functionCall.args["item"]!!.jsonPrimitive.content
            // Call function with parameter
            addList(itemName)
            // Confirm the function call to the model
            val response = JsonObject(
                mapOf(
                    "success" to JsonPrimitive(true),
                    "message" to JsonPrimitive("Item $itemName added to the todo list")
                )
            )
            FunctionResponsePart(functionCall.name, response)
        }
        else -> {
            val response = JsonObject(
                mapOf(
                    "error" to JsonPrimitive("Unknown function: ${functionCall.name}")
                )
            )
            FunctionResponsePart(functionCall.name, response)
        }
    }
}

Java

Futures.addCallback(sessionFuture, new FutureCallback<LiveSessionFutures>() {

    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    @Override
    @OptIn(markerClass = PublicPreviewAPI.class)
    public void onSuccess(LiveSessionFutures ses) {
        ses.startAudioConversation(::handleFunctionCallFuture);
    }

    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

// ...

ListenableFuture<JsonObject> handleFunctionCallFuture = Futures.transform(response, result -> {
    for (FunctionCallPart functionCall : result.getFunctionCalls()) {
        if (functionCall.getName().equals("addList")) {
            Map<String, JsonElement> args = functionCall.getArgs();
            String item =
                    JsonElementKt.getContentOrNull(
                            JsonElementKt.getJsonPrimitive(
                                    locationJsonObject.get("item")));
            return addList(item);
        }
    }
    return null;
}, Executors.newSingleThreadExecutor());

Следующие шаги