Skip to main content

AIエージェント向けの効果的なガードレール

本ドキュメントは、AIエージェントを利用した開発において、プロンプトへの依存を減らし、品質とルールを「仕組み」で強制するためのベストプラクティスをまとめた。

1. プロンプトではなく仕組み(ガードレール)で解決する​

AIへの「テストを書いて」「この規約を守って」というお願い(プロンプト)は、いずれ必ず無視されるタイミングが来る。人間への指示ではなく、機械的・決定論的な仕組みで品質を強制する必要がある。

2. CLI中心の運用原則:探索・計測はツール、判断はAI​

AIエージェントの性能を最大限に引き出すためには、「探索と計測はCLIツールを優先して使い、AIにはその結果の解釈と判断を任せる」という役割分担が重要である。

  • 再現性と決定論の確保:

    • AIが自ら grep や find を繰り返してコードベースを探索するよりも、静的解析ツールやGit履歴分析ツールを実行させ、確定的なデータを取得させるほうが再現性は高まる。
  • 観測可能性の向上:

    • ツールが出力するログやメトリクスを介在させることで、AIがどのような根拠に基づいて判断を下したのかを人間が検証しやすくなる。
  • 指示の具体化:

    • 「リファクタリングして」という曖昧なプロンプトではなく、「ホットスポット分析で上位のファイルを特定し、その依存関係を可視化して改善案を出して」のように、ツール実行を前提とした指示に切り替える。
  • リンター・フォーマッターの導入:

    • 本プロジェクトでは Biome を採用している。
    • 重要: リンターのエラーメッセージには、AIが自己修正できるように「どう直すべきか」が明確になるルール設定を心がける。
  • Gitフック (Pre-commit / Pre-push) の設定:

    • コミット前やプッシュ前に必ずリンター、フォーマッター、型チェック(tsc)が走るようにしている。具体的な設定は メンテナンスについて を参照すること。これにより、AIがルール違反のコードをコミットできない仕組みを作る。
  • 構造・アーキテクチャのテスト:

    • ドキュメントで「XはYに依存する」と説明するのではなく、依存関係やデータ構造をテストコードとして記述し、CIで検証させる。例として dependency-cruiser の導入や型チェックによる境界防御が挙げられる。未利用・不要なコードの発見には Knip を利用する。

3. エージェント可読性(Agent Readability)の最適化​

AIエージェントはリポジトリ内のテキストしか読めない。コンテキスト(文脈)をエージェントに正しく伝える工夫が必要である。

  • 暗黙知のコード化 (ADRの活用):
  • 枯れた技術(Boring Technology)の選定:
    • APIが安定しており、LLMの事前学習データに多く含まれている技術を選定する。最新技術よりも、AIが確実に正解を出力できる技術を優先する。
  • 指示書(CLAUDE.md / .cursorrules)の軽量化:
    • システムプロンプトとして読み込まれる全体指示書は50行以下などの最小限に抑え、詳細なルールやツールの使い方への「ポインタ(ファイルパス)」のみを記述する。

4. 中央集権的な制約とローカルの実装の自由​

「何をすべきか(境界)」は厳格に守らせ、「どう実装するか(内部)」はAIの自律性に委ねる。

  • インターフェース・境界の厳密化:
    • 外部入力やモジュール間の境界では、Zod などを用いてデータの型や形状をパース・検証することを必須とし、テストやリンターで強制する。
  • 実装手法の自由:
    • データパースにZodを使うかなどの内部実装詳細はエージェントに任せ、結果だけを自動テストで担保する。

5. 特化したAIツールの活用とレビュー​

すでに導入されているツールを組み合わせることで、開発環境をさらに強固にする。

  • AI向けCLIツール・開発支援ツールの活用:
    • AIの能力拡張には Agent Skills やフロントエンドの構築支援プラグインを利用できる。
    • Difit を活用し、ローカルのGit差分をAIエージェント向けのプロンプトに変換してコードレビューにかけることで、レビュー漏れを防ぐ。
  • AIによるPRレビューと人間のレビュー:
    • CI上でPRエージェントを動かし、人間のレビュアーが見る前に軽微なバグを指摘・修正させるアプローチが有効である。人間が行うレビューの意図の伝え方については Pull Request 時のレビューについて を参照すること。

6. AIに実行させるべきではない破壊的コマンドの制限​

AIエージェントに強い権限を与えて運用する場合、取り返しのつかないインフラやデータベースの破壊操作を制限する強固なガードレールが必要である。

ガードレールを「プロンプトによるお願い」から「強制可能な仕組み」に昇華させるため、以下の4つのレイヤーで多重防御を構築する。

レイヤー役割実装手段
1. AI 設定権限の最小化と実行ブロック.claude.json の deny 設定、CLIの read-only モード
2. ローカル検証変更直後の即時フィードバックGit Hooks (Husky), リンター, 型チェック, mermaid-cli
3. CI ゲートマージ前の最終品質担保GitHub Actions, セキュリティスキャン, 結合テスト
4. インフラ保護万が一の破壊操作からの防御AWS削除保護, DBバックアップ, Terraformリモートバックエンド

破壊的操作の deny 方針​

AIエージェントには、以下のような取り返しのつかない操作の実行権限を与えないようにする。

  • インフラ・リソース削除: terraform destroy, terraform apply, aws * delete-*, kubectl delete
  • データベース破壊: DROP TABLE, TRUNCATE, データベースの初期化・削除コマンド
  • Git履歴/未保存データの破壊: git push -f(強制プッシュ), git reset --hard
  • パッケージ・イメージの誤公開: npm publish, docker push
  • 強権的なファイル操作: rm -rf, chmod -R 777, chown
  • 外部スクリプトの任意実行: curl, wget(予期せぬ外部スクリプトの拾い食いを防ぐため)

Claude Codeなどのツールでは、プロジェクトの設定ファイル(.claude.json など)で明示的にこれらを拒否(deny)する。

設定例 (.claude.json):

{
"permissions": {
"deny": [
"Bash(terraform destroy *)",
"Bash(terraform apply *)",
"Bash(rm -rf *)",
"Bash(git push -f *)",
"Bash(npm publish *)"
]
}
}

インフラ側の多重防御​

ローカルの設定ミスやAIのすり抜けを想定し、インフラ側でも防御を固める。

  • ステート管理の外部化: TerraformのStateファイルをローカルへ配置せず、リモート(S3など)で管理する。
  • 削除保護の有効化: AWS RDS等の deletion_protection を有効化する。
  • 復旧プランの策定: 自動バックアップのリストアテストを定期実施し、確実に復旧できる状態を維持する。

7. Hookによる自動検証ループ(Self-Correction Loop)​

AIがコードを出力した直後、機械的なバリデーションを走らせる。エラーがあればその結果をAIへ即座にフィードバックする「自動検証ループ」を構築する。これにより、AIが自律的にエラーを修正し、人間が確認する手間を最小化できる。

  • 自動検証の仕組み:
    1. 生成 (Generate): AIがファイルを更新する。
    2. 検証 (Validate): PostToolUse HookやGit Hooksを利用して、更新されたファイルに対してCLIツールを実行する。
    3. 拒絶・フィードバック (Deny & Feedback): 検証エラーを検知した場合、変更をブロック(deny)し、エラー内容をAIにプロンプトとして返す。
    4. 自己修正 (Fix): AIがエラー内容を解釈し、コードを修正して再試行する。

具体例:Mermaid記法の自動修正ループ​

AIはMermaid記法の図を生成するのが得意だが、構文エラーを出すことが稀にある。これを mermaid-cli で防ぐ例。

  1. AIの設定: mermaid-cli を導入し、.md ファイルの編集後にバリデーションを実行するHookを設定する。
  2. 検証実行: Hook内のスクリプトでMarkdownからMermaidブロックを抽出し、一時的な .mmd ファイルとして書き出して npx mmdc で構文チェックを行う。
  3. エラー処理: 構文エラーがあればAIに「Mermaid構文にエラーがあります:[エラー内容]。修正してください」と返す。
  4. 結果: AIが修正した後の、構文的に正しいMarkdownのみが保存される。

8. 今後追加推奨される発展的なガードレール​

開発がスケールしエージェントの処理量が増えた際に、さらに堅牢にするための追加の仕組みである。

  • コンポーネント分割を強制する仕組みの導入(長大ファイルの出力防止):
    • AIはコンテキスト長が許す限り1つのファイルにコードを書き連ねる傾向がある。これを防ぐため、Biomeの noExcessiveCognitiveComplexity などの複雑度を制限するルールを有効にし、関数の肥大化を防ぐ手法が推奨される。さらに物理的な行数制限が必要な場合は、Gitフック(Husky等)にシンプルな行数チェックスクリプト(シェルスクリプトやNode.js)を組み込み、強制的にファイル分割を促す仕組みが有効である。
  • モックデータの自動生成・管理ルール:
    • AIにE2Eテストや結合テストを任せる場合、MSW (Mock Service Worker) などを整備する。外部環境に依存せず決定論的に動くテスト環境を作ることが重要である。
  • シークレットスキャンとセキュリティテストの自動化:
    • AIが誤ってAPIキーやパスワードをハードコードしてしまうリスクを防ぐ必要がある。git-secrets などのシークレットスキャンツールをGitフックに組み込み、セキュリティリスクを漏れなく弾く。

9. 運用テンプレート:AIとの協働を円滑にする​

AIエージェントとの日常的な開発において利用できる、最小限のチェックリストとフロー。

AIに依頼する前の最小チェックリスト​

AIへタスクを依頼する前に、以下の準備ができているか確認する。

  • ゴールは明確か(何ができれば完了か)
  • コンテキストは足りているか(関連ファイル、ADR、ツール選定表の提示)
  • CLI実行を指示に含めたか(「まず knip で未使用コードを確認して」など)

PR前に機械的に通すべきチェック​

AIが作成したコードをPRへ出す前に、必ず以下の「仕組み」を通過させる。

  1. リンター・フォーマッター: npm run fix (Biome)
  2. 型チェック: npx tsc --noEmit
  3. 影響範囲の特定: npx madge --summary src/
  4. セキュリティ: semgrep scan

失敗時の切り分けフロー​

AIがタスクに失敗したり、無限ループに陥った場合の対応手順。

  1. ログの確認: 最後に実行されたCLIコマンドの出力を読み直し、AIが情報を読み飛ばしていないか確認する。
  2. 原因の特定:「AIの推論ミス」か「ツールの誤検知・設定不備」かを切り分ける。
  3. リセットと再実行: 会話が長くなりすぎて精度が落ちている場合は、新しいセッションを開始し、これまでの分析結果(CLI出力)のみを再投入する。
  4. 役割の再定義: 探索が不十分な場合は、AI任せにせず人間が具体的なCLIコマンド(grepなど)を指示して「きっかけ」を与える。