同僚と数日間にわたる機能の作業を行う際、私たちは共有ドキュメントを保持します。正式なドキュメントではありません。作業記録です。何を決定したか、なぜそうしたか、何を却下したか、未解決の質問は何か。どちらかが1日不在になっても、もう片方が中断したところから続けられます。どちらも記憶だけに頼りません。ドキュメントは私たちの外部記憶であり、個人の想起では保持できないものを永続化します。

AIコーディングアシスタントの場合、会話が依然として主な記録となります。一部のツールは永続的なメモリ機能を提供しています(Claudeのプロジェクトメモリ、Cursorのルールファイル、Copilotのワークスペースインデックス)が、これらはプロジェクトレベルで動作し、フィーチャーレベルではありません。プロジェクトがFastifyを使用していることは記憶しますが、昨日のセッションでRetryQueue抽象化を特定の理由で却下したことは記憶しません。フィーチャーレベルの意思決定では、あらゆる制約、あらゆる推論がチャット履歴の中にしか存在せず、他の場所にはありません。これにより、私は悪循環として認識するようになったダイナミクスが生まれます。開発者は会話のセッションを必要以上に長く維持します。長いセッションが生産的だからではなく、セッションを閉じるとすべてを失うことになるからです。コンテキストは他に存在しません。外部の記録はありません。そのため会話は長く伸び、扱いにくくなり、AIの初期の意思決定を思い出す能力は静かに低下していきます。保持し続ける時間が長くなるほど、保持しているものの信頼性は低下します。

今この会話を閉じて、不安なく新しい会話を始められるでしょうか

ここに、私が示唆に富むと考えるテストがあります。今この会話を閉じて、不安なく新しい会話を始められるでしょうか?その質問が不快感を引き起こす場合、重要な何かを失うと感じる場合——コンテキストは、それを保存するよう設計されたことのない媒体の中に閉じ込められています。

コンテキストが劣化する理由

劣化はランダムではありません。大規模言語モデルがコンテキストを処理する方法に起因します。

すべてのモデルには有限のコンテキストウィンドウがあります。一度に処理できるトークン数にハードリミットがあります。現在のモデルは数十万から100万トークンを超えるウィンドウを提供します。これらの数字は寛大に聞こえますが、生産的な開発セッションはコンテキストを急速に生成します。コードスニペット、設計議論、決定根拠、ファイル内容。ウィンドウはほとんどの開発者が予想するよりも速く埋まります。

研究は実務者が直感的に経験することを確認しています。2023年にStanfordとBerkeleyによる研究(Liuらによる「Lost in the Middle」)は、言語モデルが長いコンテキストの中間に置かれた情報に対して、冒頭や末尾に比べて著しくパフォーマンスが低下することを示しました。この効果は大きく、会話の最近の部分でも冒頭でもないコンテンツに対する想起精度は測定可能なほど低下します。これは特定のモデルの癖ではなく、注意機構自体の特性です。最近のトークンとシステムレベルの指示が不均衡に重み付けされます。その間のすべてが、モデルの焦点の縮小するシェアを争います。

この研究は、位置によって物事が薄れていくことを確立しました。しかし対処していないのは——そして私が実務で繰り返し観察してきたのは——何が最初に薄れるかです。私の経験では、意思決定の根拠が意思決定そのものよりも速く劣化します。AIは「PostgreSQLを使用している」と記憶していても、MongoDBではなくPostgreSQLを選んだ理由を忘れるかもしれません。JSONBサポートの必要性、チームの運用上の専門知識、文書ストアを除外したマルチテナンシーの要件。これは微妙だがコストのかかる失敗モードです。AIは表明された意思決定に従い続けながら、その意図に反する提案を行います。ドキュメントストアではうまく機能するが、PostgreSQLのリレーショナルな強みと相容れないスキーマ構造を提案します。表明された選択には技術的に準拠していますが、アーキテクチャ的には誤っています。

解決策は、開発者が自身の認知に対して本能的に適用するものと同じです。重要なことを外部化する。忘却する媒体の外に永続化する。

一部のツールは、コンテキストウィンドウが埋まるにつれて以前の会話履歴を自動的に圧縮または要約することでこの問題に対処しようとします。しかし、これは別の懸念を引き起こします。圧縮はブラックボックスです。開発者は、何が逐語的に保存されたか、何が要約されたか、何が黙って削除されたかを可視化できません。アルゴリズムは特定の設計決定に重要なニュアンスではなく、一般的な一貫性を最適化します。そして意思決定の根拠は、冗長で説明的で文脈依存であるため、自動圧縮に対して最も脆弱なコンテンツの種類です。何をは残りますが、なぜは残りません。不透明なプロセスに重要なものの保存を委ねることは戦略ではなく、希望です。

これが私が他の場所で説明したアライメント手法に欠けている部分です——AIとキュレーションされたプロジェクトコンテキストを共有する(私がKnowledge Primingと呼ぶもの)ことと、設計会話を逐次的なレベルで構造化すること(Design-First collaboration)は、人間とAIの間に共有メンタルモデルを構築します。しかし、そのアライメントは、デフォルトではそれを生み出した会話と同じくらい一時的です。私たちが構築に投資した共有メンタルモデルは、セッションが長くなるにつれて侵食され——セッションが終了すると完全に消滅します。

コンテキストアンカリングは、そのアライメントを永続化する実践です。

外部記憶

解決策は、意思決定コンテキストを外部状態として扱うことです。会話の外に存在し、意思決定をその場で捉え、人間とAIの両方にとってセッションを横断する権威ある参照として機能する生きたドキュメントです。

これは以前の作業のプライミングドキュメントとは異なります。区別は重要です。

プライミングドキュメントはプロジェクトレベルのコンテキストを捉えます。技術スタック、アーキテクチャパターン、命名規則、コード例です。比較的安定しており、四半期ごと、または重要なアーキテクチャ変更があった際に更新されます。すべての機能とすべてのセッションで共有されます。AIに「プロジェクトがどのように動作するかを示します」と伝えます。

フィーチャードキュメントはフィーチャーレベルのコンテキストを捉えます。開発中に下された特定の決定、それらを形成した制約、何が検討され却下されたか、何が未解決のままか、進捗の現在の状態です。急速に進化し、潜在的にはセッションごとに更新されます。AIに「この特定の作業の現在の状況と、そこに至った経緯を示します」と伝えます。

これら2つは同じコンテキスト戦略の2つのレイヤーを形成します。新しいセッションを開始する際、両方が読み込まれます。プロジェクトコンテキストは安定した基盤として、フィーチャーコンテキストは現在の状況の記録として機能します。プライミングドキュメントは語彙を提供します。フィーチャードキュメントは履歴を提供します。

自然な反論として、現代のAIツール(ファイル参照を持つCursor、ワークスペースインデックスを持つCopilot)はすでにコードベースを直接読み取ることができるというものがあります。AIがコードを見られるなら、なぜ別個のドキュメントを維持する必要があるのでしょうか?

なぜならコードは結果を捉えるのであり、根拠を捉えないからです。リトライ処理にBullMQを直接使用しているコードベースは、RetryQueue抽象化が提案され、議論され、意図的に却下されたのか——あるいは直接的なアプローチが単に最初に生成されたものであり、疑問視されなかったのか——を読み手に何も伝えません。却下された代替案はコードの中に不可視です。決定を駆動した制約は不可視です。残っている未解決の質問は不可視です。

注目に値する実用的な副産物があります。50行のフィーチャードキュメントは、何百行、何千行の実装コードでも全く表現できない決定コンテキストを運び、しかもトークンコストのわずかな割合で実現します。ウィンドウ内のコンテキストが少ないほど、モデルの注意はより良く保持されます。長いコンテキストが引き起こす劣化は、単に劣化する対象が少なくなります。トークン効率はフィーチャードキュメントを維持する理由ではありません(根拠の保存が理由です)が、スケールでのコスト影響は別途検討に値する複合的な利点です。

これは2011年にMichael NygardがArchitecture Decision Records(ADR)を提案した際に特定したギャップと全く同じです。コードは何が構築されたかを示します。何が却下されたか、選択を形成した制約は何だったか、どのようなトレードオフが受け入れられたか、何が未解決のままか——これらは示しません。ADRが存在するのは、経験豊富なエンジニアが、コードの背後にある根拠はコード自体と少なくとも同等に価値があり——そしてはるかに脆弱であることを認識していたからです。

フィーチャードキュメントは、AIコラボレーションにおいて同じギャップを埋めます。本質的には、決定が下された後に書かれるのではなく、決定が下されるリアルタイムで進化する生きたADRです。

すでにADRを使用しているチームにとって、フィーチャードキュメントは進行中のADRです。機能が出荷されると、重要な決定は正式なADRへと昇格します。まだADRを使用していないチームにとって、これは自然な入り口です。より軽量で反復的、そして即座に実用的です。

純粋に個人のツールが見逃すもう1つの次元があります。チーム全体にわたる調整です。複数の開発者が同じ機能に取り組む場合(それぞれが独自のAIセッションを持つ)、フィーチャードキュメントは共有記録となります。開発者AがAIと共に1つのセッションで行った設計決定は、独立して開始された開発者BのAIセッションで利用可能になります。ドキュメントがなければ、開発者BのAIは開発者Aがすでに却下した抽象化を再提案するかもしれません。共有メンタルモデルは、1人の人間と1つのAIの間で共有されるだけでなく、チーム全体、セッション全体、時間を超えて共有されます。

フィーチャードキュメントは、コンテキストウィンドウが保持できないものを生き残らせます。

実際の運用での様子

以前のDesign-Firstの作業で取り上げた通知サービスは、有用な例を示します。

設計会話の後(機能が確認され、コンポーネントが議論され、契約が合意された後)、保存する価値のある一連の決定がありました。リトライにはラッパー抽象化なしでBullMQを直接使用。関数型サービスで、クラスは使用しない。v1ではメールのみ。配信にはSendGrid。これらの決定、そして重要なことに各々の根拠が、現在の制約、未解決の質問、実装の状態とともにフィーチャードキュメントに書き込まれました。

ドキュメントは簡潔で、50行未満でした。正式なテンプレートではありませんが、作業記録です。決定とその根拠、AIが遵守しなければならない現在の制約、未解決のままの未解決の質問、完了したことと残っていることの簡単なチェックリスト。本質的な状態を捉えるのに十分で、ドキュメント化それ自体を目的としたものにはなりませんでした。

# Feature: Notification Service v1

## Decisions
| Decision                    | Reason                                  | Rejected Alternative                                |
|-----------------------------+-----------------------------------------+-----------------------------------------------------|
| BullMQ directly, no wrapper | Native retry with backoff is sufficient | RetryQueue abstraction (unnecessary indirection)    |
| Functional services         | Match codebase convention               | Class-based (rejected: convention)                  |
| SendGrid for delivery       | Deliverability + team experience        | SES (cheaper, less reliable), Mailgun (no team exp) |

## Constraints
- Email-only for v1 (no SMS/push)
- All queries include tenantId (multi-tenant)
- Must use existing auth middleware

## Open Questions
- [ ] Rate limiting strategy (awaiting product input)

## State
- [x] Design approved (all 5 levels)
- [x] NotificationHandler + TemplateRenderer implemented
- [ ] DeliveryTracker (next session)
  

3回目のセッション開始時にその価値が明らかになりました。以前の45分間の会話を再構築する(技術スタックを再説明し、設計決定を再確立し、制約を再述する)のではなく、私はフィーチャードキュメントを共有しました。AIは30秒で完全なアライメントを達成しました。以前のセッションを記憶していたからではなく、決定が新たに読み取れる形式に外部化されていたからです。すべての新しいセッションは、コールドスタートではなくウォームスタートになりました。共有メンタルモデルを再構築する必要はありませんでした。読み込まれたのです。

実際には、更新は自然な休止点で行われました。設計レベルの終了時、重要な決定が下された時、未解決の質問が解決された時です。時折、私自身が更新を書きました。時折、AIに決定とその根拠の要約を依頼し、その要約をドキュメントに編集しました。労力は最小限でした。各重要な瞬間の後に数行を加えるだけであり、ドキュメント化の作業ではありませんでした。

予想していなかった二次的な利点がありました。ドキュメントを更新する規律は、私自身の思考を効率化しました。ラッパーよりも直接BullMQ統合を選んだ理由を書き留めることで、私は根拠を明確に表現せざるを得なくなり——時折、自分の根拠が思っていたよりも弱いことに気づきました。ドキュメントはAIのための外部記憶であるだけでなく、私自身の意思決定における明晰さを強制する機能でもありました。

3回のセッションを通じて、ドキュメントは進化しました。新しい決定が蓄積され、未解決の質問が解決され、実装の状態が進みました。機能に参加する同僚——あるいは新しいAIセッション——は、このドキュメントを読むことで、数日分の作業の完全なコンテキストを数分で得ることができました。繰り返しはありません。再説明もありません。ドキュメントが共有理解を前進させました。

キャリブレーション

コンテキストアンカリングはどこでも必要ではありません。フィーチャーが複数のセッションにまたがる場合——コンテキストを失うリスクが現実的で、それを再確立するコストが高い場合——に特に価値があります。

シナリオアンカリングが必要か?理由
クイックな質問、単一のユーティリティ不要会話が短く、劣化は無関係
単一セッションの機能(1時間未満)軽量 — 再訪の可能性があれば主要な決定を記録決定と状態の箇点がいくつかあれば、再開に十分
セッションをまたぐ複数日の機能はい — 完全なフィーチャードキュメントコンテキスト喪失のコストは時間単位で、分数ではない
複数の開発者が関わる機能はい — 共有ドキュメント独立したAIセッションにわたって決定を調整

クイックなデバッグの質問やワンオフのユーティリティの場合、ドキュメントを維持するオーバーヘッドは正当化されません。午後の作業にかかる機能の場合、再訪の可能性があれば軽量な記録は価値があるかもしれません。数日にわたる作業の場合、完全なコンテキストアンカリングは何倍もの価値を発揮します。ここが、長時間の会話をしがみつく悪循環が最も発生しやすく、外部化された決定がその循環を最も効果的に断ち切る場所です。

リトマステストはここに戻ってきます。チャットセッションを閉じて、不安なく、新しいセッションを開始できるか、回復不可能な何かを失ったと感じることなく——コンテキストが適切にアンカリングされているか。セッションを維持する必要を感じる場合、その不快感がシグナルです。それは決定が会話の中にしか存在せず、会話はそれらが恒久的に存在する場所ではないことを意味します。

結論

これは本質的に、チャット駆動の開発からドキュメント駆動の開発への移行です。会話は意思決定を行うための媒体であり続けますが、ドキュメントは記録となります。会話は設計上使い捨てです——思考が行われる場所であり、結論が保存される場所ではありません。ドキュメントは永続します。

人間とAIの間の共有メンタルモデルは、一時的である必要はありません。ドキュメント化され、永続的で、共有可能にすることができます。これに先行する手法——セッション開始前にキュレーションされたプロジェクトコンテキストを共有すること、コードが書かれる前に設計会話を逐次的なレベルで構造化すること——と合わせて、コンテキストアンカリングは一連の流れを完成させます。静的コンテキスト、動的 アライメント、永続的な決定。各レイヤーが前のレイヤーに基づいて構築されます。

そして、それが機能しているかどうかを判断する最もシンプルなテストは、最も実用的なものでもあります。セッションを閉じる。新しく始める。それが effortless に感じられる場合——最初からやり直すのに30分の再説明ではなく、30秒のドキュメント共有で済む場合——コンテキストは本来あるべき場所にあります。会話の外に、人間とAIの両方がいつでも読める形式で。