5.6 KiB
title, category, date
| title | category | date |
|---|---|---|
| DevLog @ 2025.04.22 | DevLog | 2025-04-22 |
낮 시간의 일기
안녕하세요, @LemonNeko 입니다. 이번에는 제가 DevLog 작성에 참여해서 개발 이야기를 나눠 보려 합니다.
두 달 전, 저희는 AIRI 의 웹 인터페이스를 Electron 으로 포팅했습니다 #7 (지금은 Tauri 로 다시 리팩터링됐지만요 🤣 #90). 덕분에 화면 위에 데스크톱 펫처럼 띄울 수 있게 됐죠. 그와 동시에 AIRI 가 휴대폰을 쓸 수 있게 하면 어떨까 하는 생각이 있었는데, 계속 미뤄 두고 있었습니다.
지난 주말(2025.04.20), 시간을 좀 내서 ADB 와 상호작용할 수 있는 MCP 서버 데모 airi-android 를 만들었습니다. AIRI 에게 기본적인 모바일 조작 능력을 주는 것이죠 (사실 대부분의 LLM 이 이걸 통해 휴대폰을 조작할 수 있습니다). 데모 영상입니다:
Docker 이미지로도 패키징해서 MCP 서버 목록에 등록했습니다. 관심 있으시면 편하게 써 보세요.
사실 처음 생각은 Tool Calling 코드를 좀 짜고 프롬프트를 수정해서, LLM 에게 "이 도구들로 휴대폰을 조작할 수 있다"고 알려 주면 끝이라는 것이었습니다. 그런데 요즘 MCP 가 너무 유행이라 FOMO 가 와서 MCP 로 구현하기로 했습니다.
MCP 서버를 쓰려면 먼저 MCP 가 뭔지 이해해야 했습니다 (물론 저는 실전 전에 이론부터 파는 타입은 아니라서, 일단 뛰어들어 Cursor 에게 써 보게 하는 쪽을 선호합니다). MCP(Model Context Protocol)는 애플리케이션이 LLM 에게 컨텍스트를 제공하는 방식을 표준화하려는 프로토콜입니다. 몇 가지 핵심 개념을 제안하죠:
- Resources: 서버가 데이터와 콘텐츠를 LLM 에게 컨텍스트로 제공할 수 있습니다.
- Prompts: 재사용 가능한 프롬프트 템플릿과 워크플로를 만듭니다.
- Tools: LLM 이 여러분의 서버를 통해 동작을 수행할 수 있게 합니다.
아, 리소스 — 이건 압니다! Ruby on Rails 에서 사용자는 일종의 리소스죠. 그럼 ADB 기기도 리소스일까요? LLM 이 연결된 기기 목록을 보게 하려면 이렇게 쓰면 될까요:
from mcp.server.fastmcp import FastMCP
from ppadb.client import Client
mcp = FastMCP("airi-android")
adb_client = Client()
@mcp.resource("adb://devices")
def get_devices():
return adb_client.devices()
틀렸습니다! Cursor 에게 기기 목록을 가져오라고 했더니 어떻게 해야 할지 모르더군요. 어떤 기기가 연결됐는지 능동적으로 확인하고 싶다고 했으니, 이건 도구(tool)입니다. 음, 제가 완전히 이해하지 못했던 모양입니다.
LLM 이 휴대폰을 조작하게 하는 정확한 방법은 아직 못 찾았고, 여러분과 함께 이야기해 보고 싶습니다. 다만 Cursor 는 이렇게 동작합니다:
- 스크린샷 기능으로 휴대폰 화면에 무엇이 있는지 대략 파악합니다.
- UI 자동화 도구로 조작하려는 요소의 정확한 위치를 얻습니다.
- 클릭하거나 스와이프합니다.
- 위 단계를 반복합니다.
지금까지는 잘 동작하는 것 같은데, 작은 의문이 몇 가지 있습니다:
- 화면에 UI 컴포넌트가 아니라 그래픽 API 로 직접 그리는 게임이 떠 있다면, UI 자동화 도구는 요소 위치를 얻을 수 없어 조작도 못 합니다.
- LLM 응답에는 길이 제한이 있습니다. 조작이 복잡하면 단계별로 나눠서 끝내야 할 텐데, airi-factorio 처럼 각 단계가 끝날 때마다 자동으로 알려서 다음 단계를 트리거할 수 있을까요?
- 어떤 앱은 화려한 애니메이션이 있어서, 조작 직후 스크린샷을 찍으면 결과가 안 보일 수 있습니다. 조작 후 잠시 기다렸다 찍어야 할까요, 아니면 아예 화면 녹화를 써야 할까요?
- AI 가 휴대폰을 직접 조작하게 하는 것의 보안은 어떨까요? 어떤 위험이 있을까요?
몇 가지 소회입니다.
AI 와 작업하면서 사람과 함께 코딩하는 기분이 든 건 이번이 처음입니다. 제 목표가 "AI 가 내 도구를 쓰게 하는 것"이어서 AI 가 제 클라이언트가 되어 버린 탓인지도 모르겠습니다. 저는 계속 AI 의 피드백에 맞춰 코드를 고쳐야 했으니까요. 동시에 AI 는 제 동료이기도 했습니다. 함께 고민하고 문제를 풀어야 했거든요. 이 스크린샷을 보세요. 정말 그렇게 보이지 않나요?
개발하면서 작은 요령도 배웠습니다. 예를 들어 명령줄로 Android 에뮬레이터를 띄우면 Android Studio 를 열 필요가 없어서 메모리 부담이 크게 줄어듭니다.
emulator -avd Pixel_6_Pro_API_34
다음에는 AIRI 데스크톱 펫을 MCP 서버에 연결해서 뭘 하고 싶어 하는지 보려고 합니다. 어쩌면 지금 ReLU 가 하는 것처럼 Telegram 을 열고 우리와 대화할지도 모르죠. 다만 Telegram API 를 쓰지 않고서요.
다소 두서없고 알맹이가 부족했을지 모를 DevLog 를 읽어 주셔서 감사합니다. 다음에 또 만나요!
