Scaling Managed Agents: Decoupling the brain from the hands
ースケールする統率されたエージェント群: 脳を手から切り離すー
こんにちは。yamamotoです。
私は非エンジニアですが、Anthropicからエージェントハーネスをホストサービス上で簡単に設計するサービスMaganed Agentsが発表され、これまでエンジニア含むAIエージェント界隈でハーネス設計の熱い議論が交わされていた中、その構築コストが格段に下がりました。
今回はそれと同時に公開された記事を非エンジニアの視点で補足しながら丁寧に説明します。
Key Message: ここだけ読めばわかる!メタ・ハーネスという設計哲学
OSがハードウェアを汎用的な抽象概念へと仮想化することで数十年にわたって存続してきたように、Managed Agentsは 未来のハーネス、サンドボックス、その他のコンポーネントを収容できるシステム として設計されています。
中央の Harness(脳)が司令塔として位置し、4つのコンポーネントと点線の矢印で接続されています。
左に Session(イベントログ)
右に Sandbox(コード実行環境)
上に Tools + Resources / MCP(外部ツール群)
下に Orchestration(起動・リトライのスケジューラ)
ポイントは各コンポーネントが薄いインターフェースのみで結ばれており、密結合ではないことを視覚的に表現しています。
どのパーツも独立して故障・交換可能であるという、記事全体の「脳と手を切り離す」設計思想がこの1枚に凝縮されています。
Managed Agentsは メタ・ハーネス であり、Claudeが将来必要とする特定のハーネスについて独自の主張を持ちません。Claude Codeのような汎用ハーネスも、特定ドメインに特化したハーネスも、すべてを収容できます。
メタ・ハーネス設計の要点は以下の通り。
| 設計方針 | opinionated(定型化する) | unopinionated(柔軟にする) |
|---|---|---|
| 対象 | インターフェースの形 | その裏で動く実装 |
| 具体例 | セッション操作、サンドボックス実行の能力 | 脳や手の数・場所 |
| 保証 | 長期間の信頼性とセキュリティ | 将来のモデルや制御手法への適応 |
以下記事本文を全文解説します。
"Harnesses encode assumptions that go stale as models improve. Managed Agents—our hosted service for long-horizon agent work—is built around interfaces that stay stable as harnesses change."
ハーネスには、モデルが進化するにつれて陳腐化する前提条件が組み込まれている。それに対し、長期的なエージェント作業のためのホスト型サービスである「Managed Agents」は、ハーネスがどれほど変化しようとも、安定し続けるインターフェースを中心に構築されている。
Get started with Claude Managed Agents by following our docs.
Claude Managed Agentsの説明を我々のドキュメンテーションを振り返るとところから始めよう。
A running topic on the Engineering Blog is how to build effective agents and design harnesses for long-running work. A common thread across this work is that harnesses encode assumptions about what Claude can’t do on its own. However, those assumptions need to be frequently questioned because they can go stale as models improve.
エンジニアリングブログで継続的に取り上げているテーマは、いかにして効果的なエージェントを構築し、長期にわたる作業(long-running work)のためのハーネスを設計するかである。
これら一連の取り組みに共通しているのは、「ハーネスには、Claudeが自力ではできないことに関する前提条件が組み込まれている」という点だ。
しかし、モデルが進化するにつれてそれらの前提条件は陳腐化(go stale)していくため、頻繁に問い直す必要がある。
【非エンジニアの補足】
ハーネスとは本質的にAIエージェントをコントロールしたり、限界を補うための仕組みです。
たとえばコンテキスト窓の上限に近づくとタスクを早期に切り上げてしまう挙動に対して、ハーネス側でコンテキストリセットを組み込んで対処していました。
しかしモデルが進化するとその振る舞い自体が消失し、リセット機構はただの無駄になった事例を挙げています。
つまり、ハーネスに埋め込まれた補助機構は、モデルの世代交代によって不要になるか、場合によっては性能を阻害する負債にすらなりえます。
Anthropicがここで提起しているのは、ハーネスの具体的な実装に依存しない、安定したインターフェースの層をどう設計するかという問いということです。
As just one example, in prior work we found that Claude Sonnet 4.5 would wrap up tasks prematurely as it sensed its context limit approaching—a behavior sometimes called “context anxiety.” We addressed this by adding context resets to the harness. But when we used the same harness on Claude Opus 4.5, we found that the behavior was gone. The resets had become dead weight.
一例を挙げれば、以前の取り組みにおいて、Claude Sonnet 4.5はコンテキストの限界が近づいていることを察知すると、タスクを途中で切り上げてしまうことがあった。これは「コンテキスト不安(context anxiety)」とも呼ばれる振る舞いである。我々はこれに対し、ハーネスに「コンテキスト・リセット」の機能を加えることで対処した。しかし、同じハーネスをClaude Opus 4.5で使用したところ、その振る舞いは消失していた。リセット機能は「デッドウェイト(無用の長物)」と化していたのである。
We expect harnesses to continue evolving. So we built Managed Agents: a hosted service in the Claude Platform that runs long-horizon agents on your behalf through a small set of interfaces meant to outlast any particular implementation—including the ones we run today.
我々は、ハーネスが今後も進化し続けると予想している。そこで、Managed Agentsを構築した。これはClaude Platformにおけるホスト型サービスであり、今日我々が運用しているものも含め、特定の実装よりも長生きすることを意図した最小限のインターフェース・セットを通じて、ユーザーの代わりに長期にわたるエージェント作業を実行するものである。
Building Managed Agents meant solving an old problem in computing: how to design a system for “programs as yet unthought of.” Decades ago, operating systems solved this problem by virtualizing hardware into abstractions—process, file—general enough for programs that didn't exist yet. The abstractions outlasted the hardware. The read() command is agnostic as to whether it’s accessing a disk pack from the 1970s or a modern SSD. The abstractions on top stayed stable while the implementations underneath changed freely.
Managed Agentsを構築するということは、コンピューティングにおける古くからの課題を解決することと同じだった。それは、まだ考案もされていないプログラム(programs as yet unthought of)のためのシステムをいかに設計するか、という課題である。
数十年前、オペレーティングシステム(OS)は、ハードウェアを「プロセス」や「ファイル」といった概念へ抽象化することで、この問題を解決した。
これらの抽象概念は、当時まだ存在していなかったプログラムにも対応できるほど汎用的なものであった。結果として、抽象概念はハードウェアよりも長生きすることとなった。
例えば read() コマンドは、アクセス先が1970年代のディスクパックであろうと現代のSSDであろうと、それを区別しない(agnostic)。
下層の実装が自由に入れ替わる一方で、その上に位置する抽象概念は安定し続けたのである。
【非エンジニアの補足】
Anthropicは今回提案するManaged Agentsの設計思想を正当化しています。具体的には、OSがディスクパックからSSDへのハードウェア進化をread()という抽象化で吸収したように、Managed Agentsもsession(イベントログ)、harness(Claudeを呼びツール呼び出しをルーティングするループ)、sandbox(コード実行環境)という3つの抽象を定義し、その背後の実装を自由に入れ替え可能にしています。
| 時代・対象 | 下層の実装 (Implementation) | 安定したインターフェース (Abstraction) |
|---|---|---|
| 1970年代のPC | 巨大な磁気ディスクパック |
read() コマンド |
| 現代のPC | 超高速なNVMe SSD |
read() コマンド |
| 現在のエージェント | Sonnet 4.5 + リセットロジック | session.fetch() |
| 未来のエージェント | 超知能モデル + 未知の制御法 | session.fetch() |
Managed Agents follow the same pattern. We virtualized the components of an agent: a session (the append-only log of everything that happened), a harness (the loop that calls Claude and routes Claude’s tool calls to the relevant infrastructure), and a sandbox (an execution environment where Claude can run code and edit files). This allows the implementation of each to be swapped without disturbing the others. We're opinionated about the shape of these interfaces, not about what runs behind them.
Managed Agentsもまた、同じパターンに従っている。我々はエージェントの構成要素を仮想化した。すなわち
| 抽象 | 定義 | 役割 |
|---|---|---|
| Session | 起きたことすべてを記録する追記型のログ | 状態の永続化と復旧 |
| Harness | Claudeを呼び出し、ツール呼び出しを関連インフラへルーティングするループ | 推論と制御のオーケストレーション |
| Sandbox | Claudeがコードを実行し、ファイルを編集できる実行環境 | 計算とアクションの実行 |
である。
これにより、互いに干渉することなく、それぞれの実装を入れ替えることが可能になった。
我々の設計原則は、このようにインターフェースの形には意見を持つ=定型化が必要(opinionated)だが、その裏で何が動くかには意見を持たない=柔軟でよいと考える(unopinionated)。
これにより将来のモデル進化やハーネスの刷新に対して、システム全体が壊れない構造を実現している。
※Anthropicの経験に基づく話、このセクションは読み飛ばしても大丈夫です
Don’t adopt a pet
入れ替えの効かない大事なペットを飼うな、取り換えの効く家畜を飼え。
We started by placing all agent components into a single container, which meant the session, agent harness, and sandbox all shared an environment. There were benefits to this approach, including that file edits are direct syscalls, and there were no service boundaries to design.
私たちは、まずすべてのエージェント構成要素を単一のコンテナに配置することから始めた。これは、セッション、エージェントハーネス、およびサンドボックスがすべて同一の環境を共有することを意味していた。このアプローチには、ファイル編集が直接的なシステムコール(syscall)で行えることや、設計すべきサービス境界が存在しないことなど、いくつかの利点があった。
But by coupling everything into one container, we ran into an old infrastructure problem: we’d adopted a pet. In the pets-vs-cattle analogy, a pet is a named, hand-tended individual you can’t afford to lose, while cattle are interchangeable. In our case, the server became that pet; if a container failed, the session was lost. If a container was unresponsive, we had to nurse it back to health.
しかし、すべてを一つのコンテナに結合したことで、私たちはインフラストラクチャにおける古くからの問題に直面した。つまり、ペットを飼い始めてしまったのである。
「ペット vs 家畜(pets-vs-cattle)」の比喩において、「ペット」とは名前を付け、手塩にかけて育て、失うわけにはいかない個体のことを指す。対して「家畜」は、代替可能な存在である。
私たちのケースでは、サーバーがその「ペット」になってしまった。
もしコンテナが故障すれば、セッション(記憶)は失われる。もしコンテナの反応がなくなれば、私たちはそれを手厚く看病して(復旧させて)やらなければならなかったのである。
Nursing containers meant debugging unresponsive stuck sessions. Our only window in was the WebSocket event stream, but that couldn’t tell us where failures arose, which meant that a bug in the harness, a packet drop in the event stream, or a container going offline all presented the same. To figure out what went wrong, an engineer had to open a shell inside the container, but because that container often also held user data, that approach essentially meant we lacked the ability to debug.
コンテナの「看病」とは、応答しなくなったセッションのデバッグ作業をすることだ。私たちの唯一の手がかりはWebSocketのイベントストリームであったが、それだけではどこで障害が発生したのかを特定できなかった。つまり、ハーネスのバグ、イベントストリームのパケットロス、あるいはコンテナのオフライン化、これらすべてが同じ現象として現れてしまったのである。
何が起きたのかを突き止めるには、エンジニアがコンテナ内部でシェルを開く必要があった。しかし、そのコンテナにはユーザーデータも保持されていることが多かったため、このアプローチは事実上、私たちには「デバッグ能力が欠如している」ということを意味していた。
【非エンジニアの補足】
WebSocketは「現在進行形のデータ」を流すことには適しているが、過去の内部状態を保存するものではない。障害発生時に通信が途絶すると、外部からはコンテナ内部の状態を追跡する術を失う。すべてのコンポーネントが単一コンテナに集約されていたため、WebSocketの接続が切れた際、その原因が「ハーネスのロジックエラー」なのか、「インフラのネットワーク障害」なのか、「コンテナ自体のクラッシュ」なのかを外部から判別する手段がなかった。
A second issue was that the harness assumed that whatever Claude worked on lived in the container with it. When customers asked us to connect Claude to their virtual private cloud, they had to either peer their network with ours, or run our harness in their own environment. An assumption baked into the harness became a problem when we wanted to connect it to different infrastructure.
第二の課題は、ハーネスが「Claudeが作業する対象は、すべて同一コンテナ内に存在する」という前提で設計されていたことである。
顧客から「Claudeを自社のVPC(仮想プライベートクラウド)に接続したい」という要望を受けた際、顧客は自社ネットワークを我々のネットワークとピアリング(接続)するか、あるいは我々のハーネスを顧客自身の環境で実行するかの二択を迫られることになった。
ハーネスに固着(baked into)した前提条件が、異なるインフラストラクチャへ接続しようとする際の障壁となったのである。
※飛ばした人はここから読んでください。
Decouple the brain from the hands
そこで脳と手を切り分けた。
【非エンジニアの補足】
ここで提案される抽象化されたコマンド(psueudocode)を表にまとめます。
| Component | Interface (pseudocode) | Satisfied by |
|---|---|---|
| Session |
getSession(session_id) → (Session, Event[]), getEvents(session_id) → PendingEvent[], emitEvent(id, event)
|
任意のイベント地点から順序通りに消費でき、追記を受け付け(Postgres, SQLite, インメモリ配列など) |
| Orchestration | wake(session_id) → void |
IDを受け取って関数を呼び出し、失敗時にリトライできる任意のスケジューラ(cronジョブ、キューコンシューマ、whileループなど) |
| Harness | yield Effect<T> → EffectResult<T> |
エフェクトをyieldし、進捗をSessionに追記する任意のループ |
| Sandbox |
provision({resources}), execute(name, input) → String
|
一度構成され、ツールとして何度でも呼び出せる任意のエクゼキュータ(ローカルプロセス、リモートコンテナなど) |
| Resources | [{source_ref, mount_path}] |
コンテナが参照で取得できる任意の永続ストア(Filestore, GCS, git remote, S3など) |
| Tools | {name, description, input_schema} |
名前と入力スキーマで記述できる任意の機能(MCPサーバー、カスタムツールなど) |
The solution we arrived at was to decouple what we thought of as the “brain” (Claude and its harness) from both the “hands” (sandboxes and tools that perform actions) and the “session” (the log of session events). Each became an interface that made few assumptions about the others, and each could fail or be replaced independently.
我々が辿り着いた解決策は、「脳」(Claudeとハーネス)を、「手」(アクションを実行するサンドボックスやツール)および「セッション」(セッションイベントのログ)の両方から切り離すことであった。
各要素は、互いに対する前提条件をほとんど持たない「インターフェース」へと進化した。これにより、それぞれのコンポーネントが独立して故障し、あるいは独立して置換されることが可能になったのである。
The harness leaves the container. Decoupling the brain from the hands meant the harness no longer lived inside the container. It called the container the way it called any other tool: execute(name, input) → string. The container became cattle. If the container died, the harness caught the failure as a tool-call error and passed it back to Claude. If Claude decided to retry, a new container could be reinitialized with a standard recipe: provision({resources}). We no longer had to nurse failed containers back to health.
「脳」を「手」から切り離したことで、ハーネスはもはやコンテナの内部には存在しなくなった。ハーネスは、他のあらゆるツールを呼び出すのと同様の方式で、コンテナを呼び出すようになった。すなわち
execute(name, input) → string
というインターフェースである。
これにより、コンテナは取り換えの効く家畜となった。もしコンテナが死んでも、ハーネスはその失敗を「ツール呼び出しエラー」として捉え、Claudeにそのまま返す。
Claudeがリトライを決定すれば、標準的な
provision({resources})
を使って、新しいコンテナを即座に再初期化できる。
我々はもはや、故障したコンテナを「看病」して復旧させる必要がなくなったのである。
Recovering from harness failure. The harness also became cattle. Because the session log sits outside the harness, nothing in the harness needs to survive a crash. When one fails, a new one can be rebooted with wake(sessionId), use getSession(id) to get back the event log, and resume from the last event. During the agent loop, the harness writes to the session with emitEvent(id, event) in order to keep a durable record of events.
ハーネスもまた取り換えの効く家畜となった。セッションログがハーネスの外部に置かれているため、ハーネス内のいかなる要素もクラッシュを生き延びる(永続化する)必要がなくなったからである。
あるハーネスが故障した際、新しい個体を wake(sessionId) で再起動し、 getSession(id) を使ってイベントログを回収すれば、最後のイベントから作業を再開できる。
エージェントのループ実行中、ハーネスはイベントの永続的な記録を維持するために、emitEvent(id, event) を用いてセッションへの書き込みを行う。
| 操作 | インターフェース | 役割 |
|---|---|---|
| 再起動 | wake(sessionId) |
新しいハーネスを立ち上げる |
| ログ回収 | getSession(id) |
イベントログを取得する |
| イベント記録 | emitEvent(id, event) |
永続的なイベント記録を維持する |
The security boundary.
セキュリティ境界の確立
In the coupled design, any untrusted code that Claude generated was run in the same container as credentials—so a prompt injection only had to convince Claude to read its own environment. Once an attacker has those tokens, they can spawn fresh, unrestricted sessions and delegate work to them. Narrow scoping is an obvious mitigation, but this encodes an assumption about what Claude can't do with a limited token—and Claude is getting increasingly smart. The structural fix was to make sure the tokens are never reachable from the sandbox where Claude’s generated code runs.
これまでの密結合な設計においては、Claudeが生成した「信頼できないコード」も認証情報と同じコンテナ内で実行されていた。
そのため、プロンプト・インジェクション攻撃によってClaudeに自分自身の環境変数を読み取らせるだけで、攻撃が成立してしまうリスクがあった。
一度攻撃者にこれらのトークンを奪われれば、制限のない新しいセッションを勝手に立ち上げられ、タスクを代行されてしまう恐れがある。
「トークンのスコープ(権限範囲)を狭める」というのは明白な緩和策ではあるが、これ自体が「限定的なトークンさえあれば、Claudeにはこれ以上のことはできないだろう」という前提条件をシステムに組み込むことに他ならない。そして、Claudeは日に日に賢くなっている。
構造的な解決策は、Claudeが生成したコードが動く「サンドボックス」から、トークンが決して到達できない状態にすることであった。
【非エンジニアの補足】
・以前の密結合:
一つの部屋(コンテナ)の中に、「脳(ハーネス)」と「手(サンドボックス)」、そして「金庫の鍵(トークン)」が同居していた。手が脳を騙せば、すぐに鍵に手が届く状態だった。
・新しい疎結合:
「脳」は安全な管理区域(Managed Agentsのホスト環境)に置かれ、鍵(トークン)もそこに保管される。「手」は遠隔地にある完全に隔離された部屋(サンドボックス)に置かれるため、絶対に安全。
We used two patterns to ensure this. Auth can be bundled with a resource or held in a vault outside the sandbox. For Git, we use each repository’s access token to clone the repo during sandbox initialization and wire it into the local git remote. Git push and pull work from inside the sandbox without the agent ever handling the token itself. For custom tools, we support MCP and store OAuth tokens in a secure vault. Claude calls MCP tools via a dedicated proxy; this proxy takes in a token associated with the session. The proxy can then fetch the corresponding credentials from the vault and make the call to the external service. The harness is never made aware of any credentials.
これを確実にするために、我々は2つのパターンを採用した。認証情報は、リソースにバンドル(同梱)されるか、あるいはサンドボックス外のヴォルト(保管庫)に保持される。
- リソースへのバンドル(Gitの例)
Gitの場合、サンドボックスの初期化時に各リポジトリのアクセストークンを使用してリポジトリをクローンし、それをローカルの git remote に組み込んで(wire into)おく。これにより、エージェント自身がトークンを直接扱うことなく、サンドボックス内部から git push や pull を実行できるようになる。
/ - 外部ヴォルトとプロキシ(カスタムツールの例)
カスタムツールについては、MCPをサポートし、OAuthトークンを安全なヴォルトに保存する。Claudeは専用のプロキシを介してMCPツールを呼び出す。プロキシの役割: セッションに関連付けられた「識別用トークン」を受け取る。認証の代行: プロキシは、その識別用トークンに対応する「実際の認証情報」をヴォルトから取得し、外部サービスへの呼び出しを行う。この仕組みにより、ハーネス(脳)が認証情報を知ることは一切ない。
The session is not Claude’s context window
ーセッションはClaudeのコンテキストウィンドウではないー
Long-horizon tasks often exceed the length of Claude’s context window, and the standard ways to address this all involve irreversible decisions about what to keep. We’ve explored these techniques in prior work on context engineering. For example, compaction lets Claude save a summary of its context window and the memory tool lets Claude write context to files, enabling learning across sessions. This can be paired with context trimming, which selectively removes tokens such as old tool results or thinking blocks.
コンテキスト・エンジニアリングの主な手法
Compaction: 膨大な履歴をギュッと要約して圧縮する重要な流れを残しつつ、トークン消費を抑える
Memory Tool: 外部ファイルに知識や進捗を書き出すセッションが終了しても、次回以降に情報を引き継げる
Trimming: 不要になった古いデータ(出力ログなど)を削る窓枠(コンテキスト)が溢れるのを物理的に防ぐ
これらの技術は便利だが、本質的には「情報の取捨選択」を迫るものであり、一度捨ててしまった情報は二度と参照できないというリスクを孕んでいる。
Managed Agentsは、この課題に対してさらに踏み込んだアプローチを取る。
But irreversible decisions to selectively retain or discard context can lead to failures. It is difficult to know which tokens the future turns will need. If messages are transformed by a compaction step, the harness removes compacted messages from Claude’s context window, and these are recoverable only if they are stored. Prior work has explored ways to address this by storing context as an object that lives outside the context window. For example, context can be an object in a REPL that the LLM programmatically accesses by writing code to filter or slice it.
コンテキストを選択的に保持したり破棄したりするという「取り返しのつかない決断」は、失敗を招く可能性がある。将来のターンでどのトークンが必要になるかをあらかじめ知ることは困難だからだ。
コンパクション(要約・圧縮)のステップによってメッセージが変換される際、ハーネスは圧縮された元のメッセージをClaudeのコンテキストウィンドウから削除する。これらは、別途保存されていない限り復元することはできない。
これまでの研究では、コンテキストをコンテキストウィンドウの外部に存在するオブジェクトとして保存することで、この問題に対処する方法が探求されてきた。
例えば、コンテキストをREPL内のオブジェクトとして扱い、LLMがコードを書いてフィルタリングやスライシング(切り出し)を行うことで、プログラム的にアクセスできるようにする手法などが挙げられる。
In Managed Agents, the session provides this same benefit, serving as a context object that lives outside Claude’s context window. But rather than be stored within the sandbox or REPL, context is durably stored in the session log. The interface, getEvents(), allows the brain to interrogate context by selecting positional slices of the event stream. The interface can be used flexibly, allowing the brain to pick up from wherever it last stopped reading, rewinding a few events before a specific moment to see the lead up, or rereading context before a specific action.
Managed Agentsにおいて、セッションはこれと同じ利点を提供し、Claudeのコンテキストウィンドウの外部に存在するコンテキストオブジェクトとして機能する。しかし、コンテキストはサンドボックスやREPLの中に保存されるのではなく、セッションログに永続的に保存される。
インターフェースである
getEvents() // イベントストリームの任意位置のスライスを選択してコンテキストを照会
は、イベントストリームの任意の位置のスライスを選択することで、脳がコンテキストを照会することを可能にする。
このインターフェースは柔軟に使用でき、最後に読み終えた場所から再開したり、特定の瞬間の数イベント前まで巻き戻して経緯を確認したり、あるいは特定のアクションの前にコンテキストを読み直したりすることを可能にする。
【非エンジニアの補足】
従来のアプローチでは、コンテキスト(会話履歴や作業記録)はClaudeの「頭の中」(コンテキストウィンドウ)か、作業場(サンドボックス/REPL)の中にしか存在しませんでした。頭の中には容量制限があり、作業場はコンテナごと消える可能性があります。
Managed Agentsでは、これを「外部の議事録」に置き換えています。
getEvents() は、この議事録の好きなページを開いて読み返せる栞のような仕組みです。たとえば「3時間前にどんな判断をしたか」を確認したいとき、Claudeは議事録の該当箇所だけをピンポイントで参照できます。
議事録自体はセッションログとして永続的に保存されているため、コンテナが壊れても、ハーネスが再起動しても、記録が失われることはありません。
Any fetched events can also be transformed in the harness before being passed to Claude’s context window. These transformations can be whatever the harness encodes, including context organization to achieve a high prompt cache hit rate and context engineering. We separated the concerns of recoverable context storage in the session and arbitrary context management in the harness because we can’t predict what specific context engineering will be required in future models. The interfaces push that context management into the harness, and only guarantee that the session is durable and available for interrogation.
取得されたイベントは、Claudeのコンテキストウィンドウに渡される前に、ハーネス内で変換することもできる。これらの変換は、高いプロンプトキャッシュヒット率を達成するためのコンテキスト構成やコンテキストエンジニアリングなど、ハーネスがエンコード(定義)したものであれば何でも可能である。
将来のモデルでどのような特定のコンテキストエンジニアリングが必要になるか予測できないため、我々は「セッションにおける復旧可能なコンテキストストレージ」と「ハーネスにおける任意のコンテキスト管理」という関心事を分離した。インターフェースはコンテキスト管理の役割をハーネスへと押し出し、セッション側に対しては、それが永続的であり、照会(インターロゲーション)が可能であることのみを保証している。
Many brains, many hands
ー脳や手が多くてもいけるー
Many brains.
Decoupling the brain from the hands solved one of our earliest customer complaints. When teams wanted Claude to work against resources in their own VPC, the only path was to peer their network with ours, because the container holding the harness assumed every resource sat next to it. Once the harness was no longer in the container, that assumption went away. The same change had a performance payoff. When we initially put the brain in a container, it meant that many brains required as many containers. For each brain, no inference could happen until that container was provisioned; every session paid the full container setup cost up front. Every session, even ones that would never touch the sandbox, had to clone the repo, boot the process, fetch pending events from our servers.
脳と手を切り離したことで、初期の顧客からの苦情の1つが解決された。チームが自社のVPC内のリソースに対してClaudeを働かせたいと考えたとき、以前はネットワークを我々とピアリングするしか道がなかった。なぜなら、ハーネスを保持するコンテナが、あらゆるリソースは自分の隣にあるという前提を持っていたからである。ハーネスがコンテナ内に存在しなくなったことで、その前提は消滅した。
この変更はパフォーマンス面でも報われた。当初、脳をコンテナに入れていたときは、多くの脳(セッション)には同数のコンテナが必要であることを意味していた。それぞれの脳について、コンテナがプロビジョニングされるまで推論を開始できず、すべてのセッションがコンテナのセットアップコストを前払いで支払わなければならなかった。たとえ一度もサンドボックスに触れないセッションであっても、リポジトリをクローンし、プロセスを起動し、サーバーから保留中のイベントを取得しなければならなかった。
That dead time is expressed in time-to-first-token (TTFT), which measures how long a session waits between accepting work and producing its first response token. TTFT is the latency the user most acutely feels.
この「デッドタイム」は、セッションが仕事を受け入れてから最初の応答トークンを生成するまでの待ち時間を測定する、Time-To-First-Token(TTFT)に現れる。TTFTは、ユーザーが最も痛烈に感じるレイテンシである。
Decoupling the brain from the hands means that containers are provisioned by the brain via a tool call (execute(name, input) → string) only if they are needed. So a session that didn't need a container right away didn't wait for one. Inference could start as soon as the orchestration layer pulled pending events from the session log. Using this architecture, our p50 TTFT dropped roughly 60% and p95 dropped over 90%. Scaling to many brains just meant starting many stateless harnesses, and connecting them to hands only if needed.
脳と手を切り離したことで、コンテナは必要になった場合にのみ、ツール呼び出し
execute(name, input) → string
を通じて脳によってプロビジョニングされるようになった。
そのため、すぐにコンテナを必要としないセッションは、コンテナを待つ必要がなくなった。オーケストレーション層がセッションログから保留中のイベントを引き出した瞬間に推論を開始できるようになったのである。このアーキテクチャを採用したことで、我々のp50 TTFTは約60%低下し、p95は90%以上低下した。多くの脳へとスケーリングすることは、単に多くのステートレスなハーネスを起動し、必要に応じてのみ手と接続することを意味するようになった。
Many hands.
We also wanted the ability to connect each brain to many hands. In practice, this means Claude must reason about many execution environments and decide where to send work—a harder cognitive task than operating in a single shell. We started with the brain in a single container because earlier models weren't capable of this. As intelligence scaled, the single container became the limitation instead: when that container failed, we lost state for every hand that the brain was reaching into.
我々はまた、個々の脳を多くの手(many hands)に接続する能力も求めていた。実際問題として、これはClaudeが多くの実行環境について推論し、どこに作業を送り出すべきかを決定しなければならないことを意味する。これは、単一のシェル内で操作するよりも高度な認知タスクである。
Decoupling the brain from the hands makes each hand a tool, execute(name, input) → string: a name and input go in, and a string is returned. That interface supports any custom tool, any MCP server, and our own tools. The harness doesn’t know whether the sandbox is a container, a phone, or a Pokémon emulator. And because no hand is coupled to any brain, brains can pass hands to one another.
初期のモデルにはその能力がなかったため、当初は脳を単一のコンテナに入れて開始した。しかし、知能がスケールするにつれて、むしろ単一のコンテナが制限となった。
そのコンテナが故障すると、脳が手を伸ばしていたすべての実行環境の状態(state)が失われてしまったからである。
Conclusion
The challenge we faced is an old one: how to design a system for “programs as yet unthought of.” Operating systems have lasted decades by virtualizing the hardware into abstractions general enough for programs that didn't exist yet. With Managed Agents, we aimed to design a system that accommodates future harnesses, sandboxes, or other components around Claude.
我々が直面した課題は古くからあるもので、まだ考え出されていないプログラムのために、いかにシステムを設計するかという問題である。
オペレーティングシステムは、ハードウェアを十分に汎用的な抽象概念へと仮想化することで、まだ存在しなかったプログラムを受け入れ、数十年にわたって存続してきた。Managed Agentsにおいて我々が目指したのは、未来のハーネス、サンドボックス、あるいはClaudeを取り巻くその他のコンポーネントを収容できるシステムを設計することだ。
Managed Agents is a meta-harness in the same spirit, unopinionated about the specific harness that Claude will need in the future. Rather, it is a system with general interfaces that allow many different harnesses. For example, Claude Code is an excellent harness that we use widely across tasks. We’ve also shown that task-specific agent harnesses excel in narrow domains. Managed Agents can accommodate any of these, matching Claude’s intelligence over time.
Managed Agentsは同じ精神に基づいたメタ・ハーネスであり、Claudeが将来必要とするであろう「特定の」ハーネスについて独自の主張を持たない。
むしろ、多種多様なハーネスを許容する汎用的なインターフェースを備えたシステムである。
例えば、Claude Codeは我々が幅広いタスクで使用している優れたハーネスだ。また、特定の狭いドメインにおいては、タスク特化型のエージェント・ハーネスが優れていることも示されている。
Managed Agentsはこれらすべてを収容でき、進化し続けるClaudeの知能に長期的に適応することができる。
Meta-harness design means being opinionated about the interfaces around Claude: we expect that Claude will need the ability to manipulate state (the session) and perform computation (the sandbox). We also expect that Claude will require the ability to scale to many brains and many hands. We designed the interfaces so that these can be run reliably and securely over long time horizons. But we make no assumptions about the number or location of brains or hands that Claude will need.
メタ・ハーネスの設計ではClaudeを取り巻く「インターフェース」については定型化が必要と思う。
我々は、Claudeがセッションを操作し、サンドボックスを実行する能力が今後必要になることを予見している。
また、Claudeが「多くの脳」と「多くの手」にスケーリングする能力が必要になることも予見している。
我々は、これらが長期間にわたって信頼性高く、かつ安全に実行されるようインターフェースを設計した。
しかし、Claudeが必要とする脳や手の「数」や「場所」については、いかなる前提も設けていない。
