Poradniki

Tworzenie inteligentnych aplikacji na Androida: wnioskowanie w chmurze i hybrydowe

Czas czytania: 8 min

Witamy z powrotem w serii postów na blogu "Tworzenie inteligentnych aplikacji na Androida", w której przekształcamy podstawową aplikację na Androida w spersonalizowane, inteligentne i autonomiczne środowisko. W naszym poprzednim poście omówiliśmy, jak tworzyć inteligentne funkcje na urządzeniu za pomocą Gemini Nano przy użyciu interfejsu Prompt API z pakietu ML Kit.

W tym poście pokażemy, jak wykorzystać Firebase AI Logic do tworzenia funkcji AI hostowanych w chmurze i hybrydowych: 

  • uzasadnianie odpowiedzi w kontekście rzeczywistym;
  • dynamiczne kierowanie żądań między chmurą a lokalnym wykonywaniem za pomocą wnioskowania hybrydowego;
  • tłumaczenie treści za pomocą niestandardowych systemów routingu.

Czasami przypadek użycia wymaga modeli AI z większą wiedzą o świecie, znacznie większym oknem kontekstu lub możliwością obsługi złożonych zapytań. W takich sytuacjach możemy korzystać z modeli w chmurze. 

Innym razem chcesz mieć to, co najlepsze z obu światów: używać wnioskowania hybrydowego do uruchamiania na urządzeniu, gdy jest to możliwe, aby obniżyć koszty, a jednocześnie korzystać z chmury, aby zapewnić zgodność ze wszystkimi urządzeniami.

features.png
Funkcje w chmurze i hybrydowe w Jetpacker: asystent muzeum z uzasadnieniem w internecie, hybrydowe tworzenie opinii o restauracji i czat z obsługą klienta z tłumaczeniem na żywo kierowanym przez niestandardowy routing.

Przyjrzyjmy się, jak zaimplementowaliśmy 3 funkcje w chmurze i hybrydowe w Jetpacker:

  • asystent muzeum z uzasadnieniem w internecie;
  • hybrydowe tworzenie opinii o restauracji;
  • czat z obsługą klienta hotelu z tłumaczeniem na żywo kierowanym przez niestandardowy routing.

Używanie uzasadnienia LLM do uzyskiwania aktualnych informacjiAsystent muzeum z uzasadnieniem LLM

Asystent muzeum to interaktywny chatbot, który pomaga użytkownikom planować wizyty w muzeum. Udostępnia on odwiedzającym aktualne informacje o konkretnych eksponatach, aktualnych godzinach otwarcia, cenach biletów i innych kwestiach.

museum_assistant_upscaled.png
Asystent muzeum to chatbot, który odpowiada na pytania, np. „Jak mogę uzyskać zniżkę na bilet do Luwru?”.

Podczas tworzenia funkcji AI częstym wyzwaniem jest uzyskanie odpowiedzi modelu z aktualnymi, dokładnymi i szczegółowymi informacjami z rzeczywistego świata. Modele w chmurze mają ogromną wiedzę o świecie, ale mogą nie znać wystaw sezonowych ani aktualnych godzin otwarcia.

grounding.png
Dane uzasadniające są dodawane do okna kontekstu, aby model mógł poprawnie i dokładnie odpowiadać na pytania.

Aby rozwiązać ten problem, możemy użyć technik uzasadniania, aby dodać dodatkowy kontekst do okna kontekstu modelu. Pakiet SDK Firebase AI Logic obsługuje 3 rodzaje uzasadniania:

  • Uzasadnianie URL-em: uzasadnianie odpowiedzi za pomocą treści z konkretnej strony internetowej (np. aktualnych cen biletów lub regulaminu muzeum).
  • Uzasadnianie wyszukiwarką Google: umożliwia modelowi wysyłanie zapytań do indeksu wyszukiwarki Google w czasie rzeczywistym w celu uzyskania aktualnych informacji.
  • Uzasadnianie Mapami: używanie danych o lokalizacji z Map Google.

W Jetpacker dynamicznie tworzymy dostępne narzędzia na podstawie włączonych flag funkcji i inicjujemy model generatywny za pomocą pakietu 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
    )

Gdy użytkownik wysyła zapytanie do asystenta, jeśli włączone jest uzasadnianie URL-em, do prompta dołączamy bezpośrednio adresy URL konkretnych zasobów muzeum:

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)

Nie każde zadanie realizowane z wykorzystaniem AI wymaga modelu w chmurze, a nie każde urządzenie jest online. Aby pomóc deweloperom w zrównoważeniu opóźnienia, kosztów i dostępności offline, wprowadziliśmy niedawno interfejs Firebase API do wnioskowania hybrydowego.

W Jetpacker funkcja opinii o restauracji umożliwia użytkownikom ocenianie wybranych tematów i automatyczne tworzenie opinii. Aby udostępnić tę funkcję wszystkim użytkownikom, priorytetowo traktujemy wykonywanie lokalne za pomocą Gemini Nano i przełączamy się na modele w chmurze na urządzeniach, które nie obsługują Gemini Nano. 

review_upscaled.png
Funkcja opinii o restauracji używa wnioskowania hybrydowego do tworzenia opinii na podstawie tematów.
// 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
    )
)

Interfejs Hybrid Inference API obsługuje 4 różne tryby routingu:

  • PREFER_ON_DEVICE: priorytetowo traktuje wykonywanie lokalne i przełącza się na chmurę, jeśli Gemini Nano jest niedostępny.
  • PREFER_IN_CLOUD: priorytetowo traktuje wykonywanie w chmurze i przełącza się na urządzenie, jeśli urządzenie przejdzie w tryb offline.
  • ONLY_ON_DEVICE: ogranicza wykonywanie wyłącznie do urządzenia.
  • ONLY_IN_CLOUD: ogranicza wykonywanie wyłącznie do chmury.

Po wygenerowaniu opinii kopiujemy ją do schowka i używamy intencji, aby otworzyć Mapy Google bezpośrednio na stronie opinii o restauracji, co zapewnia płynne korzystanie:

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)
}

Niestandardowy routing hybrydowy: tłumaczenie czatu z obsługą klienta hotelu z symulowanymi personami

Czat z obsługą klienta hotelu został stworzony, aby umożliwić użytkownikom dopracowanie logistyki i sprawdzenie szczegółów hotelu. Ta funkcja używa instrukcji systemowych do skonfigurowania zlokalizowanego asystenta recepcji. Przekazując w instrukcjach konkretne informacje, takie jak preferowany język i informacje o hotelu, możemy skonfigurować personę konwersacyjną reprezentującą konkretny hotel.

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"
    )

Ponieważ odpowiedzi recepcjonisty są w lokalnym języku hotelu (np. francuskim w przypadku Hotelu Le Meurice w Paryżu), musimy przetłumaczyć wiadomości na preferowany język użytkownika.

translation_upscaled.png
Wiadomości na czacie z obsługą klienta hotelu są automatycznie tłumaczone na preferowany język użytkownika. 

Modele hybrydowe mogą konfigurować proste preferencje routingu, ale złożone scenariusze wymagają niestandardowej logiki routingu. W Jetpacker implementujemy niestandardowy stos routingu, który uwzględnia:

  • Identyfikacja języka: za pomocą interfejsu ML Kit Language Identification API na urządzeniu możemy wykryć język wiadomości przychodzącej.
  • Tłumaczenie na urządzeniu (Gemini Nano): interfejs Prompt API z pakietu ML Kit umożliwia tłumaczenie popularnych par językowych bezpośrednio na urządzeniu, co pozwala oszczędzać przepustowość i koszty chmury.
  • Tłumaczenie w chmurze (Gemini 3 Flash): w przypadku bardziej złożonych języków używamy Gemini Flash 3, aby uzyskać tłumaczenie wyższej jakości.
// 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"
    )

Gdy wiadomość wymaga przetłumaczenia, identyfikujemy język źródłowy i stosujemy niestandardową logikę routingu, wykonując tłumaczenie na urządzeniu lub w chmurze:

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")
            }
        }
    }
}

W tym przykładzie niestandardowa logika routingu uwzględnia tylko język źródłowy i docelowy tłumaczenia. W zależności od przypadku użycia aplikacji możesz jednak rozszerzyć logikę routingu, aby uwzględniała inne czynniki, takie jak wersja modelu na urządzeniu, łączność z siecią, stan baterii i inne.

Zabezpieczanie potoków AI: Sprawdzanie aplikacji Firebase

Korzystanie z AI w chmurze otwiera możliwości nadużywania kluczy API lub nieautoryzowanych płatności. Aby zabezpieczyć wywołania API, zintegrowaliśmy Sprawdzanie aplikacji Firebase za pomocą funkcji Play Integrity (produkcja) i lokalnego dostawcy debugowania (na potrzeby lokalnego programowania lub emulatorów).

W pliku JetPackerApplication.kt instalujemy dostawcę debugowania podczas uruchamiania i wywołujemy anonimowe uwierzytelnianie, aby utworzyć bezpieczną sesję użytkownika:

//  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()
}

Podczas tworzenia lokalnego emulatora funkcja Sprawdzanie aplikacji drukuje lokalny tajny token w logcat:

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

Po zarejestrowaniu w konsoli Firebase lokalne żądania są w pełni weryfikowane i uwierzytelniane przez funkcję Sprawdzanie aplikacji, co chroni nasze zaplecze i umożliwia testowanie aplikacji lokalnie.

Podsumowanie

Łącząc możliwości modelu w chmurze (uzasadnianie, instrukcje systemowe) z możliwościami na urządzeniu (routing hybrydowy, tłumaczenie, sprawdzanie zabezpieczeń aplikacji), stworzyliśmy inteligentną, bezpieczną i dostępną offline aplikację podróżniczą.

Aby rozpocząć, zapoznaj się z pełnym kodem źródłowym Jetpacker na GitHubie i dokumentacją Firebase:

Dokumentacja Firebase AI Logic
Interfejs Firebase Hybrid Inference API

Więcej informacji

Zapoznaj się z pozostałymi częściami tej serii postów na blogu:

Część 1: wprowadzenie do aplikacji i ogólny przegląd.
Część 2: inteligencja na urządzeniu. Szczegółowe omówienie interfejsów GenAI API z pakietu ML Kit i Gemini Nano, aby tworzyć funkcje skoncentrowane na ochronie prywatności, takie jak podsumowanie planu podróży, analizowanie paragonów i lokalne przetwarzanie dźwięku.
Część 3 (ten post!): Wnioskowanie hybrydowe i w chmurze. Dowiedz się, jak używać Firebase AI Logic do uzasadniania odpowiedzi LLM za pomocą danych z rzeczywistego świata, takich jak Mapy Google i kontekst internetowy.
Część 4: integracja z systemem. Integracja z systemem inteligencji Androida za pomocą AppFunctions.
Część 5 (już wkrótce): przepływy pracy agenta w aplikacji. Rozszerz aplikację o kompleksowego asystenta rezerwacji opartego na A2UI i ADK.

Chcesz dowiedzieć się więcej o tworzeniu aplikacji na Androida? Obserwuj kanał dla deweloperów aplikacji na Androida w YouTube lub LinkedIn.

Wszystkie fragmenty kodu w tym poście na blogu są objęte tym powiadomieniem o prawach autorskich:

Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0
Autorzy:
Czytaj dalej