방법

지능형 Android 앱 빌드: 클라우드 및 하이브리드 추론

8분 길이
3 작성자
Thomas Ezan, Jolanda Verhoef, Caren Chang

기본 Android 앱을 가져와 맞춤설정된, 지능형, 에이전트형 환경으로 변환하는 "지능형 Android 앱 빌드" 블로그 게시물 시리즈에 다시 오신 것을 환영합니다. 이전 게시물에서는 ML Kit의 프롬프트 API를 통해 Gemini Nano를 사용하여 지능형 온디바이스 기능을 빌드하는 방법을 살펴보았습니다.

이 게시물에서는 Firebase AI Logic 을 활용하여 클라우드 호스팅 및 하이브리드 AI 기능을 빌드하는 방법을 알아봅니다.

  • 실제 상황에서 답변 그라운딩
  • 하이브리드 추론을 사용하여 클라우드와 로컬 실행 간에 요청을 동적으로 라우팅
  • 맞춤 라우팅 시스템으로 콘텐츠 번역

사용 사례에 따라 더 많은 세계 지식, 훨씬 더 큰 컨텍스트 윈도우 또는 복잡한 쿼리를 처리할 수 있는 기능이 있는 AI 모델이 필요할 수 있습니다. 이러한 시나리오에서는 클라우드 모델을 활용할 수 있습니다. 

또는 하이브리드 추론을 사용하여 사용 가능한 경우 온디바이스에서 실행하여 비용을 절감하고 클라우드로 대체하여 모든 기기의 호환성을 보장하는 두 가지 기능의 장점을 모두 누릴 수 있습니다.

features.png
Jetpacker의 클라우드 및 하이브리드 기능: 웹 그라운딩이 있는 박물관 어시스턴트, 하이브리드 레스토랑 리뷰 초안 작성, 맞춤 라우팅된 실시간 번역이 포함된 지원 채팅

Jetpacker에서 세 가지 클라우드 및 하이브리드 기능을 구현한 방법을 살펴보겠습니다.

  • 웹 그라운딩이 있는 박물관 어시스턴트
  • 하이브리드 레스토랑 리뷰 초안 작성
  • 맞춤 라우팅된 실시간 번역이 포함된 호텔 지원 채팅

최신 정보를 위한 LLM 그라운딩LLM 그라운딩이 있는 박물관 어시스턴트 챗봇

박물관 어시스턴트 는 사용자가 박물관 방문을 계획하는 데 도움이 되도록 설계된 대화형 챗봇입니다. 방문자에게 특정 전시회, 현재 운영 시간, 티켓 가격 등에 관한 최신 세부정보를 제공합니다.

museum_assistant_upscaled.png
박물관 어시스턴트는 '루브르 박물관 티켓 할인을 받는 방법'과 같은 질문에 답변하는 챗봇입니다.

AI 기능을 빌드할 때 모델이 최신 정보, 정확한 정보, 구체적인 실제 정보를 사용하여 답변하도록 하는 것은 일반적인 과제입니다. 클라우드 모델은 방대한 양의 세계 지식을 보유하고 있지만 계절별 전시회나 당일 운영 시간에 관해 알지 못할 수 있습니다.

grounding.png
모델이 질문에 올바르고 정확하게 답변할 수 있도록 컨텍스트 윈도우에 그라운딩 데이터가 추가됩니다.

이러한 격차를 해소하기 위해 그라운딩 기법을 사용하여 모델의 컨텍스트 윈도우에 추가 컨텍스트를 추가할 수 있습니다. Firebase AI Logic SDK는 세 가지 유형의 그라운딩을 지원합니다.

  • URL 그라운딩: 특정 웹페이지의 콘텐츠 (예: 현재 티켓 가격 또는 박물관 규칙)를 사용하여 응답을 그라운딩합니다.
  • Google 검색 그라운딩: 모델이 최신 세부정보를 위해 실시간 Google 검색 색인을 쿼리하도록 허용합니다.
  • 지도 그라운딩: Google 지도 위치 데이터를 사용합니다.

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)

모든 AI 태스크에 클라우드 기반 모델이 필요한 것은 아니며 모든 기기가 온라인 상태인 것도 아닙니다. 개발자가 지연 시간, 비용, 오프라인 사용 가능성의 균형을 맞출 수 있도록 최근에 하이브리드 추론을 위한 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
    )
)

하이브리드 추론 API는 다음과 같은 4가지 고유한 라우팅 모드를 지원합니다.

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

접수 담당자 응답은 호텔의 현지 언어 (예: 파리의 Hotel Le Meurice의 경우 프랑스어)로 제공되므로 메시지를 사용자의 선호하는 언어로 번역해야 합니다.

translation_upscaled.png
호텔 지원 채팅 메시지는 사용자의 선호하는 언어로 자동 번역됩니다. 

하이브리드 모델은 간단한 라우팅 환경설정을 구성할 수 있지만 복잡한 시나리오에는 맞춤 라우팅 로직이 필요합니다. Jetpacker에서는 다음을 고려하는 맞춤 라우팅 스택을 구현합니다.

  • 언어 식별: 온디바이스 ML Kit 언어 식별 API를 사용하여 받은 메시지 언어를 감지할 수 있습니다.
  • 온디바이스 번역 (Gemini Nano): ML Kit의 Prompt API를 사용하면 기기에서 직접 일반적인 언어 쌍을 번역하여 대역폭과 클라우드 비용을 절약할 수 있습니다.
  • 클라우드 번역 (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")
            }
        }
    }
}

이 예에서는 맞춤 라우팅 로직이 번역의 출발어와 도착어만 고려합니다. 그러나 앱의 사용 사례에 따라 온디바이스 모델 버전, 네트워크 연결, 배터리 상태 등 다른 요소를 포함하도록 라우팅 로직을 확장할 수 있습니다.

AI 파이프라인 보호: Firebase 앱 체크

마지막으로 클라우드에서 AI를 사용하면 API 키 악용 또는 승인되지 않은 결제 가능성이 열립니다. API 호출을 보호하기 위해 Play Integrity (프로덕션)와 로컬 디버그 제공자 (로컬 개발 또는 에뮬레이터용)를 모두 사용하여 Firebase 앱 체크 를 통합했습니다.

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

에뮬레이터에서 로컬로 빌드할 때 앱 체크는 로컬 토큰 보안 비밀을 logcat에 출력합니다.

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

Firebase Console에 등록되면 로컬 요청은 앱 체크에 의해 완전히 확인되고 인증되어 백엔드를 보호하면서 앱을 로컬로 테스트할 수 있습니다.

결론

클라우드 모델 기능 (그라운딩, 시스템 안내)과 온디바이스 기능 (하이브리드 라우팅, 번역, 보안 앱 체크)을 결합하여 스마트하고 안전하며 오프라인에서 사용할 수 있는 여행 앱을 만들었습니다.

GitHub에서 Jetpacker의 전체 소스 코드를 확인하고 Firebase 문서를 살펴보고 시작하세요.

Firebase AI Logic 문서
Firebase 하이브리드 추론 API

자세히 알아보기

이 블로그 게시물 시리즈의 다른 부분을 확인하세요.

1부: 앱 소개 및 개략적인 개요.
2부: 온디바이스 인텔리전스. ML Kit의 생성형 AI API 및 Gemini Nano를 자세히 살펴보고 여행 일정 요약, 영수증 파싱, 로컬 오디오 처리와 같은 개인 정보 보호 우선 기능 빌드.
3부 (이 게시물): 하이브리드 및 클라우드 추론. Firebase AI Logic을 사용하여 Google 지도 및 웹 컨텍스트와 같은 실제 데이터에서 LLM 답변을 그라운딩하는 방법을 알아봅니다.
4부: 시스템 통합. AppFunctions를 사용하여 Android 인텔리전스 시스템과 통합.
5부 (출시 예정): 인앱 에이전트형 워크플로. A2UI 및 ADK로 구동되는 엔드 투 엔드 예약 어시스턴트로 앱을 확장합니다.

Android 개발에 관해 더 자세히 알고 싶으신가요? YouTube 또는 LinkedIn에서 Android 개발자를 팔로우하세요.

이 블로그 게시물의 모든 코드 스니펫은 다음 저작권 고지를 따릅니다.

Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0
작성자:
계속 읽기