Claude CodeやCodexを使う前に、スペックファイルを3つ作成してください
1年間、Claude CodeとCodexから全く安定しない結果を得てきた。役割が明確な3つのスペックファイルがその問題を解決した。
AIコーディングエージェントをほぼ毎日使い続けて約1年、幻覚コードや間違ったAPIよりも、一貫性のなさの方がずっと気になっていました。同じタスクを少し違う言い方で伝えると、ある日は綺麗な出力が得られ、翌日はひどい結果になる。セッションが長くなるほど悪化しました。20回前のメッセージで合意した内容をエージェントが忘れてしまうからです。
根本原因は構造的なものでした。セッションをまたいでエージェントに意図を伝えるための枠組みが何もなかったため、会話のたびにゼロから始まり、予測不能な方向へ流れていきました。
結果を変えた3つのレイヤー
役割が明確な3つのファイルに指示を分割したことで、一貫性の問題はほぼ一夜にして解消しました。
レイヤー1のCLAUDE.md は毎セッション自動的に読み込まれます。ビルドコマンド、技術スタックのバージョン、フォルダ構造、コーディング規約、行動の境界線(常にすること、確認してからすること、絶対にしないこと)といったプロジェクトレベルの定数を保持します。
レイヤー2のSPEC.md は特定の機能の「何を」と「なぜ」を記録します。目的、要件、成功基準、技術的制約、スコープの境界線。実装の詳細については何も書きません。
レイヤー3のplan.md は、スペックを2〜5分で実行できるタスクに分解し、明示的なファイルパス、テスト優先の実行順序、コミットのチェックポイントを持ちます。
すべてを1つのファイルに詰め込むとうまくいかない理由
LLMの指示追従に関する研究では、これを「指示の呪い(Curse of Instructions)」と呼んでいます。単一のコンテキスト内の指示の数が増えると、個々の指示への遵守率が急激に低下します。実際に試してみました。プロジェクトのルール、機能のスペック、タスクリストを1つのファイルに詰め込んだとき、エージェントは後半にある指示の約半分を無視しました。
役割で分離することで解決しました。エージェントはレイヤー1からプロジェクト全体に適用されるルールを、レイヤー2から機能の意図を、レイヤー3から実行手順を読み取ります。各ファイルはモデルが十分に注意を向けられる長さに収まっています。
CLAUDE.mdはシンプルに保つのが効果的
このファイルはすべてのセッションで読み込まれるため、普遍的に適用されるものだけを含める必要があります。ビルドコマンド、スタックのバージョン、フォルダのレイアウト、命名規則。行動の3段階の境界線を加えます。常にすること、先に確認することすること、絶対にしないこと。
最もうまくいったアプローチは、最小限の状態から始めて、エージェントが同じミスを繰り返すたびにルールを少しずつ追加していくことでした。最初から包括的なCLAUDE.mdを書こうとすると、まさに避けようとしていた遵守率の低下を引き起こす肥大化につながりました。
いくつか具体的な落とし穴があります。APIキーやコードスニペットはすぐに古くなるので入れないこと。リンターがすでに強制しているルールを重複させないこと。そして単一の機能に固有のものはレイヤー2に移すこと。
スペックファイルは「何を」「なぜ」に集中し、「どうやって」はエージェントに任せる
従来のPRDとの違いは、これらのスペックがエージェントによる消費のために構造化されているという点です。5つのセクションで十分です。目的、要件、成功基準、技術的制約、境界線。
実装の決定はエージェントに委ねます。エージェントは既存のコードベースを分析して適切なアプローチを選べます。「どうやって」を指示しようとしたとき、エージェントは既存のパターンとの衝突を無視してそのまま従うか、まったく無視するかのどちらかでした。
スペックを手書きする代わりの方法として、エージェントにインタビューしてもらう方法があります。一度に1つの質問、できる限り選択式という2つのルールを設けます。その結果できたスペックは、自分でゼロから書いたものよりも抜け漏れが少ない傾向がありました。
完成したスペックはdocs/specs/YYYY-MM-DD-topic.mdに保存してGitにコミットします。こうするとエージェントがgit diffを通じてスペックの変更履歴にアクセスでき、レビュアーにとってはコード変更の背景にある意図の記録になります。
セッションの分割は最も見落とされがちな習慣
スペック作成中のブレインストーミングとQ&Aは、コンテキストウィンドウのかなりの部分を消費します。同じセッションでそのまま実装に入ると、エージェントは以前のコンテキストへのアクセスを徐々に失います。
セッションを3つに再構成しました。セッション1でSPEC.mdを作成し、セッション2でplan.mdを作成し、セッション3以降でタスクを1つずつ実行します。精度の改善は最初の1週間で実感できました。
このアプローチを機能させた3つの習慣があります。エージェントが推測しないようにすべてのタスクに明示的なファイルパスを書くこと、TDDの順序(テスト、実装、確認、コミット)をplan.mdに固定すること、コンテキストの使用量が約50%に達したら新しいセッションを開始すること。
成熟度モデルが示す「スペックがソースになる」世界
Martin Fowlerのチームは最近、エージェントベースのソフトウェア開発の成熟度モデルを3つのレベルで定義しました。レベル1はスペックを書いて実装し、スペックを捨てる。レベル2はスペックをコードと並行して生きたドキュメントとして維持する。レベル3はスペックが唯一の真実の源泉となり、コードは生成された成果物になる。
知る限り、多くのチームや個人はまだレベル1にも達していません。1回限りのプロンプトを送って、うまくいくことを祈っている状態です。
レベル1からレベル2への移行に必要なのは1つの習慣だけです。スペックファイルをGitにコミットすること。レベル2からレベル3への移行は、コードを変更する前にスペックを更新することを意味します。今日できる最小のステップは、プロジェクトのCLAUDE.mdを作成し、次の機能の前にSPEC.mdを書くことです。
ニュースレターに登録
最新のプロジェクト、記事、AIとWeb開発の実験に関する情報をお届けします。