はじめに
生成AIを使ったコード開発が急速に普及している。GitHub Copilot、ChatGPT、Claude、そして各種IDEに統合されたAIアシスタントや独立したコーディングエージェント。これらのツールは開発効率を飛躍的に向上させ、もはやAIなしでの開発は考えられないという声も聞こえてくる(主に心の底から)。
しかし、この革新的な変化の中で、看過できない問題が顕在化している。現在のAIで生成したコードは、2年後の進化したAIで再生成すれば、より効率的で保守性の高いコードに置き換えられる。これ自体は技術進歩として歓迎すべきことだが、重要な情報が失われている。
それは「なぜそのコードをそのように実装したのか」という意思決定の記録だ。
この問題は単なる技術的な課題ではない。私たちがどのようにソフトウェアを作り、保守し、進化させていくかという、エンジニアリングの本質に関わる問題だ(そして、2年後の自分に恨まれない方法でもある)。
プロンプトと成果物の分離がもたらす課題
従来の開発では、コードとともにコメントやドキュメントで意図を残してきた。しかしAI時代では、以下の情報が分離してしまう:
- 入力:プロンプト(要件、制約、背景情報)
- 出力:生成されたコード
生成されたコードだけがリポジトリに残り、そのコードを生成した際のプロンプトや文脈は失われる。2年後、より優れたAIでコードを改善しようとしても、元の要件や制約条件、設計判断の根拠が不明なため、適切な改善ができない。
これは「なんでこんな実装になってるの?」と聞かれて「AIがそう書いたから...」としか答えられない悲しい未来への第一歩だ。
ADRからPDRへ:解決策の提案
ソフトウェアアーキテクチャの分野では、ADR(Architecture Decision Records)によって設計判断を記録する文化が定着している。同様に、AI時代にはPDR(Prompt Decision Records)が必要だ。
PDRに記録すべき要素:
- 使用したAIモデルとバージョン(GPT-4なのかClaude-3なのか、未来の自分は知りたがっている)
- 入力したプロンプトの完全なテキスト
- プロンプトに込めた意図と背景
- 検討した他の選択肢
- 採用した理由とトレードオフ
- 生成パラメータ(temperature、max_tokens等)
既存ツールにおける実装例
既存ツールの現状についてはこちらがめちゃくちゃよくまとまっております。
Cursor Rules
Cursorでは.cursorrules
ファイルでプロジェクト固有のコンテキストを定義できる。これにより、AIは常にプロジェクトの規約や方針を理解した上でコードを生成する(理解しているフリをすることもあるが)。
具体的には、プロジェクトのルートディレクトリに.cursorrules
ファイルを配置することで、以下のような指示を永続化できる:
このプロジェクトではTypeScriptを使用し、関数型プログラミングのアプローチを優先する。 エラーハンドリングはResult型を使用し、例外は投げない。 すべての関数にはJSDocコメントを必須とする。
このファイルはプロジェクト全体で共有される暗黙知を形式知化する役割を果たし、新しいメンバーがジョインした際のオンボーディングツールとしても機能する。
Cline Rules
Clineも同様に、プロジェクトルールを定義する仕組みを提供している。これらのルールファイルは、実質的にプロンプトの一部を永続化する仕組みだ。
Clineの特徴的な点は、ルールを階層的に管理できることだ。グローバルルール、プロジェクトルール、ディレクトリ固有のルールを定義でき、より細かい粒度でAIの振る舞いを制御できる。例えば:
/backend
ディレクトリ:「APIエンドポイントはRESTfulな設計に従う」/frontend
ディレクトリ:「ReactコンポーネントはHooksを使用した関数コンポーネントとする」/tests
ディレクトリ:「テストはAAA(Arrange-Act-Assert)パターンに従う」
このようなコンテキストの階層管理により、大規模プロジェクトでも一貫性を保ちながら、部分ごとに最適化されたAI支援を受けられる。
Anthropic CLAUDE.md
AnthropicのCLAUDE.mdアプローチは、プロジェクトの全体的なコンテキストを単一のマークダウンファイルにまとめる。これは包括的なプロンプトテンプレートとして機能し、AIとの対話の基盤となる。
CLAUDE.mdの強みは、単なるルールの羅列ではなく、プロジェクトのストーリーを語る点にある。典型的な構成は:
# プロジェクト概要 このプロジェクトの目的と背景 # アーキテクチャ システムの全体構成と主要コンポーネントの説明 # 開発規約 - コーディングスタイル - 命名規則 - ディレクトリ構造 # よくある質問と回答 過去の設計判断とその理由
この形式により、AIは単にルールに従うだけでなく、プロジェクトの「なぜ」を理解した上でコードを生成できる。まさに本記事で提唱するPDRの考え方を先取りした実装と言えるだろう。
実装における具体的な課題
バージョン管理
プロンプトもコードと同様にバージョン管理が必要だ。しかし、以下の課題がある:
- プロンプトの変更がコードに与える影響の追跡
- AIモデルのバージョンアップに伴う互換性管理
- プロンプトとコードの紐付けの維持(gitのblameコマンドに「AI」と表示される悲しさ)
標準化の欠如
現状、プロンプトを記録・管理する標準的な方法は存在しない。各ツールが独自の方法を実装しているため、ツール間での移植性がない。まるで文字コードの乱立時代を彷彿とさせる。
再現性の問題
同じプロンプトでも、以下の要因により出力が変わる:
- AIモデルのバージョン
- 生成パラメータ
- APIのバージョン
- 実行タイミング(モデルの更新)
今後の展望と提案
短期的な対策
既存ツールの活用 Cursor、Cline、GitHub Copilotなどが提供するルールファイル機能を積極的に活用し、プロジェクト固有のコンテキストを記録・管理する。
プロンプトのコメント埋め込み 生成されたコードに、使用したプロンプトをコメントとして埋め込む(将来の自分への手紙として)。
中長期的な標準化
業界標準として、以下のような仕様が必要になるかもしれない:
# prompt-decision-record.yaml version: 1.0 timestamp: 2024-12-XX model: provider: openai name: gpt-4 version: gpt-4-0125-preview mood: cooperative # 冗談です parameters: temperature: 0.7 max_tokens: 2000 prompt: | 実際のプロンプトテキスト context: requirements: | 要件の説明 constraints: | 制約事項 decisions: | 設計判断の根拠 output_file: src/feature/***.py
おわりに
AI活用が当たり前になる開発環境において、コードの「なぜ」を残すことは、技術的負債を防ぐ重要な実践だ。2年後により良いAIが登場したとき、過去の意思決定を理解できれば、真に価値のある改善が可能になる。
私たちエンジニアは、常に未来の自分や同僚のことを考えてコードを書いてきた。可読性、保守性、拡張性—これらはすべて「未来の誰か」のための配慮だ。AI時代においても、この精神は変わらない。むしろ、AIの進化速度を考えれば、より一層重要になる。
プロンプトは新しい形の設計書だ。コードレビューと同じように、プロンプトレビューが必要になるかもしれない。リファクタリングと同じように、プロンプトリファクタリングが日常になるかもしれない(プロンプトの可読性を議論する日も近い)。もしくはそのような考慮をすべて超えて全てを理解する生成AIのモデルが成長する可能性もある。
PDRのような仕組みの標準化は、AI時代のソフトウェア開発における必須要件となるだろう。エンジニアとして、この課題に真剣に取り組む時期に来ているが、個人ではどうにもならない気もするので。頑張れ、Anthropic!!!