Cursor や Claude Code(Anthropicが提供するAIコーディングエージェント)を使っていて、10行の修正を頼んだはずが、気づけば400行の差分(変更箇所の一覧)になっていた、という経験はないでしょうか。
この現象に心当たりがあるエンジニア、あるいはこれからAIエージェントをチームの開発フローに組み込もうとしているリード層に向けて、原因と具体的な設定方法を整理します。TypeScriptコミュニティで知られるMatt Pocock氏が公開しているリポジトリ「mattpocock/skills」の設計思想が、この問題を防ぐ手がかりになります。
何が起きるか
「この関数をリファクタリングして」と頼んだだけなのに、次のようなことが起きます。
- 3つの他ファイルが依存している公開APIの名前を勝手に変更する
- チームが半年前に禁止したパターンをそのまま使う
- すべてをモック(テスト対象の代わりに使う偽物)にして、何も検証していないテストを書く
どれも「動くコードを書く」という点では成功しています。ただし、レビューする側からすると、意図しない変更が紛れ込んだ危険な差分です。CIが通っても、本番でしか顕在化しないバグの温床になりかねません。
なぜ起きるか
原因はモデルの性能ではありません。エージェントに与えている「context(文脈情報)」がほぼ空だからです。
多くの人は2行程度のシステムプロンプトで済ませています。「あなたは優秀なエンジニアです」といった抽象的な指示だけでは、プロジェクト固有の規約は一切伝わりません。エージェントは新人エンジニアと同じで、オンボーディング資料がなければチームの暗黙知に従えないのです。
さらに細かく分解すると、原因は3段階に分かれます。
1つ目は、役割(ロール)とトーンの未定義です。「テストを書いて」とだけ頼むと、エージェントはユニットテストとインテグレーションテストのどちらを優先すべきか、モックをどこまで使ってよいかを自分で判断します。判断基準がなければ、実装の細部まで検証する壊れやすいテストを量産します。
2つ目は、「やってはいけないこと」の欠如です。多くのプロンプトは「〜してください」という肯定形の指示だけで構成されています。エージェントは目についた箇所を親切心で「クリーンアップ」しがちで、それが依頼範囲外の変更を生む主因です。
3つ目は、指示ファイルの構造化不足です。プロジェクトの規約を1つの巨大なテキストにまとめて渡すと、エージェントは関連性の低い情報まで読み込み、肝心のルールを見落とします。タスクの種類ごとにファイルを分割し、必要なときだけ読み込ませる設計が欠けているケースが目立ちます。
自分のプロジェクトが該当するか確認する方法
まず、リポジトリのルートに .agents や .cursor/rules、CLAUDE.md といったファイル・ディレクトリが存在するか確認してください。
ls -la | grep -E ".agents|.cursor|CLAUDE.md|AGENTS.md"何も出てこない場合は、エージェントへの文脈提供がほぼゼロの状態です。次に、直近でAIエージェントに依頼したタスクの差分を振り返ってください。
git log --oneline -20
git show --stat <該当コミットのハッシュ>依頼した内容に対して変更ファイル数が3倍以上になっている、あるいは依頼と無関係なファイルが含まれている場合は、この記事の対策が有効です。Cursorを使っている場合は .cursorrules または .cursor/rules/*.mdc の中身も確認してください。ルールファイルが存在していても、内容が「You are a helpful assistant」程度の一般論で止まっているなら、実質的に未設定と同じです。
対策の手順
ステップ1:グローバルルールを1ファイルにまとめる
プロジェクト全体で常に読み込ませたい前提条件を書きます。モノレポ構成であればパッケージマネージャの種類、言語のデフォルト、レガシーコードの扱いなどです。
.agents/
rules/
global.md
skills/
typescript.md
testing.md
git-workflow.mdglobal.md には「TypeScriptがデフォルトで、legacyディレクトリ以外ではJSを書かない」といった、プロジェクトの根幹に関わるルールだけを書きます。あれもこれも詰め込むと、結局読まれなくなります。
ステップ2:役割定義を具体化する
「あなたはシニアテストエンジニアです」で終わらせず、判断基準まで明文化します。たとえば次のような一文を加えるだけで、テストの質が変わります。
You never mock what you don't own.
You prefer integration tests over unit tests when the tradeoff is reasonable.「自分が所有していないものはモックしない」というルールは、外部ライブラリやAPIをモックして中身のないテストを量産する事態を防ぎます。
ステップ3:「やらないこと」を明記する
肯定形の指示だけでなく、禁止事項を並べたセクションを必ず作ります。
- Do not use any in TypeScript unless absolutely necessary and commented.
- Do not introduce new dependencies without asking.
- Do not refactor code unrelated to the task at hand.3つ目の「タスクと無関係なコードをリファクタリングしない」は、差分が膨れ上がる事故のほとんどを防ぐ一文です。まずこれだけでも既存のルールファイルに追加してみる価値があります。
ステップ4:ファイルをタスク単位で分割し、ルーティングさせる
1つのファイルに全部書くのではなく、write-typescript.md review-pr.md のようにタスクごとに分けます。各ファイルの冒頭に「いつ使うか」を書いておくと、エージェント側のルーティング(どの指示を読み込むかの判断)に使われます。
# When to use this
Use this skill when writing or modifying .test.ts files.Claude Codeでは CLAUDE.md からの参照、Cursorでは .cursor/rules/*.mdc の alwaysApply や globs 設定を使って、ファイルパターンごとに読み込むルールを切り替えられます。設定項目の詳細は各ツールの公式ドキュメントで、ルールファイルのフロントマター(先頭のメタデータ部分)の仕様を確認してください。
まとめ
AIエージェントの暴走差分は、モデルの限界ではなく文脈設計の不足が原因です。
.agentsやルールファイルの有無をまず確認する- 直近の差分を振り返り、依頼範囲を超えた変更がないか点検する
- グローバルルール・役割定義・禁止事項・タスク別ファイルの4点をルールに追加する
まずは「タスクと無関係なコードは触らない」という一文を、今使っているルールファイルに足すところから始めてみてください。