포스트

PreAct: 반복 작업에서 점점 빨라지는 컴퓨터 사용 에이전트

목차

  1. 개요
  2. 방법론
  3. 주요 결과
  4. 한계와 주의사항
  5. 결론
  6. Reference

개요

컴퓨터 사용 에이전트(Computer-Using Agent, CUA)는 API가 아니라 화면을 읽고 클릭하고 입력하면서 실제 소프트웨어를 조작한다. 그런데 이들은 매번 작업을 처음부터 푼다. 같은 작업을 다시 시키면 화면을 다시 읽고, 모든 탭을 다시 추론하며, 전체 비용을 또 한 번 지불한다.

이 논문이 제시하는 PreAct는 같은 작업을 반복할 때 에이전트가 점점 빨라지도록 만든다. 작업을 처음 성공하면 PreAct는 그 실행 과정을 작은 상태 머신 프로그램으로 컴파일한다. 상태(state)는 화면을 검사하고, 전이(transition)는 행동을 수행하는 구조다. 이후 같은 작업이 오면 에이전트를 호출하는 대신 이 프로그램을 직접 재생한다.

재생은 처음부터 끝까지 8.5배에서 13배 빠르며, 단계별 언어 모델 호출이 전혀 없다. 다만 재생은 맹목적이지 않다. 각 단계에서 PreAct는 화면이 프로그램이 기대하는 상태와 일치하는지 먼저 확인한 뒤에만 행동하고, 뭔가 어긋나면 즉시 전체 에이전트에게 제어권을 넘긴다.

AndroidWorld의 “Emilia Gonzalez 연락처 추가” 같은 작업을 떠올려 보면 차이가 분명해진다. 일반 CUA는 매 실행마다 스크린샷을 읽고 어디를 누를지 추론하면서 대여섯 차례의 시각-언어 추론을 반복한다. 화면도, 탭 순서도 그대로인데 다시 실행할 수 있는 어떤 것도 남기지 않았기 때문에 두 번째에도 전체 비용을 낸다. PreAct의 출발점은 사람이 일하는 방식이다. 처음에는 메뉴를 더듬으며 느리지만, 몇 번 반복하면 거의 자동에 가까운 루틴이 된다.

이 글에서 다루는 논문은 Pine AI의 Bojie Li가 작성한 “PreAct: Computer-Using Agents that Get Faster on Repeated Tasks”이다.

방법론

PreAct는 하나의 규율을 두 시점에 적용한다. 먼저 예측하고, 그 예측을 신뢰하기 전에 실시간 화면과 대조한다. 실행 시점에는 재생기가 각 상태의 술어(predicate)를 검사한 뒤에야 전이를 수행한다. 저장 시점에는 같은 검사를 새로 컴파일된 프로그램 전체에 한 번 더 적용해, 통과한 프로그램만 코퍼스에 들인다.

상태 머신 프로그램이라는 표현

PreAct가 저장하는 것은 나중에 그대로 실행하는 바로 그 프로그램이다. 연락처 추가 작업을 예로 들면, 컴파일된 프로그램은 작은 그래프다. 각 상태는 검증 술어를 갖는다. 연락처 폼이 열려 있다, 이름 필드에 입력한 값이 보인다 같은 화면 조건이다. 각 전이는 행동을 갖는다. Create contact를 탭한다, 이름을 입력한다 같은 동작이다.

실행 중 입력된 구체적 값(이름, 성, 전화번호)은 파라미터로 추출되어 메타데이터에 기록된다. 따라서 단일 프로그램이 파라미터를 새 값에 바인딩하는 것만으로 모든 “연락처 추가” 요청을 처리한다.

형식적으로 프로그램은 튜플 P = (S, T, M, V)이다. S는 상태 집합(id, 설명, 검증 술어), T는 전이 집합(각 전이는 행동 a를 실행해 상태 si에서 sj로 이동), M은 메타데이터(작업 설명, 앱 컨텍스트, 파라미터 스키마, 어떤 작업 패밀리에 속하는지 식별하는 dedup 시그니처), V는 질의응답 작업을 위한 데이터 추출 술어다.

이 그래프 형식은 평탄한(flat) 스크립트가 줄 수 없는 세 가지를 제공한다.

속성설명
상태별 검증행동이 의도한 효과를 내지 못했을 때 즉시 알 수 있다
분기한 상태가 술어에 따라 선택되는 여러 전이를 가질 수 있다
제자리 확장전체를 재생성하지 않고 새 상태와 전이를 끼워 넣을 수 있다

선택-재생-폴백-검증 루프

목표 T가 주어지면 하네스는 다음 루프를 돈다.

먼저 프로그램 선택기(Program Selector)가 코퍼스를 T로 질의해 후보 프로그램 P 또는 “후보 없음”을 반환한다. P가 있으면 재생기(Replayer)가 그래프를 따라 걸으며 각 상태의 술어를 실시간 화면과 대조하고 각 전이의 행동을 실행한다. 이 경로에서는 언어 모델 호출 없이 수 초 만에 작업이 끝난다.

술어가 거짓이거나 행동에 오류가 나면 하네스는 전체 에이전트(CUA)에게 제어권을 넘긴다. CUA는 실시간 화면에서 작업을 이어 끝내고 새로운 trace를 기록한다. 성공한 trace는 새 프로그램 P로 컴파일되고, 저장 전 검증 게이트를 통과해야만 코퍼스에 들어간다. 같은 dedup 시그니처를 가진 기존 프로그램이 있으면 교체된다.

알고리즘은 코퍼스에 대한 유일한 부작용을 UPSERT 호출 하나로 제한한다. 이중 술어(재생 성공이면서 평가 점수 통과)로 게이트되므로, 코퍼스는 기대값 측면에서 단조 증가(monotonic)한다. 중요한 차이는 맹목적 record-and-replay와의 대비다. RPA 스크립트나 캐시된 행동 trace는 화면이 그대로일 것이라 믿고 저장된 행동을 순서대로 발사한다. PreAct는 각 상태의 검증 술어를 실시간 화면과 먼저 대조한 뒤에만 전이를 수행한다.

저장 전 검증 게이트

게이트는 실행 시점의 검사를 프로그램 전체에 한 번 더 적용한 것이다. 에이전트가 성공해 trace가 후보 P로 컴파일되면, 하네스는 그것을 곧바로 신뢰하지 않는다. 환경을 작업의 깨끗한 초기 상태로 리셋하고, 그곳에서 P를 재생하며, 벤치마크 자체의 평가기에게 작업이 실제로 해결되었는지 묻는다. 재생이 오류 없이 종료 상태에 도달했고 평가기가 통과 점수를 줄 때만 P가 저장된다.

두 절반 모두 필요하다. 평가기 통과만 확인하면, 백엔드가 삼켜 버린 잘못된 행동이 아무 효과 없이 지나갔는데도 이전 단계의 상태가 우연히 통과 조건을 유지하는 경우를 걸러내지 못한다. 더 중요한 실패 모드는 깨끗하게 재생됐는데도 통과하지 못하는 경우다. 프로그램이 모든 행동을 100퍼센트 커버리지로 실행하는데도 최종 상태가 평가기를 만족시키지 못하는 상황이다. 연락처 폼을 채우고 Save를 눌렀지만 오래된 필드 때문에 실제로는 연락처가 기록되지 않는 식이다.

논문은 이를 cov=100%/score=0 손실 재생(lossy replay)이라 부르며, 게이트가 정확히 이것을 잡아야 한다고 강조한다. 다만 이 설계에는 한 가지 가정이 깔려 있다. 게이트가 프로그램을 검사가 아니라 재실행으로 검증하므로, 작업의 행동이 한 번 더 수행된다. 모든 작업이 스크립트된 환경 리셋에서 시작하는 벤치마크에서는 안전하지만, 메시지 전송이나 결제처럼 되돌릴 수 없는 부작용이 있는 작업에는 부작용 없는 검증 경로가 필요하다.

주요 결과

세 가지 플랫폼에서 평가했다. 폰은 AndroidWorld, 데스크톱은 OSWorld, 웹은 WebArena다.

벤치마크서브셋CUA 모델
AndroidWorldofficial-15 (15개 작업, 8개 앱 도메인)Gemini 3 Flash
OSWorldtest_tiny (6개 작업)Claude Sonnet 4.6
WebArenashopping_admin (12개 작업)Claude Sonnet 4.6

프로그램 컴파일과 선택기 추론에는 일관되게 Claude Sonnet 4.6을 사용했다. 각 시드(42, 100, 1337, 2024, 7777)마다 기존 코퍼스를 따로 떼어 두고 빈 코퍼스에서 시작했다. 같은 작업 목록에 대해 cold(빈 코퍼스)를 먼저 실행하고 이어서 warm(cold가 구축한 코퍼스)을 실행하는 짝지은 프로토콜을 썼다. 전체 검증은 약 50시간의 자율 컨테이너 시간과 30에서 35달러의 LLM 비용으로 수행됐다.

반복 실행은 빨라진다

두 번째로 작업을 만났을 때 더 빠르면서 더 나쁘지 않다는 것이 기본 약속이다. AndroidWorld official-15에서 세 개의 Gemini 3 Flash 시드에 대해 cold에서 warm으로 성공률이 올랐다. 평균 9.33에서 10.67로 작업 1.33개 증가했고, 어떤 시드도 퇴행하지 않았다.

이 향상은 단순한 운 좋은 검색이 아니다. seed 42에서 셋업을 통과한 13개 작업 중 8개가 cold의 신선 에이전트 풀이에서 warm의 재생 또는 하이브리드로 이동했다.

구분warm 비용/속도
재생된 프로그램단계별 언어 모델 호출 없음, LLM 비용 0에 근접
WebArena 재생신선 에이전트 풀이보다 8.5배에서 13배 빠른 실측 시간
Android 재생코퍼스 적중 시 수 초 안에 완료

대가는 일회성 컴파일-검증 비용이다. 저장되는 프로그램당 Android에서 실측 시간 162퍼센트, OSWorld에서 217퍼센트가 추가된다. 대략 한 번 더 푸는 비용이며, 작업이 처음 재발하는 순간 상환된다.

결과는 모델에 종속되지 않는다. 같은 서브셋에서 Gemini 3 Flash를 Claude Sonnet 4.6으로 바꿔도 동일한 73.3퍼센트(11/15)와 동일한 세 개의 안정적 실패(BrowserDraw, SystemBrightnessMax, SystemWifiTurnOn)가 두 모델과 세 시드 모두에서 나왔다. 이 셋은 접근성 트리에 노출되지 않는 캔버스, 스크롤을 거부하는 밝기 슬라이더, 오래된 상태 표시줄 Wi-Fi 아이콘 같은 벤치마크 UI의 속성으로, 방법이 아니라 벤치마크를 한정한다.

검증 게이트와 폴백의 정량 효과

재사용은 양날의 검이다. warm 실행을 싸게 만드는 같은 코퍼스가, 실행은 되지만 작동하지 않는 프로그램을 저장하면 그것을 틀리게 만들 수 있다. 이를 보이기 위해 게이트를 껐다. 세 플랫폼 모두에서 cold/warm 곱하기 게이트 on/off의 2x2 절제 실험을 돌렸다.

다음은 각 플랫폼의 cold에서 warm으로의 평균 변화(작업 수)이다.

플랫폼 (모델)게이트 ON게이트 OFF게이트 이득
AndroidWorld official-15 (Gemini, n=5)+1.2-1.42.6
OSWorld test_tiny (Claude, n=5)+0.2-2.42.6
WebArena shopping_admin (Claude, n=4+4)-4.0-5.751.75

모바일과 데스크톱에서 게이트가 켜진 에이전트는 반복 실행에서 향상하거나 유지된다. 게이트가 꺼진 에이전트는 같은 작업을 두 번째로 풀면서 더 적게 푼다. 손실 프로그램이 코퍼스에 쌓이기 때문이다. 방향은 세 플랫폼 모두 같고, 14개 짝지은 쌍 중 동점이 아닌 13개 모두에서 일관됐다. 게이트의 한계 가치는 1.75에서 2.6개 작업 사이에 들어가며, 이는 컴파일러가 손실 프로그램을 내놓는 빈도라는 구조적 속성으로 해석된다.

게이트가 잡아내는 실패는 직접 관측 가능하다. 게이트 off 조건에서 100퍼센트 커버리지로 재생되고 성공을 보고하면서도 평가기에서 0점을 받는 다섯 개의 프로그램을 기록했다.

플랫폼작업무엇이 잘못되는가
AndroidContactsAddContact재생 완료, 연락처는 기록 안 됨
AndroidMarkorCreateFolder재생 완료, 폴더가 기대 경로에 없음
OSWorldChrome history clean재생 완료, 브라우저 상태 불일치
OSWorldLibreOffice Calc formula재생 완료, 셀 수식 오류
OSWorldLibreOffice Calc chart재생 완료, 차트 속성 불일치

WebArena가 게이트 on에서도 낮은(-4.0) 이유는 작업이 답 추출형이기 때문이다. 거의 모든 컴파일된 프로그램이 이후 바뀐 페이지에서 값을 읽으므로 게이트가 정당하게 대부분을 거부해 코퍼스를 비운다. 여기서 두 번째 메커니즘이 등장한다. 게이트가 특정 작업의 코퍼스를 비웠을 때, 포기하지 않고 새로 탐색하는 폴백이다. 강력한 record-and-replay 기준선인 Muscle-Mem과 비교했다.

시스템Cold SRWarm SRwarm 마이너스 cold
Muscle-Mem (맹목적 선형 캐시)7.06.25-0.75
Workflow-Use (작업별 스크립트)7.00-7.0
PreAct 게이트 OFF5.752.0-5.75
PreAct 게이트 ON6.02.0-4.0
PreAct 게이트 ON 더하기 캐시 미스 폴백7.256.25-1.0

캐시 미스 폴백을 더하자 warm SR이 2.0에서 6.25로 올라 Muscle-Mem의 6.25와 정확히 일치했다. warm 마이너스 cold 격차는 -4.0에서 -1.0으로 좁혀졌다. warm 분포에 대한 Welch 양측 t 검정은 절댓값 t 약 0.21, p 약 0.84로, 두 시스템이 이 벤치마크에서 통계적으로 구별 불가능함을 보인다. 이 폴백은 게이트의 Android/OSWorld 가치를 훼손하지 않는다. 게이트는 여전히 손실 컴파일을 코퍼스 진입 전에 거부해 단조성을 유지한다.

컴파일 단계 모델을 Claude에서 Gemini 3 Flash로 바꿔도 게이트 거부율은 83퍼센트 대 89퍼센트로 같은 대역에 머물렀다. 게이트는 Claude 특유가 아니라 메커니즘 주도임을 확인한다.

결과를 바꾸지 않은 요소들

음성으로 나온 절제 실험들은 PreAct가 작동하는 이유의 명백한 대안 설명을 배제한다.

요소결과
프로그램 선택기 선택평범한 임베딩 검색기가 100퍼센트 정확 패밀리 검색을 달성, 에이전트형 선택기의 75.6퍼센트를 능가
프롬프트 수준 PreAct 내용프로덕션 경로에서 전혀 전달되지 않음, 73.3퍼센트는 원본 T3A 프롬프트로 달성
코드 수준 런타임 가드레일n=5에서 집계상 중립, cold 평균 동일, warm 0.4개 작업 차이로 시드 변동 내
상태 머신 대 평탄 스크립트평탄 10.6 대 검증 런타임 11.67, 일치 시드에서 0.67개 작업 우위(시사적)

선택기는 해석 가능한 로그와 튜닝 불필요성 때문에 기본값으로 유지하되, 검색 성능 때문은 아니다. 유일하게 성공률을 움직이는 노브는 단계 예산 캡(step-budget cap)이다. 이는 부작용이 아니라 의도된 속도/정확도 트레이드오프로, 작업당 8배 복잡도에 20에서 30단계로 클램프한 캡은 무제한 60단계 대비 약 1.8개 작업의 성공률을 실패 꼬리에서 약 30퍼센트 적은 실측 시간과 맞바꾼다.

한계와 주의사항

논문은 여섯 가지 남은 한계를 명시한다.

한계내용
L1 아키텍처 기준선ActionEngine 스타일 평탄 스크립트와의 직접 비교는 0.67개 작업 우위(p=0.125)로 시사적이나 유의하지 않음
L2 벤치마크 커버리지6/15/12개 작업 서브셋은 작은 표본, 절대 퍼센트포인트는 분모 의존
L3 컴파일 비용검증 재생이 OSWorld 217퍼센트, Android 162퍼센트의 실측 시간 추가, 고처리량 배포에서 문제
L4 컴파일 충실도LLM 컴파일러가 상당 비율로 손실 상태 머신 생성, 게이트가 저장 시 거름
L5 선택기 비결정성축어적 검색 73퍼센트 정확 id, 패러프레이즈 강건성 75.6퍼센트 기능적, 0퍼센트 잘못된 작업 패밀리
L6 재설정 가능/멱등 환경 가정검증과 재생이 작업 재실행을 전제, 비멱등 작업은 부작용 없는 검증 경로 필요

분포 외 일반화에서도 코퍼스는 깨끗하게 전이되지 않는다. OSWorld test_tiny에서 구축한 코퍼스를 33개의 비-test_tiny 작업에 적용하자, warm-OOD 평균이 16.7/30(55.6퍼센트)으로 cold-OOD 통과(약 20/30, 67퍼센트)보다 약 11퍼센트포인트 아래였다. 선택기가 가끔 유사한 작업을 잘못 검색하고, 출처 도메인의 취약한 XPath/상태 술어가 OOD 페이지에서 실패해 재생 예산을 소모하기 때문이다. 코퍼스의 가치는 본 적 있는 작업의 반복 호출에 집중되며, 작은 작업 서브셋으로 구축한 코퍼스는 분포 외 일반화에 오히려 불리하게 작용한다.

세 개의 AndroidWorld 작업과 한 개의 OSWorld 작업은 모든 시드, 두 백엔드, 모든 가드레일/예산 설정, 두 게이트 조건에서 실패한다. 이들은 에이전트 추론이 아니라 UI 패턴 자체의 속성으로, 방법이 아니라 벤치마크를 한정하는 하네스 결정적 실패다.

결론

PreAct는 단순한 관찰에서 출발한다. 컴퓨터 사용 에이전트는 이미 푼 작업을 다시 유도해서는 안 된다. 이를 실행에 옮기는 데는 두 가지 약속이 필요했다. 첫째는 표현에 관한 것으로, 에이전트가 기억하는 것은 다시 해석해야 하는 전사본이 아니라 직접 실행할 수 있는 상태 머신 프로그램이다. 둘째는 규율에 관한 것으로, 에이전트는 무엇이든 신뢰하기 전에 실시간 화면과 대조한다. 재생 중 각 행동 전에, 그리고 프로그램이 메모리에 들어가기 전에 깨끗한 상태에서 재실행한 프로그램 전체에 대해 한 번 더 확인한다.

기대했던 조각들은 대부분 중요하지 않았다. 런타임 가드레일은 집계 수치를 바꾸지 않았고, 프롬프트 수준 가이드는 프로덕션에서 쓰이지 않았으며, 작은 임베딩 검색기가 에이전트형 LLM 선택기만큼 잘했다. 결과를 이끈 것은 짝지음 그 자체였다. 실행 가능한 메모리와, 검증되지 않은 것은 어떤 것도 보관하지 않는 거부다.

에이전트가 더 크고 오래가는 스킬 라이브러리를 쌓을수록, 핵심 질문은 에이전트가 무엇을 했는지 기억할 수 있느냐가 아니라 그 기억 중 어느 것이 여전히 참인지 가려낼 수 있느냐가 된다.

Reference

</content> </invoke>