🤖

Issue 分割してもコンテキストを失わない、PLANS.md で実装計画を定型化する AI 駆動開発ワークフロー

に公開

現在多くのエンジニアが Claude Code や Codex、Cursor などを使用して AI を使った開発をしていると思います。僕はメインで Claude Code を利用しつつ、うまくいかないときに Codex を使ったり、高速なレスポンスが欲しいときには Cursor の Composer を使います。

断片的なツールの Tips や Agent のノウハウはよく目にしますが、開発全体のワークフローという点ではあまり情報を目にする機会が少なく秘伝のタレ化しているように感じています。

そこで今回は僕が現在運用している AI 駆動開発のワークフローをご紹介します。

インスパイアを受けた記事

このワークフローの根幹はこの記事で紹介されている「論点駆動開発」にインスパイアを受けています。ただ、他者が完全にコピーするには特化が進んでいると感じたため、自分ができそうな範囲で模倣して運用しています。

https://mh4gf.dev/articles/2025-11-context-for-coding-agent

ワークフローの全体像

メインの開発は Claude Code を使ったカスタムコマンドとサブエージェントで固まりつつあります。

Issue 作成 -> プランニング -> 実装 -> レビューに渡る開発における全てのステップをカスタムコマンドあるいはサブエージェントにしています。細かな違いはあれど、この一連のフローは多くの開発者で共通していると思います。

個人的に難しいと感じていて、かつ、他者と違いが生まれるのは、プランニングとコンテキストの管理ではないでしょうか。

現在の形になるまで僕が抱えていた課題は以下でした:

  • Claude Code が出力する実装計画を読むのが大変
  • 複数の Sub Issue を持つような大きな課題でコンテキスト管理ができない

それぞれに次のようなアプローチを採用し、課題の解消とまでは言えないものの緩和できています。

  • PLANS.md による実装計画の定型化
  • GitHub Issue を介したコンテキスト同期

それぞれ詳しく説明していきます。

PLANS.md による実装計画の定型化

Claude Code に「計画をマークダウンで出力して」と依頼したことが誰しもあると思います。しかし、その出力内容に辟易したこともあるのではないでしょうか。

冗長な進捗リスト、何行にも渡る実装ステップ。マークダウンにコードを書き始めていて「もうそれは実装しているのと同義じゃない?」と何度も思いました。

ここに現れたのが OpenAI が10月のイベントで紹介した PLANS.md でした。

https://cookbook.openai.com/articles/codex_exec_plans#surprises--discoveries

PLANS.md(一部和訳)
# Codex Execution Plans (ExecPlans):

この文書は、コーディングエージェントが動作する機能やシステム変更を実装するために従うべき設計文書である「実行計画(ExecPlan)」の要件を説明します。読者は、このリポジトリの完全な初心者として扱ってください。つまり、現在の作業ツリーとあなたが提供する単一のExecPlanファイルしか持っていません。過去の計画の記憶も外部コンテキストもありません。

## How to use ExecPlans and PLANS.md

実行可能な仕様(ExecPlan)を作成する際は、PLANS.mdに_文字通り_従ってください。コンテキストにない場合は、PLANS.mdファイル全体を読んで記憶を更新してください。正確な仕様を作成するために、元の資料を徹底的に読み(そして再読し)ましょう。仕様を作成する際は、スケルトンから始めて、調査しながら詳細を埋めていきます。

実行可能な仕様(ExecPlan)を実装する際は、ユーザーに「次のステップ」を尋ねないでください。単に次のマイルストーンに進みます。すべてのセクションを最新の状態に保ち、停止ポイントごとにリスト内のエントリを追加または分割して、進捗状況と次のステップを明確に記述します。曖昧さは自律的に解決し、頻繁にコミットします。

実行可能な仕様(ExecPlan)について議論する際は、後世のために仕様内のログに決定事項を記録します。仕様への変更が行われた理由は明確でなければなりません。ExecPlanは生きた文書であり、_ExecPlanのみ_から常に再開できるべきです。

困難な要件や重大な未知の問題を持つ設計を調査する際は、マイルストーンを使用して概念実証や「トイ実装」などを実装し、ユーザーの提案が実現可能かどうかを検証できるようにします。ライブラリを見つけるか入手してソースコードを読み、深く調査し、完全な実装の指針となるプロトタイプを含めます。

## Requirements

譲れない要件:

* すべてのExecPlanは完全に自己完結していなければなりません。自己完結とは、現在の形式で初心者が成功するために必要なすべての知識と指示が含まれていることを意味します。
* すべてのExecPlanは生きた文書です。貢献者は、進捗があるとき、発見があるとき、設計決定が確定したときに改訂する必要があります。各改訂版は完全に自己完結したままでなければなりません。
* すべてのExecPlanは、完全な初心者がこのリポジトリの事前知識なしに機能をエンドツーエンドで実装できるようにする必要があります。
* すべてのExecPlanは、単に「定義を満たす」コード変更ではなく、実証可能に動作する振る舞いを生み出さなければなりません。
* すべてのExecPlanは、専門用語を平易な言葉で定義するか、使用しないかのいずれかでなければなりません。

目的と意図が最優先です。まず、ユーザーの視点からなぜこの作業が重要なのかを数文で説明します。つまり、この変更後に誰かができるようになることで、以前はできなかったこと、そしてそれが動作していることをどのように確認するかです。次に、何を編集し、何を実行し、何を観察すべきかを含めて、その結果を達成するための正確な手順を読者に案内します。

あなたの計画を実行するエージェントは、ファイルのリスト表示、読み取り、検索、プロジェクトの実行、テストの実行ができます。しかし、事前のコンテキストは知らず、以前のマイルストーンからあなたが意味したことを推測できません。依存するすべての前提を繰り返してください。外部のブログやドキュメントを指さないでください。知識が必要な場合は、自分の言葉で計画自体に埋め込みます。ExecPlanが以前のExecPlanに基づいており、そのファイルがチェックインされている場合は、参照として組み込みます。そうでない場合は、その計画からすべての関連コンテキストを含める必要があります。

## Formatting

フォーマットと形式はシンプルで厳格です。各ExecPlanは、トリプルバッククォートで始まり終わる、`md`とラベル付けされた単一のフェンスコードブロックでなければなりません。内部に追加のトリプルバッククォートのコードフェンスをネストしないでください。コマンド、トランスクリプト、差分、またはコードを表示する必要がある場合は、その単一のフェンス内でインデントされたブロックとして提示します。ExecPlanのコードフェンスを途中で閉じないように、ExecPlan内部のコードフェンスの代わりにインデントを使用して明確にします。すべての見出しの後に2つの改行を使用し、#、##などを使用し、順序付きおよび順序なしリストの正しい構文を使用します。

ExecPlanをMarkdown(.md)ファイルに書き込む際、ファイルの内容が_単一のExecPlanのみ_である場合、トリプルバッククォートは省略してください。

平易な散文で書きます。リストよりも文章を優先します。簡潔さが意味を曖昧にする場合を除き、チェックリスト、表、長い列挙は避けます。チェックリストは`Progress`セクションでのみ許可され、そこでは必須です。ナラティブセクションは散文を優先したままでなければなりません。

## Guidelines

自己完結性と平易な言葉が最も重要です。通常の英語ではないフレーズ(「daemon」、「middleware」、「RPC gateway」、「filter graph」)を導入する場合は、すぐに定義し、このリポジトリでどのように現れるか(たとえば、表示されるファイルやコマンドの名前を挙げて)読者に思い出させます。「以前に定義したとおり」や「アーキテクチャドキュメントによると」とは言わないでください。繰り返しになっても、ここに必要な説明を含めます。

一般的な失敗モードを避けます。未定義の専門用語に依存しないでください。コンパイルはできるが意味のあることを何もしないほど狭く「機能の文言」を記述しないでください。重要な決定を読者に外注しないでください。曖昧さが存在する場合は、計画自体でそれを解決し、なぜそのパスを選んだのかを説明します。ユーザーに見える効果を過度に説明し、付随的な実装の詳細を過少に指定する側に誤ります。

観察可能な結果で計画を固定します。実装後にユーザーができること、実行するコマンド、見るべき出力を述べます。受け入れは、内部属性(「HealthCheck構造体を追加」)ではなく、人間が検証できる動作(「サーバーを起動した後、[http://localhost:8080/health](http://localhost:8080/health)に移動するとHTTP 200がボディOKで返される」)として表現する必要があります。変更が内部的なものである場合は、その影響をどのように実証できるかを説明します(たとえば、変更前に失敗し変更後に成功するテストを実行し、新しい動作を使用するシナリオを示すことによって)。

リポジトリのコンテキストを明示的に指定します。完全なリポジトリ相対パスでファイルに名前を付け、関数とモジュールを正確に名前付けし、新しいファイルを作成する場所を説明します。複数の領域に触れる場合は、初心者が自信を持ってナビゲートできるように、それらの部分がどのように組み合わされるかを説明する短いオリエンテーション段落を含めます。コマンドを実行する際は、作業ディレクトリと正確なコマンドラインを示します。結果が環境に依存する場合は、前提を述べ、合理的な場合は代替案を提供します。

べき等で安全であること。ダメージやドリフトを引き起こすことなく複数回実行できるように手順を書きます。ステップが途中で失敗する可能性がある場合は、再試行または適応する方法を含めます。移行または破壊的な操作が必要な場合は、バックアップまたは安全なフォールバックを詳しく説明します。進みながら検証できる、追加的でテスト可能な変更を優先します。

検証はオプションではありません。テストを実行し、該当する場合はシステムを起動し、何か有用なことをしているのを観察する手順を含めます。新しい機能や能力については包括的なテストを説明します。初心者が成功と失敗を区別できるように、予想される出力とエラーメッセージを含めます。可能な場合は、コンパイル以上に変更が効果的であることを証明する方法を示します(たとえば、小さなエンドツーエンドのシナリオ、CLI呼び出し、またはHTTPリクエスト/レスポンストランスクリプトを通じて)。プロジェクトのツールチェーンに適した正確なテストコマンドと、その結果の解釈方法を述べます。

証拠を捕捉します。手順がターミナル出力、短い差分、またはログを生成する場合は、単一のフェンスブロック内にインデントされた例として含めます。成功を証明するものに焦点を当てて簡潔に保ちます。パッチを含める必要がある場合は、大きなブロブを貼り付けるのではなく、読者が指示に従って再作成できるファイルスコープの差分または小さな抜粋を優先します。

## Milestones

マイルストーンはナラティブであり、官僚主義ではありません。作業をマイルストーンに分割する場合は、それぞれを、スコープ、マイルストーンの終わりに存在する以前に存在しなかったもの、実行するコマンド、観察することを期待する受け入れを説明する簡単な段落で紹介します。ストーリーとして読みやすく保ちます:目標、作業、結果、証明。進捗とマイルストーンは異なります:マイルストーンはストーリーを語り、進捗は詳細な作業を追跡します。両方が存在しなければなりません。単に簡潔さのためにマイルストーンを省略せず、将来の実装に重要となりうる詳細を省略しないでください。

各マイルストーンは独立して検証可能であり、実行計画の全体的な目標を段階的に実装する必要があります。

## Living plans and design decisions

* ExecPlanは生きた文書です。重要な設計決定を行う際は、決定とその背後にある考えの両方を記録するために計画を更新します。すべての決定を`Decision Log`セクションに記録します。
* ExecPlanには、`Progress`セクション、`Surprises & Discoveries`セクション、`Decision Log``Outcomes & Retrospective`セクションを含め、維持する必要があります。これらはオプションではありません。
* オプティマイザの動作、パフォーマンストレードオフ、予期しないバグ、またはアプローチを形成した逆/適用解除セマンティクスを発見した場合は、短い証拠スニペット(テスト出力が理想的)とともに`Surprises & Discoveries`セクションにそれらの観察を捕捉します。
* 実装の途中でコースを変更する場合は、`Decision Log`にその理由を文書化し、`Progress`に影響を反映します。計画は、あなたのためのチェックリストと同じくらい次の貢献者のためのガイドです。
* 主要なタスクまたは完全な計画の完了時に、達成されたこと、残っていること、学んだ教訓を要約する`Outcomes & Retrospective`エントリを書きます。

## Prototyping milestones and parallel implementations

より大きな変更のリスクを軽減する場合、明示的なプロトタイピングマイルストーンを含めることは許容され、しばしば奨励されます。例:実現可能性を検証するために依存関係に低レベルの演算子を追加する、またはオプティマイザの効果を測定しながら2つの構成順序を探索する。プロトタイプは追加的でテスト可能に保ちます。スコープを「プロトタイピング」として明確にラベル付けし、実行および結果の観察方法を説明し、プロトタイプを昇格または破棄する基準を述べます。

テストを合格させ続ける追加的なコード変更の後に減算を行うことを優先します。並列実装(たとえば、大規模な移行中に古いパスと一緒にアダプターを保持する)は、リスクを軽減するか、大規模な移行中にテストが合格し続けるのを可能にする場合は問題ありません。両方のパスを検証する方法と、テストで一方を安全に廃止する方法を説明します。複数の新しいライブラリまたは機能領域を扱う場合は、これらの機能の実現可能性を_互いに独立して_評価するスパイクを作成し、外部ライブラリが期待どおりに動作し、単独で必要な機能を実装することを証明することを検討します。

## Skeleton of a Good ExecPlan
```md
# <短く、アクション志向の説明>

このExecPlanは生きた文書です。`Progress``Surprises & Discoveries``Decision Log``Outcomes & Retrospective`のセクションは、作業が進むにつれて最新の状態に保たれなければなりません。

PLANS.mdファイルがリポジトリにチェックインされている場合は、リポジトリルートからそのファイルへのパスをここで参照し、この文書はPLANS.mdに従って維持されなければならないことに注意してください。

## Purpose / Big Picture

この変更後に誰かが得るものと、それが動作していることをどのように確認できるかを数文で説明します。有効にするユーザーに見える動作を述べます。

## Progress

チェックボックス付きのリストを使用して、詳細なステップを要約します。すべての停止ポイントは、部分的に完了したタスクを2つ(「完了」vs.「残り」)に分割する必要がある場合でも、ここに文書化する必要があります。このセクションは常に作業の実際の現在の状態を反映しなければなりません。

- [x] (2025-10-01 13:00Z) 完了したステップの例。
- [ ] 未完了のステップの例。
- [ ] 部分的に完了したステップの例(完了:X;残り:Y)。

進捗率を測定するためにタイムスタンプを使用します。

## Surprises & Discoveries

実装中に発見された予期しない動作、バグ、最適化、または洞察を文書化します。簡潔な証拠を提供します。

- 観察:…
  証拠:…

## Decision Log

計画に取り組んでいる間に行われたすべての決定を次の形式で記録します:

- 決定:…
  理由:…
  日付/著者:…

## Outcomes & Retrospective

主要なマイルストーンまたは完了時に、結果、ギャップ、学んだ教訓を要約します。元の目的に対して結果を比較します。

## Context and Orientation

読者が何も知らないかのように、このタスクに関連する現在の状態を説明します。完全なパスで主要なファイルとモジュールに名前を付けます。使用する明らかでない用語を定義します。以前の計画を参照しないでください。

## Plan of Work

散文で、編集と追加のシーケンスを説明します。各編集について、ファイルと場所(関数、モジュール)、および挿入または変更するものに名前を付けます。具体的で最小限に保ちます。

## Concrete Steps

実行する正確なコマンドとそれらを実行する場所(作業ディレクトリ)を述べます。コマンドが出力を生成する場合は、読者が比較できるように、予想される短いトランスクリプトを示します。このセクションは作業が進むにつれて更新されなければなりません。

## Validation and Acceptance

システムを起動または実行する方法と、何を観察するかを説明します。受け入れを、特定の入力と出力を伴う動作として表現します。テストが関与する場合は、「<プロジェクトのテストコマンド>を実行し、<N>個の合格を期待します;新しいテスト<名前>は変更前に失敗し、変更後に合格します」と言います。

## Idempotence and Recovery

ステップを安全に繰り返すことができる場合は、そう言います。ステップがリスクが高い場合は、安全な再試行またはロールバックパスを提供します。完了後に環境をクリーンに保ちます。

## Artifacts and Notes

最も重要なトランスクリプト、差分、またはスニペットをインデントされた例として含めます。成功を証明するものに焦点を当てて簡潔に保ちます。

## Interfaces and Dependencies

規範的であること。使用するライブラリ、モジュール、サービスに名前を付け、その理由を述べます。マイルストーンの終わりに存在しなければならない型、トレイト/インターフェース、関数シグネチャを指定します。`crate::module::function`または`package.submodule.Interface`などの安定した名前とパスを優先します。例:

crates/foo/planner.rsで定義:

    pub trait Planner {
        fn plan(&self, observed: &Observed) -> Vec<Action>;
    }

上記のガイダンスに従えば、単一のステートレスエージェント、または人間の初心者が、あなたのExecPlanを上から下まで読んで、動作する観察可能な結果を生み出すことができます。それが基準です:自己完結、自己充足、初心者ガイド、結果重視。

計画を改訂する際は、生きた文書のセクションを含むすべてのセクションに変更が包括的に反映されていることを確認する必要があり、計画の下部に変更とその理由を説明するメモを書く必要があります。ExecPlanは、ほとんどすべてについて、何だけでなくなぜを説明する必要があります。

実装計画を定型フォーマットにする時点でナイスアイデアなのですが、中でも面白かったのが Surprises & Discoveries(驚きと発見)と Decision Log(決定ログ)です。これは Claude Code が素で出力する計画にはないものでした。

計画段階では抜け漏れがあり内容が頻繁に変わります。そのときに、どのような重大な発見があったか、その方針転換をいつどのような理由で決めたかが残るのはコンテキストを引き継ぐうえで大切です。

しばらくはこの OpenAI のフォーマットで運用していましたが、PLANS.md のさらなる改良案を冒頭の記事で拝見して速攻で真似しました。Open Questions に具体も抽象も含めた残論点が集約されるため、小さな改修の実装から、いくつもの Sub Issue を抱える親 Issue の PLAN でも機能します。

実際に使っているカスタムスラッシュコマンド /create-plan はこちらです。

https://github.com/sasamuku/dotfiles/blob/main/.claude/commands/create-plan.md

GitHub Issue を介したコンテキスト同期

大きな開発タスクでは Epic Issue を作り、Sub Issue を複数ぶら下げることがあります。Epic Issue に抽象度の高いゴールを設定、Sub Issue で具体的な実装タスクを切り出す形になります。

このような状況では共通の問題を取り扱う PLANS.md が分散して配置される問題が生じます。

Epic Issue に紐づく git worktree を切り、そこで課題に対する計画 PLANS.md を作成します。Sub Issue A に紐づく新しい git worktree を切り、そこでも PLANS.md を作成、Sub Issue B に紐づく新しい... というように git worktree で並列開発が便利になった反面、それぞれの環境にコンテキストが散らばる現象が起こります。

PLANS.md をリポジトリにプッシュできれば問題ないのですが、コーディングエージェントのノイズにならないためにもなるべく不必要なドキュメントはプッシュしたくありません。

解決策として、GitHub Issue を外部メモリとしたコンテキスト同期を行っています。

ローカルで作成した PLANS.md を /sync-plan コマンドによって GitHub Issue にも同期しています。これにより、ローカル環境で孤立していた PLANS.md を Epic Issue から参照できるようになります。

そして Sub Issue で進捗や変更があれば /update-plan-from-subissues で各 PLANS.md が持つコンテキストを Epic Issue に吸い上げます。Epic Issue 作成時に見えていなかったギャップなどあれば方針を練り直すことができます。

副次的なメリットとして、検討や思考のログが Issue に残るので、後から「あれ、なんでこうしたんだっけ?」となったときにも参照できます。

おわりに

2025年12月現在での AI 駆動開発におけるプランニングとコンテキスト管理の方法をご紹介しました。

去年のちょうど今頃に Cursor を使い始めて超絶感動していたのですが、たった1年で AI コーディングにまつわるエンジニアリングも大きく変化しましたね。

恐らく現在のやり方もすぐに陳腐化していくと思いますが、根っこにあるコンテキストエンジニアリングの考え方はしばらく有効なんじゃないかなと思います。

来年もこうした変化を楽しみながらやっていきたいですね!

参考リンク

Discussion