같은 브라우저에 탭이 여러 개 열려 있으면 지금 보이는 화면만으로 작업 대상을 정하기 어렵다. 참고하려고 연 탭과 글을 작성할 탭이 다를 수도 있다. 나는 에이전트가 첫 행동부터 추측하지 않도록 현재 작업을 읽는 입구를 먼저 두었다.
현재 화면이라는 말에 여러 상태가 섞여 있었다
사람이 고른 화면, 요청을 받았을 때의 기본 대상, 실행 중인 프로그램의 대상은 항상 같지 않다. 다른 자료를 보려고 화면을 바꿨다고 예약 프로그램의 목적지가 함께 바뀌면 안 된다. 반대로 사용자가 특정 사이트에 쓰라고 말했는데 현재 탭만 고집하는 것도 요청을 잘못 해석한 것이다.
그래서 첫 확인에는 프로젝트와 프로필, 탭의 연결을 포함했다. 열린 탭의 주소와 제목 같은 메타데이터를 보고 맞는 기존 탭을 찾는다. 모든 탭의 본문을 미리 읽을 필요는 없다. 먼저 위치를 좁힌 뒤 실제 페이지에서 필요한 상태를 확인하면 다른 원고를 건드릴 가능성과 불필요한 읽기를 함께 줄일 수 있다.
대화의 기억보다 이번 요청을 먼저 연결했다
이전에 블로그 작업을 많이 했더라도 이번에 카페에서 글을 부탁하면 카페를 기본 대상으로 삼아야 한다. current-target의 규칙은 현재 요청의 목적지와 이전 프로그램의 기본 목적지를 구분한다. 특정 블로그를 명시한 경우처럼 이번 요청이 더 구체적이면 그 조건을 적용한다. 과거 작업이 익숙하다는 이유로 지금의 의도를 덮지 않는 것이다.
참고 자료의 언급도 목적지와 나눴다. 카페 내용을 참고해서 블로그에 쓰라는 요청에서 카페는 읽을 곳이고 블로그는 쓸 곳이다. 이를 같은 사이트 목록으로만 저장하면 에이전트가 참고 탭으로 이동한 뒤 거기에 작성할 수 있다. 내가 보존하려 한 것은 탭 선택의 순간보다 작성 대상의 역할이었다.
문맥은 확인 결과이지 권한 증명이 아니다
context에서 계정 이름을 읽을 수 있어도 실제 인증이 계속 유효하다는 뜻은 아니다. 저장된 표시명, 선택된 프로필, 현재 사이트에서 확인한 로그인 상태를 나눠야 한다. 사이트가 로그아웃됐거나 다른 계정을 보여 주면 저장된 이름을 근거로 실행을 밀어붙일 수 없다.
문맥에는 진행 중인 작업과 결과 확인이 남아 있는지도 들어간다. 기존 작업이 있는데 새 작업을 시작해 상태를 치우는 방식은 피해야 한다. 현재 일을 읽는 첫 단계는 편의를 위한 탐색이면서, 아직 해결되지 않은 입력이 있는지 확인하는 자리이기도 하다. 이 판단 뒤에 실제 실행 계약을 읽는다.
읽을 때와 실행할 때 문맥을 다시 대조한다
목록을 확인한 뒤에도 사용자가 프로젝트를 바꾸거나 탭을 닫을 수 있다. 그러므로 최초 context를 읽었다는 사실만으로 나중의 실행을 허용할 수는 없다. 외부 제어 처리기는 요청의 profile·workspace·tab 연결을 현재 호스트 상태와 대조한다. 맞지 않으면 다른 탭을 대신 고르기보다 문맥 변경 오류를 돌려준다.
조사 중에도 이 계약을 확인했다. 플러그인 inspect 요청에 완전한 context를 넣지 않은 호출은 거절됐고, 기존 문맥을 명시한 읽기 요청으로 확인을 이어갔다. 이를 제품이 고장 난 사건으로 쓰지 않았다. 호출자가 제공해야 할 연결 조건을 빠뜨린 경우였으며, 오류가 짧고 구체적이면 에이전트도 관련 입력만 바로잡을 수 있다.
작은 합성 모듈로 대상 선택을 떼어 봤다
공유 예제에서는 신뢰할 scope와 명시한 목적지, 기존 탭 목록과 참고 탭을 받는다. 목적지를 지정하지 않으면 요청 당시 탭을 쓰고, 다른 플랫폼을 지정하면 같은 범위에서 유일한 기존 탭을 찾는다. 후보가 여러 개거나 없으면 멈춘다. 예제는 새 탭을 만들지 않고 자연어를 완전히 해석한다고도 주장하지 않는다.
실제 제품은 계정 선택과 프로젝트 실행처럼 더 넓은 동작을 한다. 공유 모듈은 한 프로필 안의 작은 계약을 새로 작성한 것이므로 원래 브라우저의 완성된 권한 시스템을 대신하지 않는다. 독자가 자기 시스템에 붙일 때는 scope를 사용자 입력에서 그대로 믿지 말고 호스트가 신뢰할 수 있는 값으로 만들어야 한다.
사용자가 몰라도 되는 정보와 알아야 하는 정보
사용자에게 내부 탭 ID를 외우게 할 필요는 없다. 다만 실행할 사이트와 계정, 참고할 자료가 어떻게 선택됐는지는 확인할 수 있어야 한다. 내부 연결은 프로그램이 처리하고, 판단할 정보는 사람이 읽을 말로 보여 주는 것이 내가 원하는 단순함이다. 입력 필드를 숨기는 것과 실행 대상을 숨기는 것은 다르다.
이 글의 근거는 실제 코드와 개발 기록, 새 합성 모듈의 시험이다. 실제 서비스에서 새 글을 쓰거나 계정 전환을 추가로 실행한 검증은 아니다. 전체 원고의 모든 상황에 같은 선택 규칙을 적용할 수도 없다. 애매한 대상이 남으면 필요한 선택을 다시 확인하도록 두는 편이 잘못된 확신보다 다음 작업자에게 도움이 된다.