android-studio

2 개의 포스트

line

AI 에이전트를 위한 Android CLI: 대규모 모바일 개발 환경에 적용하기 (새 탭에서 열림)

LINE Android처럼 수백 개의 Gradle 모듈과 대규모 코드를 가진 저장소에서는 단순한 `grep`·`glob` 검색만으로 AI 에이전트가 의미론적 질문에 답하기 어렵고, 불필요한 결과와 재시도로 토큰 비용이 급증합니다. LINE 개발팀은 Android CLI를 문서 검색과 Android Studio 연동의 기반으로 활용하되, 고정된 바이너리·래퍼·스킬·프롬프트를 조합해 보안, 환경 일관성, 오류 처리, 토큰 효율성을 보완하고 있습니다. 핵심은 CLI를 에이전트에 그대로 노출하지 않고, 저장소 규모와 조직 환경에 맞게 통제된 인터페이스로 제공하는 것입니다. ## 대규모 Android 저장소에서 AI 에이전트가 겪는 문제 - 수백 개의 Gradle 모듈과 방대한 코드 때문에 검색 한 번에도 지나치게 많은 결과가 반환됩니다. - 검색 결과가 에이전트 컨텍스트에 포함되면서 토큰과 비용이 빠르게 증가합니다. - 텍스트 검색만으로는 다음과 같은 의미론적 질문에 정확히 답하기 어렵습니다. - 특정 심볼의 선언 위치 - 심볼의 실제 참조 위치 - IDE가 판단하는 사용되지 않는 코드나 경고 - 의존성 내부 심볼의 위치 - 관련 없는 결과를 바탕으로 에이전트가 반복 검색과 재시도를 수행하면서 비효율이 커집니다. - 따라서 Android CLI를 그대로 적용하기보다는 래퍼, 스킬, 프롬프트를 통한 보완이 필요합니다. ## 문서 검색을 Android CLI로 전환 - Android CLI는 빌드·배포, SDK 관리, 환경 진단, 공식 문서 검색, Android Studio 연동 등을 제공합니다. - 첫 적용 대상은 Android, Jetpack Compose, AndroidX, Firebase 등의 공식 문서 검색이었습니다. - 모델의 사전 학습 지식은 최신 API 변경을 반영하지 못할 수 있어 잘못된 시그니처를 생성하는 환각이 발생할 수 있습니다. - 최신 Android Knowledge Base를 직접 참조하면 문서의 권위와 최신성을 확보할 수 있습니다. - 기존에는 Google Cloud Knowledge MCP 서버를 사용했지만 다음 운영 부담이 있었습니다. - 개발자별 Google Cloud API 인증 설정 - 인증 프록시 운영 - API 할당량 제한 대응 로직 유지 - Android CLI의 `docs` 명령은 다음 두 단계로 사용됩니다. - `docs search`: 키워드로 공식 문서 검색 - `docs fetch`: 검색 결과의 KB URL로 문서 본문 조회 - 이 기능은 `get-android-dev-knowledge` 스킬로 에이전트에 제공됩니다. - 기존 MCP 방식과 비교해 인증, 프록시, 할당량 처리 인프라를 제거하고 더 적은 토큰으로 최신 문서를 참조할 수 있습니다. ## CLI 바이너리를 저장소에 번들링한 이유 LINE 팀은 전역 설치된 `android` 명령 대신 `.agents/tools/android-cli/android`처럼 저장소 내부의 고정 경로에 바이너리를 포함했습니다. ### 환경 파편화 방지 - 개발자마다 CLI 버전, 설치 위치, 운영체제가 달라지는 문제를 줄입니다. - 저장소를 클론하면 동일한 버전을 사용할 수 있습니다. - 개발자 장비뿐 아니라 CI와 AI 에이전트 실행 호스트에서도 동일한 환경을 보장합니다. ### 보안 정책과 래퍼 적용 - Android CLI는 호출 과정에서 일부 데이터를 수집할 수 있습니다. - 이를 막으려면 호출마다 `--no-metrics` 인자를 지정해야 합니다. - 에이전트가 해당 인자를 누락할 수 있으므로 모든 호출을 통과시키는 래퍼에서 강제하는 방식이 안전합니다. - 래퍼가 실제 바이너리를 안정적으로 찾으려면 바이너리 위치가 고정되어 있어야 하므로 저장소 번들링이 유리합니다. - 대규모 저장소에 이미 `git-lfs`가 적용되어 있어 바이너리 포함 비용도 감당할 수 있었습니다. ## `--no-metrics` 관련 버그와 오류 출력 개선 - Android CLI 1.0 도입 과정에서 정보 수집 기능이 `--no-metrics` 처리 전에 초기화되는 버그가 발견되었습니다. - 이 때문에 메트릭 수집을 비활성화해도 `~/.android/cli`에 쓰기를 시도할 수 있습니다. - 샌드박스나 파일 시스템 권한으로 쓰기가 차단되면 여러 페이지의 Java 스택 트레이스가 출력됩니다. - 장황한 스택 트레이스는 에이전트 컨텍스트를 불필요하게 차지하고 문제 해결도 어렵게 만듭니다. - 래퍼는 CLI 실행 전에 다음을 수행합니다. - `~/.android/cli` 디렉터리 생성 시도 - 임시 파일을 만들어 쓰기 권한 확인 - 쓰기가 막히면 한 줄짜리 파싱 가능한 오류 출력 - 에이전트는 이제 긴 예외 대신 “쓰기 권한을 부여한 뒤 재시도하라”는 원인과 조치를 직접 전달받습니다. - 반복적으로 발생하는 오류를 에이전트가 처리하기 쉬운 구조화된 메시지로 변환하는 방식은 이후 Android Studio 연동에도 적용됩니다. ## Android Studio 연동의 의미론적 기능 Android CLI 1.0에서는 실행 중인 Android Studio와 연결해 IDE 수준의 분석을 명령줄에서 수행할 수 있게 되었습니다. - `studio check` - Android Studio 실행 여부를 확인합니다. - 대상 프로젝트가 열려 있는지 확인합니다. - 프로젝트 인덱싱이 완료되었는지 확인합니다. - 다른 Studio 기능을 사용하기 위한 전제 조건입니다. - `studio analyze-file` - 빌드하지 않고 단일 파일에 IDE 인스펙션을 적용합니다. - 에러와 경고를 반환합니다. - `is never used`처럼 단순한 `grep`으로 파악하기 어려운 의미론적 문제도 찾을 수 있습니다. - `studio find-declaration` - 심볼의 선언 위치를 찾습니다. - 프로젝트 코드뿐 아니라 `.aar`, `.jar` 의존성 내부도 검색합니다. - `studio find-usages` - 특정 심볼이 사용된 위치를 찾습니다. - `studio render-compose-preview` - `@Preview`가 적용된 Jetpack Compose 화면을 PNG 이미지로 렌더링합니다. ## CLI를 래퍼와 스킬로 감싼 설계 - Android Studio 기능도 CLI를 에이전트에 직접 노출하지 않고 얇은 래퍼와 스킬을 통해 제공합니다. - 가장 먼저 `studio-check` 스킬을 만들었습니다. - 에이전트가 CLI의 복잡한 입출력과 환경 전제 조건을 직접 처리하지 않도록 하는 것이 목적입니다. - 래퍼는 권한 확인, 실행 환경 검증, 오류 메시지 정규화 같은 공통 처리를 담당합니다. - 스킬은 에이전트가 언제 어떤 기능을 사용해야 하는지 안내하는 고수준 인터페이스 역할을 합니다. 실무적으로는 대규모 저장소에서 Android CLI를 전역 도구로 배포하기보다, 버전을 고정한 바이너리를 저장소에 포함하고 모든 호출을 래퍼로 통제하는 방식을 추천할 수 있습니다. 특히 검색 결과를 무작정 늘리는 대신 문서 검색, 심볼 탐색, IDE 분석처럼 목적에 맞는 의미론적 명령을 스킬로 제공하면 토큰 낭비와 에이전트의 반복 작업을 크게 줄일 수 있습니다.

figma

피그마의 새로운 SVG 내 (새 탭에서 열림)

Figma는 SVG에 정보를 최대한 많이 담는 방식보다, 단순하고 작은 마크업이 다양한 도구와 더 잘 호환된다는 결론에 도달했다. 새 SVG Exporter는 불필요한 구조와 중복을 제거하고, 기본 도형과 간결한 경로를 사용해 파일 크기와 가독성, 호환성을 개선했다. 특히 Android Studio처럼 SVG 일부 기능만 지원하는 도구에서도 더 안정적으로 가져올 수 있도록 설계했다. ## SVG가 도구마다 다르게 렌더링되는 이유 - SVG는 JPG·PNG와 달리 픽셀 이미지가 아니라 화면에 이미지를 그리는 명령어로 구성된 벡터 형식이다. - 확대해도 선명하기 때문에 로고, 아이콘, 반응형 웹 자산에 적합하다. - 하지만 SVG 마크업을 픽셀로 변환하는 표준 렌더링 방식은 없다. - 각 디자인 도구와 개발 도구가 자체 SVG 파서와 렌더러를 사용하며, SVG 사양 전체가 복잡해 많은 도구가 일부 기능만 지원한다. - 예를 들어 `defs`에 정의한 요소를 `use`로 재사용하는 기능은 Android Studio에서 대부분 제대로 지원되지 않는다. - Figma의 기존 SVG는 복잡한 그룹, 마스크, 클리핑 패스, 중복 참조 때문에 파일이 크고 사람이 읽기 어려웠다. - 사용자들은 SVGO, svgito 같은 후처리 도구를 사용하거나 SVG를 직접 정리해야 했다. ## “모든 정보를 보존하자”는 기존 접근의 한계 - Figma는 디자인 도구 간 SVG 교환이 보편적인 데이터 형식이 되기를 기대했다. - 그래서 다른 도구가 디자인을 정확하게 가져갈 수 있도록 SVG에 가능한 한 많은 구조적 정보를 포함했다. - 그러나 실제 생태계에서는 도구마다 지원 범위와 구현 품질이 달랐다. - 결과적으로 더 많은 정보가 정확성을 보장하기보다, 일부 도구에서는 import 실패와 파일 비대화의 원인이 됐다. - 새 Exporter는 이상적인 상호 운용성보다 실제 사용 환경에서의 호환성과 단순성을 우선한다. ## 기본 도형을 SVG 프리미티브로 표현 - 단순한 사각형과 원을 복잡한 `path` 명령어로 표현하지 않고 SVG의 기본 도형 요소를 사용한다. - 기존 방식: ```xml <path d="M0 100V0H100V100H0Z"/> ``` - 변경된 방식: ```xml <rect width="100" height="100"/> ``` - `rect`, `circle` 같은 요소는 의미가 명확해 사람이 읽고 수정하기 쉽다. - 마크업 길이도 줄어들어 파일 크기와 처리 부담을 낮춘다. ## 내부선과 외부선 처리 방식 개선 - SVG의 기본 stroke는 도형 경계의 중앙에만 그려진다. - 디자인 도구에서 지원하는 내부선(inside stroke)이나 외부선(outside stroke)을 표현하려면 별도 우회가 필요하다. - 기존 Figma 방식은 stroke 폭을 두 배로 늘린 뒤 `mask`로 불필요한 절반을 숨겼다. - 이 방식은 `mask`, 중복 경로, 추가 참조를 만들어 SVG를 복잡하게 만들었다. - 새 방식은 도형의 좌표 자체를 조정한다. - 내부선은 도형의 경계를 안쪽으로 이동한 뒤 원래 stroke 폭을 사용한다. - 외부선도 시각적 결과에 맞도록 경로 위치를 조정한다. - 따라서 마스크 없이도 유사한 시각적 결과를 얻고 마크업을 크게 줄일 수 있다. ## 불필요한 마크업 제거 - 렌더링에 직접 영향을 주지 않는 요소와 속성을 제거한다. - `title` - `desc` - 불필요한 `g` - `id` - `version` - 클리핑도 항상 출력하지 않고 실제로 필요할 때만 생성한다. - 기존에는 클리핑 여부와 관계없이 프레임에 `clipPath`를 넣었지만, 새 방식은 효과가 없는 마크업을 생략한다. - `defs`에 요소를 정의하고 `use`로 참조하던 구조도 가능한 경우 인라인 요소로 바꾼다. - 중복 제거 효과는 일부 포기하지만, 여러 SVG importer가 더 안정적으로 처리할 수 있고 구조가 훨씬 단순해진다. ## 최종 결과 - 작은 검은색 사각형과 회색 내부선을 표현하는 기존 SVG는 여러 단계의 그룹, 클리핑 패스, 마스크, `use` 참조로 구성됐다. - 새 SVG는 다음처럼 단일 `rect` 요소와 속성만으로 표현된다. ```xml <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <rect x="15" y="15" width="70" height="70" fill="black" stroke="#CCCCCC" stroke-width="10"/> </svg> ``` - 결과적으로 SVG가 더 작고, 읽기 쉽고, 직접 수정하기 쉬워졌다. - Android Studio 같은 제한적인 SVG 지원 환경과의 호환성도 개선됐다. Figma의 사례는 SVG를 생성할 때 정보와 추상화를 무조건 많이 보존하기보다, 실제 소비 도구가 안정적으로 이해할 수 있는 최소한의 마크업을 사용하는 것이 실용적임을 보여준다. SVG를 배포할 때는 기본 도형, 단순한 경로, 필요한 경우에만 사용하는 마스크·클리핑을 우선하고, SVGO 같은 최적화 도구로 후처리하는 것도 유용하다.