도구 및 실적

Claude Code 및 Android CLI를 사용한 에이전트형 엔지니어링

스피커

정보

강연 소개

AI 채팅 창에 복사하여 붙여넣는 대신 에이전트에게 위임하세요. 이 실용적인 예시 중심 세션에서는 Claude Code와 Android CLI를 사용하여 에이전트 엔지니어링을 한 단계 업그레이드하는 방법을 보여줍니다. 복잡한 개발 작업을 자동화하고 기능을 더 빠르게 출시하기 위한 전체 워크플로를 살펴보겠습니다.

학습할 내용

  • Android CLI, 스킬, 후크, MCP를 사용하여 하네스의 토큰 효율성을 최적화합니다.
  • 장기 실행 작업을 하위 에이전트에 오프로드하고 병렬화합니다.
  • 조기 종료를 중지하고 테스트가 통과할 때까지 실행되는 지속적인 확인 루프를 설정합니다.

요약

  • Android CLI는 코딩 에이전트에게 에뮬레이터, Firebase Crashlytics와 같은 Android 도구에 대한 셸 액세스 권한을 제공합니다. 셸 공간에 있으며 에이전트 전반에서 작동합니다.
  • 컨텍스트 손상을 방지하려면 에이전트 대화를 약 150,000토큰으로 유지하세요. 작업을 범위가 지정된 문제로 분할하고 Gradle을 자동 모드로 실행하여 긴 로그를 방지합니다.
  • AGENTS.md를 250줄 미만으로 유지하고 아키텍처 제약 조건과 같은 영구 규칙에 사용합니다. 에이전트가 이 파일을 수정하도록 허용하면 성능이 저하되고 비용이 증가합니다.
  • 결정론적 후크와 컨텍스트별 기술은 방대한 파일보다 에이전트 작업을 더 잘 관리합니다. 검증된 기술만 설치하거나 기본 Android CLI 기술로 시작합니다.
  • 검증 루프는 개발자가 수동 QA 테스터 역할을 하지 못하도록 합니다. 빠른 단위 테스트를 먼저 실행하고 느린 에뮬레이터 실행을 마지막에 실행하도록 검사를 계층화합니다.

리소스

Gemini Notebook

주제

  • claude-code
  • android-cli
  • agentic-engineering
  • 벤치마킹
  • performance

스크립트

소개 및 환경 설정

  • 안녕하세요. 저는 Android 개발자 관계팀의 벤입니다.

  • 저는 제품 관리자 스티븐입니다.

  • 오늘은 Claude Code와 Android CLI를 사용하여 에이전트 방식으로 앱을 만드는 방법을 알아보겠습니다.

  • 따라서 개발자의 역할이 조금씩 변화하고 있으며, 변화의 속도가 매우 빠르다고 할 수 있습니다. 사실, 특히 온라인으로 시청하는 경우 이 강연의 내용은 이미 오래된 것일 수 있습니다.

  • 따라서 작성한 내용과 제시하는 정보에 대해 적극적인 입장을 취했지만, 오늘 실행하는 데모는 현실에 기반을 두고 있으므로 이제 신뢰할 수 있습니다.

  • 또 다른 점은 이 강연에서 Claude Code를 사용했지만, 이 정보는 에이전트에 구애받지 않는다는 것입니다.

  • 이는 사고방식에 가깝기 때문에 앱을 빌드할 때 선호하는 모든 도구에 적용할 수 있습니다.

  • 따라서 자율 에이전트 팀을 관리하는 세상과 이러한 에이전트가 성공할 수 있도록 설정하는 방법에 대해 생각해 보시기 바랍니다.

  • 기능 구현에 실패했을 때 그냥 포기하고 '아, AI는 아직 이걸 못 하는구나'라고 생각하는 대신, 한 걸음 물러서서 어떤 정보가 누락되었는지 생각해 보고 오늘날 버그를 처리하는 것처럼 처리해야 합니다.

  • Claude Code, Codex, Antigravity와 같은 에이전트 하네스를 만드는 팀의 자료를 읽어보면, 이들이 실제로 이러한 하네스를 개발하는 방식이 바로 이와 같다는 것을 알 수 있습니다. 이를 미래의 모습을 엿보는 기회로 삼는다면, 우리 모두가 나아갈 방향이 바로 이곳일 것입니다.

  • 따라서 지금은 빌더와 Android 개발자에게 그 어느 때보다 흥미로운 시기일 것입니다. 하지만 저와 같은 분이라면 정확히 무엇에 집중해야 할지 알기 어려울 수 있습니다.

  • 개발자에게는 지능적으로 확장되는 도구와 워크플로가 필요합니다. 그래야 새로운 모델이 한계를 넓혀도 기존의 노력이 헛되지 않습니다.

  • Google은 모델이 개선될 때마다 상담사를 위한 워크플로가 더 지능적으로 개선되어 궁극적으로 사용자에게 더 나은 결과를 제공하기를 바랍니다.

  • 오늘 다룰 주제는 크게 4가지입니다.

  • 먼저 에이전트가 성공할 수 있는 환경을 설정하는 것이 왜 중요한지 설명하겠습니다.

  • 그런 다음 컨텍스트와 이를 가장 잘 관리하는 방법에 대해 간략히 설명합니다.

  • 그런 다음 에이전트 내에서 작업하는 Android 개발자가 사용할 수 있는 최고의 도구를 살펴보고, 마지막으로 에이전트 워크플로에 루프를 추가해야 하는 이유를 설명하겠습니다.

  • 그럼 시작하겠습니다.

  • 환경입니다.

  • 하지만 그게 실제로 무슨 의미일까요?

  • 앞서 말씀드렸듯이, 에이전트가 성공할 수 있는 환경을 만들고자 합니다. 사용자가 계속해서 프롬프트를 다시 입력하고 방향을 잡아주지 않아도 에이전트가 스스로 성공할 수 있는 환경이죠. 그렇게 해야만 여러 에이전트를 동시에 실행할 수 있고, 에이전트 팀이 사용자를 대신해 업무를 처리할 때 진정한 생산성 향상을 이룰 수 있습니다.

  • 하지만 이는 단순히 코드에 액세스할 수 있는 것 이상의 의미가 있습니다.

  • 이들은 프로젝트 사양과 해당 프로젝트에서 작업하는 방법에 대한 규칙이 포함된 정확한 문서에 액세스할 수 있어야 합니다.

  • 이건 당연한 거죠.

  • 사람들이 하는 다른 일로는, 에이전트를 시작하는 것뿐만 아니라 실제로 자신에게 할당된 기능을 개발하게 된 결정이 어떻게 내려졌는지에 대한 맥락을 제공하기 위해 에이전트를 팀 채팅 공간에 연결하는 것입니다. 개발자로서 문제를 해결할 때 사용하는 잠재의식적인 정보이기 때문에 에이전트에게도 도움이 될 수 있습니다.

  • 이전 결정 기록과 pull 요청도 마찬가지입니다.

  • 풀 요청에 대한 댓글, 알림을 받는 항목 등을 확인할 수 있어야 하며, 이를 통해 작업하고 수정할 수 있습니다.

  • 또한 기기나 에뮬레이터에 액세스하지 않고 Android 코드를 작성할 수 없듯이 에이전트도 그렇게 할 수 없습니다.

  • 에뮬레이터는 놀라운 기능을 갖추고 있고 무엇이든 할 수 있는 것처럼 보이지만, 에뮬레이터는 정말로 도움이 됩니다.

  • 프로파일러도 마찬가지입니다.

  • 성능 작업을 하려면 프로파일링을 할 수 있어야 하며, 이를 위해서는 실제 기기에 액세스할 수 있어야 합니다.

  • 또한 에이전트가 앱에서 사용하는 모든 백엔드 서비스와도 통신할 수 있어야 합니다.

  • 이때 Android CLI가 필요합니다.

  • '도구의 새로운 기능' 세션에서도 언급되었지만, Android CLI는 다양한 Android 도구와 인터페이스하기 위한 새로운 CLI입니다.

  • 그 자체로 AI 제품은 아니며 CLI, 즉 명령줄 인터페이스입니다.

  • 따라서 Android SDK Manager, 에뮬레이터 시작 기능 등 다양한 기능에 액세스할 수 있습니다.

  • 또한 Crashlytics와 같은 도구 및 백엔드에도 연결됩니다.

  • 사용 중인 에이전트와 상관없이 작동하며 셸 공간에 상주합니다.

  • 그렇습니다.

  • 이 링크에서 설치할 수 있지만, 실제로 작동하는 모습을 보는 것이 더 쉬울 것 같습니다.

데모: Android CLI로 ANR 수정하기

  • 좋습니다.

  • 따라서 에이전트가 성공할 수 있도록 설정하는 것이 왜 중요한지 설명하는 데 그치지 않고, 이 원칙을 Sideline이라는 프로덕션 애플리케이션에 실제로 적용해 보았습니다.

  • Sideline은 테니스 선수를 위한 Android 애플리케이션으로, 공 위치, 선수 위치, 코트 위치에 관한 실시간 피드백을 제공합니다.

  • 동영상 다시보기를 통해 오프라인 코칭 피드백을 제공하고 최고 속도, 이동 거리, 최장 랠리와 같은 피트니스 데이터를 제공합니다.

  • 이 모든 기능은 Android 기기에서 직접 실행되는 커스텀 TF Lite 모델을 통해 구동됩니다.

  • 우선, 존재 여부를 알 수 없는 문제는 해결할 수 없다는 점을 말씀드리고 싶습니다.

  • Android CLI를 사용하여 개발자 환경에 Firebase Crashlytics를 추가했고, 이를 통해 발생하고 있는지도 몰랐던 몇 가지 문제를 발견할 수 있었습니다.

  • 첫 번째는 Pixel 11 Pro Fold 기기에서 애플리케이션 응답 없음 오류(ANR)가 발생했는데 에뮬레이터에서는 재현되지 않는다는 것이었습니다.

  • 다행히 Android CLI는 Android 기기 스트리밍을 지원합니다.

  • 이 문제를 해결하라고 지시하자 에이전트는 ANR이 발생한 기기에 연결을 생성했습니다. 당시 저는 수정 사항을 검증할 Pixel 11 Pro Fold가 없었기 때문에 이 기능이 특히 유용했습니다.

  • 따라서 에이전트에게 수정 사항을 검증하는 데 필요한 기기에 액세스할 수 있는 기능을 제공함으로써 궁극적으로 가능한 기능 집합을 확장할 수 있었습니다.

  • 시간을 절약하기 위해 모든 실험을 미리 실행하고 여기에 요약했습니다.

  • 자세히 설명하지는 않겠지만, Android 17과 관련된 선호도 호출 문제가 있었습니다.

  • 두 줄짜리 간단한 수정이었고, 제가 보기에는 괜찮아 보였습니다.

    setenv("KMP_AFFINITY", "disabled", 1);
    setenv("KMP_INIT_AT_FORK", "false", 1);
  • 그래서 pull 요청을 만들고 병합한 후 Play에 제출된 새 빌드로 업데이트했습니다.

  • 따라서 성공에 필요한 기능을 갖춘 코딩 환경을 설정하지 않았다면 실제 문제를 식별할 수 없었을 것이고 수정 사항을 검증할 수도 없었을 것입니다.

  • 따라서 1.0 빌드에서는 문제가 해결된 것을 확인할 수 있습니다.

  • 하지만 새로운 문제가 발생했으며 이에 대해서는 나중에 살펴보겠습니다.

컨텍스트 및 토큰 한도 관리

  • 좋습니다.

  • 다음은 컨텍스트입니다.

  • 약 1년 반에서 2년 전, 그리 오래되지 않은 시간이지만 AI 분야에서는 평생과도 같은 시간인데요. 당시에는 더 큰 컨텍스트 윈도우를 확보하기 위한 경쟁이 있었습니다. 모델에 더 많은 정보를 제공할수록 더 나은 결과를 얻을 수 있다는 이론이었죠. 그래서 developer.android.com 전체를 프롬프트에 포함하려고 시도하는 등 무모한 일도 했지만, 제대로 작동하지 않았습니다.

  • 하지만 컨텍스트 윈도우가 대체로 정체되어 있음에도 불구하고 모델 기능은 여전히 향상되고 있습니다.

  • 이것이 Android Bench 1.0입니다.

  • Android Bench는 AI의 Android 코드 작성 능력을 평가하는 벤치마크입니다.

  • 작업이 현실적입니다.

  • 이러한 것들이 여러분이 작업하는 종류의 일이며, 컨텍스트 윈도우는 100만 개 수준에서 정체되었지만 모델 기능은 계속 향상되고 있습니다.

  • 하지만 예산은 여전히 고정되어 있으므로 중요한 일에 예산을 아껴야 합니다.

  • 작업 중인 문제에 도움이 되지 않는 항목은 포함하지 않는 것이 좋습니다.

  • 그리고 많은 에이전트 하네스는 실제로 100만 컨텍스트 윈도우를 모두 노출하지 않습니다. 의미가 없다고 생각하기 때문입니다.

  • 그렇게 하면 결과가 더 나빠질 뿐입니다.

  • 실제로 최적의 지점이 있으며 모델에 따라 달라지지만, 대화를 약 150,000토큰으로 유지하면 컨텍스트 손실 없이 모델의 모든 기능을 활용할 수 있습니다.

  • 하지만 맥락은 입력하는 내용에만 국한되지 않습니다.

    [
      {
        "role": "system",
        "content": "You are an expert Android engineering agent..."
      },
      {
        "role": "workspace_context",
        "content": { "project_root": "/workspace/android-app", "build_system": "Gradle (Kotlin DSL)", "target_sdk": 35 }
      },
      {
        "role": "available_tools",
        "content": [ { "name": "read_file" }, { "name": "edit_file" }, { "name": "bash" }, { "name": "skill_android_cli" } ]
      },
      {
        "role": "user",
        "content": "ProfileViewModelTest is failing when loading errors. Fix the ViewModel and verify with unit tests."
      },
      {
        "role": "assistant",
        "tool_calls": [ { "name": "read_file", "arguments": { "path": "app/src/main/.../ProfileViewModel.kt" } } ]
      },
      {
        "role": "tool",
        "content": "class ProfileViewModel(...) : ViewModel() { ... // full file contents + Gradle output appended here }"
      }
    ]
  • 실제로는 보이지 않는 비하인드 스토리가 꽤 많습니다.

  • 여러 부분으로 구성되어 있습니다.

  • 첫 번째는 시스템 요청 사항입니다.

  • 시스템 요청 사항은 에이전트가 제공합니다.

  • 이 에이전트와 작업하는 방법, 에이전트가 수행해야 하는 동작을 알려주는 프롬프트와 같습니다.

  • 또한 작업공간 정보, 현재 작업 디렉터리, 보유한 SDK, 설치된 기술(이에 대해서는 잠시 후에 설명하겠습니다), MCP 도구, 에이전트가 제공하는 도구도 포함됩니다.

  • 모델은 함수를 호출할 수 있다는 것을 알아야 하므로 컨텍스트를 차지합니다.

  • 하지만 가장 중요한 것은 에이전트에게 새 메시지를 보낼 때마다 전체 메시지와 도구 호출 기록이 함께 전송된다는 점입니다.

  • 특히 Gradle을 사용하면 이 시간이 누적되어 상당한 시간이 될 수 있습니다.

  • 모두 아시다시피 Gradle 로그는 매우 길고, 정말 길고, 매우 상세합니다.

  • 대부분은 필요하지 않습니다.

  • 이 점에 유의하시기 바랍니다.

  • Gradle을 자동 모드로 실행할 수 있습니다.

    ./gradlew assembleDebug --quiet
  • 또는 더 큰 에이전트 하네스가 이를 잘라냅니다.

  • 따라서 Claude Code와 Android 스튜디오는 전체 Gradle 로그를 전송하지 않습니다.

  • 하지만 최소 에이전트 중 하나를 사용하는 경우, 모든 것을 모델에 전송하는 것이 기본 철학이기 때문에 모델이 가장 잘 알고 있습니다. 따라서 mini-SWE-agent는 전체 Gradle 로그를 전송하며, 이로 인해 비용이 매우 빠르게 증가할 수 있습니다.

  • 하지만 어떻게 이 150,000이라는 마법의 창을 유지할 수 있을까요?

  • 핵심은 워크플로를 사용하는 것입니다.

  • 그리고 수많은 워크플로가 있습니다.

  • 제가 정말 좋아하는 것은 맷 포콕이라는 사람이 만든 것인데, 이 세션을 관리하는 데 도움이 되는 일련의 기술이 있습니다.

  • 'grill-me'라는 스킬로 시작합니다.

  • 전체 프로젝트를 처음 시작하거나 프로젝트 내에서 새 기능을 시작할 때 이 스킬을 실행하면 에이전트가 여러 질문을 합니다.

  • 그러면 'grill-me'라고 말할 수 있습니다.

  • 앱에 새로운 시간 알람 관리자를 빌드하고 싶습니다."

  • 그러면 이 도구는 무엇을 구현해야 하는지, 어디에 속하는지 등에 관해 질문을 다시 던집니다.

  • 그러면 문제의 모호함이 사라지고 머릿속에서 문제로 정리됩니다.

  • 그런 다음 대규모 사양 문서를 작성하는 다음 스킬을 실행합니다.

  • 그런 다음 이를 문제로 분할하는 또 다른 기술이 있으며, 사용자가 선호하는 문제 관리자에 이를 제출합니다.

  • 그리고 각 문제는 대략 150,000개의 창에 맞아야 합니다.

  • 그런 다음 터미널이나 IDE에서 작업 중인 문제 중 하나를 선택하고, 원하는 대로 빌드하고, 루프를 확인하고, 마지막에 컨텍스트를 지우고, 더 이상 대화 기록이 없으며, 창 내에 머물렀습니다.

  • 좋습니다.

AGENTS.md 권장사항

  • 다음으로 AGENTS.md에 대해 알아보겠습니다.

  • AGENTS.md는 이 프로젝트 또는 전체 작업공간에서 작업 중인 모든 문제에 적용되는 추가 정보를 에이전트에 제공할 수 있는 곳입니다.

  • 하지만 모든 프롬프트에 제공되므로 항상 이상적으로 적용되는 항목만 포함하는 것이 중요합니다.

  • 따라서 아키텍처 및 모듈 규칙이 효과적입니다.

  • 특히 클로즈드 소스 앱에서 작업하는 경우 에이전트가 알 수 없는 사항입니다.

  • 하지만 이 기능이 어디에 속하는지 처음부터 추론하는 데 시간을 낭비하지 않으려면 이해하는 것이 중요합니다.

  • 따라서 디자인 시스템 모듈에 속하는 UI 구성요소와 같은 항목을 넣을 수 있습니다. 또 다른 유용한 항목은 일반적인 코드 검토 실수나 항상 입력해야 하는 일반적인 항목입니다.

    # AGENTS.md
    
    - UI components belong in :core:designsystem
    
    - Never use java.util.Date;
      always use kotlinx.datetime
    
    ## General guidance
    - Avoid changing public API signatures. Anything under an `internal` directory
      is not part of the public API and may change freely.
    - The SDK code is written for Java 8.
  • 이 프로젝트에서는 kotlinx.datetime를 사용하는 것이 좋습니다.

  • 항상 적용되는 권장사항을 제공하고 싶었지만, 현실은 모델이 출시될 때마다 달라집니다.

  • 모델마다 추가 컨텍스트에 대한 동작이 다릅니다.

  • 예를 들어 Opus 4.6 시절에는 '절대 이렇게 하지 마세요'라는 문구가 대문자로 표시되는 경우가 많았습니다.

  • 그러다 Opus 5가 출시되었을 때 Anthropic은 '사실 대문자는 더 이상 효과가 없습니다.

  • 소문자를 사용하세요."

  • 이것이 제가 말씀드리고자 하는 바입니다. 계속해서 파악하고 있어야 합니다.

  • 하지만 보편적으로 적용되는 몇 가지 사항은 짧게 유지하는 것입니다.

  • 따라서 250줄 미만으로 유지하세요.

  • 다음은 의견이 조금 갈리는 부분입니다. 많은 분들이 이 방법을 좋아하시지만, 올해 2월에 발표된 연구에 따르면 에이전트가 자체 AGENTS.md를 수정하도록 허용하면 성능이 약 2~3% 저하된다고 합니다. 큰 문제는 아니지만,

  • 하지만 중요한 점은 비용이 20% 증가했다는 것입니다.

  • 에이전트가 자체 AGENTS.md를 작성하도록 허용했기 때문에 성능이 약간 저하되고 비용이 급증했습니다.

  • 이 문제를 해결하는 방법으로, 에이전트가 각 pull 요청이 끝날 때마다 회고를 작성하도록 한 다음, 팀이 회고에서 이를 모두 함께 읽고 어떤 수정 사항을 적용할지 결정할 수 있습니다. 에이전트를 사용하는 대규모 팀에서 작업하는 경우 이 파일이 중요한 팀 인프라의 핵심 요소가 되기 때문입니다.

  • 간단히 말씀드리면, 저희가 빌드한 Sideline 애플리케이션의 AGENTS.md입니다.

  • 여기에서 강조하고 싶은 점은 두 가지입니다.

  • 첫째, 명확하게 정의된 아키텍처를 사용하면 토큰과 컨텍스트 길이를 절약할 수 있습니다.

  • 기본적으로 에이전트가 코드베이스를 지속적으로 더 많이 살펴보고 더 많은 추론을 수행할 필요가 없습니다.

  • 이는 따라야 할 매우 명확하게 정의된 가이드라인을 제공합니다.

  • 두 번째로 강조하고 싶은 점은 특히 비공개 소스 애플리케이션에 관한 것입니다.

  • 물론 클로즈드 소스인 경우 에이전트가 코드베이스를 학습할 수 없습니다.

  • 따라서 이러한 경우에는 AGENTS.md를 지속적으로 정리, 검토, 미세 조정, 개선하는 데 추가 시간과 주기를 할애하는 것이 특히 중요합니다. 장기적으로 도움이 되기 때문입니다.

  • AGENTS.md에 모든 것을 넣어서는 안 된다면 에이전트나 모델 동작을 어떻게 변경해야 할까요?

  • 첫 번째는 후크입니다. 후크는 사용자가 AGENTS.md에 넣는 작업에 매우 유용합니다. 예를 들어 작성을 완료하면 항상 린터를 실행하는 것과 같은 작업입니다.

    // settings.json
    
    "hooks": {
      "Stop": [{
        "command": "./gradlew lintDebug"
      }]
    }
  • 이것이 유인 요소가 될 수 있습니다.

  • 후크는 에이전트가 구독할 수 있는 모든 이벤트를 노출하는 것으로, 생각할 수 있는 거의 모든 이벤트에 대한 후크가 있지만 주요 후크는 세션 시작, 세션 중지, 파일 읽기 및 쓰기입니다.

  • 따라서 AGENTS.md 하단에 '항상 린터를 실행해' 또는 '완료되었다고 말하기 전에 항상 테스트 모음을 실행해'라고 작성하는 대신, 결정론적 스크립트를 실행할 수 있는 중지 후크를 사용하면 AI의 약간의 무작위성을 제어하는 데 도움이 됩니다.

  • 또 다른 예로, 에이전트가 읽거나 쓸 수 없도록 하고 싶은 파일이 있는 경우, 즉 서버로 전송하고 싶지 않은 비밀 파일이 있거나 AGENTS.md 에이전트가 쓸 수 없도록 하고 싶은 경우 이를 위한 후크를 사용할 수 있습니다.

  • 읽기 또는 쓰기 후크가 있으면 수정하려는 파일이 전달되고 '아니요, 그렇게 할 수 없습니다'라고 반환할 수 있습니다.

  • 결정론을 추가하는 방법일 뿐입니다.

에이전트 스킬 및 아키텍처

  • 다음은 기술입니다.

  • 이제 AGENTS.md를 갈고리로 바꾸는 기술이 있습니다.

  • 그건 완전히 다른 문제입니다.

  • 하지만 스킬은 관련성이 있는 경우에만 맥락을 추가하는 방법입니다.

  • 따라서 AGENTS.md는 항상 관련성이 있는 항목에 사용됩니다.

  • 스킬은 특정 상황(주로 문서)과 관련된 작업에 사용됩니다.

  • 기술은 세 부분으로 구성됩니다. 이름, 설명(중요한 부분이며 1,024자로 제한됨), 본문이 있습니다.

    ---
    
    name: android-cli
    description: >
      Loaded into context (≤1024 chars)
    ---
    # Skill Body
  • 본문은 방대할 수 있으며, 다른 스크립트를 포함할 수도 있습니다. 이는 매우 일반적입니다.

  • 스킬을 사용하면 다양한 작업을 할 수 있습니다.

  • 예를 살펴보겠습니다.

  • Android CLI 설명입니다.

  • 다 읽을 필요는 없습니다.

  • Android CLI가 관련되는 경우를 설명하는 간단한 설명이라고 생각하면 됩니다.

  • 그리고 이것이 본문입니다.

  • 용량이 크기 때문에 이 모든 것을 항상 로드하고 싶지는 않습니다.

  • Android CLI를 사용하려고 할 때만 이 기능을 로드하고 싶으며, 스킬을 통해 이를 수행할 수 있습니다.

  • 하지만 설치할 기술을 신중하게 선택하는 것이 중요합니다.

  • 온라인에서 볼 수 있는 수백 가지 에이전트 엔지니어링 기술이 포함된 저장소를 무작정 설치해서는 안 됩니다.

  • 첫째, 이는 엄청난 보안 위험입니다.

  • 스킬에 무엇이 포함되어 있는지 알 수 없으며, 에이전트에게 어떤 작업이든 수행하도록 지시할 수 있습니다.

  • Android 기술 세트가 있지만, 검토해 본 결과 그런 내용은 없습니다.

  • 두 번째로, 100개의 설명에 1,000자를 곱하면 코딩을 시작하기도 전에 100,000자를 추가한 것입니다.

  • 이미 그 기간에 가까워지고 있는 거죠.

  • 따라서 Android 기술의 경우 모든 항목에 Android CLI 기본 기술을 설치하는 것이 좋습니다. 그러면 Android CLI에서 사용 가능한 기술을 검색하고 앱에 적합한 기술을 설치할 수 있습니다.

    > android init
    
    ✓ Installed base skill: android-cli
    
    # Audit & add skills only when needed:
    > android skills find compose
    > android skills add edge-to-edge
  • 또는 어떤 기술을 사용할 수 있는지 알고 있다면 프로젝트에 적합한 기술을 수동으로 추가할 수 있습니다. 예를 들어 Compose 기술이나 화면 전체 기술은 매우 보편적입니다.

  • 물론 기술을 감사하는 기술도 있습니다.

  • Claude Code에는 /skill-doctor가 있습니다. 이 기능은 활성화되지 않는 스킬을 포함하고 있는지 확인하고 알려주므로, 1, 000자 설명이 낭비되는 것을 방지할 수 있습니다.

  • Claude Code를 사용하지 않는 경우에도 거의 모든 에이전트 하네스에는 동일한 작업을 수행할 수 있는 통계 화면이나 감사 화면이 있습니다.

  • Android CLI 링크입니다.

  • 하지만 기술 목록 명령어가 있고 프로젝트에 Navigation 3이 있다고 가정해 보겠습니다.

    android skills list
    android skills add navigation-3
  • Navigation 3는 상당히 새로운 라이브러리이므로 아직 많은 학습이 이루어지지 않았습니다. Navigation 3 기술을 추가할 수 있습니다.

  • 죄송합니다.

  • 다음은 MCP입니다.

  • 하지만 Android CLI를 MCP 서버가 아닌 CLI로 만든 이유에 대한 질문을 자주 받습니다.

  • CLI는 AI가 존재하기 전, 마우스가 존재하기 전부터 구축되어 왔습니다. CLI는 빠르고 구성 가능하며 셸 세션에서 로컬로 실행되므로 사실상 무료로 실행할 수 있습니다.

  • 또한 Terminal Bench와 같은 벤치마크가 소프트웨어 엔지니어링에서 가장 큰 벤치마크가 되었기 때문에 모델 제작자들은 터미널 사용량을 적극적으로 늘려왔습니다. 그래서 요즘은 CLI를 사용하는 데 매우 능숙합니다.

  • 하지만 그렇다고 해서 MCP가 쓸모없다는 의미는 아닙니다.

  • MCP 서버는 이미 사용 중인 외부 서비스에 매우 유용하며, 특히 이미 MCP 서비스를 호스팅하고 있는 경우에 더욱 그렇습니다.

  • 바로 연결할 수 있으며, 설치 없이 에이전트에 추가 컨텍스트를 제공할 수 있습니다.

  • GitHub, Figma, Slack과 같은 서비스가 현재 MCP 서버를 노출하고 있습니다.

  • 그리고 항상 셸에서 실행하던 작업은 셸에 그대로 둘 수 있습니다. Android CLI를 통한 Android 명령어뿐만 아니라 Perfetto와 Gradle도 개발에 사용하는 모든 항목에 액세스할 수 있는 로컬에 두는 것이 좋습니다.

  • 저는 성능 관련 업무를 담당했습니다.

  • 저는 항상 Perfetto가 성능 문제를 해결하는 데 필요한 유일한 도구라고 말하곤 했습니다.

  • 하지만 라훌의 이전 강연에서 보았듯이 학습 곡선이 너무 가파릅니다.

  • AI가 실적 개선에 어떻게 도움이 되는지 살펴보겠습니다.

AI를 사용한 앱 성능 최적화

  • 감사합니다, 벤님.

  • 따라서 Sideline 애플리케이션이 작동하려면 초당 30프레임으로 실시간 실행되어야 합니다.

  • 이 Pixel 10 Pro Fold에서 볼 수 있듯이 초당 프레임 수는 약 20~22프레임만 달성하고 있습니다.

  • 이러한 프레임 드롭은 애플리케이션이 광고한 대로 작동하지 않는다는 것을 의미하므로 문제가 될 수 있습니다. 따라서 이 문제를 해결해야 합니다.

  • Android CLI에는 Android 프로파일러 명령어가 있습니다.

  • 이 요구사항을 코딩 에이전트에 추가하고 초당 30프레임 요구사항을 충족하도록 지시하면 두 가지 흥미로운 일이 발생합니다.

  • 첫 번째는 Android 프로파일러 명령어를 사용하여 수정사항을 찾는 것입니다.

  • 연결된 Pixel 10 Pro Fold 기기에서 시스템 트레이스를 기록한 결과, AI 스레드가 기기의 가장 느린 코어에서 실행되고 있는 것으로 확인되었습니다.

  • 두 번째는 Android 문서 검색을 사용했다는 점입니다. 흥미롭게도 명시적으로 요청하지 않았는데도 Performance Hint API의 공식 가이드를 가져왔습니다.

  • 에이전트가 학습한 것은 시스템 일정을 최적화하는 것이었고, 이를 통해 초당 30프레임 요구사항을 충족할 수 있었습니다.

  • 따라서 기본적으로 가이드에 따라 수정이 이루어졌습니다.

  • Android CLI의 핵심은 에이전트와 연결하여, 어떤 작업을 수행해야 하든 해당 도구에 익숙하지 않더라도 적절한 도구를 찾을 수 있도록 도와준다는 점입니다.

  • 실행해 보면 Sideline이 사용자의 초당 30프레임 요구사항을 충족하며 이제 Pixel 10 Pro Fold에서 작동하는 것을 확인할 수 있습니다.

작업 검증 루프 구현

  • 좋습니다.

  • 이제 루프를 사용하여 이 모든 것을 종합해 보겠습니다.

  • 에이전트에게 큰 변경사항을 구현해 달라고 요청하면 에이전트가 완료되었다고 알려주는 경험은 누구나 해봤을 것입니다.

  • 그리고 앱을 설치하고 직접 클릭하면서 버그를 입력하는 방식은 이제 그만해야 합니다.

  • 에이전트의 QA 테스터 역할을 멈추고 완료의 기준을 사전에 정의해야 합니다.

  • 예를 들어 보겠습니다.

  • 전체 프로젝트를 Nav3로 마이그레이션하려고 합니다. 그러면 에이전트가 사라지고 시간이 좀 걸리지만, 자신 있게 돌아와서 '마이그레이션이 완료되었습니다.

  • 내가 최고야."

  • 하지만 휴대전화를 회전하면 앱이 다운되고, 모든 슬라이드 전환을 놓치고, Gradle 파일을 정리하지 않습니다.

  • 이것은 지금 우리가 살고 있는 세상과 비슷합니다.

  • 이상적으로는 이렇게 할 필요가 없지만, 이것이 현재의 현실입니다.

  • 따라서 기대하는 바를 먼저 정의했어야 합니다. 그러면 에이전트가 모든 기준을 충족할 때까지 루프를 돌 수 있었을 것입니다.

  • 이것이 바로 확인 루프입니다.

  • 이러한 방식의 효과를 입증하는 강력한 데이터가 있습니다.

  • 이것이 Android Bench 2.0입니다. 발표 초반에 언급한 AI 벤치마크의 새 버전입니다.

  • 현재 합격률은 약 40%입니다.

  • 이러한 작업은 매우 어렵고, 매우 크고 현실적이지만, 그중 하나는 Nav2에서 Nav3로의 전환이며, 이는 현재 프로젝트에서 진행 중인 작업입니다.

  • Fable 5.1의 경우 통과율이 22%입니다. 이는 'Nav2를 Nav3으로 이전'과 같은 자연스러운 프롬프트 설정만으로 얻은 결과입니다.

  • 하지만 실패한 테스트 모음을 미리 제공하면, 즉 답을 제공하지 않고 Nav3로 마이그레이션하는 방법을 알려주지 않고 이미 실패한 테스트 모음을 제공하고 모든 작업이 완료되면 통과하도록 하면 전체 벤치마크의 통과율이 90%로 급증합니다.

  • 이를 통해 알 수 있는 것은 이러한 모델이 이제 우리가 생각할 수 있는 거의 모든 Android 작업을 구현할 수 있지만, '완료'가 무엇을 의미하는지 항상 알지는 못한다는 것입니다.

  • 따라서 실패하는 전체 테스트 모음을 미리 작성할 필요가 없습니다.

  • 검증 루프는 프롬프트 추가만큼 간단할 수 있습니다.

  • 예를 들어 UI에서 작업하는 경우 Compose 미리보기를 렌더링하고 Figma 사양과 일치하는지 확인한 후 결과를 표시하도록 요청할 수 있습니다.

  • "완료했습니다"라는 텍스트 응답을 그대로 받아들이는 대신 결과를 보여주고 완료되었음을 증명하라고 요청하면 실제로 효과가 있는 것 같습니다.

  • 비즈니스 로직을 작업 중인 경우 단위 테스트를 실행하도록 요청할 수 있습니다. 또는 처음에 살펴본 것처럼 비정상 종료 수정을 작업 중인 경우 원격 테스트 실험실을 통해 비정상 종료가 발생한 실제 기기에서 비정상 종료가 수정되었는지 확인하도록 요청할 수 있습니다.

  • 실제로 Claude Code에는 검증 루프를 빌드하는 데 도움이 되는 기능이 내장되어 있습니다.

  • 꼭 확인해 보세요.

  • Android 스튜디오에서 자체 에이전트를 사용하는 경우 Android 스튜디오는 작업 중인 항목에 따라 루프를 빌드할 수 있는 다양한 도구를 노출합니다.

  • 따라서 린터와 마찬가지로 모든 린트 오류가 수정될 때까지 중지하지 않도록 지시할 수 있습니다. 제가 정말 좋아하는 것은 여정입니다. 여정을 실행하고 여전히 작동하는지 확인하도록 요청할 수 있습니다.

  • 또는 여정을 작성한 경우(여정은 작성하기가 매우 쉽고 작업 중인 기능에 관한 프롬프트일 뿐임) 해당 여정을 실행하고 완료를 선언하기 전에 통과하도록 지시할 수 있습니다.

  • 하지만 여정을 실행하는 데는 시간이 다소 걸립니다.

  • 따라서 인증 루프의 수준을 계층화할 수도 있습니다.

  • 따라서 먼저 단위 테스트와 Compose 미리보기가 모두 올바르게 렌더링되는지 확인하도록 요청할 수 있습니다.

  • 이 테스트를 통과하면 연결된 테스트와 Android Journeys를 실행하고, 이 테스트를 통과한 경우에만 원격 기기 테스트 실험실과 같은 전체 테스트 모음을 실행하세요. 전체 테스트 모음은 몇 시간 정도 걸립니다.

  • 추가 정보를 제공하면 각 실행에서 각 단계를 수행하는 대신 계층별로 루프가 실행됩니다.

  • 모델은 자신감이 넘치니까요.

  • 따라서 항상 완료되었다고 생각하고 항상 첫 번째 시도에서 모든 테스트를 통과할 것이라고 생각합니다.

  • 그럼 Sideline에서 살펴보겠습니다.

Android XR 및 자율 버그 수정

  • 이 아이디어를 Sideline 애플리케이션에 적용해 보겠습니다. 곧 출시 예정인 XR 글라스를 위한 새로운 기능을 추가하는 방식으로 진행하겠습니다.

  • 아직 하드웨어가 없으므로 XR 에뮬레이터를 사용하고 코딩 에이전트에게 새 폼 팩터에 맞게 Sideline을 확장하도록 지시합니다.

  • 이때 에이전트에게 JVM 테스트, Compose 미리보기 테스트, 에뮬레이터 테스트 순으로 반복하도록 구체적으로 요청할 것입니다.

  • 각 루프는 이전 루프를 기반으로 빌드하도록 지시받습니다.

  • 이렇게 하면 첫 번째 루프와 두 번째 루프 사이에 6개의 Compose 미리보기 상태를 정의하는 데 사용되는 JVM 테스트가 있다는 것을 알 수 있습니다.

  • 물론 에뮬레이터가 호출되지 않으므로 매우 빠르게 실행됩니다.

  • 마찬가지로 루프 2와 루프 3 사이에서 긴 문자열과 같은 문제가 에뮬레이터를 실행하기 전에 표시되고 수정됩니다.

  • 마지막으로 에뮬레이터 루프가 실행되면 JVM 테스트와 Compose 미리보기에서 수정할 수 없었던 추가 버그를 찾습니다.

  • 하지만 기본적으로 각 루프를 통해 애플리케이션을 더욱 강화하고 있으며, 가장 빠르지만 가장 강력하지 않은 루프를 먼저 실행한 다음 가장 느리지만 가장 강력한 루프를 실행하고자 합니다.

  • 결과는 다음과 같습니다.

  • 이제 글라스에 스윙 유형과 라켓에서 나오는 공의 속도가 표시되므로 테니스를 치면서 공에서 눈을 떼지 않고도 실시간으로 게임플레이에 대한 피드백을 받을 수 있습니다.

  • 앞서 언급한 두 가지 Crashlytics 문제로 돌아가 보겠습니다.

  • 이 접근 방식이 효과가 있다는 것을 이미 검증했으므로 Claude Code에서 /schedule 명령어를 사용하여 이를 반복할 수 있으며, 원하는 주기를 설정할 수 있습니다. 이제 모든 버그를 수정하고 수정되었는지 검증하는 자가 복구 애플리케이션이 생겼습니다. 엔지니어가 검토하고 병합할 수 있도록 pull 요청으로 전송합니다.

핵심 내용 및 리소스

  • 됐습니다

  • 오늘 준비한 내용은 여기까지입니다.

  • 한 가지 핵심 사항을 꼽자면, 에이전트가 성공할 수 있는 환경을 구축하고 이를 오늘날 소프트웨어 개발과 버그를 처리하는 방식과 유사하게 취급하는 세상에 대해 생각하기 시작해야 한다는 것입니다.

  • 이렇게 하면 병렬 에이전트를 사용할 수 있습니다.

  • 온라인에서 이 주제에 관한 많은 조언을 찾을 수 있으며, 그중 많은 조언이 서로 상충될 것입니다.

  • 이는 빠르게 변화하는 환경의 현실입니다.

  • 따라서 프로젝트에 맞는 자체 평가를 작성하는 것이 가장 좋습니다.

  • 새로운 조언이나 모델이 나오면 실제로 측정하여 도움이 되는지 확인할 수 있습니다.

  • 물론 모든 것에는 기술이 필요합니다.

  • Claude Code에서 평가를 빌드하는 데 도움이 되는 스킬이 있습니다.

    /claude-api build-eval
  • 꼭 확인해 보세요.

  • 오늘은 Android Bench에 관해 이야기했습니다.

  • Android Bench는 Google의 평가 도구입니다.

  • 이는 상황이 개선되고 있는지 확인하는 방법입니다.

  • 이러한 도구를 빌드하면서 얻은 교훈을 듣고 같은 실수를 반복하지 않으려면 Android Bench 강연을 확인하세요.

  • 패널도 2개 있습니다.

  • 미국에 하나, 런던에 하나가 있습니다.

  • 커뮤니티에서 이러한 개념을 실제로 적용하는 방법에 대해 이야기하는 두 가지 동영상이 온라인에 게시될 예정입니다.

  • Android 개발자 커뮤니티 회원들이 패널로 참여하여 이를 업무에 어떻게 적용하고 있는지 이야기해 주실 예정입니다.

  • 여러분의 의견도 기다리고 있습니다.

  • Google은 실제로 도움이 되는 제품을 만들고 있는지 의견을 듣고 싶습니다.

  • 설문조사에 참여해 주세요.

  • 화면에 그대로 두겠습니다.

  • 그리고

  • 경청해 주셔서 감사합니다.

  • 감사합니다.

코드

코드 스니펫

'데모:Android CLI로 ANR 수정'의 07: 18에 나오는 C++ 스니펫
setenv("KMP_AFFINITY", "disabled", 1);
setenv("KMP_INIT_AT_FORK", "false", 1);
'컨텍스트 및 토큰 한도 관리'의 09:22에 나오는 JSON 스니펫
[
  {
    "role": "system",
    "content": "You are an expert Android engineering agent..."
  },
  {
    "role": "workspace_context",
    "content": { "project_root": "/workspace/android-app", "build_system": "Gradle (Kotlin DSL)", "target_sdk": 35 }
  },
  {
    "role": "available_tools",
    "content": [ { "name": "read_file" }, { "name": "edit_file" }, { "name": "bash" }, { "name": "skill_android_cli" } ]
  },
  {
    "role": "user",
    "content": "ProfileViewModelTest is failing when loading errors. Fix the ViewModel and verify with unit tests."
  },
  {
    "role": "assistant",
    "tool_calls": [ { "name": "read_file", "arguments": { "path": "app/src/main/.../ProfileViewModel.kt" } } ]
  },
  {
    "role": "tool",
    "content": "class ProfileViewModel(...) : ViewModel() { ... // full file contents + Gradle output appended here }"
  }
]
'컨텍스트 및 토큰 한도 관리'의 10:16에 있는 셸 스니펫
./gradlew assembleDebug --quiet
'Best practices for AGENTS.md'의 12:34에 있는 마크다운 스니펫
# AGENTS.md

- UI components belong in :core:designsystem

- Never use java.util.Date;
  always use kotlinx.datetime

## General guidance
- Avoid changing public API signatures. Anything under an `internal` directory
  is not part of the public API and may change freely.
- The SDK code is written for Java 8.
'Best practices for AGENTS.md'의 15:24에 있는 JSON 스니펫
// settings.json

"hooks": {
  "Stop": [{
    "command": "./gradlew lintDebug"
  }]
}
'에이전트 기술 및 아키텍처'의 16:44에 있는 마크다운 스니펫
---

name: android-cli
description: >
  Loaded into context (≤1024 chars)
---
# Skill Body
'에이전트 기술 및 아키텍처'의 17:52에 있는 셸 스니펫
> android init

✓ Installed base skill: android-cli

# Audit & add skills only when needed:
> android skills find compose
> android skills add edge-to-edge
'에이전트 기술 및 아키텍처'의 18:38에 있는 셸 스니펫
android skills list
android skills add navigation-3
'핵심 내용 및 리소스'의 29:32 지점 텍스트 스니펫
/claude-api build-eval