Руководства

Создание интеллектуальных приложений для Android: облачный и гибридный вывод

Время на чтение: 8 минут
3 Авторы
Thomas Ezan, Jolanda Verhoef, Caren Chang

Мы продолжаем серию статей Создание умных приложений для Android. В ней мы рассказываем, как превратить обычное приложение для Android в персонализированное, интеллектуальное и агентное. В предыдущей статье мы рассказали, как создавать интеллектуальные функции на устройстве с помощью Gemini Nano через Prompt API из ML Kit.

В этой статье мы расскажем, как использовать Firebase AI Logic для создания облачных и гибридных функций на основе ИИ: 

  • Обоснование ответов реальным контекстом
  • Динамическая маршрутизация запросов между облаком и локальным выполнением с помощью гибридного вывода
  • Перевод контента с помощью настраиваемых систем маршрутизации

Иногда для решения задачи требуются модели ИИ с более обширными знаниями о мире, большим окном контекста или возможностью обрабатывать сложные запросы. В таких случаях можно использовать облачные модели. 

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

features.png
Облачные и гибридные функции в Jetpacker: помощник в музее с веб-основой, гибридный черновик отзыва о ресторане и чат поддержки с живым переводом, маршрутизируемым по запросу.

Ниже описано, как мы реализовали три облачные и гибридные функции в Jetpacker:

  • помощник по музею с обоснованием с использованием информации в интернете;
  • составление отзывов о ресторанах в гибридном режиме;
  • чат поддержки отелей с переводом в реальном времени.

Использование LLM для получения актуальной информацииЧат-бот помощника музея с использованием LLM

Помощник по музеям  – это интерактивный чат-бот, который помогает пользователям планировать посещения музеев. На нем посетители могут найти актуальную информацию о выставках, времени работы, ценах на билеты и т. д.

museum_assistant_upscaled.png
Музейный помощник – это чат-бот, который отвечает на вопросы, например "Как получить скидку на билет в Лувр?"

При создании функций на основе ИИ часто возникает проблема, связанная с тем, что модель должна отвечать на вопросы, используя актуальную, точную и конкретную информацию из реального мира. Облачные модели обладают огромным объемом знаний о мире, но могут не знать о сезонных выставках или часах работы в текущий день.

grounding.png
Обосновывающие данные добавляются в окно контекста, чтобы модель могла правильно и точно отвечать на вопросы.

Чтобы устранить этот недостаток, мы можем использовать методы обоснования, чтобы добавить дополнительный контекст в окно контекста модели. Firebase AI Logic SDK поддерживает три типа обоснования:

В Jetpacker доступные инструменты создаются динамически на основе включенных флагов функций, а генеративная модель инициализируется с помощью Firebase AI SDK:

// implementation("com.google.firebase:firebase-ai-logic")

private var toolList = mutableListOf<Tool>()

init {
    if (ENABLE_SEARCH_GROUNDING) {
        toolList.add(Tool.googleSearch())
    }
    if (ENABLE_URL_GROUNDING) {
        toolList.add(Tool.urlContext())
    }
}

private val generativeModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash",
        systemInstruction = content {
            text("You are a helpful museum assistant answering questions about a museum. Use plain text.")
        },
        tools = toolList
    )

Если пользователь задает вопрос помощнику, а привязка к URL включена, мы добавляем в запрос URL ресурсов музея:

val groundingText = if (FeatureFlags.ENABLE_URL_GROUNDING) {
    "\n If the following message above is about the rules and terms to visit Le Louvre, " +
    "if needed answer this urls ${urlList.joinToString()}"
} else {
    ""
}

val prompt = "$text $groundingText"

var response = chat.sendMessage(prompt)

Не для каждой задачи ИИ требуется облачная модель, и не каждое устройство подключено к интернету. Чтобы помочь разработчикам найти баланс между задержкой, стоимостью и доступностью офлайн, мы недавно представили Firebase API для гибридного вывода.

В Jetpacker функция отзывов о ресторанах позволяет пользователям выбирать темы и автоматически составлять отзывы. Чтобы включить эту функцию для всех пользователей, мы отдаем приоритет локальному выполнению с помощью Gemini Nano и переходим к облачным моделям на устройствах, которые не поддерживают Gemini Nano. 

review_upscaled.png
Функция отзывов о ресторанах использует гибридный вывод, чтобы составить отзыв на основе тем
// implementation("com.google.firebase:firebase-ai-logic")
// implementation("com.google.firebase:firebase-ai-ondevice:16.0.0-beta03")


// Initialize the model with hybrid routing configuration
val reviewModel = Firebase.ai.generativeModel(
    modelName = "gemini-3.1-flash-lite",
    onDeviceConfig = OnDeviceConfig(
        inferenceMode = InferenceMode.PREFER_ON_DEVICE
    )
)

Hybrid Inference API поддерживает четыре режима маршрутизации:

  • PREFER_ON_DEVICE. Приоритет отдается локальному выполнению, а при недоступности Gemini Nano используется облако.
  • PREFER_IN_CLOUD – приоритет отдается облачной обработке, но если устройство переходит в офлайн-режим, используется обработка на устройстве.
  • ONLY_ON_DEVICE. Ограничивает выполнение только на устройстве.
  • ONLY_IN_CLOUD – выполнение разрешено только в облаке.

После того как отзыв будет создан, мы скопируем его в буфер обмена и с помощью намерения откроем страницу отзывов о ресторане в Google Картах.

private fun copyAndOpenMapsReview(context: Context, reviewText: String, placeId: String) {
    val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText("User Review", reviewText)
    clipboard.setPrimaryClip(clip)

    val uri = Uri.parse("https://search.google.com/local/writereview/mobile?placeid=$placeId")
    val intent = Intent(Intent.ACTION_VIEW, uri).apply {
        setPackage("com.google.android.apps.maps")
    }
    context.startActivity(intent)
}

Собственная гибридная маршрутизация: перевод чата поддержки отеля с использованием симулированных личностей

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

private val generativeModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        systemInstruction = content {
            text("""
              You are a helpful hotel receptionist at $hotelName only speaking $language. 
              Answer politely in $language. The bar closes at 10pm and breakfast is from 7am to 10am.
              There's someone at the desk 24/7. You can retrieve your luggage from the storage room 
              at the back of the lobby at any time.
              """)
        },
        modelName = "gemini-3-flash-preview"
    )

Поскольку ответы администратора предоставляются на местном языке (например, в парижском отеле Le Meurice – на французском), нам нужно переводить сообщения на язык пользователя.

translation_upscaled.png
Сообщения чата службы поддержки отелей автоматически переводятся на предпочитаемый язык пользователя. 

Гибридные модели позволяют настраивать простые правила маршрутизации, но для сложных сценариев требуется специальная логика. В Jetpacker мы используем собственный стек маршрутизации, который учитывает:

  • Определение языка. С помощью ML Kit Language Identification API, работающего на устройстве, мы можем определить язык входящего сообщения.
  • Перевод на устройстве (Gemini Nano). Prompt API из ML Kit позволяет переводить распространенные языковые пары прямо на устройстве, экономя трафик и средства на облачные сервисы.
  • Облачный перевод (Gemini 3 Flash). Для более сложных языков мы используем Gemini Flash 3, чтобы получать более качественные переводы.
// implementation("com.google.android.gms:play-services-mlkit-language-id:17.0.0") 

// ML Kit for Language Identification (powered by Google Play Services)
private val languageIdentifier = LanguageIdentification.getClient()

// On-device translator model (prefer Gemini Nano) for translating common language pairs
private val hybridTranslationModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash",
        onDeviceConfig = OnDeviceConfig(mode = InferenceMode.PREFER_ON_DEVICE)
    )

// Cloud translator model for more complex language pairs
private val cloudTranslationModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash"
    )

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

fun translateMessage(message: SupportChatMessage) {
    viewModelScope.launch {
        // 1. Detect language using ML Kit Language Identification
        val sourceLang = try {
            Tasks.await(languageIdentifier.identifyLanguage(message.text))
        } catch (e: Exception) {
            "Undefined"
        }

        // 2. Custom routing: we've verified the translation quality for English and Korean with Gemini Nano, and will translate message on-device for those two languages
        val routeToCloud = sourceLang != "en" && sourceLang != "kr"

        val prompt = "Translate the following text to $selectedLanguage. Just return the translated sentence: ${message.text}."

        val (translatedText, routePrefix) = if (routeToCloud) {
            val result = cloudTranslationModel.generateContent(prompt)
            result.text to "[Cloud]"
        } else {
            val result = hybridTranslationModel.generateContent(prompt)
            result.text to "[On-Device]"
        }

        if (translatedText != null) {
            _translations.update { current ->
                current + (message.id to "$routePrefix: $translatedText")
            }
        }
    }
}

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

Защита конвейеров ИИ: проверка приложений Firebase

Наконец, использование ИИ в облаке открывает возможности для злоупотребления ключами API или несанкционированного выставления счетов. Чтобы защитить вызовы API, мы интегрировали Firebase App Check, используя Play Integrity (для рабочей среды) и локальный поставщик отладки (для локальной разработки или эмуляторов).

В файле JetPackerApplication.kt мы устанавливаем поставщика отладки при запуске и запускаем анонимную аутентификацию, чтобы установить безопасный сеанс пользователя:

//  implementation("com.google.firebase:firebase-appcheck-playintegrity") 
//  implementation("com.google.firebase:firebase-appcheck-debug")  
//  implementation("com.google.firebase:firebase-auth") 

override fun onCreate() {
    super.onCreate()
    Firebase.initialize(context = this)
    Firebase.appCheck.installAppCheckProviderFactory(
        DebugAppCheckProviderFactory.getInstance()
    )
    Firebase.auth.signInAnonymously()
}

При локальной сборке на эмуляторе App Check выводит секрет локального токена в logcat:

Enter this debug secret into the allow list in the Firebase Console: a8c2dd4c-xxxx-xxxx-xxxx-ef6c114ba27e

После регистрации в консоли Firebase местные запросы полностью проверяются и аутентифицируются с помощью Проверки приложений, что обеспечивает защиту нашего внутреннего сервиса и позволяет тестировать приложение локально.

Заключение

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

Ознакомьтесь с полным исходным кодом Jetpacker на GitHub и документацией Firebase, чтобы начать работу:

Документация по Firebase AI Logic
Firebase Hybrid Inference API

Подробнее…

Ознакомьтесь с другими частями этой серии записей в блоге:

Часть 1. Общие сведения о приложении.
Часть 2. Использование ИИ на устройстве. Изучите GenAI API и Gemini Nano в ML Kit, чтобы создавать функции, обеспечивающие конфиденциальность, например краткий пересказ маршрута, распознавание чеков и обработку локального аудио.
Часть 3 (эта статья): Гибридные и облачные рассуждения. Узнайте, как использовать логику ИИ Firebase, чтобы ответы БЯМ основывались на реальных данных, например из Google Карт и веб-контекста.
Часть 4. Интеграция с системой. Интеграция с интеллектуальной системой Android с помощью AppFunctions.
Часть 5 (скоро). Рабочие процессы с агентами в приложениях. Добавьте в приложение помощника по бронированию, работающего на основе A2UI и ADK.

Хотите узнать больше о разработке для Android? Подпишитесь на канал Android Developers на YouTube или LinkedIn!

Все фрагменты кода в этой записи блога сопровождаются следующим уведомлением об авторских правах:

Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0
Автор:
Продолжить чтение