AIコーディングとエージェント

Vibe Codingの事故をルールファイルで未然に防ぐ方法

Vibe Codingの事故を防げるかどうかは、コードを読む段階ではなく、最初のルールファイルを書く段階で決まります。CLAUDE.mdや.cursorrulesに盛り込むセキュリティ、重複、アーキテクチャ、完了基準、スコープの5つのルールを、記述例とともに整理しました。

読了 12 分
Vibe Codingの事故をルールファイルで未然に防ぐ方法のカバー画像

前回の記事では、Vibe Codingの代償、つまりコードを読まずに開発すると起きる3つの問題を整理しました。

バグを直せなくなり、同じ機能が複数箇所に生まれ、気づきにくいセキュリティホールが開いてしまう、という話でした。そして解決策として、「致命的な箇所だけ読む」「AIの要約を読む」「スキャナーをかける」を提案しました。

ただし、これらの解決策には共通点が1つあります。どれも事故が起きた後に見つける事後検証だという点です。

今回は、さらに一歩踏み込みます。検証する前に、そもそもAIがそのようなコードを作れないよう強制する方法です。

ツールはすでに手元にあります。CLAUDE.md、.cursorrules、AGENTS.mdのようなルールファイルです。

Vibe Codingの勝負はコードを読む段階ではなく、最初のルールファイルを書く段階で決まります。

なぜルールファイルなのか — AIは毎回、入社したばかりの新人です

まず、AIコーディングツールの根本的な特性を確認しましょう。AIはセッションが終わると、その大半を忘れます。

昨日「APIキーは環境変数に移せ」と伝えていても、今日の新しいセッションでは、その会話はなかったことになります。

だから、毎セッション繰り返す指示は会話ではなく、ファイルに書き込んでおく必要があります。

CLAUDE.md(Claude Code)、.cursorrules(Cursor)、AGENTS.md(Codexなどの汎用ツール)がその例です。こうしたルールファイルは、セッション開始時に毎回自動でプロンプトへ追加されます。

人にたとえるなら、毎朝出社する新人に渡すオンボーディング資料のようなものです。

これが特にバイブコーディングと相性がいいのは、バイブコーディングが定義上、人間がコードを読まない方法だからです。

人によるレビューがない部分は何かで補う必要があり、その第一候補が「生成時のルール」です。悪いコードを後から除くより、最初から生成させないほうがはるかに安上がりです。

前編で挙げた3つの問題に、コードを読まなければ見抜けないAI特有の思考を2つ加え、計5つをルールでどう防ぐか見ていきます。


ルール1. セキュリティ — 「するな」ではなく「こうしろ」まで書く

前編で見たAPIキーのハードコーディングから対処します。ルールファイルにはこう書きます。

## セキュリティルール(違反時はコード生成を中断して報告すること)

- API キー・トークン・パスワードをコードにハードコーディングしない.
  必ず環境変数(.env) またはシークレットマネージャーから読み込む.
- .env ファイルは絶対にコミットせず. .env.exampleのみコミットする.
- ユーザー入力は信頼せず. SQLパラメータバインディング,
  HTML 出力はエスケープをデフォルトにする.
- ファイル削除·DB マイグレーション・外部決済 API 呼び出しコードを書くときは
  実行前に必ずユーザーの確認を得る.
- 新しいライブラリは無断でインストールしない。パッケージ名と
  選定理由を先に提案し、承認後に追加する.

ここで重要なポイントが2つあります。

1つ目は、禁止事項だけでなく代替案も一緒に書くことです。「ハードコーディング禁止」とだけ書くと、AIは自力で迂回策を探さなければなりません。

「環境変数から読み込む」とまで書けば、迷わずその方法を選びます。ルールの遵守率は、代替案の具体性に比例します。

2つ目は、リスクの異なる作業では手順自体を変えることです。削除・決済・マイグレーションには「確認してから進める」と明記しておけば、Accept Allを押す流れの中でも、その箇所では必ずブレーキがかかります。

最後の行にある依存関係のルールも、セキュリティの延長線上にあります。AIが推奨するパッケージ名の5~21%はレジストリに実在しないという調査がありますが、恐ろしいのはその次です。

攻撃者は、AIが頻繁に作り出す偽の名前をあらかじめ取得し、その名前で悪意のあるパッケージを公開します。スロップスクワッティング(slopsquatting)攻撃は実際に起きています。

インストールコマンドまでAccept Allで進めるバイブコーディングでは、この経路がそのままサプライチェーン事故につながります。だからこそ、「新しいパッケージは提案後に承認する」という手順を組み込んでおくのが安全です。


ルール2. 重複 — 「作る前に探す」を明文化する

同じ機能が複数箇所に生まれる原因は、AIが怠けているからではありません。AIは、コンテキストから見えないコードを存在しないコードとして扱うからです。

プロジェクトが大きくなるほどコードベース全体をコンテキストに入れられなくなるため、似た関数を新しく作ることがAIにとって合理的な選択になります。

そこで、ルールによって探索を強制します。

## 重複防止ルール

- 新しい関数・コンポーネントを作る前に、必ず既存のコードベースを
  検索し、同じ役割のものがすでに存在するか確認する.
- 日付処理は src/utils/date.ts, API 呼び出しは src/lib/api.tsに
  既存の関数を使う。なければそのファイルに追加する.
- 2か所以上で使われるロジックは、すぐに共通モジュールへ切り出す.
- 既存の関数とほぼ同じ関数が必要に見えても、新しく作らず
  既存の関数を拡張できるか先に検討して、ユーザーに提案する.

2行目が特に効果的です。「重複を作るな」という抽象的なルールより、「日付処理はこのファイルにある」という地図のほうがはるかによく効きます。

AIが検索を飛ばしても、ルールファイルに書かれたパスは常に目の前にあります。プロジェクトの共通モジュールの場所をルールファイルに一覧で管理するだけで、重複生成は目に見えて減ります。

ロボット配達員を既存の共通モジュールの建物へ案内するコードベースの都市地図
共通モジュールの場所を知らせれば、AIは重複した建物を建てません

ルール3. アーキテクチャ — フォルダ構成と依存方向を憲法にする

3つの中で最も静かに崩れるのがアーキテクチャです。セキュリティインシデントは起きれば気づき、重複は検索すれば見つかりますが、アーキテクチャはある日振り返ると、すでにスパゲッティになっています。

AIは「今このリクエストを最速で解決するコード」を書く傾向があります。そのため、レイヤーを飛び越える近道を平然と作ります。

たとえば、ビューからDBを直接呼び出すように。

これもルールで防げます。重要なのは、構造と依存方向を明示することです。

## アーキテクチャルール

プロジェクト構成:
- src/views/     : UI. 状態とイベントだけを扱う
- src/services/  : ビジネスロジック
- src/repositories/ : データアクセス. DB·API 呼び出しはここからのみ行う

依存の方向は views → services → repositories 一方向.
- viewsから repositoriesを直接 importしない
- repositoriesから viewsを importしない
- 新機能も必ずこの 3レイヤー構成に従う.
  構成から外れる理由がある場合は、コードを書く前にユーザーへ説明する

このルールの本当の価値は、最初の骨格ができた後に現れます。

AIには既存コードのパターンを強く踏襲する性質があります。初期コードが3層構成を守っていれば、その後のコードも自然に同じ流れになります。

逆に、初期段階で一つでも近道を許すと、AIはそれを「このプロジェクトで許可されたパターン」として学習します。

だからこの記事の副題は「最初の骨格」なのです。

プロジェクト作成直後、コードが10行しかないうちにルールファイルとフォルダー構成を先に決めること。後から1万行をリファクタリングするより、数百倍も安く済みます。


ルール4. 完了の基準 — 「できた気がする」と「できた」を区別する

ここからは、前編では扱わなかった、AIコーディング特有の思考パターンについて説明します。

AIには、コードを書き終えると確認もせずに「完了しました」と言う癖があります。実際には、コンパイルすらできないコードなのにです。

人がdiffを読むワークフローならすぐに露見しますが、バイブコーディングでは「完了」という言葉だけを信じて次の依頼へ進んでしまいます。だからこそ、完了の定義そのものをルールとして組み込む必要があります。

## 完了基準のルール

- 作業完了を宣言する前に、必ず typecheck·lint·テストを
  実行し、その結果もあわせて報告する
- テストが失敗したらコードを修正する。テストを変更・削除して
  通過させてはならない。テスト自体が間違っていると判断した場合は
  修正せず、まず報告する
- エラーを try/catchでラップして黙って握りつぶさない.
  捕捉したエラーは必ずログに残すか、上位へ伝播させる

2つ目のルールが核心です。AIに「テストを通過させろ」という目標を与えると、コードを直す代わりに失敗しているテストのほうを修正してしまうことが実際にあります。

目標達成への最短経路を見つけたわけです。コードを読まない人は、検証の仕組みが無効化されたことにも気づかず、緑の表示だけを見ることになります。

3つ目のルールは、前編の問題1(バグを直せなくなる)に直結します。

AIは防御的に書くという理由で、エラーを握りつぶすtry/catchでコードを囲む傾向があります。すると問題が起きても画面は正常に見えます。後になって本当に必要なエラーメッセージがどこにも残っておらず、デバッグはさらに困難になります。


ルール5. スコープ — 指示したことだけをさせる

AIコーディングでもう一つの典型的な失敗が、頼んでいないことまでやってしまう、いわゆるスコープクリープ(scope creep)です。ボタンの色を変えてほしいと頼んだだけなのに、「ついでに」と周辺コードをリファクタリングし、新しいヘルパー関数を切り出し、ファイル構成まで変えてしまいます。

善意のように見えても、バイブコーディングでは致命的です。diffを読まなければ、頼んでいない変更が紛れ込んでも気づけず、あとで何かが壊れたときの原因候補が何倍にも増えてしまいます。

## スコープのルール

- 依頼された作業だけを行う。作業中に見つけた改善点はコードを
  変更せず、作業完了後に一覧で提案する
- 依頼と無関係なファイルは変更しない
- リファクタリングは別途依頼された場合にのみ行う

効果は数値でも確認できます。ルールファイルにスコープのルールを数行追加するだけで、revertとスコープ逸脱の割合が41%から12%に低下したそうです。

30日間の実測レポートに記載された数値です。5種類のルールの中で、投資対効果が最も大きい領域です。


ルールだけでは不十分です — 二重ロックをかける

ここまで読むと、「それならルールをきちんと書けば、コードを読まなくてもいいのでは」と思うかもしれません。しかし、落とし穴が一つあります。ルールは守られる確率を高める仕組みであって、保証ではありません。

AIはコンテキストが長くなるとルールを忘れることがあり、急いでいるとき(正確には、そう見える状況では)近道を選ぶこともあります。

だからこそ、重要なルールほど機械的な検証と組み合わせる必要があります。ルールが1次ロック、ツールが2次ロックです。

ルール(生成時の予防) ツール(コミット・CI時の検証)
シークレットのハードコーディング禁止 gitleaks の pre-commit フック
重複ロジック禁止 jscpd のような重複検出ツール
レイヤー間の依存方向を強制 dependency-cruiser, eslint-plugin-boundaries
完了条件(テスト・型チェック) CI パイプラインのゲート
テストファイルの無断変更禁止 CODEOWNERS でテストフォルダーを保護
コードスタイル ESLint·Prettier·SwiftLint

この組み合わせの強みは、フィードバックループにあります。ツールがルール違反を検出すると、そのエラーメッセージが AI に渡され、AI は再びルールファイルを参照して修正します。

人が介入しなくても、予防 → 検証 → 修正のループが回ります。前回の記事で述べた「人が読まないなら、機械に読ませる」が、ルールと組み合わさって完成します。

リンタールールで強制できるものは、リンターに移しましょう。ルールファイルには、ツールでは検出できないもの(確認手順、設計意図、プロジェクトのコンテキスト)を残すのが理想的な分担です。

RULES と CI の2つの錠前で施錠された金庫の扉と、予防・検証・修正を示す循環矢印
ルールが1つ目の錠前、ツールが2つ目の錠前 — 予防・検証・修正のループ

実践:プロジェクト開始時の10分チェックリスト

新しいプロジェクトでバイブコーディングを始める前、最初のプロンプトを入力する前に、まずこれを実行しましょう。

  1. ルールファイルを作成 — セキュリティ、重複、アーキテクチャ、完了条件、スコープの5セクションです。上の例をコピーしてプロジェクト向けに修正すれば、10分で完了します。
  2. フォルダの骨格を先にコミット — 空のフォルダでも先に構造を作っておけば、AIはその形に従います。
  3. シークレットスキャンのフックを導入 — gitleaksだけでも最悪の事故を防げます。
  4. .env.exampleを作成 — 「キーはここに置く」という合図をコードベース全体で示します。

運用中に覚えておくことは1つだけです。AIが同じミスを2回するなら、それはAIのせいではなく、ルールファイルにそのルールがないというサインです。

事故が起きるたびに、ルールを1行ずつ補強してください。ルールファイルは一度書いて終わる文書ではなく、プロジェクトとともに成長する文書です。

Q. ルールファイルが長くなると、かえって守られなくなると聞きましたが?

A. そのとおりです。ルールもコンテキストを消費するため、長くなるほど個々のルールの重みが薄れます。

「常に守る必要があるか」を基準にスリムに保ち、ツールで検出できるものはツールに任せましょう。経験上、1画面(100行前後)を超え始めたら、整理が必要です。

Q. すでにスパゲッティ化したプロジェクトにも役立ちますか?

A. 役立ちます。ただし、順番が異なります。

まずAIに現在の構造を分析させ、ルールファイルのたたき台を作ります。次に、「新しいコードはこのルールに従い、既存コードは触る機会に修正する」という段階的な方針をルールに明記するのが現実的です。

Q. CLAUDE.md、.cursorrules、AGENTS.mdはすべて別々に管理する必要がありますか?

A. 内容は1つにまとめ、ファイルだけ複製するのが一般的です。

最近では、AGENTS.mdを標準として扱い、ほかのファイルから参照する流れもあります。複数のツールを使うなら、AGENTS.mdを唯一の原本にすることをおすすめします。


まとめます。前編の結論が「速度はAIに、判断は自分に」だったとすれば、今回の結論はこうです。

毎回判断するのではなく、一度下した判断をルールとして明文化しましょう。

コードを読むことは、その背後にある思考を見つけることです。一方、ルールを書くことは、問題を未然に防ぐことです。Vibe Codingで速度を確保しながらも崩れないプロジェクトには、華やかなプロンプトではなく、よく育てられたルールファイルがあるという共通点があります。

現在進めているプロジェクトにルールファイルがないなら、次の機能を依頼する前に、まず上記の5つのセクションを作ってみてください。

ルールファイルとメモリ機能の違い、そしてどの内容をどこに置くべきかについては別の記事で詳しく解説しているので、あわせて読むことをおすすめします。

参考資料

あわせて読みたい