メニュー

AI

Anthropicの「脳と手を分ける」設計:Managed Agentsの作りとRustへの移植

公開
茹で時間
10 分
言語
日本語 · English

この記事で分かること

  • Managed Agentsは、エージェントを「セッション(出来事の記録)」「ハーネス(Claudeを呼ぶループ)」「サンドボックス(コードを動かす環境)」の3つに分け、どれかが落ちても残りで再開できる作りにしています
  • 生成したコードが動くサンドボックスには資格情報を入れず、Gitは初期化時に結び付け、MCPは保管庫とプロキシ経由で呼びます。コンテナを必要なときだけ用意する形にして、最初の応答までの時間の中央値は約60%減りました
  • Messages APIは、始めた時点ではRustの開発者がいなかったチームが、設計を人、実装をClaudeに分けてRustに移しました。旧版と同じ出力かを本番の通信の複製で確かめてから切り替え、CPUは40〜50%ほど減ったと話しています
目次(5項目)
  1. 3つの部品に分けた理由
  2. 資格情報をサンドボックスに置かない
  3. 待ち時間、手を置く場所、料金
  4. Messages APIの実装をClaudeに任せてRustに移す
  5. Opus 5.5の発表の裏側とDreams

エージェントの実行基盤を組むときは、どこまでを1つの箱に入れるかが問題になります。モデルを呼ぶループも会話の記録も、コードを実行する環境と同じコンテナに置けば、作るのは楽です。ただ、コンテナが落ちると全部を失いますし、外部のサービスの鍵もコードから読める場所に置くことになります。

ポッドキャストのLatent Spaceが10月27日に公開した回で、Claude Platformを率いる2人がこの問題への答えを「脳と手を分ける」という言い方で語っています。エンジニアリングのKatelyn Lesseさんと、プロダクトのAngela Jiangさんです。番組の要約は根拠としてAnthropicの技術記事「Scaling Managed Agents: Decoupling the brain from the hands」を挙げています。4月8日に公開された記事です。この記事では番組の話を技術記事と公式ドキュメントで確かめ、自分でエージェントを組むときに使える部分を拾います。

Anthropicの技術記事「Scaling Managed Agents」の画像。赤紫の地に、横に長い緑の格子と、縦に長い青の格子が中央で重なった図
出典:Scaling Managed Agents: Decoupling the brain from the hands(Anthropic Engineering)

3つの部品に分けた理由

Managed Agentsは、Claude Platformでエージェントを動かすホスト型のサービスで、4月8日に公開ベータとして始まりました。技術記事によると、エージェントは次の3つに分けてあります。

  • セッション: 起きたことを追記だけで残す記録
  • ハーネス: Claudeを呼び、Claudeのツール呼び出しを各所に振り分けるループ
  • サンドボックス: Claudeがコードを実行し、ファイルを編集する環境

記事はClaudeとハーネスを「脳」、サンドボックスとツールを「手」と呼んでいます。

最初は3つとも1つのコンテナに入れていたそうです。ファイルの編集がそのままシステムコールになり、サービスの境界を設計しなくて済む利点はありました。一方で、コンテナが落ちるとセッションごと失われました。応答しないセッションを調べるにはコンテナの中にシェルで入るしかなく、そのコンテナには利用者のデータも入っていたため、実質的にデバッグできなかったと書いています。顧客が自社の仮想ネットワーク(VPC)の資源にClaudeをつなぎたいときも、ネットワークを相互接続するか、ハーネスを顧客の環境で動かすしかありませんでした。

分けたあとのハーネスは、コンテナをほかのツールと同じようにexecute(name, input) → stringで呼びます。コンテナが落ちればツールの呼び出しのエラーとしてClaudeに返し、Claudeがやり直すと決めればprovision({resources})で新しいコンテナを用意します。ハーネスが落ちたときは、wake(sessionId)で新しいハーネスを起こし、getSession(id)で記録を取り戻して最後の出来事から再開する流れです。記録はハーネスの外にあるので、ハーネスの中には落ちても困るものが残りません。

資格情報をサンドボックスに置かない

分けた効果の1つがセキュリティの境界です。1つのコンテナの作りでは、Claudeが生成した信頼できないコードが資格情報と同じ場所で動いていました。攻撃者はプロンプトインジェクションでClaudeにコンテナの中を読ませるだけで、トークンを手に入れられる作りでした。技術記事によると、トークンの権限を絞る対策は「限られたトークンでClaudeに何ができないか」という前提に頼っていて、Claudeが賢くなるほど危うくなるということです。そこで、Claudeの生成したコードが動くサンドボックスから、トークンにそもそも届かないようにしました。

使っている形は2つあります。Gitでは、サンドボックスの初期化のときにリポジトリごとのアクセストークンでクローンし、ローカルのリモートに結び付けておきます。エージェントはトークンを触らずにpushとpullができるわけです。MCPのツールでは、OAuthのトークンを保管庫に置き、Claudeは専用のプロキシ経由でツールを呼びます。プロキシはセッションに結び付いたトークンを受け取り、保管庫から資格情報を取り出して外部のサービスを呼ぶので、ハーネスも資格情報を知りません。

利用者からはこの保管庫がvaultsという機能として見えます。外部のサービスの資格情報を一度登録し、セッションを作るときにIDで指定する形で、エンドユーザーごとに保管庫を分けられます。保管庫と資格情報はワークスペースの単位で共有され、取り消すときは保管庫か資格情報を消す仕様です。

番組では出口の制御も挙がっていました。サンドボックスの通信先を許可するドメインの一覧で絞るか、通信を全部止める方法です。ただし、許可の一覧があれば安全とは限りません。Anthropicは5月の記事「How we contain Claude across products」で、Claude Coworkで起きた事例を書いています。通信先の許可にapi.anthropic.comが入っていたことが原因でした。作業フォルダーに置かれた悪意のあるファイルに、攻撃者のAPIキーと隠れた指示が入っていて、Claudeはほかのファイルを攻撃者のアカウントにアップロードしました。宛先は許可したドメインなので、プロキシは通しています。Anthropicは許可の一覧を、宛先の絞り込みより「そのドメインで呼べる機能を全て渡すもの」と捉え直しました。その上で、仮想マシンに割り当てたセッションのトークン以外を拒むプロキシを足しています。自分で許可の一覧を作るときも、そのドメインで何ができるかまで見ておく必要がありそうです。

待ち時間、手を置く場所、料金

分けた効果は速さにも出ています。脳をコンテナに入れていたころは、サンドボックスを使わないセッションでも、コンテナの準備を待つ必要がありました。リポジトリをクローンし、プロセスを起動し、未処理の出来事を取ってくるまで、推論を始められなかったのです。分けたあとは脳がツールの呼び出しでコンテナを必要なときだけ用意します。技術記事によると、最初のトークンが返るまでの時間(TTFT)は、中央値で約60%、遅いほうから5%の値で90%以上減りました。

脳と手を1対1にしなくてよくなったので、1つの脳が複数の手を使い、脳どうしで手を渡すこともできます。手はどれも「名前と入力を渡すと文字列が返る」ツールなので、ハーネスはサンドボックスがコンテナなのか、スマートフォンなのかを知りません。

手を自社の環境に置く選択肢もあり、自分でホストするサンドボックスでは、Claudeは引き続きAnthropicの側で動き、ツールの実行だけを自社の基盤のワーカーが受け持ちます。ただし、ツールの入力と出力は、モデルが次の手を決めるためにAnthropicの制御基盤を通ります。ツールの結果もAnthropicに届く前提で、扱うデータを選んだほうがよさそうです。

料金はトークンの通常の料金に、セッションがrunningの間だけ1時間あたり0.08ドルが加わります(料金のページ)。次の入力やツールの承認を待っている時間は数えません。

Messages APIの実装をClaudeに任せてRustに移す

番組の後半は脳と手の話から離れて、Claude Platformそのものの作り直しの話になります。ゲストの1人が1年ほど前に入社したとき、Messages APIはPythonの大きな1つのアプリで、Google Cloudの1つのリージョンで動いていたそうです。利用が増えるにつれて足りなくなったのはGPUよりCPUで、APIの実行、サンドボックス、増えたコードのCIのどれもがCPUを使います。必要に応じて増やせたCPUを、前もって確保しなければならなくなったと話しています。

そこで、Messages APIをRustで書き直しました。始めた時点ではチームにRustの開発者が1人もおらず(途中で経験者を数人採用)、設計は人、実装はClaudeが受け持っています。番組で大事だったと挙げられたのは、計画と検証の2つです。

  1. APIをまるごとRustで複製した版を作る
  2. 本番の通信の複製を流し、Pythonの版とRustの版の出力が同じかを確かめる
  3. 出力が一致するのを確かめながら、少しずつRustの版に切り替える

書き直しに合わせて機能を足すことはせず、移植に徹したそうです。並行してほかのメンバーがPythonの版に機能を足し続けていたので、Rustの版で対応していない機能を足すと静的解析が知らせる仕組みも用意しました。収録の前の週に切り替えを終え、CPUは40〜50%ほど、TTFTは10〜20%ほど改善したと話しています。どちらも口頭での大まかな値で、Anthropicが文書で出した数字ではありません。

ゲストは番組の終わりでも、人がコードを1行ずつ細かく読むより、全体の計画と設計、それに検証の仕組みを重く見ていると話しています。Claude Codeのチームが、検証の手段をClaudeに渡し、作るべきかや設計の型は人が決めるとしていたのと同じ分け方です(Claude Codeチームのコードレビュー)。

Opus 5.5の発表の裏側とDreams

番組の冒頭ではOpus 5.5の発表の裏側も語られています。蒸留のために推論を抜き出されるのを防ぐ目的で、思考のブロックをターンをまたいで保つ仕組みを入れると、顧客の既存のハーネスが壊れることがあります。Fable 5.1でこの仕組みを入れたときは、既存の顧客に移行の猶予を与え、その対象者を管理するために社内の認可の仕組み(trust grants)を使ったそうです。自分のハーネスで思考のブロックを捨てたり書き換えたりしている場合は、モデルを替えるときにAPIの要件の変更を確かめたほうがよさそうです。

もう1つ、Managed Agentsの上に作った実験としてDreamsが挙がっていました。ドキュメントによると、既存の記憶と過去のセッションの記録を読み、重複をまとめ、古い記述を新しい値に置き換えた別の記憶を作ります。番組では「あるエージェントが別のエージェントの作業を読み、記憶を書き戻す」と説明しています。今は研究プレビューで、使うには専用のベータのヘッダーが必要です。

番組の要約は、落ちても残す必要があるのはどこか、信頼できない作業を実行するのはどこか、コードが動く場所に本当に必要な秘密は何か、という3つの問いを、エージェントの実行基盤を設計する人に向けて残しています。

udon
Microsoft 365、ServiceNow、Copilotなどを自ら検証し実務で使える「コシのある知見」を記録しています。