Articlelangchain.com·2026년 7월 8일·0

How Deep Agents Run Untrusted Code Without a Sandbox

Quick Summary

Deep Agents의 코드 인터프리터는 에이전트가 작성한 오케스트레이션 코드를 별도 컴퓨터형 샌드박스 없이도 WASM, QuickJS, 제한된 capability bridge, durable pause로 안전하게 실행하려는 설계다.

How Deep Agents Run Untrusted Code Without a Sandbox 관련 대표 이미지

🖼️ 인포그래픽

How Deep Agents Run Untrusted Code Without a Sandbox 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

How Deep Agents Run Untrusted Code Without a Sandbox 내용을 설명하는 본문 이미지

💡 한 줄 요약

Deep Agents의 코드 인터프리터는 에이전트가 작성한 오케스트레이션 코드를 별도 컴퓨터형 샌드박스 없이도 WASM, QuickJS, 제한된 capability bridge, durable pause로 안전하게 실행하려는 설계다.

📌 핵심 요약

  • 글은 Deep Agents에 도입된 dynamic subagents를 배경으로, 에이전트가 짧은 스크립트를 작성해 여러 subagent를 오케스트레이션하는 방식이 강력하지만 신뢰할 수 없는 코드를 실행해야 한다는 어려운 문제를 만든다고 설명한다.
  • 작성자는 프롬프트 인젝션이 해결되지 않았기 때문에 에이전트가 언젠가는 허용되지 않은 행동을 시도할 수 있다고 전제하고, 신뢰 가능한 시스템을 위해 실행 격리, capability 격리, durable pause가 필요하다고 정리한다.
  • 실행 격리는 WebAssembly를 통해 구현된다. WASM은 별도의 선형 메모리와 호스트가 제공한 기능만 사용할 수 있는 VM 경계를 제공하며, QuickJS를 WASM 안에 넣어 JavaScript 실행 엔진 자체도 격리 경계 안에 둔다.
  • capability 격리는 전통적 샌드박스처럼 파일시스템, 셸, 네트워크 등 넓은 권한에서 시작해 줄이는 방식이 아니라, 아무 권한도 없는 코드 인터프리터에 필요한 기능만 harness를 통해 좁게 연결하는 방식으로 설명된다.
  • durable pause는 QuickJS가 WASM 안에서 실행된다는 점을 활용해 인터프리터의 선형 메모리를 LangGraph state에 직렬화하고, 사람 승인 뒤 복원해 중단된 비동기 호출이 나중에 반환된 것처럼 이어가게 하는 방식으로 제시된다.

🧩 주요 포인트

  1. 글은 Deep Agents에 도입된 dynamic subagents를 배경으로, 에이전트가 짧은 스크립트를 작성해 여러 subagent를 오케스트레이션하는 방식이 강력하지만 신뢰할 수 없는 코드를 실행해야 한다는 어려운 문제를 만든다고 설명한다.
  2. 작성자는 프롬프트 인젝션이 해결되지 않았기 때문에 에이전트가 언젠가는 허용되지 않은 행동을 시도할 수 있다고 전제하고, 신뢰 가능한 시스템을 위해 실행 격리, capability 격리, durable pause가 필요하다고 정리한다.
  3. 실행 격리는 WebAssembly를 통해 구현된다. WASM은 별도의 선형 메모리와 호스트가 제공한 기능만 사용할 수 있는 VM 경계를 제공하며, QuickJS를 WASM 안에 넣어 JavaScript 실행 엔진 자체도 격리 경계 안에 둔다.
  4. capability 격리는 전통적 샌드박스처럼 파일시스템, 셸, 네트워크 등 넓은 권한에서 시작해 줄이는 방식이 아니라, 아무 권한도 없는 코드 인터프리터에 필요한 기능만 harness를 통해 좁게 연결하는 방식으로 설명된다.
  5. durable pause는 QuickJS가 WASM 안에서 실행된다는 점을 활용해 인터프리터의 선형 메모리를 LangGraph state에 직렬화하고, 사람 승인 뒤 복원해 중단된 비동기 호출이 나중에 반환된 것처럼 이어가게 하는 방식으로 제시된다.

🧠 상세 정리

1. Dynamic subagents가 만든 실행 문제

글은 Deep Agents에 최근 도입된 dynamic subagents에서 출발한다. 기존처럼 subagent를 도구 호출 하나씩 dispatch하는 대신, 에이전트가 짧은 스크립트를 작성해 subagent들을 오케스트레이션하도록 만든다는 설명이다. 이 스크립트는 코드 인터프리터에서 실행되며, 에이전트가 코드를 쓰고 실행하는 구조가 된다. 작성자는 이 패턴이 강력하지만, 신뢰할 수 없는 코드를 안전하고 안정적으로 실행해야 한다는 까다로운 전제 위에 놓여 있다고 문제를 제기한다.

2. 신뢰할 수 없는 에이전트 코드에 필요한 세 가지 조건

작성자는 단순히 신뢰할 수 없는 코드를 실행하는 문제와, 신뢰할 수 없는 입력의 영향을 받은 에이전트가 작성한 코드를 실행하는 문제를 구분한다. 프롬프트 인젝션이 아직 해결되지 않았기 때문에, 에이전트 작성 코드가 결국 해서는 안 되는 일을 시도할 수 있다고 봐야 한다는 입장이다. 그래서 에이전트를 믿는 대신 가능한 행동을 제한해야 한다고 말한다. 그 기준은 호스트를 침해하지 못하게 하는 실행 격리, 의도적으로 넘겨준 데이터와 행동만 다루게 하는 capability 격리, 사람 입력을 기다렸다가 나중에 같은 지점에서 재개할 수 있는 durable pause다.

3. 원격 컨테이너형 샌드박스와 작은 코드 인터프리터의 대비

Interrupt 2026에서 발표된 두 접근은 같은 요구사항을 다루지만 방향이 다르다. LangSmith Sandboxes는 에이전트에 완전한 원격 컨테이너를 제공해, 로컬 코딩 에이전트와 비슷한 자유도를 주되 다른 머신 위에서 격리하는 방식이다. 반면 Deep Agents용 Code Interpreters는 훨씬 작은 런타임을 택한다. 에이전트가 프로그램을 작성하고 실행할 수는 있지만, 제공된 harness 내부에서만 동작하게 한다. 글의 초점은 오케스트레이션 워크플로가 반드시 컴퓨터 전체 형태의 샌드박스를 필요로 하지는 않으며, 더 작은 표면으로도 샌드박스가 주는 격리의 이점을 유지할 수 있다는 주장에 있다.

4. WASM과 QuickJS로 만드는 실행 격리

실행 격리 부분에서 글은 신뢰할 수 없는 코드를 실행하는 모든 시스템이 결국 단단한 경계를 필요로 한다고 설명한다. 여기서 사용되는 경계는 WebAssembly다. WASM은 자체 메모리를 가진 in-process VM 안에서 실행되며, 외부와는 호스트가 제공한 capability를 통해서만 상호작용한다. 별도의 선형 메모리를 쓰기 때문에 WASM 내부 코드는 호스트 프로세스의 포인터를 역참조해 임의의 메모리를 읽거나 훼손할 수 없다. 그 안에서 실제 코드를 실행하기 위해 QuickJS를 사용하며, QuickJS가 작고 빠른 JavaScript 엔진이고 WASM으로 깔끔하게 컴파일된다는 점을 장점으로 든다.

5. Capability isolation과 bridge의 역할

실행 경계가 호스트 침해를 막는다면, capability isolation은 에이전트가 무엇을 할 수 있는지를 제한한다. 글은 결혼식을 계획하는 에이전트 예시를 통해, 민감한 데이터 접근과 외부 행동 권한이 한 루프 안에 합쳐지면 단 하나의 악의적 RSVP만으로도 개인 예산을 읽고 업체에 승인 메시지를 보내는 위험이 생긴다고 설명한다. 전통적 샌드박스는 파일시스템, 의존성, 셸 같은 컴퓨터형 권한에서 시작하므로 권한을 빼앗는 방식이 된다. 반대로 코드 인터프리터는 처음에는 파일 읽기, 네트워크 요청, 의존성 설치가 불가능하고 언어 기능만 가진다. subagent 호출도 프로세스 관리자나 네트워크 스택이 아니라 좁은 계약의 함수로 bridge되며, harness가 동시 실행 수와 호출당 생성 수를 제한한다.

6. Durable pause와 공개된 실험적 패키지

마지막 요구사항은 실행 중인 프로그램을 안전하게 멈춘 뒤 살아 있게 유지하는 것이다. 프로덕션 에이전트는 위험한 행동 전에 사람 승인을 기다려야 하며, 그 승인은 몇 초 뒤일 수도 있고 몇 시간 또는 며칠 뒤일 수도 있다. 글은 QuickJS가 WASM 안에서 실행되기 때문에 프로그램을 다시 구성하지 않고 프로그램 자체를 멈출 수 있다고 설명한다. 인터프리터의 선형 메모리를 LangGraph state에 직렬화하고, 재개 시 harness가 스냅샷을 복원한 뒤 기다리던 호출에 결과를 되돌려준다. 끝부분에서는 quickjs-rs와 langchain-quickjs가 실험적 패키지로 공개되었고, close partner들과 production 적용을 진행하며 런타임을 다듬고 있다고 밝힌다.

🧾 핵심 주장 / 시사점

  • 이 글의 핵심은 에이전트가 작성한 코드를 신뢰하지 않는 것이다. 안전성은 에이전트의 선의나 모델의 판단력에 기대는 대신, 실행 경계와 명시적으로 넘겨준 기능만 사용하는 구조로 확보된다.
  • 코드 인터프리터 접근은 전통적 샌드박스와 출발점이 다르다. 컴퓨터 전체를 준 뒤 권한을 줄이는 것이 아니라, 아무 capability도 없는 언어 런타임에서 시작해 필요한 기능만 좁은 bridge로 연결한다는 점이 보안 모델의 중심이다.
  • durable pause는 단순한 일시정지가 아니라 사람 승인과 장시간 대기를 전제로 한 에이전트 실행 모델이다. 메모리 스냅샷을 상태로 저장하고 같은 지점에서 이어가는 방식은, 위험한 행동을 사람 검토와 결합하려는 Deep Agents 설계의 중요한 축으로 제시된다.

✅ 액션 아이템

  • 동적 subagent 오케스트레이션은 유지하되 WASM 격리·QuickJS·capability bridge·durable pause를 함께 반영해 보안 기준을 맞춘다.
  • 실행기는 아무 권한도 없는 상태에서 시작하고 host 기능은 harness를 통해 필요한 것만 노출되도록 최소권한 구성을 정리한다.
  • 프롬프트 인젝션 가정을 전제로 LangGraph 상태 직렬화 기반 durable pause의 승인 시점, 복원 조건, 실패 처리 기준을 정한다.

❓ 열린 질문

  • WASM 내부 QuickJS에서 파일시스템·셸·네트워크 호출을 모두 차단할 때 실제 운영에서 허용 가능한 최소 예외 범위는 어디까지인가?
  • durable pause로 선형 메모리를 직렬화해 복원할 때 어떤 상태 혼재가 발생하면 비동기 호출 재개가 실패할 가능성이 큰가?
  • 프롬프트 인젝션 전제가 유지되는 상황에서 오케스트레이션 코드의 자동 실행 범위를 어디까지 허용하고 나머지는 사람 승인으로 제한해야 하는가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.