ADK Kotlin 1.0 사용법: Android AI 에이전트 구조를 잡는 방법
Google이 ADK for Kotlin 1.0을 공개하면서 Android와 Kotlin 서버 개발자도 본격적으로 프로덕션 AI 에이전트를 설계할 수 있는 선택지가 생겼습니다. 핵심은 단순히 Kotlin 바인딩이 나왔다는 점이 아닙니다. Kotlin Multiplatform 기반 코어, 타입 안전한 도구 호출, Android-first 확장, 세션 복원, Room과 AppSearch 기반 상태 저장까지 포함됐다는 점입니다.
이 글은 “ADK Kotlin 1.0 사용법”, “Android AI agent”, “Kotlin function calling”을 찾는 개발자를 위한 실무 가이드입니다. 예제 코드를 그대로 복사하기보다, 어떤 구조로 시작해야 유지보수가 쉬운지에 초점을 맞춥니다.
ADK Kotlin 1.0이 해결하는 문제
모바일 앱에 AI 에이전트를 붙일 때 흔한 문제는 세 가지입니다. 첫째, 모델 호출 코드와 앱 비즈니스 로직이 섞입니다. 둘째, 도구 호출 스키마가 문자열 기반으로 흩어집니다. 셋째, 앱 프로세스가 죽거나 네트워크가 끊겼을 때 대화와 작업 상태를 복구하기 어렵습니다.
ADK Kotlin 1.0은 이 문제를 프레임워크 레벨에서 다루려는 도구입니다. Google 설명에 따르면 Python과 Java ADK 코어와 기능 parity를 맞췄고, Kotlin Multiplatform 기반으로 모델 백엔드, 세션 제공자, 메모리 시스템에 종속되지 않는 구조를 제공합니다.
Android 쪽에서는 LiteRT-LM과 ML Kit 기반 온디바이스 실행, Firebase AI Logic을 통한 클라우드 reasoning, Room 기반 세션 persistence, AppSearch 기반 semantic memory 같은 확장이 소개됐습니다. 모바일 개발자에게 중요한 건 “모든 걸 클라우드로 보내지 않아도 된다”는 선택지가 생긴 점입니다.
기본 아키텍처는 세 층으로 나누는 게 좋습니다
ADK Kotlin을 앱에 넣을 때는 다음 세 층으로 분리하는 편이 안전합니다.
첫째, Agent layer입니다. 사용자의 목표를 해석하고, 어떤 도구를 호출할지 결정합니다. 여기에는 모델, 프롬프트, agent instruction, delegation 규칙이 들어갑니다.
둘째, Tool layer입니다. 실제 앱 기능을 실행합니다. 캘린더 조회, 로컬 DB 검색, 서버 API 호출, 알림 예약, 파일 저장 같은 기능입니다. 이 계층은 일반 Kotlin 서비스처럼 테스트 가능해야 합니다.
셋째, State layer입니다. 대화, 실행 중인 작업, 사용자 확인 상태, 요약된 컨텍스트를 저장합니다. Android에서는 Room, AppSearch, DataStore를 조합할 수 있습니다.
이렇게 나누면 모델을 바꿔도 Tool layer 테스트가 유지되고, 도구를 추가해도 Agent layer의 instruction만 좁게 수정할 수 있습니다.
타입 안전한 도구 호출을 활용하는 방법
Google 예제에서 중요한 부분은 KSP(Kotlin Symbol Processing)를 활용한 @Tool, @Param 기반 함수 정의입니다. 런타임 reflection에 의존하지 않고 빌드 시점에 함수 호출 정의를 만들 수 있습니다. 이는 Android에서 특히 중요합니다. reflection은 성능, 난독화, 런타임 오류 측면에서 부담이 됩니다.
도구를 만들 때는 함수 이름보다 입력 제약이 중요합니다. 예를 들어 'deleteFile(path: String)' 같은 도구는 위험합니다. 모델이 임의 경로를 넘길 수 있기 때문입니다. 대신 'deleteDraftNote(noteId: String)'처럼 도메인 객체 중심으로 좁히는 게 낫습니다.
좋은 도구 설계 기준은 다음과 같습니다.
- 입력 타입이 앱 도메인과 맞다.
- 함수 하나가 너무 많은 일을 하지 않는다.
- 실패 이유를 구조화해서 반환한다.
- 민감 작업은 confirmation flow를 요구한다.
- 네트워크 오류와 권한 오류를 구분한다.
도구 설명도 짧아야 합니다. “사용자의 초안을 삭제한다. 사용자가 명시적으로 삭제를 요청했고 confirmation이 완료된 경우에만 호출한다” 정도면 충분합니다.
Android에서 온디바이스와 클라우드를 나누는 기준
모든 작업을 클라우드 모델에 보낼 필요는 없습니다. 반대로 모든 작업을 온디바이스 모델로 처리하려고 하면 품질과 지연시간이 불안정할 수 있습니다. 기준을 정해야 합니다.
온디바이스가 적합한 작업은 개인정보가 강하거나 짧고 반복적인 작업입니다. 예를 들어 로컬 노트 검색, 간단한 분류, 최근 사용 패턴 요약, 오프라인 상태에서의 초안 생성이 여기에 들어갑니다.
클라우드가 적합한 작업은 장문 reasoning, 복잡한 코드/문서 생성, 외부 지식이 필요한 질의, 여러 도구를 조합해야 하는 작업입니다. Firebase AI Logic 같은 경로를 쓰면 앱에서 직접 모델 API 키를 들고 있지 않아도 됩니다.
하이브리드 구조에서는 routing 기준을 명시해야 합니다. “민감 데이터 포함 여부”, “컨텍스트 길이”, “정확도 요구”, “오프라인 필요성”, “비용”을 기준으로 삼으면 됩니다.
세션 복원과 human-in-the-loop는 처음부터 넣어야 합니다
모바일 앱은 서버와 다릅니다. 프로세스가 쉽게 죽고, 사용자는 앱을 백그라운드로 보냅니다. 에이전트가 긴 작업을 하다가 앱이 종료되면 상태 복원이 필요합니다. ADK Kotlin 1.0의 session resumability는 이 지점에서 중요합니다.
예를 들어 여행 일정 앱에서 에이전트가 “항공권 PDF를 읽고 일정표를 만든 뒤 캘린더에 추가”하는 작업을 한다고 가정해보겠습니다. PDF 파싱, 일정 추출, 사용자 확인, 캘린더 쓰기까지 여러 단계가 있습니다. 중간에 앱이 종료되면 사용자는 처음부터 다시 하고 싶지 않습니다. 작업 상태와 확인 대기 상태를 저장해야 합니다.
민감 작업은 human-in-the-loop로 멈춰야 합니다. 캘린더 생성, 메시지 발송, 결제, 파일 삭제, 개인정보 공유는 자동 실행하지 않습니다. 모델이 “이 작업을 하면 좋겠다”고 판단할 수는 있지만, 실행은 사용자의 명시적 확인 이후로 미룹니다.
작은 예제로 시작하는 추천 순서
처음부터 멀티 에이전트 구조를 만들 필요는 없습니다. 첫 버전은 단일 agent + 3개 도구면 충분합니다.
- 'searchLocalNotes(query)'로 로컬 데이터를 검색합니다.
- 'summarizeNote(noteId)'로 선택된 항목을 요약합니다.
- 'createDraft(title, body)'로 초안을 저장합니다.
이 정도만으로도 도구 호출, 권한, 세션 저장, 오류 처리, confirmation flow를 검증할 수 있습니다. 이후에 캘린더, 서버 API, 알림 도구를 추가하면 됩니다.
멀티 에이전트는 역할이 실제로 나뉠 때만 도입하세요. “검색 agent”, “요약 agent”, “작성 agent”처럼 이름만 나누면 디버깅이 어려워집니다. 도구 권한과 실패 책임이 다를 때 분리하는 게 기준입니다.
실행 체크리스트
- Agent, Tool, State layer를 분리했다.
- 도구 함수는 도메인 중심 입력을 받고 임의 경로·임의 URL을 받지 않는다.
- 민감 작업은 confirmation flow 없이는 실행되지 않는다.
- 온디바이스와 클라우드 routing 기준을 문서화했다.
- 세션 복원 시 사용자가 중간 단계부터 이어갈 수 있다.
- Room 또는 AppSearch에 저장할 데이터와 저장하지 않을 데이터를 구분했다.
- 모델 응답보다 도구 호출 결과를 기준으로 성공 여부를 판단한다.
- 첫 실험은 단일 agent와 3개 이하 도구로 시작한다.
출처: Google Developers Blog, “Announcing ADK for Kotlin 1.0”