Managed Agents 확장하기: 두뇌와 손을 분리하기
핵심 내용
세션·하네스·샌드박스를 분리해 Managed Agents의 확장성과 보안을 높였다.
자세히 보기
Managed Agents는 에이전트의 핵심 구성요소를 session, harness, sandbox로 분리해, 구현은 바뀌어도 인터페이스는 오래 유지되도록 설계했다. 하네스가 container 안에 묶여 있던 구조를 벗어나면서, 인프라 장애와 세션 복구, VPC 연동, 보안 경계 문제가 함께 풀렸다.
처음에는 모든 구성요소를 하나의 container에 넣었지만, 그 결과 서버가 pet처럼 되어 버렸다. container가 죽으면 세션도 함께 사라졌고, WebSocket 이벤트 스트림만으로는 하네스 문제인지 네트워크 문제인지 container 다운인지 구분하기 어려웠다.
구조를 바꾼 뒤에는 하네스가 container를 직접 실행 환경으로 다루지 않고 execute(name, input) → string 같은 tool call로만 접근한다. container가 실패하면 하네스는 이를 tool-call 오류로 받아 Claude에게 돌려주고, 필요하면 provision({resources})로 새 container를 다시 띄울 수 있다.
하네스 자체도 cattle로 만들었다. 세션 로그가 하네스 밖에 있으므로 하네스가 죽어도 wake(sessionId)로 다시 시작해 getSession(id)에서 이벤트 로그를 읽고, emitEvent(id, event)로 이어서 수행할 수 있다.
보안 측면에서도 분리가 중요했다. 예전처럼 untrusted code가 Claude와 같은 container에서 돌면 prompt injection이 환경 변수와 token에 닿을 수 있었지만, 이제 token은 sandbox 밖에 둔다. Git은 repo access token으로 초기 clone만 수행하고 local remote에만 연결하며, custom tools는 MCP와 vault를 통해 OAuth token을 proxy가 대신 처리한다.
세션은 Claude의 context window와도 분리된다. compaction이나 trimming처럼 되돌릴 수 없는 요약 대신, 세션 로그에 이벤트를 영구 저장하고 getEvents()로 positional slice를 꺼내 쓰는 방식이다. 하네스는 이 이벤트를 필요에 따라 재가공해 prompt cache 효율이나 context engineering을 수행할 수 있다.
이 분리는 many brains와 many hands 확장도 가능하게 했다. container를 미리 띄워 둘 필요가 없어져 inference는 pending event를 읽는 즉시 시작할 수 있었고, 그 결과 p50 TTFT는 약 60%, p95는 90% 이상 줄었다. 한편 각 hand는 단순한 tool로 취급되어, Claude는 container, phone, Pokémon emulator 같은 서로 다른 실행 환경을 동일한 방식으로 다룰 수 있다.
이 한국어 요약은 AI가 자동으로 만들었습니다. 원문의 주장과 맥락은 원문에서 확인해 주세요. 저작권은 원저작자에게 있습니다.