Tutoriais

Criar apps Android inteligentes: inferência híbrida e na nuvem

Leitura de 8 minutos

Bem-vindos de volta à série de postagens do blog "Criar apps Android inteligentes", em que transformamos um app Android básico em uma experiência personalizada, inteligente e agente. Na postagem anterior, mostramos como criar recursos inteligentes no dispositivo usando o Gemini Nano pela API Prompt do Kit de ML.

Nesta postagem, vamos mostrar como aproveitar o Firebase AI Logic para criar recursos de IA híbridos e hospedados na nuvem: 

  • Embasar respostas no contexto do mundo real
  • Solicitações de roteamento dinâmico entre a nuvem e a execução local usando a inferência híbrida
  • Traduzir conteúdo com sistemas de roteamento personalizados

Às vezes, um caso de uso exige modelos de IA com maior conhecimento mundial, uma janela de contexto muito maior ou a capacidade de processar consultas complexas. Nesses casos, podemos aproveitar os modelos de nuvem. 

Outras vezes, você quer o melhor dos dois mundos: usar a inferência híbrida para executar no dispositivo quando disponível para reduzir custos, enquanto volta para a nuvem para garantir a compatibilidade com todos os dispositivos.

features.png
Recursos híbridos e de nuvem no Jetpacker: assistente de museu com embasamento na Web, redação de avaliações de restaurantes híbridas e chat de suporte com tradução ao vivo roteada personalizada.

Vamos conferir como implementamos três recursos híbridos e de nuvem no Jetpacker:

  • um assistente de museu com embasamento na Web
  • redação de avaliações de restaurantes híbridas
  • chat de suporte de hotel com tradução ao vivo roteada personalizada.

Usar o embasamento de LLM para informações atualizadasChatbot de assistente de museu com embasamento de LLM

O assistente de museu é um chatbot interativo criado para ajudar os usuários a planejar visitas a museus. Ele oferece aos visitantes detalhes atualizados sobre exposições específicas, horários de funcionamento atuais, preços de ingressos e muito mais.

museum_assistant_upscaled.png
O assistente de museu é um chatbot que responde a perguntas, como "Como posso conseguir um desconto de ingresso para o Louvre?"

Ao criar recursos de IA, é comum que o modelo responda com informações do mundo real novas, precisas e específicas. Embora os modelos de nuvem possuam grandes quantidades de conhecimento mundial, eles podem não saber sobre exposições sazonais ou horários de funcionamento do dia.

grounding.png
Os dados de embasamento são adicionados à janela de contexto para permitir que o modelo responda a perguntas corretamente e com precisão.

Para preencher essa lacuna, podemos usar técnicas de embasamento para adicionar contexto extra à janela de contexto do modelo. O SDK do Firebase AI Logic oferece suporte a três tipos de embasamento:

  • Embasamento de URL: respostas de embasamento usando conteúdo de uma página da Web específica (por exemplo, preços de ingressos atuais ou regras de museus).
  • Embasamento da Pesquisa Google: permite que o modelo consulte o índice de pesquisa do Google em tempo real para detalhes atualizados.
  • Embasamento do Maps: usa dados de localização do Google Maps.

No Jetpacker, construímos dinamicamente as ferramentas disponíveis com base nas flags de recursos ativadas e inicializamos o modelo generativo usando o SDK de IA do 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 o usuário consulta o assistente, se o embasamento de URL estiver ativado, anexamos os URLs de recursos específicos do museu diretamente ao comando:

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)

Nem toda tarefa de IA exige um modelo baseado na nuvem, e nem todo dispositivo está on-line. Para ajudar os desenvolvedores a equilibrar latência, custo e disponibilidade off-line, apresentamos recentemente a API do Firebase para inferência híbrida.

No Jetpacker, o recurso de avaliação de restaurantes permite que os usuários avaliem tópicos selecionados e redijam uma avaliação automaticamente. Para ativar isso para todos os usuários, priorizamos a execução local com o Gemini Nano e voltamos aos modelos de nuvem em dispositivos que não oferecem suporte ao Gemini Nano. 

review_upscaled.png
O recurso de avaliação de restaurantes usa a inferência híbrida para redigir uma avaliação com base em tópicos
// 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
    )
)

A API Hybrid Inference oferece suporte a quatro modos de roteamento distintos:

  • PREFER_ON_DEVICE:prioriza a execução local e volta para a nuvem se o Gemini Nano não estiver disponível.
  • PREFER_IN_CLOUD:prioriza a execução na nuvem e volta para o dispositivo se ele ficar off-line.
  • ONLY_ON_DEVICE:restringe a execução estritamente ao dispositivo.
  • ONLY_IN_CLOUD:restringe a execução estritamente à nuvem.

Depois que a avaliação é gerada, ela é copiada para a área de transferência e usamos uma intent para abrir o Google Maps diretamente na página de avaliação do restaurante, proporcionando uma experiência do usuário integrada:

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

Roteamento híbrido personalizado: tradução de chat de suporte de hotel com personas simuladas

O chat de suporte de hotel foi criado para permitir que os usuários finalizem a logística e verifiquem os detalhes do hotel. Esse recurso usa instruções do sistema para configurar um assistente de recepcionista localizado. Ao transmitir informações específicas, como o idioma preferido e as informações do hotel, nas instruções, podemos configurar uma persona conversacional que representa um hotel específico.

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

Como as respostas da recepcionista estão no idioma local do hotel (por exemplo, francês para o Hotel Le Meurice em Paris), precisamos traduzir as mensagens para o idioma preferido do usuário.

translation_upscaled.png
As mensagens do chat de suporte do hotel são traduzidas automaticamente para o idioma preferido do usuário 

Embora os modelos híbridos possam configurar preferências de roteamento simples, cenários complexos exigem lógica de roteamento personalizada. No Jetpacker, implementamos uma pilha de roteamento personalizada que considera:

  • Identificação de idioma: usando a API de identificação de idioma do Kit de ML no dispositivo, podemos detectar o idioma da mensagem recebida.
  • Tradução no dispositivo (Gemini Nano) : a API Prompt do Kit de ML permite traduzir pares de idiomas comuns diretamente no dispositivo, economizando largura de banda e custo da nuvem.
  • Tradução na nuvem (Gemini 3 Flash) : para idiomas mais complexos, usamos o Gemini Flash 3 para obter uma tradução de maior qualidade.
// 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 uma mensagem precisa ser traduzida, identificamos o idioma de origem e aplicamos nossa lógica de roteamento personalizada, executando a tradução no dispositivo ou na nuvem:

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

Neste exemplo, a lógica de roteamento personalizada considera apenas o idioma de origem e de destino da tradução. No entanto, com base no caso de uso do seu app, você pode expandir a lógica de roteamento para incluir outros fatores, como a versão do modelo no dispositivo, a conectividade de rede, o status da bateria e muito mais.

Como proteger os pipelines de IA: Firebase App Check

Por fim, o uso de IA na nuvem abre possibilidades de abuso de chaves de API ou faturamento não autorizado. Para proteger as chamadas de API, integramos o Firebase App Check usando o Play Integrity (produção) e o provedor de depuração local (para desenvolvimento local ou emuladores).

No arquivo JetPackerApplication.kt, instalamos o provedor de depuração na inicialização e acionamos a autenticação anônima para estabelecer uma sessão de usuário segura:

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

Ao criar localmente em um emulador, o App Check imprime um segredo de token local no logcat:

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

Depois de registrado no console do Firebase, as solicitações locais são totalmente verificadas e autenticadas pelo App Check, protegendo nosso back-end e permitindo que testemos o app localmente.

Conclusão

Ao combinar os recursos do modelo de nuvem (instruções de embasamento e sistema) com os recursos no dispositivo (roteamento híbrido, tradução, verificações de segurança do app), criamos um app de viagens inteligente, seguro e disponível off-line.

Confira o código-fonte completo do Jetpacker no GitHub e consulte a documentação do Firebase para começar:

Documentação do Firebase AI Logic
API Firebase Hybrid Inference

Saiba mais

Confira as outras partes desta série de postagens do blog:

Parte 1: introdução do app e uma visão geral de alto nível.
Parte 2: inteligência no dispositivo. Aprofunde-se nas APIs GenAI do Kit de ML e no Gemini Nano para criar recursos com foco na privacidade, como resumo de itinerários, análise de recibos e processamento de áudio local.
Parte 3 (esta postagem): Raciocínio híbrido e na nuvem. Saiba como usar o Firebase AI Logic para embasar respostas de LLM em dados do mundo real, como o Google Maps e o contexto da Web.
Parte 4: integração do sistema. Integração com o sistema de inteligência do Android usando AppFunctions.
Parte 5 (em breve): fluxos de trabalho de agentes no app. Estenda o app com um assistente de reservas completo com tecnologia A2UI e ADK.

Tem interesse em saber mais sobre o desenvolvimento para Android? Siga o Android Developers no YouTube ou no LinkedIn.

Todos os snippets de código nesta postagem do blog seguem a notificação de direitos autorais abaixo:

Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0
Escrito por:
Continuar lendo