개발자 관계팀 엔지니어
프로덕션에 즉시 사용 가능한 생성형 AI를 Android 앱에 빌드하려면 LLM에 연결하는 것만으로는 부족하며 엔터프라이즈급 보안과 비용 관리가 필요합니다. 이 세션에서는 Firebase AI Logic을 통해 개발자가 안전하고 예산에 맞는 AI 환경을 대규모로 배포하는 방법을 알아봅니다.
보안 기초, Firebase 앱 체크, 비용 관리, 동적 모델 라우팅부터 멀티모달 기능 활용까지 다룹니다.
스크립트
Android Developer Summit에 오신 것을 환영합니다.
저는 Firebase 제품 관리자인 안키타 삭세나입니다.
저는 Firebase팀의 개발자 관계 엔지니어인 아서 톰슨입니다.
오늘은 Android 앱에 생성형 기능을 추가하는 방법을 보여드리겠습니다.
좋습니다.
Firebase란?
Firebase에 대해 들어본 적이 있는 분은 손을 들어주세요.
아, 많이 보이네요.
좋습니다.
Firebase는 Google의 앱 개발 플랫폼입니다.
Firebase는 20개 이상의 제품이 통합된 통합 플랫폼을 제공하므로 추가 소프트웨어를 사용할 때와 같은 단편적인 환경을 경험하지 않아도 됩니다.
모바일 앱에 생성형 AI를 배포할 때의 과제에 대해 이야기해 보겠습니다.
세 가지 주요 과제를 확인했습니다.
첫째, API 키 유출입니다. API 키를 추출하는 데 몇 분밖에 걸리지 않습니다.
둘째, 모델 이름 업데이트: 개발자는 앱에 모델 이름을 하드 코딩하지 않는 것이 좋습니다. 그렇지 않으면 새 모델이 출시될 때마다 다른 버전을 푸시해야 합니다.
세 번째는 파일 개인 정보 보호입니다. 개발자나 앱 사용자에게는 데이터가 보호되고 앱에 적절한 보호 장치가 마련되는 것이 매우 중요합니다.
앞서 논의한 문제를 해결하기 위한 핵심 솔루션으로 Firebase AI Logic을 소개합니다.
Firebase AI Logic이 제공하는 가치 제안은 무엇인가요?
Google에서 복잡한 맞춤 백엔드를 모두 처리하므로 개발자가 직접 개발할 필요가 없습니다.
둘째, 클라이언트 SDK를 사용하면 모바일 앱에서 직접 안전하게 Gemini API를 호출할 수 있습니다.
내부적으로 아키텍처가 어떻게 흐르는지 살펴보겠습니다.
왼쪽에는 Firebase 클라이언트 SDK가 있습니다.
현재 Google에서는 다양한 클라이언트 SDK를 지원하고 있습니다.
Google에서 지원하는 Kotlin도 언급하고 싶습니다.
개발자가 AI 작업을 수행하려고 하면 SDK가 Firebase AI Logic에 요청을 전송하고, Firebase AI Logic은 이 요청을 Gemini Developer API 또는 Agent Platform Gemini API로 안전하게 라우팅합니다.
따라서 기본적으로 오늘 만드는 모든 커스텀 백엔드를 처리합니다.
이를 통해 얻는 가치는 비용 없이 TTM(time to market)을 단축할 수 있다는 점입니다.
이제 재미있는 부분입니다.
FriendlyMeals 앱을 보여주는 데모입니다.
참고로 이 세션의 나머지 데모에서도 동일한 앱을 사용할 예정이므로 자유롭게 다운로드하세요.
여기에서 QR 코드를 사용하여 스캔할 수 있습니다.
데모를 살펴보겠습니다.
FriendlyMeals 앱은 기본적으로 입력한 재료를 기반으로 레시피를 식별하는 데 도움이 됩니다.
이 워크플로에서는 기본적으로 이러한 요소를 캡처하는 두 가지 방법을 보여줍니다.
첫 번째는 가지고 있는 재료를 입력하는 것입니다.
둘째, 재료 사진을 찍습니다.
첫 번째 워크플로인 재료 입력을 사용해 보겠습니다.
냉장고에서 찾을 수 있는 건 이게 전부야.
레시피가 생성되는 동안 몇 가지 사항을 말씀드리겠습니다.
내부적으로는 Gemini 모델을 호출하고 있습니다.
이 특정 사용 사례에서는 Gemini 3.8 Flash를 세 번 호출합니다.
상단의 이미지는 실제로 최신 버전인 2.1 Nano Banana인 Gemini Nano Banana 모델을 사용하고 있습니다.
코드를 살펴보기 전에 Firebase AI Logic을 통해 얻을 수 있는 가치 제안을 다시 한번 강조하고 싶습니다.
첫 번째는 서버리스 SDK입니다.
AI 기능을 추가하고 싶지만 백엔드를 설정하고 싶지는 않습니다.
이때 클라이언트 측 SDK가 필요합니다.
Android 앱에서 Gemini를 직접 호출합니다.
두 번째는 강력한 기본 제공 보안 기능입니다.
따라서 Gemini를 호출할 때 Firebase 앱 체크, 서버 프롬프트 템플릿 등을 활용할 수 있습니다. 이러한 보안 기능에 대해서는 잠시 후에 자세히 설명하겠습니다.
세 번째는 멀티모달 입력 및 스트리밍과 같은 고급 기능 지원입니다.
마법의 배낭에 관한 이야기를 생성하는 간단한 AI 기능을 추가하는 앱을 빌드한다고 가정해 보겠습니다.
import com.google.firebase.Firebase
import com.google.firebase.ai.ai
@Composable
fun MagicBackpackGenerator() {
var output by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
val model=Firebase.ai.generativeModel("gemini-4-argon")
val response = model.generateContent("Write a story about a magic backpack")
output = response.text.toString()
}
MagicBackpackUI(output)
}이 세 가지 간단한 단계를 거치면 AI 기능을 추가하고 프로덕션에 사용할 수 있습니다.
Firebase AI Logic을 사용하면 앱에 AI 기능을 쉽게 추가할 수 있으므로, 가장 먼저 고려해야 할 질문은 이 기능을 어떻게 보호할 것인가입니다.
그럼 Firebase 앱 체크를 시작으로 보안 세부정보를 살펴보겠습니다.
Firebase 앱 체크는 요청이 앱에서 전송되었음을 증명하여 데이터를 보호하고, 사용자를 보호하며, API 리소스에 액세스할 수 있는 사용자를 제어하는 데 도움이 됩니다.
앱이 악용되지 않도록 보호하는 추가 보안 레이어입니다.
코드를 작성하기 전에 Firebase Console에서 몇 가지 단계를 수행해야 합니다.
Firebase Console의 앱 체크에서 Android 앱을 등록하고 각 증명 제공자를 추가합니다.
Play Integrity 또는 reCAPTCHA Enterprise와 같은 도구를 사용합니다.
앱 체크를 설정한 후에는 시행되지 않는 모드로 시작해야 합니다.
이렇게 하면 앱에서 원격 분석을 제공하여 시행 전에 모든 앱이 백엔드에 대한 API 호출을 성공적으로 가져오고 있는지 확인할 수 있습니다.
원격 분석이 제대로 수신되는 것을 확인한 후 앱 체크를 시행하면 유효한 하드웨어 증명 토큰이 없는 요청은 거부됩니다.
앱 체크를 구현하는 코드는 다음과 같습니다.
class FireTravelApp : Application() {
lateinit var appContainer: AppContainer
private set
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Firebase.appCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance()
)
} else {
Firebase.appCheck.installAppCheckProviderFactory(
PlayIntegrityAppCheckProviderFactory.getInstance()
)
}
appContainer = AppContainer(this)
}
}애플리케이션 클래스에서 앱 체크 제공자를 설치합니다.
개발 단계에서는 디버그 제공자를 사용하고 프로덕션 단계로 넘어갈 준비가 되면 Play Integrity 또는 reCAPTCHA Enterprise로 전환하는 것이 좋습니다.
하지만 다른 Firebase 호출을 하기 전에 먼저 앱 체크를 구성해야 한다는 점을 항상 기억하세요.
AI 기능을 빌드할 때 개발자는 앱 코드에 프롬프트를 직접 하드 코딩하는 경우가 많지만, 이로 인해 두 가지 큰 문제가 발생합니다.
첫째, 프롬프트에 즉흥적인 수정이 필요한 경우 전체 업데이트를 푸시해야 합니다.
둘째, 앱을 압축 해제하는 사람은 누구나 독점 프롬프트 엔지니어링에 액세스할 수 있습니다.
이 문제를 해결하기 위해 Firebase AI Logic은 서버 프롬프트 템플릿을 사용합니다.
프롬프트를 기기에 보관하는 대신 클라우드에 저장합니다.
Firebase Console에 표시되는 서버 프롬프트 템플릿의 모습입니다.
템플릿은 .prompt 형식으로 작성합니다.
---
model: 'gemini-3-flash'
input:
schema:...
tools:...
---
{{role "system"}}
You're a storyteller that tells nice and joyful stories with happy endings.
{{role "user"}}
Create a story about {{topic}} with the length of {{length}} words in the {{language}} language.여기에서 모델 이름을 설정할 수 있습니다.
언제든지 업데이트할 수 있습니다.
전체 앱 업데이트를 푸시할 필요는 없습니다.
시스템 안내를 업데이트할 수도 있으며, 입력 및 출력에 엄격한 JSON 스키마를 사용합니다.
이 경우에도 앱을 출시할 필요가 없습니다.
클라우드에 있으므로 프롬프트를 조정하거나 모델을 즉시 교체할 수 있습니다.
Kotlin에서 코드는 다음과 같습니다.
val generativeModel = Firebase.ai.templateGenerativeModel()
val response = generativeModel.generateContent("storyteller-v1",
mapOf(
"topic" to topic,
"length" to length,
"language" to language
)
)
output.value = response.text여기서 언급할 점은 서버 프롬프트 템플릿이 공개 프리뷰 상태라는 것입니다.
인증 전용 모드를 구현할 수도 있습니다.
이 방법은 Firebase 인증 사용자 토큰을 사용하여 요청을 승인합니다.
보안 기능을 보완하고 애플리케이션을 완전히 잠그려면 Firebase Console에서 직접 템플릿 전용 모드를 사용할 수도 있습니다.
앱이 게시되면 앱이 어떻게 작동하는지 파악하고 싶을 수 있습니다.
AI Monitoring 탭에서 클릭 한 번으로 AI Monitoring을 사용 설정하고 샘플링 레이트를 구성할 수 있습니다.
Firebase는 맞춤 분석 코드를 작성하지 않아도 측정항목, 지연 시간, 토큰 수를 자동으로 캡처합니다.
방금 살펴본 두 가지 모드는 모두 동일한 창에서 사용할 수 있습니다.
Firebase Console에서 AI 모니터링을 사용 설정하면 AI 모니터링 대시보드에 직접 데이터가 전송됩니다.
95번째 백분위수 지연 시간을 관찰하고, 갑작스러운 오류 급증을 파악하고, 텍스트, 이미지, 오디오와 같은 다양한 형식의 토큰 소비를 추적할 수 있습니다.
Trace 뷰어를 검사하여 특정 trace를 확인할 수도 있습니다.
이 경우 사용 중인 모델과 같은 차이점을 보여주므로 지연 시간, 성공률을 확인할 수 있습니다.
Firebase Console에서 모든 원격 분석과 AI 기능의 작동 방식에 대한 가시성을 확보할 수 있습니다.
이 경우 토큰 사용량이 갑자기 급증하거나 지연 시간이 갑자기 급증하면 하이브리드를 통해 비용을 절감하거나 지연 시간을 줄일 수 있습니다.
생성형 AI 기능이 앱의 핵심 요소가 되면서 클라우드에만 100% 의존하는 것은 올바른 선택이 아닐 수 있습니다.
Android의 온디바이스 모델인 Nano 4를 활용하면 세 가지 주요 이점을 얻을 수 있으며, 이는 모두에게 익숙한 이점일 것입니다.
첫 번째는 오프라인 모드입니다.
따라서 대규모 회의에 참석 중이거나 비행기 또는 지하철에 있더라도 AI 기능은 계속 작동합니다.
비용
추론이 기기에서 실행되므로 이러한 기능을 추가할 수 있으며 AI 기능의 비용 증가에 대해 걱정할 필요가 없습니다.
세 번째는 데이터 개인 정보 보호입니다.
따라서 민감한 데이터인 경우 추론이 기기 외부로 전송되지 않는다고 사용자에게 보장할 수 있습니다.
따라서 Firebase AI Logic을 사용하면 이러한 추론 모드를 설정하고 PREFER_ON_DEVICE, PREFER_IN_CLOUD, ONLY_ON_DEVICE와 같은 명확한 라우팅 전략을 사용할 수 있습니다.
ONLY_ON_DEVICE를 선택하면 SDK가 클라우드를 완전히 우회하여 기기 내 모델에 직접 액세스합니다.
휴대전화로 전환하겠습니다.
다시 FriendlyMeals로 이동하여 기기 내 기능을 살펴보겠습니다.
먼저 냉장고에 있는 재료를 기반으로 레시피를 만들어 보겠습니다.
앞서 Ankita가 재료를 직접 입력하여 레시피를 생성하는 수동 방식을 사용하는 것을 보셨습니다.
다른 방법을 시도해 보겠습니다.
생성된 것이 아닌 실제 냉장고를 예로 들어보겠습니다.
냉장고에 올리브가 많으니 어떤 레시피가 생성되는지 살펴보겠습니다.
이와 관련해 몇 가지를 지적하고 싶습니다.
하나는 이미지가 기기 외부로 전송되지 않았다는 것입니다.
이미지는 Nano by Gemma를 통해 로컬에서 분석되었습니다.
Nano 4.
두 번째는 응답이 돌아오는 속도입니다.
소재가 생성되었습니다.
따라서 두 가지 이점을 얻을 수 있습니다.
데이터가 기기를 벗어나지 않으며 지연 시간도 크게 줄어듭니다.
올리브가 가득한 냉장고에서 어떤 레시피가 나오는지 살펴보겠습니다.
이번에는 클라우드를 사용합니다.
냉장고에서 식별된 재료를 가져와 클라우드로 전송하고, Firebase AI Logic을 사용하여 레시피를 생성합니다.
냉장고에 연어가 없는데 레시피에 연어가 있네.
슬라이드로 돌아가겠습니다.
데모에서 보았듯이 로컬 모델과 클라우드 모델 간의 전환은 매우 간단합니다.
현재 Firebase AI Logic은 네트워크 가용성에 기반한 기본 라우팅을 사용하여 추론을 지원합니다.
이러한 추론을 관리하기 위해 가드레일이라고 생각할 수 있습니다.
따라서 이 아키텍처에는 멀티모달, 입력 및 출력 스키마와 같은 기능에 대한 기본 제공 지원과 Gemini Nano 4와의 완전한 통합이 포함되어 있습니다.
그럼 이러한 가드레일이 실제로 어떻게 구현되는지 살펴보겠습니다.
따라서 하이브리드 라우팅을 사용하면 복잡한 미들웨어를 빌드하거나 많은 대체 로직을 직접 빌드할 필요가 없습니다.
코드 측면에서는 추가 매개변수에 불과합니다.
onDeviceConfig 매개변수를 전달하여 원하는 모드를 설정합니다.
import com.google.firebase.Firebase
import com.google.firebase.ai.ai
@Composable
fun MagicBackpackGenerator() {
var output by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
val model = Firebase.ai.generativeModel(modelName = "gemini-3.8-flash",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.PREFER_ON_DEVICE))
val response = model.generateContent("Write a story about a magic backpack")
output = response.text.toString()
}
MagicBackpackUI(output)
}이 경우 SDK는 로컬 모델을 먼저 시도하고 사용할 수 없는 경우 자동으로 클라우드로 대체합니다.
지금까지 안전한 앱을 빌드하고 기기 내 모델을 활용하는 방법을 살펴보았으니 이제 비용 최적화에 대해 알아보겠습니다.
생성형 기능은 빠르게 확장될 수 있으므로 클라우드 비용도 빠르게 증가할 수 있습니다.
따라서 예산을 예측 가능하게 하고 애플리케이션을 재정적으로 효율적으로 만드는 데 도움이 되는 적절한 사전 예방적 인프라 제어 및 자동화 기능을 갖추기 위해 적절한 안전장치를 마련해야 합니다.
아서가 온디바이스 추론은 완전히 무료라고 강조했지만, 복잡한 추론 작업이 필요하고 대체가 필요하며 클라우드로 라우팅해야 하는 시나리오는 항상 존재합니다.
이러한 클라우드 호출이 발생할 때는 예산을 예측 가능하게 유지하기 위한 가드레일이 필요합니다.
바로 이럴 때 Firebase 지출 한도가 필요합니다.
지출 한도를 사용하면 앱 비용을 더 세부적으로 관리할 수 있습니다.
따라서 프로젝트 전반에 적용되는 일반적인 예산 설정이나 이메일로만 전송되는 예산 알림 대신 Firebase AI Logic과 같은 개별 서비스에 특정 예산 한도를 설정할 수 있습니다.
지출이 100%에 도달하면 Firebase에서 AI 서비스를 자동으로 일시중지하여 과도한 청구를 방지합니다.
단순한 지출 한도 외에도 몇 가지 고급 비용 최적화 전략이 있습니다.
오늘 강조하고 싶은 기능은 Firebase AI Logic 트리거입니다.
중간에 커스텀 로직이 필요한 경우에는 어떻게 해야 할까요?
바로 Firebase AI Logic 트리거입니다.
콘텐츠를 생성하기 전이나 후에 함수를 실행할 수 있습니다.
이를 사용하여 사용자를 확인하고, 입력을 필터링하고, 컨텍스트를 추가하고, 응답을 조정할 수 있습니다.
비용 최적화와 보안에 대해 살펴보았으니 이제 모델 기능으로 넘어가 Firebase AI Logic에서 제공하는 기능을 살펴보겠습니다.
이러한 멀티모달 환경을 지원하기 위해 Firebase AI Logic은 프로덕션에 즉시 사용 가능한 모델과 도구의 포괄적인 카탈로그를 제공합니다.
고속 추론, 텍스트, 코드, 미디어의 경우 Gemini 4 Argon, Gemini 3.1 Pro, Gemini 3.8 Flash 등을 사용할 수 있습니다.
또한 검색 및 지도 그라운딩을 사용하여 이러한 모델을 실제 데이터에 연결할 수 있습니다.
마지막으로 음성의 경우 자연스러운 텍스트 음성 변환과 Gemini Live 오디오 생성을 제공합니다.
휴대전화로 한 번 더 전환해 보겠습니다.
여기 달콤하고 짭짤한 맛이 있습니다.
죄송합니다. 그게 아닙니다.
여기 치즈 케첩 토스트 레시피가 있습니다.
맛있겠네요
먼저 Live API를 살펴보겠습니다.
이 경우 반환되는 동영상을 사용하여 "Gemini, 테이블에 있는 재료가 무엇인지 알려줘"라고 말할 수 있습니다.
노트북 화면의 이미지를 기반으로 하면 가지고 있는 재료는 빵, 체다 치즈, 케첩입니다.
좋습니다.
그럼 레시피의 첫 번째 단계를 시작해도 될까요?
예.
첫 번째 단계는 토스터 오븐이나 브로일러를 중불로 예열하는 것입니다.
감사합니다.
좋습니다.
이 경우 Live API를 사용했기 때문에 제가 대화를 종료할 때까지 대화가 계속 열려 있었습니다.
또 다른 기능은 음성 텍스트 변환, 아니 텍스트 음성 변환입니다.
이 예시에서는 TTS를 사용하여 레시피 안내를 제공합니다.
따라서 읽을 필요 없이 '생성' 또는 '말하기'를 누르면 안내 텍스트가 텍스트 음성 변환 모델로 전송됩니다.
오디오를 생성하고 기기로 다시 전송합니다.
재생할 수도 있고 나중에 재생할 수 있도록 캐시할 수도 있습니다. 여기에서 볼 수 있듯이 재생됩니다.
1.
토스터 오븐 또는 브로일러를 중불로 예열합니다.
2.
베이킹 시트나 토스터 트레이에 식빵 두 조각을 올립니다.
잘하셨네요
멋지죠?
Firebase AI Logic을 사용하면 코드 몇 줄만으로 이러한 멋진 기능을 구현할 수 있습니다.
슬라이드로 다시 전환하겠습니다.
시연을 통해 Gemini Live API의 작동 방식을 살펴보았는데, 핸즈프리 대화형 환경을 직접 빌드하려면 어떻게 해야 할까요?
이때 Gemini Live API를 사용하면 양방향 음성 대화를 만들 수 있습니다.
Android 앱은 실시간 마이크 오디오 및 카메라 프레임을 업스트림으로 스트리밍하고 자연스럽고 지연 시간이 짧은 음성 대답을 실시간으로 수신할 수 있습니다.
Kotlin에서는 이 설정이 매우 익숙해 보입니다.
val model = Firebase.ai.liveModel(
modelName = "gemini-3.1-flash-live-preview",
generationConfig = liveGenerationConfig {
responseModality = ResponseModality.AUDIO
},
systemInstruction = "Your main job is to change the color...",
tools = listOf(Tool.functionDeclarations(listOf(changeColorFunction)))
)
val session = model.connect(::handler)
session.startAudioConversation(::handler)
session.stopAudioConversation()오디오 응답을 위해 구성된 라이브 모델을 인스턴스화하고 스트림 핸들러를 사용하여 세션에 연결합니다.
여기서 가장 중요한 점은 SDK가 내부적으로 전체 WebSocket 및 스트리밍 프로토콜을 처리한다는 것입니다.
따라서 코딩할 필요가 없습니다.
계속해서 코드를 작성합니다.
데모를 마무리하고 앱 개발의 미래를 살펴보면서 워크플로를 위한 강력한 도구인 Firebase 에이전트 스킬을 소개해 드리겠습니다.
# Execute to add agent capabilities to your workspace
npx skills add firebase/agent-skills또한 Antigravity와 Android 스튜디오를 사용하는 경우 Firebase AI Logic이 온보딩 과정에 이미 직접 통합되어 있습니다.
세 가지 핵심 내용을 정리해 드리겠습니다. 첫째, 빌드를 시작하세요. 둘째, 오늘 다룬 보안 도구와 같은 프로덕션 도구를 초기에 활용하세요. 셋째, 가능한 한 에이전트 기술을 사용하세요.
감사합니다.
import com.google.firebase.Firebase
import com.google.firebase.ai.ai
@Composable
fun MagicBackpackGenerator() {
var output by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
val model=Firebase.ai.generativeModel("gemini-4-argon")
val response = model.generateContent("Write a story about a magic backpack")
output = response.text.toString()
}
MagicBackpackUI(output)
}class FireTravelApp : Application() {
lateinit var appContainer: AppContainer
private set
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Firebase.appCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance()
)
} else {
Firebase.appCheck.installAppCheckProviderFactory(
PlayIntegrityAppCheckProviderFactory.getInstance()
)
}
appContainer = AppContainer(this)
}
}---
model: 'gemini-3-flash'
input:
schema:...
tools:...
---
{{role "system"}}
You're a storyteller that tells nice and joyful stories with happy endings.
{{role "user"}}
Create a story about {{topic}} with the length of {{length}} words in the {{language}} language.val generativeModel = Firebase.ai.templateGenerativeModel()
val response = generativeModel.generateContent("storyteller-v1",
mapOf(
"topic" to topic,
"length" to length,
"language" to language
)
)
output.value = response.textimport com.google.firebase.Firebase
import com.google.firebase.ai.ai
@Composable
fun MagicBackpackGenerator() {
var output by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
val model = Firebase.ai.generativeModel(modelName = "gemini-3.8-flash",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.PREFER_ON_DEVICE))
val response = model.generateContent("Write a story about a magic backpack")
output = response.text.toString()
}
MagicBackpackUI(output)
}val model = Firebase.ai.liveModel(
modelName = "gemini-3.1-flash-live-preview",
generationConfig = liveGenerationConfig {
responseModality = ResponseModality.AUDIO
},
systemInstruction = "Your main job is to change the color...",
tools = listOf(Tool.functionDeclarations(listOf(changeColorFunction)))
)
val session = model.connect(::handler)
session.startAudioConversation(::handler)
session.stopAudioConversation()# Execute to add agent capabilities to your workspace
npx skills add firebase/agent-skills