프로젝트 로그 #11: UI Tree vs 스크린샷 — 실제 성능 테스트
요약
기존의 스크린샷 및 OCR 기반 비전 시스템을 Android UI 계층 구조 트리(UI Tree) 방식으로 교체하여 성능을 테스트한 결과입니다. UI 트리 방식은 이미지 처리 과정이 생략되어 단순 작업에서 약 3배 빠른 속도를 보여주었습니다.
핵심 포인트
- UI 트리 방식은 XML 덤프와 텍스트 검색을 통해 OCR보다 훨씬 빠른 속도를 제공함
- 단순 작업에서 기존 시스템 대비 약 3배의 성능 향상을 확인
- 접근성 레이블이 없는 앱의 경우 UI 트리 방식이 작동하지 않는 한계가 있음
- UI 트리 우선 시도 후 실패 시 OCR로 전환하는 폴백(fallback) 전략이 필요함
Day 11. 기존의 비전 시스템 (vision system)과 새로운 시스템을 나란히 실행해 보았습니다. 결과는 놀라웠습니다.
어제 저는 비전 시스템을 다시 작성했습니다. 스크린샷 (Screenshots)과 템플릿 매칭 (template matching)은 순위가 밀려났습니다. Android의 UI 계층 구조 트리 (UI hierarchy tree)가 주력이 되었습니다.
오늘 저는 재작성 작업이 실제로 가치가 있었는지 확인하기 위해 동일한 작업에 대해 두 시스템을 나란히 실행했습니다.
테스트 (The Test)
저는 세 가지 동일한 작업을 설정하고 각각 두 번씩 실행했습니다. 한 번은 기존의 스크린샷 기반 시스템으로, 한 번은 새로운 UI 트리 (UI tree) 시스템으로 실행했습니다. 동일한 휴대폰, 동일한 앱, 동일한 명령어를 사용했습니다.
| 작업 (Task) | 기존 시스템 (Screenshots) | 새로운 시스템 (UI Tree) |
|---|---|---|
| WhatsApp 열기 | 3.2s | 2.1s |
| ... |
새로운 시스템은 단순한 작업에서 거의 3배 더 빠릅니다. 작업이 복잡해질수록 그 차이는 더 커집니다.
UI Tree가 승리하는 이유
기존 시스템은 다음 과정을 거쳐야 했습니다:
- 스크린샷 촬영 (1-2초)
- OCR 또는 템플릿 매칭 (template matching) 실행 (2-4초)
- 결과 파싱 (Parse)
- 좌표 계산
새로운 시스템은:
- XML 파일을 덤프 (dump)하는 하나의 ADB 명령어를 실행합니다.
- XML에서 일치하는 요소를 검색합니다.
- 요소의 경계값 (bounds)에서 정확한 좌표를 읽습니다.
이미지 처리도, OCR 로딩 시간도, 템플릿 매칭 루프도 없습니다. 그저 구조화된 문서에 대한 텍스트 검색일 뿐입니다.
어제 제가 잘못 알고 있었던 것
저는 UI 트리 (UI tree)가 0.51초 정도 걸린다고 말했습니다. 실제로 사용해 보니 더 빨랐습니다. 덤프 (dump)와 풀 (pull)을 합쳐 약 0.30.7초 정도 걸립니다. XML 파일은 크기가 작습니다 (보통 100KB 미만). 파싱 (parsing)은 즉각적입니다.
하지만 제가 예상하지 못한 부분이 하나 있었습니다. UI 트리가 너무 상세하다는 점입니다. 단일 화면에 200개 이상의 요소가 있을 수 있습니다. content-desc나 text를 통해 이 모든 요소를 검색하는 데 Python으로 몇 밀리초 (milliseconds)가 소요됩니다. 무시할 수 있는 수준이지만, 휴대폰 CPU에서의 XML 파싱이 공짜는 아니라는 점을 상기시켜 줍니다.
여전히 어려운 점
UI 트리 접근 방식에는 사각지대가 있습니다. 모든 앱이 요소에 레이블 (label)을 잘 붙여두지는 않는다는 점입니다.
WhatsApp은 훌륭합니다. 전송 버튼에는 content-desc="Send message"가 있고, 뒤로 가기 버튼에는 content-desc="Back"이 있으며, 검색 버튼에는 content-desc="Search"가 있습니다. 이것들은 스크린 리더 (screen readers)가 사용하는 접근성 레이블 (accessibility labels)이며, WhatsApp의 개발자들은 실제로 여기에 공을 들였습니다.
하지만 저는 로컬 뱅킹 앱을 테스트해 보았습니다. 로그인 버튼은요? content-desc="". 비밀번호 입력 필드는요? content-desc="". 아무것도 없습니다. 레이블도 없고, 텍스트도 없습니다. 식별 정보 없이 android.widget.Button과 같은 일반적인 클래스 이름 (class names)만 있을 뿐입니다.
그런 앱들의 경우, UI 트리 (UI tree)는 무용지물입니다. 저는 여전히 폴백 (fallback) 수단으로 OCR이 필요합니다. 통합된 find_target() 함수는 이를 우아하게 처리합니다. 먼저 UI 트리를 시도하고, 아무것도 발견되지 않으면 OCR과 템플릿 매칭 (template matching)으로 전환합니다.
접근성의 격차 (The Accessibility Divide)
이 프로젝트를 통해 예상치 못하게 배운 점이 있습니다. 자본력이 있는 앱들 (WhatsApp, Google 앱, Slack)은 뛰어난 접근성 레이블 (accessibility labels)을 갖추고 있다는 것입니다. 그들은 스크린 리더로 앱을 사용할 수 있게 만드는 데 투자했고, 그 투자가 의도치 않게 제 에이전트 (agent)가 자동화하기 쉽게 만들어 주었습니다.
규모가 작은 앱, 로컬 앱, 뱅킹 앱들은 접근성 레이블이 전혀 없는 경우가 많습니다. 제 에이전트가 앱을 자동화할 수 있는 능력은 해당 앱의 개발자들이 장애인 사용자를 배려했는지 여부에 달려 있습니다.
이는 냉혹한 깨달음입니다. 시각 장애인을 차단하는 것과 동일한 방치가 AI 에이전트 또한 차단합니다. 접근성 (Accessibility)은 단순히 포용성에 관한 것이 아니라, 소프트웨어를 기계가 읽을 수 있게 (machine-readable) 만드는 것에 관한 것입니다. 그리고 개발자들이 이를 건너뛸 때, 인간과 AI 모두가 피해를 입습니다.
다음 단계 (Day 12)
- 레이블이 없는 요소들을 위한 폴백 매핑 (fallback mapping) 구축:
content-desc가 비어 있는 경우, 클래스 + 위치 + 주변의 레이블된 요소들을 통해 요소를 식별하도록 시도 - WhatsApp을 넘어 더 많은 앱 테스트 — 뱅킹 앱, 설정, Chrome
- 어떤 앱이 "에이전트 친화적 (agent-friendly)"이고 어떤 앱이 그렇지 않은지 로깅 시작
리포지토리 (The Repo)
👉 github.com/Dexter2344/phone-agent
vision.py v4가 배포되었습니다. agent.py v10이 배포되었습니다. 통합된 타겟 파인더 (target finder)는 한 번의 호출로 UI 트리, OCR, 템플릿 매칭을 처리합니다.
오늘은 11일 차입니다. 재작성(rewrite)할 가치가 충분했습니다. 에이전트(agent)는 더 빨라졌고, 더 신뢰할 수 있으며, 더 이상 단일 기기에 종속되지 않습니다. 하지만 새로운 문제를 발견했습니다. 에이전트는 접근성(accessibility)을 고려하여 구축된 앱들만 자동화할 수 있다는 점입니다. 그것이 다음에 넘어야 할 벽입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기