AI

囲いを作れば、手綱は要らない?

  • AI
  • エージェント
  • Claude Code
  • 権限設計
  • サンドボックス
  • ロボティクス

エージェントの成果を決めているのは、モデルの賢さよりも「何を観測できるか」と「何を触れるか」でした。観測手段は三段に増やし、書き込み権限は取り返しがつくかどうかで層に分けて、壊せない場所を先に作ることで承認そのものを減らしています。設定は公開しているので、実物を並べながら書きます。

同じモデルのまま、道具を変えるとスコアが変わる

主張を数字で支えている一次資料が1つあります。Princeton のチームが出した SWE-agent(NeurIPS 2024)です。

GPT-4 Turbo を固定したまま、素の Linux シェルを与えた場合と、エージェント向けに設計したインターフェースを与えた場合を比べています。モデルは一切変えていません。結果は後者が 10.7ポイント 多く解きました。論文の言い方が的確です。

LMエージェントは独自のニーズと能力を持つ新種のエンドユーザーであり、自分が使うソフトウェアに専用のインターフェースがあれば恩恵を受ける

同じことを Anthropic 側も書いています。Writing effective tools for AI agents は「エージェントは、我々が与えたツールの範囲でしか有効になれない」と書いています。multi-agent research system の記事には、ツールの説明文を書き直させるエージェントを1体立てただけでタスク完了時間が40%減った、という数字が出てきます。書き直したのは説明文だけです。

この話は新しくありません。Russell と Norvig の定義は、自律エージェントのリスクを論じた論文が両版を引用しているので、そちら経由で確認しました(原典は取得できていないので孫引きです)。1995年版は「エージェントとは、センサーを通じて環境を知覚し、エフェクターを通じてその環境に作用するものとして見なせる、あらゆるもののこと」と書き、2020年版では effectors が actuators に置き換わっています。語は変わっても、知覚と作用で定義する形は変わっていません。定義の中に「賢さ」は出てきません。

観測のほうを増やした

画面の見た目は、数値ゲート、オフスクリーンでのPNG書き出し、実際の導線を起動しての撮影という三段で確認しています。段が3つあるのは、前の段が実際に見落としたからで、飛ばした回はその段が拾うはずだった壊れ方がそのまま通っています。

ブログ「保存した」は検証ではないエージェントに作らせた画面の見た目を、数値ゲート・オフスクリーンのPNG・実際の導線の三段で確認しています。撮影までは自動化できても、撮った絵を見て判断する行為だけは自動化できていません。

三段目が要る理由を、Anthropic が自社モデルの限界として書いています。computer use モデルの記事にある一節です。

Claudeの画面の見え方はパラパラ漫画的で、細かい動画ストリームを観測しているわけではないため、短命なアクションや通知を見落としうる

観測の粒度が、そのまま能力の上限になっています。スクリーンショットの間隔より短い出来事は、モデルがどれだけ賢くても存在しないことになります。評価する側も同じ扱いでした。METR のガイドラインは、モデルに与えるべき最低限として「コマンドラインを使い、その結果の出力を見る」能力を挙げています。独立した項目として並んでいるわけではありませんが、ひとつの句の中で、コマンドラインを実行できることとは別の能力として、出力を見られることが明記されています。

エージェントの定義でツールを絞る

作用の側は、2つの層で絞っています。1つ目がエージェントを定義する層です。

週次でコードベースを走査するサブエージェントには、書き込み系のツールを1つも渡していません。残したのは Read Grep Glob と集計用の Bash だけです。

ブログ見つけさせて、直させないPRのレビューで担保しきれずに漏れるものを拾うため、週次でコードベースを走査するだけのサブエージェントを立てています。修正はさせず検知と報告に限り、報告はレビュー側で裏を取る運用を1か月ほど回した記録です。

公開している標準の swift-workflow は、実装まで通すスキルでありながら WriteEdit も持ちません。Bashxcrunswift に限定してあります。エージェントを定義する規約の側にも役割ごとの型が入っていて、権限モードの dontAsk は宣言していないツールを自動で拒否します。

GitHubGitHub - LabeeHive/standards: Shared standards repository for Labee LLC projects — a Claude Code plugin marketplace of skills, agents, and workflowsShared standards repository for Labee LLC projects — a Claude Code plugin marketplace of skills, agents, and workflows - LabeeHive/standards

取り返しがつくかどうかで層を分ける

2つ目がハーネスの層です。こちらは dotfiles に置いてあり、allowaskdeny の3段に分かれています。

問答無用で拒否する側から並べます。

Bash(rm -f *)  Bash(rm -rf *)  Bash(curl *)  Bash(wget *)
Bash(git push -f *)  Bash(git push --force-with-lease *)
Bash(git reset *)  Bash(chmod 777 *)  Bash(npx *)  Bash(pnpx *)

確認せずに通す側はこうです。

Bash(git status)  Bash(git log *)  Bash(git diff *)
Bash(git switch *)  Bash(git branch *)  Bash(git fetch *)

並べると分け方が見えます。拒否側はほぼ全部が取り返しのつかない操作で、許可側は全部が読み取り専用の git コマンドです。あいだの askgit commit git push git rebase git checkout が入っていて、ここが毎回聞かれます。

OWASP の AI Agent Security Cheat Sheet が「影響が大きい、あるいは 不可逆な 操作には明示的な承認を要求せよ」と書いていて、層の分け方がそのまま対応しています。人間に残した操作がコミットとタスク完了の2つだけなのも同じ理由です。判断が難しいから残したのではなく、取り返しがつかないから残しています。

npxpnpx の拒否は、LLM06:2025 の「シェルコマンドのような開放的なツールは避け、粒度の細かい代替を選べ」への回答になっています。Bash を丸ごと渡さない代わりに、開放度の高いものから個別に潰す形です。

観測は増やすが、無差別には増やさない

同じ denyRead が並んでいるのは、記事の主張と逆を向いているので書いておきます。

Read(**/.env)  Read(**/.env.*)  Read(**/secrets/**)
Read(**/config/credentials.json)  Read(**/*.pem)  Read(**/*.key)

サンドボックス側でも ~/.aws~/.ssh、それにワークスペース配下の同名ディレクトリを読み取り拒否にしています。観測手段を増やす方針は、秘密まで観測させる方針ではありません。増やすのは成果を検証するための観測で、資格情報はそこに含まれません。

壊せない場所を作れば、聞かなくてよくなる

Anthropic のベストプラクティスに、承認というゲートの弱点が書いてあります。

10回目の承認の頃には、もうレビューしていない。ただクリックを通しているだけだ

これへの答えが、承認を増やすことでも減らすことでもない形で入っています。サンドボックスを有効にしたうえで、autoAllowBashIfSandboxed を立てる。壊せない場所を先に作って、その中では聞かない、という設計です。

書き込めるのは5つのパスだけで、届くネットワークはパッケージレジストリと GitHub だけを列挙してあります。アクチュエーターの届く範囲そのものを狭めているので、その内側の Bash は毎回聞く必要がなくなります。承認疲れへの対処が、人間の注意力に頼る側ではなく、作用の範囲を定義する側に置かれていることになります。

届く範囲を広く取ったまますべての操作を承認で止める設計では、人が毎回見ることになり、回を重ねると内容を読まずに通すだけになる。範囲を先に狭めた設計では、大半の操作はゲートを通らずに進み、コミットとpushのように取り返しがつかない操作だけが承認へ回る

同じ設計が製品として出ている

これは手元の工夫ではありません。Anthropic が2025年10月に同じ設計を製品として出していて、そこに数字が付いています。自社製品について自社が社内利用で測った値なので、その前提で読む必要はあります。

社内利用では、サンドボックスによって許可プロンプトを 84% 削減できることが分かった

公式ドキュメントの設定項目は allowWriteallowedDomains で、手元の設定と名前まで一致しています。

2026年に入ってからは他社も続いています。Docker のサンドボックスは、解こうとしている問題を「エージェントを無人で、絶え間ない許可プロンプトなしに走らせながら、どうやってマシンとデータを守るか」と設定して、答えを1文で言い切っています。

あなたのコンピュータを壊せない以上、自由に走らせればいい

DockerDocker Sandboxes: Run Claude Code and More SafelySecure sandboxes for Claude Code, Gemini, Codex, and Kiro. Run coding agents with microVM-based isolation.

実装は microVM で、マウントするのは基本的にプロジェクトのワークスペース、ネットワークは既定で拒否したうえで許可リストを足す形です(アーキテクチャの詳細は製品ドキュメント側にあります)。エージェントが中で Docker を動かしてもホストのデーモンには届きません。設計の原理としては、続く記事の言い方のほうが正確です。

ガードレールは重要だ。ただしそれが、エージェント自身によってではなく、エージェントの外側で強制される場合に限る。エージェントに必要なのは本物のバウンディングボックス、つまり実行前に定義された制約と、何にアクセスし何を実行できるかの明確な限界だ。その箱の中では、エージェントは速く動けるべきだ

「エージェント自身によってではなく」がこの節の要点です。プロンプトに書いた約束は、エージェントの内側にある制約です。サンドボックスは外側にあります。

反対もある

境界と承認は別物だ、という立場があります。OpenAI の Codex は同じくサンドボックスを持ちながら、結論が違います。

サンドボックスと承認は別の制御であり、協働する。サンドボックスは技術的な境界を定める。承認ポリシーは、エージェントがその境界を越える前に、いつ止まって尋ねるかを決める

この記事は「境界を作れば聞かなくてよくなる」と書いていますが、Codex のドキュメントは「両方要る」と明言しています。

保守コストが利得を上回る、という反論もあります。しかもこれは、84%を出したのと同じ会社から5か月後に出ています。

サンドボックスは安全だが、保守の手間が大きい。新しい機能ごとに設定が要り、ネットワークやホストへのアクセスを要するものはどれも隔離を破る

Anthropic はこの理由で、サンドボックスではなく分類器を選びました。同じ記事に「Claude Code の利用者は許可プロンプトの 93% を承認している」という数字も載っています。承認というゲートが弱いこと自体は、こちらの前提と一致します。

保守コストの指摘は、手元の設定にも当てはまります。excludedCommandsdocker bun run bun test xcodebuild git push git fetch が並んでいて、これらは隔離の外で走ります。理由は1つではありません。docker は公式ドキュメントに「サンドボックスと非互換」と書かれているものです。同じドキュメントは git が落ちる例も挙げていますが、名指ししているのは mergecheckout で、書き込みを拒否されたファイルを置き換えようとするときの話でした。ここに並んでいる pushfetch がどの制約に当たったのかは、突き止めないまま外しています。残りも同じで、失敗を踏むたびに足したものです。enableWeakerNetworkIsolation も立てて隔離を弱めてあります。扱う対象が増えるほど伸びる部分なので、ガードレールとしてはまだ詰められます。

許可した先が流出経路になる、という指摘もあります。

エグレスプロキシは宛先を確認し、api.anthropic.com だと見て、通した

攻撃者の鍵で Anthropic の Files API が呼ばれ、ワークスペースのファイルがそちらへ渡っています。

www.anthropic.comHow we contain Claude across productsAnthropic is an AI safety and research company that's working to build reliable, interpretable, and steerable AI systems.

ドメイン単位の許可リストは、そのドメインが正規である限り通します。手元の設定も allowedDomains にパッケージレジストリと GitHub を並べているので、粒度としては同じ性質のものです。この点は公式ドキュメントも警告していて、github.com のような広いドメインを許可するとデータ流出の経路を作りうる、と名指しで書かれています。宛先の名前だけで判断している以上、そこから先までは見ていません。

それでもこの形にしている

3つとも妥当な指摘です。そのうえでこの形を選んでいる理由は2つあります。

1つは、分類器を選べるのは分類器を作れる側だけだからです。個人の開発機で同じ判断はできません。範囲を狭める側は設定ファイルで書けます。

もう1つは、承認を残す設計の弱さのほうが実測で示されているからです。93%承認という数字と、10回目にはもう見ていないという記述は、どちらも承認側から出てきたものです。注意力に依存しない手段を先に置くほうが確実です。その代わりに保守コストを引き受けています。

ただし境界だけで閉じているわけではありません。askgit commitgit push を残してあるので、実際には境界と承認の2層です。その意味では、Codex の「両方要る」に近い形に落ち着いています。違いは、どちらを主にしてどちらを補助にするかの比重だけです。

OpenAI の Codex は境界と承認を対等に置き、Claude Code の auto mode は承認側を分類器で自動化して比重を承認に寄せ、この記事の設定は境界側を主にして承認を取り返しがつかない操作だけに残している。三者とも2層を持つ点は同じで、違いは比重にある

対立しているように見えて、実際には同じ2層構造の中で重心の置き場所が違うだけです。境界を主にすると保守コストを引き受けることになり、承認を主にすると注意力に依存することになります。どちらの代償を選ぶか、という問いに読み替えられます。

改善余地もはっきりしています。自動許可は「壊せない場所」の定義が正しいことに依存していますが、その定義は設定ファイルの中だけでは閉じません。macOS のプライバシー権限は起動経路のほうで決まっていて、設定には一切現れないためです。ターミナルに一度許可を出せば、そこから起動したものは同じ権限を引き継ぎます。allowWrite はそこを見ていません。

ブログターミナルにリマインダー権限を渡さずにMCPからEventKitを触るClaude Desktop経由でMCPサーバーを起動するとReminders権限が通らない問題を、独立したLaunchAgentのdaemonへEventKitアクセスを集約して解決しました。結果として、ターミナルやClaude Desktopに権限を与えず、アプリ本体だけに絞れる構成になっています。

同じ設定でも、どこから起動したかで実際に触れる範囲が変わります。宣言できたつもりの境界の外側に、宣言していない経路が1本あるということです。

宣言だけではアクチュエーターの形が決まらない

許可リストは、ツールの名前と引数の形でしか作用を絞れません。それでは表現しきれない制約をどこに置くかという問題が残り、答えがフックでした。ツールが動く前に挟まるゲートです。

条件が書ける場合は、終了コード2で止めます。タスク取得のフックがそれで、全件フィルターでの呼び出しを弾き、先に一覧を引いてから絞り込めと返します。取得できてしまう呼び出しを、有害だから拒否しているのではなく、そこから先の作業が雑になるから拒否している形です。

条件が書けない場合は、判定自体をモデルに投げています。コメント追記の呼び出しに対して、内容が進捗ログなのか、それともタスク本文の書き直しなのかを判断させ、後者なら別のツールを使えと返す形です。ここは正規表現では書けません。

書いたあとに走るものもあります。.swift を書き終えたらフォーマッターを自動で当てる1本です。

作用を絞る手段が、静的なリストと、実行時のコードと、実行時のモデル判定の3層に分かれていることになります。アクチュエーターの形は、宣言だけでは決まりきりません。

外したツールは、拒否ではなく沈黙として現れる

権限を絞る設計には副作用があります。Agent SDK のサブエージェントのドキュメントに、その挙動が1行で書いてあります。

外したツールはそのセッションに存在しない。許可プロンプトもエラーも出さず、Claude はそれ無しで動く

ツールを外すことは、拒否を1つ増やすことではありません。そのツールが最初から無い状態を作ることです。そして無いことは、エラーではなく沈黙として出てきます。走査担当が「この観点は見ていません」と言うか、何も言わずに空欄を返すかを決めているのは、ツールの構成ではなく報告の形式のほうでした。

エージェントには数値ゲート、PNGの書き出し、実際の導線での撮影、ファイルの読み取りと検索という四つの観測経路が入る。外へ出る作用の経路は一本だけで、その途中に人が判断するゲートが置かれ、通るのはコミットとタスク完了に限られる

ブログ沈黙は語らない「誰も何も言わない」を問題なしと読む運用が、エージェントを入れたあとで最初に壊れました。沈黙がそのまま通っていたのは、読み手がコストを払っていたからではなく、払ったと信じられる与信が相手に積まれていたからだった、という整理です。

ロボティクスのほうが先に同じ形にたどり着いている

よく似た議論が、いま Physical AI の側で加速しています。NVIDIA の定義は、自律システムが物理世界を「知覚し、理解し、推論し、複雑な行動を実行あるいは統括する」ことを可能にするもの、と書いています。推論が、知覚と行動に挟まれた真ん中に置かれています。Google DeepMind の Gemini Robotics は、モデルの変更点を「ロボットを直接制御する目的で、物理的な行動を新しい出力モダリティとして追加した」と説明していて、ツールを足すことは出力モダリティを足すことだと読み替えられます。続くバージョンではロボットを physical agents と呼び、その能力を「知覚し、計画し、考え、ツールを使い、行動する」と並べています。

帯域が能力を決めている例も具体的です。Figure の Helix は、汎用だが速くない側を7〜9Hz、速いが汎用でない側を200Hzに分けました。賢さを1つのモデルに集約しても解けず、入出力の帯域で分割したことになります。

いちばん効いたのは、シミュレーションと現実の差を扱うレビュー論文の一文でした。

ますます現実に近づいているにもかかわらず、すべてのシミュレータは構成上モデルに基づいており、したがって不可避的に不完全である

数値ゲートが全部通っているのに画面だけが壊れている、という手元の失敗と同じ形です。観測している対象が近似である限り、近似の外側は観測できません。

転用であることは書いておきます。ロボティクス側は、センサーとアクチュエーターの設計が難しいから律速になっていると言っていて、こちらはそれを足すと成果が伸びたと言っています。難所として語られていることを伸びしろの証拠に読み替えているので、同じ主張ではありません。物理的な作用は人や物を壊すため、リスクの性質も違います。同じ構造をしている、までです。

順番の話としては、もっと古い言い方があります。Hans Moravec が『Mind Children』(Harvard University Press, 1988)で、推論を「人間の思考のもっとも薄い上塗りにすぎず」と呼び、それが働くのは無意識の感覚運動的な知識に支えられているからだ、と書いています。証明として引ける記述ではありません。ただ、賢さを上に置き観測と作用を土台に置く並べ方が、言語モデルもエージェント向けの道具も存在しない時点で書かれていたことは確かめられます。手元の設計がいまの道具の制約に合わせた後付けなのか、それとも順番のほうが先にあるのか。ここを疑ったときに、1988年の記述が残っていることは意味を持ちます。

逆を言っている側

反対側の議論も強いので、並べておきます。作り込みはスケールに食われるという Richard Sutton の系統の反論はシリーズの次回で扱うので、ここでは道具の設計に固有のものを2つ挙げます。

ブログ削れと言われたのは、道しるべではなかった「規定的な作り込みを削れ」という助言は、禁止形や思考手順のことを指しています。ヒントやフックやワークフローまで削れと読むと、裁量を渡したのに黙るエージェントが残ります。制約と整備を分けた上で、依存していた挙動を数え直した記録です。

Manus の比喩が刺さります。

モデルの進歩が満ち潮なら、私たちは Manus を船にしたい。海底に固定された柱ではなく

ただし Manus が避けろと言っているのは、実行の 途中で ツールを動的に足したり外したりすることです。キャッシュが無効化され、過去の行動が未定義のツールを参照して混乱するためで、代わりに出力側のマスクで制御しています。定義の時点で静的に絞ることを否定してはいません。混ぜて読むと反論として成立しません。

いちばん参考になったのは Cognition の2本でした。2025年の Don’t Build Multi-Agents は「行動は暗黙の決定を含んでおり、矛盾する決定は悪い結果を生む」として複数エージェントに否定的です。そして10か月後の記事では、こう書いています。

今日うまくいく multi-agent は、書き込みが単線に保たれ、追加のエージェントが行動ではなく知性を提供する構成だ

同じ会社が、否定から「読み取り専用のサブエージェントと、単線の書き込み」に着地しています。事故のたびに1つずつ足して辿り着いた形と、独立に同じ場所へ来ました。

足りていない観測手段

観測を増やすと、増やした分だけ読む量が増えます。三段は撮るところまでを自動化して、撮った絵を開いて判断する工程を人に残しているので、撮る組み合わせを増やすほど、その工程だけが比例して増えます。

観測手段そのものが生きているかを確かめる仕組みも足りていません。ゲートが黙って発火しなくなる壊れ方は既に踏んでいて対処も入れてありますが、対象は検査の側であって観測の側ではありません。撮影スクリプトが真っ黒なPNGを書き出して終了コード0で終わる種類の故障を、撮影のたびに検出する形にはなっていません。

ブログ落ちないテストは、何も証明しない検証の規約を明文化して3週間後、レビュー担当がそれを実行していなかったことが分かりました。答えは規約をもう1つ足すことではなく、検査を人の手から外して、通らなければマージそのものを止めることでした。

走査担当の Bash も、用途を grep と件数の集計に限る縛りがプロンプトに書いた約束のままです。ハーネスの層では npxpnpx をパターンで潰せているので、同じことをフックで書けるはずです。ツール定義の側で表現できるものを約束で代用している間は、それは設計ではなく運用です。