에이전트 작업이 유용하게 느껴지기 시작하고, 통제에 대한 모호한 개념이 위험해지는 곳이 바로 브라우저입니다. 에이전트는 페이지를 열고, 이를 읽고, 흐름을 따라 클릭하며, 일반적인 필드를 채울 수 있습니다. 그런 다음 로그인 페이지나 2FA(Two-Factor Authentication) 인증, 또는 결제 양식이 나타납니다. 그 순간 저는 “인간이 담당한다”는 정중한 관습적 메시지를 원하지 않습니다. 저는 런타임(runtime)이 그것을 강제하기를 바랍니다.
그것이 제가 브라우저 휠을 가져갈 때 APX가 탭 읽기를 멈추게 만든 이유입니다. 핸드오프(handoff)는 에이전트에게 보내는 메시지가 아닙니다. 그것은 에이전트 호출을 차단하는 제어 상태 변화입니다.
이것은 사소한 구현 세부 사항처럼 들릴 수 있습니다. 하지만 이것은 제가 에이전트 브라우저 작업에 대해 생각하는 방식을 바꿨습니다.
관찰하는 것이 통제하는 것과 같지 않다
APX V2는 에이전트에게 임베디드(embedded) 브라우저 탭을 제공할 수 있습니다. 데스크톱에서, 저는 에이전트가 작업하는 동안 그 탭을 볼 수 있습니다. 에이전트는 제한된 일련의 브라우저 도구를 통해 작동합니다. 즉, 탭을 열고 탐색하며, 접근성 스냅샷(accessibility snapshot)을 찍고, 보이는 텍스트를 읽으며, 해당 스냅샷에서 요소 참조를 클릭하고, 참조된 필드에 타이핑하는 것입니다.
이러한 가시적인 표면은 중요하지만, 그것만으로는 충분하지 않습니다. 에이전트가 커서를 움직이는 것을 보는 것이 중요한 질문, 즉 제가 개입할 때 무슨 일이 일어나는지에 대한 답을 주지 못합니다.
약한 대답은 “에이전트가 기다려야 한다”일 것입니다. 이는 타이밍과 해석에 너무 많은 것을 남겨둡니다. 모델은 제가 일회용 코드를 입력하는 동안 이미 페이지를 읽고 있을 수 있습니다. 예약된 클릭은 제가 인계(take over)하기로 결정한 후에 실행될 수 있습니다. 로그인 흐름 중에 찍힌 스크린샷은 제가 제 브라우저 세션 내부에 유지하려고 했던 정보를 드러낼 수 있습니다.
따라서 APX는 각 탭의 제어를 추적합니다. 탭은 유휴(idle) 상태일 수도 있고, 에이전트에 의해 제어될 수도 있으며, 일시적인 핸드오프 중일 수도 있고, 사용자에게 의해 제어될 수도 있습니다. 제가 ‘제어권 가져가기(Take Control)’를 선택하면, 데스크톱 호스트는 해당 탭의 상태를 user로 변경합니다. 이후 에이전트가 이를 읽거나 조작하려는 모든 시도는 paused_by_user 오류와 함께 실패합니다. 이는 클릭 전뿐만 아니라 페이지 읽기 전에도 적용됩니다.
마지막 부분이 핵심입니다. 브라우저는 액션 표면이자 관찰 표면이기 때문입니다. 만약 사람이 비밀번호, 2FA 코드, 카드 데이터 또는 개인 계정 세부 정보를 입력하고 있다면, 클릭만 차단하는 것은 불충분합니다. 에이전트는 페이지 상태를 검사할 수도 없어야 합니다.
로그인은 대화 요청이 아닌 인계(handoff)입니다
저는 또한 에이전트가 대화 중에 자격 증명을 요구하는 것을 원하지 않았습니다. 브라우저 도구는 로그인, 비밀번호, 2FA 또는 CAPTCHA를 위해 browser_handoff 액션을 노출합니다. 이는 짧은 이유를 기록하고, 브라우저 카드를 인계로 표시하며, 소유자가 최대 5분 동안 완료할 때까지 기다립니다.
에이전트는 두 가지 답변 중 하나만 받습니다. 즉, 현재 URL과 함께 소유자가 완료했거나, 또는 시간이 지나서 소유자가 완료하지 못해 에이전트가 중지하는 것입니다. 비밀번호나 코드, 또는 인간의 상호작용 스트림을 받지는 않습니다.
이는 모든 인증 경로를 자동화하려고 시도하는 것보다 의도적으로 덜 정교하게 만든 것입니다. 인증 흐름은 사이트마다 다르고, 종종 자동화를 위해 고의적으로 적대적이며, 에이전트 기록에 포함되어서는 안 되는 비밀이나 신원 결정과 관련되는 경우가 많습니다. 눈에 보이는 인계는 사람에게 하나의 명확한 작업을 주고 에이전트에게도 하나의 명확한 경계를 제공합니다.
제가 이미 제 브라우저를 통해 로그인된 사이트에 대해서는 두 번째의 별도 경로가 있습니다. APX는 특정 도메인에 대한 쿠키 복사 승인을 요청하여 이를 APX 브라우저 프로필로 가져올 수 있게 합니다. 이 작업은 오직 인간만 할 수 있습니다. 런타임은 소스 이름과 도메인 수를 검사할 수 있지만, 쿠키 값은 데스크톱에 남아 있습니다. 에이전트는 이것을 일반적인 “내 브라우저 읽기” 권한으로 바꿀 수 없습니다.
이러한 경로들을 분리하는 것이 중요합니다. 제가 직접 로그인하는 것은 직접적인 상호작용입니다. 기존 세션을 가져오는 것은 특정 도메인을 가진 범위가 제한된 전송입니다. 어느 쪽도 관련 없는 탭이나 도구에 대해 조용히 권한을 부여해서는 안 됩니다.
별도의 프로필은 우발적인 공유 제어를 방지합니다
컨트롤만으로는 완전한 경계가 아닙니다. APX는 에이전트에게 브라우저 프로필을 제공하고 작업 전에 소유권을 확인합니다. 에이전트는 자신의 프로필의 탭은 건드릴 수 있지만, 다른 에이전트에게 할당된 탭을 구동할 수는 없습니다. 만약 다른 에이전트가 현재 탭을 제어하고 있다면, 두 번의 실행이 하나의 페이지를 조종하도록 허용하기보다는 APX가 요청을 거부합니다.
이는 대규모 보안 기능만큼 극적이지는 않지만, 놀라울 정도로 흔한 모호성의 원인을 제거합니다. 즉, 탭은 단순히 URL이 아니라는 것입니다. 탭은 프로필, 쿠키, 현재 상태, 그리고 운영자를 가지고 있습니다. 이를 공유된 전역 상태로 취급하면 예상치 못한 일이 발생한 후 브라우저 세션을 설명하기 어려워집니다.
동일한 설계가 일반적인 도구 흐름을 형성합니다. 클릭은 최신 접근성 스냅샷의 요소를 참조합니다. 타이핑은 외부 동작이며, 신뢰할 수 없는 페이지 콘텐츠를 읽은 후에 확인이 필요합니다. 브라우저 텍스트는 신뢰할 수 없다고 표시됩니다. 에이전트는 양식이 제출되었거나 메시지가 전송되었다고 주장하기 전에 새로운 페이지 상태를 확인하도록 유도됩니다.
그 어떤 것도 브라우저 자동화를 선언적으로 안전하게 만들지는 않습니다. 대신 시스템에 멈추고, 질문하고, 증거를 보여줄 장소를 제공합니다.
제가 유지하는 설계 규칙
원래의 직감은 브라우저가 매끄럽게 느껴지도록 만드는 것이었습니다. 에이전트가 페이지를 열고, 로그인할 때 제가 돕고, 에이전트가 계속 진행하는 식입니다. 더 나은 규칙은 더욱 정밀해졌습니다. 매끄러움(seamless)은 소유권이 명확하게 유지될 때만 괜찮다는 것입니다.
좋은 인계는 네 가지 속성을 가집니다:
- 사람이 에이전트와 협상하지 않고도 탭을 가져갈 수 있어야 합니다.
- 에이전트는 에이전트의 동작뿐만 아니라 정지(stop) 신호도 읽어야 합니다.
- 민감한 입력은 채팅과 도구 출력에서 제외되어야 합니다.
- 제어권을 반환하는 것은 명시적이어야 하며, 에이전트가 작업이 재개될 수 있는 시점을 추측하지 않도록 해야 합니다.
이는 런타임에 상태를 추가합니다. 또한 문제를 일으키는 종류의 보이지 않는 상태(invisible state)를 제거합니다. 즉, 사람이 자신이 인계했다고 생각하는 동안에도 에이전트가 여전히 페이지의 소유권을 가지고 있다고 가정하는 경우입니다.
저는 에이전트가 불투명해지지 않으면서도 능력을 갖추도록 APX를 구축하고 있습니다. 브라우저에서 이 아이디어의 실질적인 버전은 간단합니다. 제가 제어권을 잡으면, 에이전트는 기다립니다—그리고 제가 타이핑하는 것을 볼 수 없습니다.