サンドボックスなしで不審なコードを実行する深層エージェントの仕組み
LangChain は、従来のサンドボックス依存を排し、不審なコードを実行可能な深層エージェントの技術を発表した。
キーポイント
サンドボックス不要の実行環境
従来の隔離されたサンドボックス環境を経由せず、エージェントが不審なコードを直接実行できるアーキテクチャを実現している。
セキュリティと自律性の両立
外部の隔離層に頼らず、内部メカニズムによってリスクを管理しつつ、より複雑で自律的なタスク実行を可能にする技術的転換点である。
エージェント能力の拡張
コード実行のボトルネックを取り除くことで、エージェントが現実世界や開発環境においてより即座に判断し行動する能力を飛躍的に向上させる。
影響分析・編集コメントを表示
影響分析
この発表は、AI エージェントが複雑なタスクを実行する際の最大のボトルネックであった「サンドボックスによる制約」を打破する画期的な試みであり、実世界での自律的なコード実行能力に大きな転換点をもたらす。一方で、隔離環境なしで不審なコードを実行する技術は、セキュリティリスクの再定義と新たな防御メカニズムの確立が不可欠となるため、業界全体のセキュリティ基準の見直しを迫る重要なニュースである。
編集コメント
セキュリティリスクを伴う大胆な技術転換ですが、エージェントの自律性を飛躍させる可能性を秘めています。今後の実装における具体的な防御メカニズムと業界への波及効果が注目されます。
サンドボックスなしで信頼できないエージェントコードを実行する

私たちは最近、Deep Agents に 動的サブエージェント を導入しました。これは、サブエージェントをツール呼び出しごとに一つずつ実行するのではなく、エージェントがそれらを調整する短いスクリプトを書くようにしたものです。このスクリプトは、コードインタプリタ で実行されます。ここではエージェントがコードの記述と実行を行います。
これは強力なパターンですが、その基盤には欺瞞的に難しい要素があります:
*信頼できないコードを安全かつ確実に実行するのは困難です。*
信頼できないコードを実行することはよく研究されている問題ですが、信頼できない入力に影響されたエージェントによって書かれたコードを実行することはそうではありません。プロンプトインジェクション が未解決のまま残っているため、エージェントが書いたコードは最終的に許可されるべきではない何かを行う可能性があると想定せざるを得ません。エージェントの行動を信頼するのではなく、その実行可能な範囲を制限します。このようにして信頼できるエージェントを実現するには、以下の 3 つの設計要件に収束します:
- エグゼキューションアイソレーション:エージェントが記述したコードは、実行先のホストを侵害できません。
- キャパビリティアイソレーション:エージェントがアクセスできるデータとアクションは、私たちが意図的に付与したものだけに限定されます。
- 永続的な一時停止:実行は人間の入力を待って停止し、その位置を失うことなく後で再開できます。
Interrupt 2026 で、これらの要件に基づいて構築された 2 つの提供物を発表しました。
- LangSmith Sandboxes は、エージェントに完全なリモートコンテナを提供します。ローカルのコーディングエージェントとほぼ同等の自由度を持ちながら、異なるマシン上でアイソレーションされます。
- Deep Agents 向けの Code Interpreters(コードインタプリタ)は、対照的なアプローチを採用しています。これはより小さなランタイム環境であり、エージェントがプログラムを記述・実行できますが、私たちが提供するハッチス内でのみ可能です。
最初の種類のサンドボックスについてはすでに記事にまとめています。本稿では後者について取り上げます。オーケストレーションワークフローが必ずしもサンドボックス化されたコンピュータを必要としない理由、そしてなぜサンドボックスが魅力的であるかというアイソレーション性を損なうことなく、より小さな攻撃面を維持できるのかについて解説します。
エグゼキューションアイソレーション
信頼できないコードを実行する誰もが同じ結論に達します。それは、そのコードと他のすべてのものの間に堅牢な境界線が必要だということです。インタプリタもプロセスから離れることなくこの境界線を必要とし、それが私たちが WebAssembly(ウェブアッスエム)を利用する理由です。
WebAssembly
WebAssembly(WASM)は、独自のメモリを持つサンドボックス化されたインプロセス VM 内で実行されるコンパクトなバイナリ形式であり、外部世界とのやり取りはホストが提供する機能を通じてのみ行われます。この独立した線形メモリこそが境界の核心です:WASM 内部で実行されているコードは、ホストプロセスへのポインタを参照できないため、割り当てられていないメモリを読み書きしたり破損したりすることはできません。WASM ランタイムでは、厳格なメモリおよび実行制限を容易に適用できますし、ハーン(テスト枠組み)と並行して動作するため、別のマシンを構築することなく計測・監視を行うことが可能です。
AWS、Shopify、そして Figma は、いずれもプラットフォーム上で信頼できないコードを実行するために WASM を採用しています。これは、WebContainers や wasmtime といったツールの背後にあるのと同じ分離モデルです。
QuickJS
WASM がサンドボックスを提供しますが、その内部でコードを実行するものも必要です。それが QuickJS の役割です:純粋な C で書かれた、小さく高速で ECMA 準拠の JavaScript エンジンです。サイズが小さいため、境界線内の信頼済み領域(trusted surface)を最小限に抑えられ、WASM へもクリーンにコンパイルできるため、エンジン自体が境界線の隣ではなくその背後に位置します。また、JavaScript はこの作業にも適しています:コンパイルステップなしでオーケストレーションロジックを記述するのに十分な表現力があり、これはエージェントが生成する短いプログラムのまさに形です。
Capability isolation
実行境界は、エージェントがホストを侵害することを防ぎますが、何を行うことを「許可」されているかについては何も語りません。エージェントの有用性と危険性は、私たちが付与する機能(capabilities)次第です。
結婚式を計画するエージェントを想像してください。有用であるためには、あらゆる場所から機密データ(契約書、RSVP 返信、家族グループチャットなど)を読み取り、外部でそれに基づいて行動する必要があります(ベンダーへのメール送信、入金の承認など)。各機能は単独では妥当ですが、これらを一つの自律的なループに組み合わせると、たった一つの敵対的な RSVP によって、プライベートな予算が読み取られ、ベンダーへ「承認された」変更をメールで送られてしまう可能性があります。
Meta の ルール・オブ・ツー はこの制約を捉えています:プロンプトインジェクションの問題が解決されるまで、エージェントは以下のうち 2 つ以上のことは行ってはなりません:
- 機密データにアクセスする
- 信頼できないコンテンツに晒される
- 状態を変更したり外部と通信したりする
ここが、インタプリタと従来のサンドボックスが最も分かれる点です。サンドボックスはコンピュータの形(ファイルシステム、依存関係、シェルなど)からスタートするため、そのセキュリティ作業は*減算的*になります:広範な権限から始めて、それを徐々に剥ぎ取っていくのです。一方、コードインタプリタは何もない状態からスタートします。そのままではファイルを読み込めず、ネットワークリクエストを送信できず、依存関係もインストールできません。持っているのは言語そのものだけです:変数、関数、オブジェクト、ループ、条件分岐など。より強力な機能はすべて、ハネスを通じて意図的に橋渡しされます。
image.png)
橋渡し機能の最も明確な例は、コード内でサブエージェントを呼び出すことです。プロセスマネージャやネットワークスタックの代わりに、エージェントは狭い契約を持つ関数を受け取り、ハネスが実行を担当します。この橋渡しを私たちが所有しているため、その制限も私たちが設定します:同時に実行できるサブエージェントの数、および単一の呼び出しで生成できる数の上限です。
Durable pauses
実行の隔離と機能制限により、実行中のプログラムは安全に保たれます。最後の要件は、それを「生きた状態」で維持することです。本番環境向けのエージェントは、危険な行為を行う前に停止して人間の承認を待つ必要がありますが、その承認は数秒後、数時間後、あるいは数日後に来ることもあり、エージェントがプロセスから退去したずっと後のことにもなり得ます。では、半分の状態でプログラムを長く一時停止し、どこで止まったかを正確に再開するにはどうすればよいのでしょうか?
QuickJS は WASM 内で実行されるため、プログラム自体を再構築するのではなく、プログラムそのものを一時停止できます。インタプリタの線形メモリを LangGraph の状態にシリアライズし、再開時にはハネスがスナップショットを復元して、それを待っていた呼び出しに戻す結果をフィードバックします。プログラム側からは、応答までに時間がかかった非同期呼び出しとしてしか見えません。
Try it
この仕組みを支える 2 つのパッケージが現在公開されています(どちらも実験段階です):
- quickjs-rs — WASM を通じて QuickJS を実行するためのランタイムおよび Python バインディング。
- langchain-quickjs — quickjs-rs を基盤とした Deep Agents のミドルウェア。
これらの本番環境への導入に向けて数社の緊密なパートナーと協力しており、その展開から得た教訓をもとにランタイムの強化を進めています。インタプリタが実際に何を実現できるかを知りたい方は、Dynamic Subagents に関する当社の投稿をお読みいただくか、ぜひご自身でお試しください!
uv add deepagents langchain-quickjs
from deepagents import create_deep_agent
from langchain_quickjs import CodeInterpreterMiddleware
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
middleware=[CodeInterpreterMiddleware()]
)
Related content

Open Source
Deep Agents
Agent Architecture
Introducing Dynamic Subagents in Deep Agents



S. Runkle,
C. Francis,
H. Lovell
June 29, 2026
9
min

Deep Agents
Open Source
Prompt Caching with Deep Agents

Alex Olsen
June 26, 2026
5
min

Deep Agents
Open Source
Agent Architecture
ループ工学の芸術

シドニー・ランクル
2026 年 6 月 16 日
7
分
エージェントが実際に行っていることを確認する
LangSmith は、開発者がエージェントのすべての意思決定をデバッグし、変更の評価を行い、ワンクリックでデプロイできるためのエージェント工学プラットフォームです。
原文を表示
Running Untrusted Agent Code Without a Sandbox

We recently introduced dynamic subagents in Deep Agents: instead of dispatching subagents one tool call at a time, we let the agent write a short script that orchestrates them. That script runs in a code interpreter, where agents write and execute code.
It's a powerful pattern, but it rests on something deceptively hard:
*It's hard to run untrusted code securely and reliably.*
Running untrusted code is a well-studied problem. Running code written by an agent influenced by untrusted input isn't. Since prompt injection remains unsolved, we have to assume agent-written code will eventually do something it shouldn't be allowed to do. Instead of trusting the agent to behave, we constrain what it can do. To make a trustworthy agent this way that comes down to three design requirements:
- Execution isolation: agent-written code can't compromise the host it runs on.
- Capability isolation: the agent can only touch the data and actions we deliberately hand it.
- Durable pauses: execution can stop for human input and resume later without losing its place.
At Interrupt 2026, we announced two offerings built around those requirements.
- LangSmith Sandboxes give an agent a full remote container: roughly the same freedom as a local coding agent, but isolated on a different machine.
- Code Interpreters for Deep Agents take the opposite tack: a smaller runtime where the agent can write and run programs, but only inside the harness we provide.
We've already written about the first kind of sandbox. This post is about the second: why orchestration workflows don’t necessarily need a sandboxed computer, and how we keep a smaller surface without giving up the isolation that makes sandboxes appealing in the first place.
Execution isolation
Everyone who runs untrusted code reaches the same conclusion: you need a hard boundary between it and everything else. An interpreter needs that boundary too without leaving the process, which is what we use WebAssembly for.
WebAssembly
WebAssembly (WASM) is a compact binary format that executes inside a sandboxed, in-process VM with its own memory, and can only interact with the outside world through host-provided capabilities. That separate linear memory is the crux of the boundary: code running inside WASM can't dereference pointers into the host process, so it can't read or corrupt memory it wasn't handed. WASM runtimes make hard memory and execution limits straightforward to enforce, and because it runs alongside the harness, we can instrument it without standing up a separate machine.
AWS, Shopify, and Figma all reach for WASM to run untrusted code on their platforms, and it's the same isolation model behind tools like WebContainers and wasmtime.
QuickJS
WASM gives us the sandbox; we still need something to run code inside it. That's what QuickJS is for: a small, fast, ECMA-compliant JavaScript engine written in plain C. It's small, which keeps the trusted surface inside the boundary small, and it compiles cleanly to WASM, so the engine itself sits behind the boundary rather than beside it. JavaScript is also a good fit for the work: it's expressive enough to write orchestration logic without a compile step, which is exactly the shape of the short programs agents produce.
Capability isolation
The execution boundary stops the agent from compromising the host, but says nothing about what it's *allowed* to do. An agent is only as useful, and only as dangerous, as the capabilities we give it.
Picture an agent planning a wedding. To be useful it has to read sensitive data from everywhere (contracts, RSVPs, the family group chat) and act on it externally (email vendors, approve a deposit). Each capability is reasonable on its own; combine them in one autonomous loop and a single hostile RSVP can read the private budget and email a vendor "approved" changes.
Meta's rule of two captures this constraint: until prompt injection is solved, an agent should be able to do no more than two of the following:
- access sensitive data
- be exposed to untrusted content
- change state or communicate externally
This is where interpreters and traditional sandboxes diverge most. A sandbox starts computer-shaped (filesystem, dependencies, a shell), so its security work is *subtractive*: you begin with broad capability and claw it back. A code interpreter starts with nothing. Out of the box it can't read a file, make a network request, or install a dependency. All it has is the language: variables, functions, objects, loops, conditionals, etc. Everything more powerful is bridged in deliberately through the harness.
.png)
The clearest example of a bridged capability is calling subagents in code. Instead of a process manager or network stack, the agent gets a function with a narrow contract, and the harness handles the execution. Because we own that bridge, we also set its limits: how many subagents can run at once, and how many a single call can spawn.
Durable pauses
Execution isolation and capability limits keep a running program safe; the last requirement is keeping it *alive*. A production-ready agent has to stop and wait for a human before doing something risky, and that approval can come back in seconds, hours, or days, often long after the agent has been evicted from the process. So how do you pause a half-finished program for that long and pick up exactly where it left off?
Because QuickJS runs inside WASM, we can pause the program itself instead of rebuilding it. We serialize the interpreter's linear memory to LangGraph state, and on resume the harness restores the snapshot and feeds the result back into the call that was waiting on it. The program sees only an async call that took a while to return.
Try it
Two of the packages behind this are now public, both experimental:
- quickjs-rs — the runtime and Python bindings for running QuickJS through WASM.
- langchain-quickjs — a Deep Agents middleware built on quickjs-rs.
We're working with a few close partners to bring them into production and tightening the runtime as we learn from those deployments. If you want to see what the interpreter actually unlocks, read our post on Dynamic Subagents, or just go and try it for yourself!
uv add deepagents langchain-quickjs
from deepagents import create_deep_agent
from langchain_quickjs import CodeInterpreterMiddleware
agent = create_deep_agent(
model="baseten:zai-org/GLM-5.2",
middleware=[CodeInterpreterMiddleware()]
)
Related content

Open Source
Deep Agents
Agent Architecture
Introducing Dynamic Subagents in Deep Agents



S. Runkle,
C. Francis,
H. Lovell
June 29, 2026
9
min

Deep Agents
Open Source
Prompt Caching with Deep Agents

Alex Olsen
June 26, 2026
5
min

Deep Agents
Open Source
Agent Architecture
The Art of Loop Engineering

Sydney Runkle
June 16, 2026
7
min
See what your agent is really doing
LangSmith, our agent engineering platform, helps developers debug every agent decision, eval changes, and deploy in one click.
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み