ビジネスアクセラレーション事業部の德永です!

実務ではClaudeをはじめとするAIコーディングエージェントを日常的に活用しているのですが、開発を続ける中で以前から「会話が長くなることによる回答精度の低下」や「トークン消費の過剰さ」に頭を悩ませていました。
精度を落とさないためにチャットセッションを新しく立ち上げたくても、リポジトリの構成やプロジェクトの背景を一から説明し直す手間がハードルとなり、だらだらと一つのセッションを使い続けて精度を悪化させてしまう悪循環に陥っていました。

そんな中、「コンテキストの肥大化と精度劣化」の仕組みと対処法について解説している資料を見つけたので、今回はその内容を自分なりに整理して紹介したいと思います。

1. なぜ会話が長くなると精度が落ちるのか?

LLMには、入力長や会話のやりとりが増えるにつれてモデルに関わらず性能が劣化していくコンテキストロットと呼ばれる現象があります。
コンテキストウィンドウに物理的な空き容量があったとしても、早い段階から精度の劣化が始まることを指します。
これはまさに私が実務で感じていた感覚そのものでした。
平均的に400Kトークンに達する頃には明らかな精度の低下があるようです。
この現象は、セッション内の領域を2つに分けて考えると整理しやすいということが分かりました。

  • Smart Zone:AIが正確かつスマートにコーディングを行える領域
  • Dumb Zone:会話が長くなり、精度が落ちていく領域

Dumb Zoneに落ちる原因は、トークンの単純な量ではなくノイズの蓄積とのことでした。AIが参照するコンテキストに含まれるのはソースコードだけではなく、コードベースの調査で一時的に読み込んだ大量のファイル、ビルドやテストの実行ログ、試行錯誤の過程で出たエラーメッセージなどがノイズとして溜まっていくそうです。
コンテキストウィンドウは有限なリソースであり、情報を詰め込むだけではノイズにしかならないため、ノイズを取り除き、最小限の高品質な情報だけを渡すコンテキストエンジニアリングだということを知りました。
参照:AIが開発/運用しやすいクラウド ― サーバーレスの視点から考える設計原則_P15

2. コンパクションを試してみた

コンパクションとは、会話の内容を要約して圧縮し、新しいセッションに引き継ぐことを指します。
資料ではこのように紹介されていました。

「調査・分析」から「実装」までを1つのセッションで終わらせようとするのをやめる。調査段階で発生した探索ノイズを切り捨てるため、セッションのコンパクション(圧縮)を行う。

具体的には以下の3ステップです。

  1. 調査・探索セッションで、コードベースの読み込みやエラー原因の特定を行う(この時点でログやファイルの読み込みノイズが溜まる)
  2. セッションの最後に「分析結果と実装計画を圧縮したドキュメントとしてまとめて」と指示し、要約を生成する
  3. 新しいチャットを立ち上げ、要約だけを入力して実装を開始する

こちらの方法を実際に検証用リポジトリで試してみました。

題材にしたコード

検証のため、あえて非効率なクエリを含んだコードを用意しました。
「N+1クエリ」と呼ばれる、1件ずつ余計なデータベースアクセスが発生してしまう典型的なパフォーマンス問題です。
以下のようなUserControllerを題材にしました。

public function index()
{
    $users = User::all();
    foreach ($users as $user) {
        echo $user->orders; // ← ここで毎回クエリが走る
    }
    return $users;
}

Step1:調査セッション

まず、実装はせずに調査だけを依頼しました。

UserController.phpを調査して、N+1クエリが発生している箇所をすべて洗い出してください。
それぞれの問題点、影響、修正方針を教えてください。
実装はまだしないでください。

3箇所の問題(N+1が2箇所、インデックス不足が1箇所)について、発生クエリ数や影響範囲まで含めた詳細な調査結果が返ってきました。例えば、index()メソッドについてはこのような形で返ってきます。

問題点:
User::all() で1クエリ、その後 $user->orders へのアクセスがループの各イテレーションで
遅延ロード(Lazy Load)を発火させる。

発生クエリ数:
1 (users取得) + N (各userのorders取得) = N+1本
ユーザーが1000件なら1001クエリが走る。

影響:
ユーザー数に比例してクエリ数が線形増加し、大量データ時にDBへの負荷が激増する。

他の2箇所についても同様の粒度で説明が続き、かなりのボリュームになりました。

Step2:要約生成

次に同じセッションの最後に、こう指示しました。

ここまでの調査結果と修正方針を、実装者がすぐ着手できる形で簡潔にまとめてください。
問題点・修正方法・変更対象ファイルだけを箇条書きでお願いします。

返ってきた要約はこちらです。

問題1: index() — N+1クエリ(ordersの遅延ロード)
- 修正: User::all() → User::with('orders')->get()
- 対象: app/Http/Controllers/UserController.php 行13

問題2: findByEmail() — emailカラムのフルテーブルスキャン
- 修正: マイグレーションで $table->unique('email') を追加
- 対象: database/migrations/xxxx_create_users_table.php

問題3: show() — 複数リレーションの遅延ロード
- 修正: User::find($id) → User::with(['orders', 'profile', 'roles'])->findOrFail($id)
- 対象: app/Http/Controllers/UserController.php 行29

調査結果と比べて、かなりの圧縮率です。

Step3:新規セッションで実装

新しいチャットを開き、この要約だけを貼り付けて実装を依頼しました。

以下の調査結果を元に、UserController.phpを修正してください。
[要約を貼り付け]

結果、リポジトリ構成やプロジェクトの説明を一切していないにもかかわらず、3箇所すべてが要約通りに正確に修正されました。また、database/migrationsディレクトリが存在しないことに気づいて作成し、マイグレーションファイルまで用意してくれました。

セッションを切り替える際に感じていた「新規セッション開始時に一から説明し直すのがめんどくさい」という悩みは、この要約を挟まずに丸ごと会話を持ち越そうとしていたことが原因だったということに今回改めて気づきました。
参照:AIが開発/運用しやすいクラウド ― サーバーレスの視点から考える設計原則_P18

3. Monorepoによるコンテキストの凝縮

資料ではこのように紹介されていました。

AIがプロジェクトの全体像を正確に把握できるよう、ソースコードだけでなく、IaC(インフラ構成コード)や設定ファイル、ステアリングファイル(AGENTS.md)などを1つのリポジトリに凝縮して管理する構成(モノレポ)が有効。

AIから見て「近接して読める」状態を作っておくことで、文脈の補完に必要な情報を迅速に参照できるようになる、という理屈です。
普段の業務では複数のリポジトリに分かれた構成で開発することが多いのですが、1つに統合するのが難しい場合でも「AIが横断的に理解する必要がある情報は近くに置く」という考え方は参考になりました。例えば、各リポジトリの構成や依存関係をまとめたステアリングファイル(AGENTS.mdのようなもの)を用意しておくだけでも似たような効果が得られそうです。

参照:AIが開発/運用しやすいクラウド ― サーバーレスの視点から考える設計原則_P25

4. ドキュメントには「WHY」を残す

次は、ドキュメントの書き方についてです。
実装を修正した後、関連するドキュメントの更新まで手が回らず、後から見返すと内容が古くなっている、という経験は何度もあります。仕様書に書かれている処理の流れと、実際のコードの中身が微妙にズレていることに後から気づき、どちらが正しいのか確認し直す、という手間が発生することも少なくありません。

AIとのやりとりでも、同じ問題が起きます。実装コードだけを更新してドキュメント側を放置すると、次のセッションでAIがその古いドキュメントを「正解」として読み込んでしまい、実際のコードと矛盾した回答を返してくるようになります。人間であればこのドキュメント古いかもと気づいて実装を確認し直せますが、AIは渡された情報をそのまま信じてしまうため、この乖離がより深刻な問題として現れます。

これに対して資料で紹介されていた考え方が、ドキュメントに残すべき情報を「WHAT(今どう動くか)」と「WHY(なぜそうしたか)」に分けるというものでした。WHATの部分の「今どういう処理になっているか」はコードや型定義自体をSource of Truthとして参照させ、ドキュメント側には「なぜこの設計にしたか」「なぜこの方法を採用しなかったか」という背景や意思決定の文脈だけを残す、という切り分けです。
今どう動くかを最初からドキュメントに書かないようにすれば、コードが変わってもドキュメントを直す必要自体がなくなり、そもそも古くなるという状態が発生しません。逆に、後から見返したときに「なぜこうなっているのか」という経緯こそドキュメントに残っていてほしい情報なので、役割分担としても納得感がありました。
更新の手間を減らしつつAIに誤った情報を渡すリスクも下げられる効果的な考え方だと感じました。

参照:AIが開発/運用しやすいクラウド ― サーバーレスの視点から考える設計原則_P51

5. まとめ

AIコーディングエージェントを使いこなす上で重要なのは、「コンテキストウィンドウは有限のリソースであり、放置するとノイズで精度が落ちる」という前提を受け入れることだと感じました。

  • 長いセッションは避け、要約ドキュメントを使ってクリーンなセッションへ切り替える(コンパクション)
  • AIが横断的に理解すべき情報は、近くに置いておく(Monorepo/ステアリングファイル)
  • ドキュメントには「WHY」だけを残し、今どう動くかはコード自体に語らせる

実際にコンパクションを試してみたことで、これまで感覚的にセッションを分けるのはめんどくさいと思っていた部分が、要約を挟むだけで解消できることが分かりました。
まずはこのコンパクションの習慣を実務でも定着させることから始めて、慣れてきたらステアリングファイルの整備やドキュメントの書き方の見直しにも手を広げていきたいと思います。
最後までお読みいただきありがとうございました!