ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Managed Agents 아키텍처: 브레인과 핸즈를 분리하는 확장 전략
    AI 2026. 4. 9. 21:25
    반응형

    에이전트(Agent) 시스템을 프로덕션에 올려본 개발자라면 누구나 한 번쯤 이런 문제를 겪어요. 컨테이너가 죽으면 세션이 날아가고, 디버깅하려면 유저 데이터가 있는 컨테이너에 직접 셸을 열어야 하고, 샌드박스에서 실행되는 코드가 크리덴셜에 접근할 수 있는 보안 구멍이 생기죠. Anthropic 엔지니어링 팀이 Managed Agents를 구축하면서 마주한 문제가 정확히 이것이었고, 그들이 찾은 해법은 "브레인(brain)과 핸즈(hands)의 분리"라는 아키텍처 원칙이에요. 이 글에서는 그 설계 결정의 배경과 구현 디테일, 그리고 우리가 에이전트 시스템을 설계할 때 가져갈 수 있는 인사이트를 정리해 볼게요.

    Anthropic Managed Agents 아키텍처 개요

    왜 모놀리식 에이전트 컨테이너는 한계에 부딪히는가

    초기 Managed Agents 설계에서는 세션(session), 하네스(harness), 샌드박스(sandbox)를 하나의 컨테이너에 모두 넣었어요. 파일 편집이 직접 syscall로 이루어지니 빠르고, 서비스 경계를 설계할 필요가 없다는 장점이 있었죠.

    하지만 이 구조는 전형적인 Pets vs Cattle 문제를 만들어요. 인프라 세계에서 "Pet"은 이름이 붙은, 잃어버리면 안 되는 개별 서버이고 "Cattle"은 언제든 교체 가능한 서버를 의미해요. 모든 것이 한 컨테이너에 들어가면 그 컨테이너가 Pet이 되어버려요.

    디버깅의 악몽

    컨테이너가 응답하지 않으면 유일한 관찰 창구는 WebSocket 이벤트 스트림뿐이에요. 그런데 이 스트림만으로는 장애의 원인이 하네스 버그인지, 패킷 드롭인지, 컨테이너 자체 장애인지 구분할 수 없어요. 결국 엔지니어가 컨테이너 안에 셸을 열어야 하는데, 유저 데이터가 같은 환경에 있으니 사실상 자유로운 디버깅이 불가능했어요.

    인프라 연결의 경직성

    하네스가 작업 대상이 같은 컨테이너 안에 있다고 가정했기 때문에, 고객의 VPC(Virtual Private Cloud)에 연결하려면 네트워크 피어링을 하거나 고객 환경에서 하네스를 직접 실행해야 했어요. 하네스에 박혀 있는 가정이 다른 인프라 연결을 가로막은 거예요.

    브레인과 핸즈 분리: 핵심 아키텍처 패턴

    Anthropic이 도달한 해법은 운영체제의 설계 철학에서 영감을 받았어요. OS가 하드웨어를 파일, 프로세스, 소켓 같은 추상화로 가상화해서 아직 존재하지 않는 프로그램도 실행할 수 있게 만든 것처럼, Managed Agents는 에이전트의 구성 요소를 가상화했어요.

    핵심 분리 구조는 다음과 같아요:

    • 세션(Session): 발생한 모든 이벤트의 append-only 로그. 하네스 외부에 독립적으로 존재해요.
    • 하네스(Harness): Claude를 호출하고 도구 호출(tool call)을 라우팅하는 에이전트 루프. 상태를 보존할 필요가 없어요.
    • 샌드박스(Sandbox): Claude가 코드를 실행하고 파일을 편집하는 실행 환경. 컨테이너로 구현돼요.

    각 컴포넌트가 인터페이스로 정의되어 있기 때문에 구현체를 독립적으로 교체할 수 있어요. 이건 마이크로서비스 아키텍처의 핵심 원리와 정확히 일치해요.

    Managed Agents 컴포넌트 분리 다이어그램

    샌드박스를 Cattle로 만들기

    분리 후 하네스는 컨테이너를 다른 도구와 동일한 방식으로 호출해요:

    execute(name, input) → string

    컨테이너가 죽으면 하네스는 이를 tool-call 에러로 처리하고 Claude에게 전달해요. Claude가 재시도를 결정하면 새 컨테이너를 표준 레시피로 초기화하면 돼요:

    provision({resources})

    더 이상 죽은 컨테이너를 되살릴 필요가 없어요.

    하네스 장애 복구

    세션 로그가 하네스 밖에 있으므로 하네스 안에 생존해야 할 상태가 없어요. 하네스가 크래시하면 새 인스턴스를 띄우고 replay(session_id)로 이벤트 로그를 가져와 마지막 이벤트부터 재개하면 돼요. 에이전트 루프 중에는 append(session_id, event)로 내구성 있는 이벤트 기록을 유지해요.

    이 패턴은 이벤트 소싱(Event Sourcing) 패턴과 본질적으로 같아요. 현재 상태를 이벤트 시퀀스에서 재구성할 수 있기 때문에 어떤 컴포넌트든 stateless하게 운영할 수 있어요.

    보안 경계: 크리덴셜 격리 전략

    모놀리식 구조에서 가장 위험한 부분은 보안이에요. Claude가 생성한 비신뢰 코드가 크리덴셜과 같은 컨테이너에서 실행되면, 프롬프트 인젝션(Prompt Injection) 한 번으로 환경 변수를 읽어 토큰을 탈취할 수 있어요. 토큰 스코프를 좁히는 것은 완화책이지만, "제한된 토큰으로 Claude가 무엇을 할 수 없는지"에 대한 가정을 인코딩하는 것이고, 모델은 점점 더 똑똑해지고 있어요.

    Managed Agents의 구조적 해결책은 토큰이 샌드박스에서 절대 도달할 수 없도록 만드는 거예요. 두 가지 패턴을 사용해요:

    • 리소스 번들링(Git 방식): 리포지토리 접근 토큰으로 샌드박스 초기화 시 clone을 수행하고 로컬 git remote에 연결해요. git push/pull은 샌드박스 안에서 작동하지만 에이전트가 토큰 자체를 다루지 않아요.
    • 보안 볼트(MCP 방식): OAuth 토큰을 샌드박스 외부의 보안 볼트에 저장하고, Claude는 전용 프록시를 통해 MCP 도구를 호출해요. 프록시가 세션에 연결된 토큰으로 볼트에서 크리덴셜을 가져와 외부 서비스를 호출하는 구조예요.

    Managed Agents 보안 아키텍처와 크리덴셜 격리

    이 설계에서 핵심 인사이트는 "가정을 코드에 박지 말고 구조로 강제하라"는 거예요. 토큰 스코프를 좁히는 건 소프트한 방어이고, 물리적으로 접근 불가능하게 만드는 건 하드한 방어예요.

    에이전트 시스템 설계에 적용할 수 있는 원칙

    Anthropic의 Managed Agents 아키텍처에서 우리가 가져갈 수 있는 설계 원칙을 정리하면:

    • 인터페이스로 가상화하라: 구체적 구현이 아니라 execute, provision, replay, append 같은 인터페이스를 기준으로 컴포넌트를 나눠요. 구현은 바뀌어도 인터페이스는 유지돼요.
    • 상태를 외부화하라: 이벤트 소싱 패턴으로 세션 상태를 외부에 두면 모든 컴포넌트를 stateless로 운영할 수 있고, 장애 복구가 단순해져요.
    • 보안은 가정이 아닌 구조로: 토큰 스코프 제한 같은 소프트 방어보다, 크리덴셜이 실행 환경에 물리적으로 없는 하드 방어를 선택해야 해요.
    • Cattle, not Pets: 모든 런타임 컴포넌트를 교체 가능하게 만들면 장애 대응이 "복구"에서 "교체"로 바뀌어요.

    에이전트 하네스는 모델의 능력이 발전하면서 계속 변할 수밖에 없어요. Claude Sonnet 4.5에서 필요했던 컨텍스트 리셋이 Claude Opus 4.5에서는 불필요해진 것처럼, 하네스에 박힌 가정은 빠르게 낡아져요. 그래서 "특정 구현보다 오래 살아남을 인터페이스"를 설계하는 것이 중요해요.

    마무리

    Anthropic의 Managed Agents 아키텍처는 결국 오래된 컴퓨팅 원칙—추상화와 가상화—를 에이전트 시스템에 적용한 사례예요. 브레인과 핸즈를 분리하고, 상태를 외부화하고, 보안 경계를 구조적으로 강제하는 이 패턴은 어떤 에이전트 프레임워크를 쓰든 적용할 수 있는 보편적 설계 원칙이에요. 직접 에이전트 시스템을 구축하고 있다면, 지금 만들고 있는 하네스가 내년에도 유효할지 자문해 보세요—인터페이스가 구현보다 오래 살아남도록 설계하는 것이 핵심이에요.

    반응형

    댓글

Designed by Tistory.