本文へ移動
📏

AIエージェントに「この不具合を直して」と頼むと、期待以上に広い差分が返ってくることがあります。テストを増やす、周辺の命名を直す、依存を更新する、設定ファイルまで触る。単体では良い改善でも、最初の依頼範囲を越えた瞬間にレビュー不能になります。

この記事では、AIエージェントの 差分スコープ設計 を扱います。実行直前に止める承認フローは AIエージェント承認フロー設計ガイド、tool ごとの危険度分類は AIエージェント tool risk tier 設計ガイド、完了後に差分を受け入れる判断は Codex レビュー完了ゲート設計ガイド、外部副作用を戻す設計は AIエージェント rollback 設計ガイド に分けています。

今回の論点は、作業を始める前に どこまで変えてよいか を change budget として固定することです。

先に結論: prompt ではなく変更契約を渡す

AIエージェントに渡す依頼は、自然文の作業説明だけでは足りません。最低限、次の6つを先に決めます。

項目決めること止める条件
Goal何を直すか目的が複数に増えた
Files触ってよいファイル許可外ファイルを編集した
Commands実行してよいコマンド破壊的・外部 write が必要になった
Data読んでよい情報secrets / PII / private log が必要になった
External effectsPR、issue、MCP write、deploy外部副作用が未承認で発生する
Stop ruleいつ止まるか前提不一致、失敗、範囲拡大が起きた

これを私は change_budget と呼んでいます。予算という名前ですが、token や金額だけの話ではありません。AIエージェントが変更してよい blast radius を、ファイル、コマンド、データ、外部副作用の単位で先に固定するための契約です。

change_budget:
  goal: "ログイン後の redirect ループを直す"
  allowed_files:
    - "src/routes/auth/**"
    - "src/lib/session.ts"
    - "tests/auth/**"
  forbidden_files:
    - "db/migrations/**"
    - ".env*"
    - "package.json"
  allowed_commands:
    - "pnpm test -- auth"
    - "pnpm run build"
  external_effects:
    github_pr: "draft_only"
    issue_comment: "forbidden"
    deploy: "forbidden"
  stop_if:
    - "schema change is needed"
    - "new dependency is needed"
    - "fix touches more than 6 files"
    - "test failure is outside auth scope"

この形にすると、エージェントの仕事は「良い修正を探す」だけでなく「範囲を越えそうなら止まる」ことまで含みます。

なぜ差分スコープが必要なのか

人間の開発でも、PR が大きくなるほどレビューの質は落ちます。AIエージェントではこの問題がさらに速く起きます。理由は単純で、エージェントは周辺コードを読めるし、テストも直せるし、見つけた改善をまとめて処理しようとするからです。

失敗パターンはだいたい次の5つです。

  1. 依頼は bug fix だったのに、設計リファクタまで混ざる
  2. 1ファイル修正のはずが、formatter や import 整理で広がる
  3. test を通すために本番コードではなく test expectation を変える
  4. 既存の未コミット変更や別ブランチの差分を成果物に混ぜる
  5. 調査中に issue comment、label、MCP write など外部副作用を起こす

OpenAI Codex の sandbox docs は、approval と sandbox を分けて説明しています。approval は Codex がいつ止まるか、sandbox はファイルやネットワークへどこまで届くかの境界です。さらに、承認する場合も task を進めるのに必要な最小スコープを選ぶ方針が示されています。つまり、ツール側の安全機構はありますが、依頼側が「どの範囲なら成功か」を書かないと、レビュー時に初めて境界を考えることになります。

Claude Code でも同じです。公式 docs では read-only を基本に、編集、テスト実行、コマンド実行には明示的な許可を求める設計が説明されています。settings では allow、ask、deny の permission rule や Read(./.env) のような deny 例もあります。これは権限設計として重要ですが、業務上の変更範囲は別に定義する必要があります。

権限が狭いことと、差分が小さいことは同じではありません。src/** に write できる agent は、権限上は正しくても、20ファイルの設計変更を作れてしまいます。だから change budget が必要です。

既存記事との役割分担

近いテーマと混ざりやすいので、先に責務を分けます。

テーマ扱うことこの記事で扱うこと
tool risk tiertool や action の危険度分類その task でどこまで変更してよいか
承認フローhigh-risk action を実行直前に止めるそもそも承認対象へ進む前の上限
review gate完了後に差分を受け入れるか見る完了前に差分が広がりすぎない条件
rollback失敗後に外部副作用を戻す外部副作用を今回の scope に入れるか判断する
予算ガードレールtoken、API、retry の消費上限code diff と外部変更の blast radius

差分スコープ設計は、レビューの代替ではありません。レビューしやすい大きさで作業を終わらせるための前段です。

change budget を5段階に分ける

私は AIエージェントの作業を、次の5段階で渡します。

レベル許可する変更向いている作業
S0 read-only読む、調べる、計画する原因調査、影響範囲調査
S1 docs-onlyMarkdown、コメント、README手順化、記事、運用メモ
S2 local patch指定ファイルのコード変更小さな bug fix、UI 文言、test 追加
S3 bounded feature指定ディレクトリ内の複数ファイル1機能の追加、API + test
S4 external actionPR、issue、MCP write、deploy明示承認つきの外部操作

重要なのは、最初から S4 を渡さないことです。たとえば原因不明の障害なら、最初の run は S0 にします。

Investigate only.
Do not edit files.
Return suspected cause, affected files, and the smallest safe fix plan.

原因が絞れたら S2 に進めます。

Implement only the auth redirect fix.
Allowed files: src/routes/auth/**, tests/auth/**
Do not modify package.json, migrations, or global middleware.
Stop if you need schema changes or more than 6 files.

この2段階に分けるだけで、調査の勢いで本番コードまで広がる事故はかなり減ります。

allowed files だけでなく forbidden files も書く

allowed_files だけでは弱い場合があります。エージェントが「必要だから」と判断して、許可外の設定や依存へ広げたくなるからです。明確に触ってほしくない領域は forbidden_files に書きます。

allowed_files:
  - "src/features/checkout/**"
  - "tests/checkout/**"
forbidden_files:
  - "db/migrations/**"
  - "src/auth/**"
  - "package.json"
  - "pnpm-lock.yaml"
  - ".github/workflows/**"

この指定は、エージェントを信頼していないからではありません。人間のレビュー対象を守るためです。

特に危ないのは、依存追加、migration、CI 設定、認証共通処理です。これらは1行の変更でも blast radius が大きい。修正に必要なら止めて報告させ、別 task に分けます。

コマンドにもスコープを付ける

ファイルだけでなく、コマンドにも予算を付けます。

コマンド種別例方針
read-onlygit diff, rg, pnpm test -- --list原則許可
local verificationpnpm test -- auth, pnpm run buildtask ごとに固定
write-localformatter、codegen対象ファイルが限定できる時だけ許可
dependency changepnpm add, lockfile 更新原則停止
external writegh pr merge, deploy, MCP write明示承認へ戻す

AIエージェントに「必要なテストを実行して」とだけ書くと、全体テスト、formatter、生成コマンドまで広がることがあります。リポジトリが大きい場合、これは時間の問題だけでなく、生成物や snapshot の意図しない更新にもつながります。

このサイトでブログ記事を追加するなら、検証は pnpm seo:update-llms と pnpm run build です。記事作成のついでに依存更新や全体 format は不要です。こういう repo 固有のルールは AGENTS.md に寄せ、task ごとの change budget で上書きします。

OpenAI Codex の AGENTS.md docs は、Codex が作業前に AGENTS.md を読む前提で、global と project の指示を重ねられると説明しています。毎回 prompt に全ルールを書くより、変わらないルールは repo に置き、今回だけの上限を prompt に置く方が運用しやすいです。

外部副作用は最初から別枠にする

外部副作用は、ファイル変更とは別の budget にします。

external_effects:
  github:
    create_pr: "allowed_after_build"
    comment: "ask"
    label: "ask"
    merge: "forbidden"
  mcp:
    read_tools: "allowed"
    write_tools: "ask"
  deploy:
    preview: "ask"
    production: "forbidden"

この分け方をしないと、「修正してPRを作って」から「ついでに label を付ける」「issue に報告する」「preview deploy する」までが1つの成功条件に見えてしまいます。

OWASP の AI Agent Security Cheat Sheet は、agent tool と permission への least privilege、high-risk action への human-in-the-loop、agent behavior の monitoring などを推奨しています。差分スコープ設計でも同じで、外部 write は tool 名ではなく target、payload、rollback、承認者まで含めて扱います。

stop rule を先に書く

一番大事なのは stop rule です。AIエージェントは、途中で前提が崩れても「なんとか進める」方向に寄りがちです。実務では、進めるべきでない瞬間を先に書きます。

stop_if:
  - "The fix requires a database migration."
  - "The root cause is outside checkout."
  - "You need to edit more than 6 files."
  - "You need to read .env or production logs."
  - "The test failure is unrelated to this task."
  - "The current branch has user changes you did not make."

止まることは失敗ではありません。むしろ、範囲外の作業を勝手に進めないことが成功です。

私が実務で使う基準は、次のどれかに当たったら止めることです。

兆候止める理由
依頼外のディレクトリが必要task の切り方が間違っている
migration が必要review と rollback が別物になる
secret / production log が必要権限と監査の話になる
dependency 更新が必要supply chain risk が増える
失敗テストが別領域修正範囲が広がる
external write が必要human approval と rollback plan が要る

NIST AI RMF は、AI リスク管理を組織や社会へのリスクを扱う枠組みとして整理しています。差分スコープ設計は、その中でも小さな実装運用の話ですが、考え方は同じです。影響範囲を map し、測れる上限を置き、超えたら manage へ戻す。AIエージェントに限らず、リスクを後工程に押し込まないための設計です。

PR 単位は change budget と一致させる

change budget は、そのまま PR 単位にもなります。

よい PR は、次の質問にすぐ答えられます。

  1. この PR の目的は1つか
  2. 触ってよいと決めたファイルだけが変わっているか
  3. 実行したコマンドは事前に決めた範囲か
  4. 外部副作用は PR 作成以外にないか
  5. 範囲外の発見事項は別 issue / 別 task に逃がしたか

悪い PR は、本文でこう言いがちです。

ついでに周辺の型エラーと lint も直しました。

これは親切に見えますが、AIエージェント運用では危険です。周辺修正が必要なら、次の change budget を切ります。

next_change_budget:
  goal: "checkout 周辺の型エラーを解消する"
  allowed_files:
    - "src/features/checkout/**"
    - "tests/checkout/**"
  forbidden_files:
    - "src/auth/**"
    - "db/migrations/**"
  stop_if:
    - "global type definition needs to change"

scope を小さくするのは、作業量を減らすためではありません。レビュー可能性を保つためです。

Codex / Claude Code に渡す最小テンプレート

最後に、実務でそのまま使える短いテンプレートを置きます。

Goal:
- Fix only [problem].

Change budget:
- Allowed files: [paths]
- Forbidden files: [paths]
- Allowed commands: [commands]
- External writes: forbidden unless explicitly approved

Stop if:
- You need to edit outside allowed files
- You need a new dependency, migration, deploy, or secret
- The fix touches more than [N] files
- Existing user changes are present in files you need

Before final:
- Show changed files
- Show commands run and results
- List any scope boundary you hit
- Do not claim completion if verification failed

Codex なら、この固定ルールを AGENTS.md と task prompt に分けます。Claude Code なら、settings の permission rule と project instruction に分けます。MCP tool を使う場合は、server 単位ではなく tool + target + payload の単位で scope を切ります。

まとめ

AIエージェントに安全に任せるには、能力を上げるだけでは足りません。変更できる範囲を先に小さく切り、範囲外に出たら止まる契約を渡す必要があります。

差分スコープ設計で決めるべきことは、次の6つです。

  1. goal を1つにする
  2. allowed files と forbidden files を書く
  3. 実行してよい command を固定する
  4. 外部副作用を別枠にする
  5. stop rule を先に書く
  6. PR 単位を change budget と一致させる

AIエージェントの失敗は、いつも大きな事故として始まるわけではありません。小さな「ついで修正」が重なって、誰もレビューできない差分になります。だからこそ、作業開始前に blast radius を固定します。

参考にした一次情報

WRITTEN BY nidoneko

Full-stack engineer with 8+ years of experience in TypeScript, React, Node.js, and cloud-native development across healthcare, finance, HR, and IoT domains.

View Profile →