Bentornato alla serie di post del blog "Creare app per Android intelligenti", in cui prendiamo un'app per Android di base e la trasformiamo in un'esperienza personalizzata, intelligente e agentica. Nel post precedente abbiamo esplorato come creare funzionalità intelligenti on-device utilizzando Gemini Nano tramite l'API Prompt di ML Kit.
In questo post, vedremo come sfruttare Firebase AI Logic per creare funzionalità di AI ibride e ospitate sul cloud:
- Basare le risposte sul contesto del mondo reale
- Eseguire il routing dinamico delle richieste tra l'esecuzione cloud e quella locale utilizzando l'inferenza ibrida
- Tradurre i contenuti con sistemi di routing personalizzati
A volte un caso d'uso richiede modelli di AI con una maggiore conoscenza del mondo, una finestra contestuale molto più grande o la capacità di gestire query complesse. In questi scenari, possiamo sfruttare i modelli cloud.
Altre volte, vuoi il meglio di entrambi i mondi: utilizzare l'inferenza ibrida per l'esecuzione on-device quando disponibile per ridurre i costi, mentre il cloud garantisce la compatibilità per tutti i dispositivi.
Vediamo come abbiamo implementato tre funzionalità cloud e ibride in Jetpacker:
- Un assistente museale con grounding web
- Stesura di recensioni di ristoranti ibride
- Chat di assistenza per hotel con traduzione live con routing personalizzato.
Utilizzare il grounding LLM per informazioni aggiornateChatbot dell'assistente museale con grounding LLM
L'assistente museale è un chatbot interattivo progettato per aiutare gli utenti a pianificare le visite ai musei. Fornisce ai visitatori dettagli aggiornati su mostre specifiche, orari di apertura attuali, prezzi dei biglietti e altro ancora.
Quando si creano funzionalità di AI, una sfida comune è fare in modo che il modello risponda con informazioni sul mondo reale aggiornate, accurate e specifiche. Sebbene i modelli cloud possiedano enormi quantità di conoscenza del mondo, potrebbero non essere a conoscenza delle mostre stagionali o degli orari di apertura del giorno corrente.
Per colmare questo divario, possiamo utilizzare tecniche di grounding per aggiungere un contesto aggiuntivo alla finestra contestuale del modello. L'SDK Firebase AI Logic supporta tre tipi di grounding:
- Grounding URL: risposte di grounding utilizzando i contenuti di una pagina web specifica (ad es. prezzi dei biglietti attuali o regole del museo).
- Grounding della Ricerca Google: consente al modello di eseguire query sull'indice della Ricerca Google in tempo reale per ottenere dettagli aggiornati.
- Grounding di Maps: utilizzo dei dati sulla posizione di Google Maps.
In Jetpacker, costruiamo dinamicamente gli strumenti disponibili in base ai flag delle funzionalità abilitate e inizializziamo il modello generativo utilizzando l'SDK AI di Firebase:
// 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 )
Quando l'utente esegue una query sull'assistente, se il grounding URL è abilitato, aggiungiamo gli URL delle risorse del museo specifiche direttamente nel prompt:
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)
Inferenzia ibrida: generazione di recensioni on-device con link diretto a Maps
Non tutte le attività AI richiedono un modello basato sul cloud e non tutti i dispositivi sono online. Per aiutare gli sviluppatori a bilanciare latenza, costi e disponibilità offline, di recente abbiamo introdotto l'API Firebase per l'inferenza ibrida.
In Jetpacker, la funzionalità Recensione del ristorante consente agli utenti di recensire argomenti selezionati e di scrivere automaticamente una recensione. Per abilitare questa funzionalità per tutti gli utenti, diamo la priorità all'esecuzione locale con Gemini Nano e torniamo ai modelli cloud sui dispositivi che non supportano Gemini Nano.
// 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 ) )
L'API Inferenza ibrida supporta quattro modalità di routing distinte:
- PREFER_ON_DEVICE: dà la priorità all'esecuzione locale e torna al cloud se Gemini Nano non è disponibile.
- PREFER_IN_CLOUD: dà la priorità all'esecuzione cloud e torna al dispositivo se il dispositivo va offline.
- ONLY_ON_DEVICE: limita l'esecuzione rigorosamente al dispositivo.
- ONLY_IN_CLOUD: limita l'esecuzione rigorosamente al cloud.
Una volta generata la recensione, la copiamo negli appunti e utilizziamo un intent per aprire Google Maps direttamente nella pagina delle recensioni del ristorante, offrendo un'esperienza utente fluida:
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) }
Routing ibrido personalizzato: traduzione della chat di assistenza per hotel con personaggi simulati
La chat di assistenza per hotel è stata creata per consentire agli utenti di finalizzare la logistica e controllare i dettagli dell'hotel. Questa funzionalità utilizza le istruzioni di sistema per configurare un assistente di reception localizzato. Passando informazioni specifiche, come la lingua preferita e le informazioni sull'hotel, nelle istruzioni, possiamo configurare un personaggio conversazionale che rappresenta un hotel specifico.
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" )
Poiché le risposte della reception sono nella lingua locale dell'hotel (ad esempio, il francese per l'Hotel Le Meurice di Parigi), dobbiamo tradurre i messaggi nella lingua preferita dell'utente.
Sebbene i modelli ibridi possano configurare semplici preferenze di routing, gli scenari complessi richiedono una logica di routing personalizzata. In Jetpacker, implementiamo uno stack di routing personalizzato che tiene conto di:
- Identificazione della lingua: utilizzando l'API di identificazione della lingua di ML Kit on-device, possiamo rilevare la lingua del messaggio in arrivo.
- Traduzione on-device (Gemini Nano): l'API Prompt di ML Kit ci consente di tradurre le coppie di lingue comuni direttamente sul dispositivo, risparmiando larghezza di banda e costi cloud.
- Traduzione cloud (Gemini 3 Flash): per le lingue più complesse, utilizziamo Gemini Flash 3 per ottenere una traduzione di qualità superiore.
// 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" )
Quando è necessario tradurre un messaggio, identifichiamo la lingua di origine e applichiamo la nostra logica di routing personalizzata, eseguendo la traduzione on-device o cloud:
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") } } } }
In questo esempio, la logica di routing personalizzata prende in considerazione solo la lingua di origine e di destinazione della traduzione. Tuttavia, in base al caso d'uso della tua app, puoi espandere la logica di routing per includere altri fattori come la versione del modello on-device, la connettività di rete, lo stato della batteria e altro ancora.
Proteggere le pipeline di AI: Firebase App Check
Infine, l'utilizzo dell'AI nel cloud apre la possibilità di abusi delle chiavi API o di fatturazione non autorizzata. Per proteggere le chiamate API, abbiamo integrato Firebase App Check utilizzando sia Play Integrity (produzione) sia il provider di debug locale (per lo sviluppo locale o gli emulatori).
Nel file JetPackerApplication.kt, installiamo il provider di debug all'avvio e attiviamo l'autenticazione anonima per stabilire una sessione utente sicura:
// 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() }
Quando crei localmente su un emulatore, App Check stampa un segreto del token locale in logcat:
Enter this debug secret into the allow list in the Firebase Console: a8c2dd4c-xxxx-xxxx-xxxx-ef6c114ba27e
Una volta registrate nella console Firebase, le richieste locali vengono completamente verificate e autenticate da App Check, proteggendo il nostro backend e consentendoci di testare l'app localmente.
Conclusione
Combinando le funzionalità del modello cloud (grounding, istruzioni di sistema) con le funzionalità on-device (routing ibrido, traduzione, controlli di sicurezza delle app), abbiamo creato un'app di viaggio intelligente, sicura e disponibile offline.
Consulta il codice sorgente completo di Jetpacker su GitHub ed esplora la documentazione di Firebase per iniziare:
Documentazione di Firebase AI Logic
API Firebase Inferenza ibrida
Scopri di più
Dai un'occhiata alle altre parti di questa serie di post del blog:
Parte 1: introduzione dell'app e panoramica di alto livello.
Parte 2: intelligenza on-device. Approfondimento delle API AI generativa di ML Kit e di Gemini Nano per creare funzionalità incentrate sulla privacy, come il riepilogo degli itinerari, l'analisi delle ricevute e l'elaborazione audio locale.
Parte 3 (questo post!): Ragionamento ibrido e cloud. Scopri come utilizzare Firebase AI Logic per basare le risposte LLM su dati del mondo reale come Google Maps e il contesto web.
Parte 4: integrazione del sistema. Integrazione con il sistema di intelligenza di Android utilizzando AppFunctions.
Parte 5 (in arrivo): workflow basati su agenti in-app. Estendi l'app con un assistente di prenotazione end-to-end basato su A2UI e ADK.
Ti interessa saperne di più sullo sviluppo di Android? Segui Android for Developers su YouTube o LinkedIn.
Tutti gli snippet di codice in questo post del blog seguono la seguente nota sul copyright:
Copyright 2026 Google LLC. SPDX-License-Identifier: Apache-2.0
-
Guide praticheBentornato alla serie di blog post "Creare app per Android intelligenti", in cui prendiamo un'app per Android di base e la trasformiamo in un'esperienza personalizzata, intelligente e agentica. Nel post precedente abbiamo introdotto Jetpacker, l'app demo che utilizzeremo in questa serie.
Caren Chang • 6 minuti di lettura -
Guide praticheJetpacker è un'app di dimostrazione tecnica che il nostro team ha creato da zero per Google I/O di quest'anno (utilizzando Antigravity). In sostanza, Jetpacker aiuta gli utenti a pianificare, esplorare e godersi la loro prossima grande avventura.
Jolanda Verhoef • 4 minuti di lettura -
Guide praticheBentornato alla serie di blog post "Creare app per Android intelligenti", in cui prendiamo un'app per Android di base e la trasformiamo in un'esperienza personalizzata, intelligente e agentica. Nel post precedente abbiamo esplorato come sfruttare Firebase AI Logic per creare funzionalità di AI ibride e ospitate sul cloud.
Ben Weiss • 6 minuti di lettura
Ricevi settimanalmente nella tua casella di posta gli ultimi insight sullo sviluppo di Android.