AIは対話で生まれたコンテキストをどう扱うのか?

私の業務の一つに、データを分析して課題を発見し、解決策の提案までをレポートにまとめる仕事がある。

昨年までは、仮説を立てて調査し、途中で行き詰まっては振り出しに戻ることを繰り返していた。今年はAIを使うことを前提に、業務の進め方そのものを見直すことにした。

実際にClaude Codeを使い、データ分析、課題の整理、解決策の検討、レポートの骨子作成までを一つの流れで進めた。分析結果や途中の判断、構成案は一つの外部ファイルへ保存し続けたため、作業が進むほど、検討の履歴と確定した骨子が同じファイルに蓄積されていった。

ところが、出来上がった骨子には、それまでの作業ログや棄却した論点まで残っていた。「この案は棄却した」とわざわざ書かれた状態である。これでは提出できないし、読み返す側にもつらい。

そこでClaude Codeに、「不要な部分を削除してほしい」と指示した。やりたかったのは、それまでに詰めてきた内容を整理し、レポートに必要な部分だけを残す編集作業だった。

しかし、指示は期待どおりには反映されなかった。私が不要だと考えた部分が残り、過去の検討過程と完成稿の境界も曖昧なままだった。

この経験から、次の疑問が生まれた。

AIは、対話の中で積み上がった情報をどのように扱っているのか。

過去の分析、途中案、最新の指示は、どのような関係で処理されるのか。対話履歴と外部ファイルは、同じように扱われるのか。長い対話では、AIは本当に最初と最後しか読まなくなるのか。

結論から言えば、AIは対話全体を一つの完成した記憶として保持しているわけではない。

AI製品が、過去の発言、現在の依頼、設定、読み込んだファイル、ツールの実行結果などをまとめ、モデルへ入力する。モデルは、その時点で受け取った情報を使って次の応答を生成する。

この仕組みを理解するには、次の三つを分けて考える必要がある。

1. 情報がどこかに保存されている
2. その情報が現在の応答時にモデルへ渡されている
3. モデルが、その情報を目的に沿って正しく利用できる

この三つは同じではない。

目次

対話そのものと、現在のコンテキストは同じではない

ここでいうコンテキストとは、モデルが次の応答を作る時点で参照できる情報の集合である。

対話履歴だけではない。製品の設定、プロジェクトのルール、読み込まれたファイル、ツールの出力、AI自身の過去の返答、要約された過去情報なども含まれ得る。

チャット画面に過去の発言がすべて表示されていても、それらが毎回そのままモデルへ渡されるとは限らない。長い対話では、製品側が過去の内容を要約・圧縮することがある。別のセッションでは、過去の会話全文ではなく、保存されたメモリやプロジェクト用の指示だけが読み込まれる場合もある。

外部ファイルも同じである。ファイルが保存されているだけでは、モデルがその内容を現在参照しているとは限らない。全文が読み込まれる場合もあれば、必要な箇所だけが検索・抽出される場合もある。

関係を単純化すると、次のようになる。

AIモデルが応答を生成するまでの流れ

図の左側にあるのは、モデルへ渡される可能性のある情報である。ただし、これらが常にすべて、同じ形式で渡されるわけではない。

対話そのものは、人間とAIが交わした履歴全体を指す。一方、現在のコンテキストは、その履歴や関連情報のうち、その時点で実際にモデルへ渡された情報の集合である。

したがって、チャット画面に残っている情報と、モデルが現在受け取っている情報は一致しない場合がある。

期待した応答が得られなかったときは、まず次の二つを分けなければならない。

  • 必要な情報がモデルへ渡されなかった
  • 情報は渡されたが、モデルがうまく利用できなかった

この区別をせずに「AIが忘れた」とまとめると、原因も対策も見えなくなる。

モデルは、受け取ったコンテキストをどう処理するのか

モデルへ渡された文章は、トークンという単位に分けて処理される。トークンは日本語の単語と一対一に対応するとは限らず、文字や単語の一部を含む計算上の単位である。

Transformerの基礎を示した「Attention Is All You Need」では、Attentionを、queryとkeyの組み合わせから重みを求め、その重みに応じてvalueを組み合わせる仕組みとして説明している。

ここでいう「位置」とは、文章をトークンに分割したときの並び順である。たとえば、「私はりんごを食べた。それは甘かった」という文を単純化して考えると、「私は」「りんごを」「食べた」「それは」「甘かった」が、それぞれ異なる位置に並んでいる。

「情報同士の関係」とは、あるトークンを処理するときに、ほかのどのトークンの情報が役立つかという関係である。

たとえば、「それは」だけを見ても、「それ」が何を指すのかは分からない。しかし、その前にある「りんごを」と結び付ければ、「それ」は「りんご」を指している可能性が高いと判断できる。

文章には、このほかにも、主語と述語、動作とその対象、質問と答えに必要な情報、指示とその適用先、以前の案と最新版など、さまざまな結び付きがある。自己Attentionでは、ある位置のトークンを処理するときに、ほかの位置にあるトークンから、どれだけ情報を取り込むかを計算する。

この「どれだけ取り込むか」を表すのがAttentionの重みである。

たとえば、「それは」を処理するとき、「りんごを」には大きな重みが付き、「私は」には小さな重みが付くかもしれない。その場合、「それは」の数値表現を作り直す際に、「りんごを」が持つ情報がより多く取り込まれる。

ただし、この重みは、文章全体にとっての重要度を示すものではない。「この段落は重要だから残す」「この言葉は不要だから削る」と直接判断する数値でもない。あくまで、あるトークンを処理するときに、ほかのトークンの情報をどの程度混ぜるかを表している。

query、key、valueの役割は、図書館で情報を探す場面にたとえると分かりやすい。

  • queryは、現在のトークンがどのような情報を必要としているかを表す
  • keyは、各トークンがどのような情報と結び付きやすいかを照合するために使われる
  • valueは、重みに応じて実際に取り込まれる情報である

モデルは、現在処理しているトークンからqueryを作り、ほかのトークンのkeyと照合する。その相性から重みを求め、重みに応じてvalueを組み合わせる。こうして、周囲の文脈を反映した新しい数値表現を作る。

ただし、Attentionは「文章中の重要な箇所を一度だけ選び、そこへ付箋を貼る機能」ではない。モデルには複数のAttentionヘッドと複数の層があり、それぞれ異なる結び付きを計算する。あるヘッドが代名詞と対象の関係を捉え、別のヘッドが動作と対象、指示と適用先などの関係を捉えることもある。

こうした計算を何層も繰り返し、モデルは各トークンの数値表現を文脈に合わせて更新する。その最終結果から、次に続くトークンの候補を計算し、一つずつ出力する。

モデルは、対話の経緯を人間のように思い出してから回答しているわけではない。現在渡されたトークン列と、学習によって得たパターンを使い、次に続くトークンを生成している。

したがって、ある情報が入力内に存在していても、それが必要な判断へ正しく反映されるとは限らない。

[Transformer原論文]が示したのはAttentionの基本構造であり、現在の各AI製品がすべて同じ実装であるという意味ではない。ここでは、入力内の情報を関係付ける基礎概念として扱っている。

コンテキストウィンドウは「記憶容量」ではない

コンテキストウィンドウとは、一回の応答生成でモデルが扱えるトークン数の範囲である。

長いコンテキストに対応したモデルは、大量の文章や長い対話を入力として受け取れる。しかし、入力できることと、入力内のすべての情報を同じ精度で利用できることは別である。

机に例えると分かりやすい。

広い机には大量の資料を置ける。しかし、資料を机の上に置けることと、必要な情報を漏れなく探し、矛盾を解消し、正しい結論を出せることは同じではない。

コンテキストウィンドウが示すのは、基本的には机の広さである。資料を使いこなす能力そのものを保証する数値ではない。

長文コンテキストを評価した[RULER]では、単純に一つの情報を探す課題だけでなく、複数の情報を追跡・集約する課題も用いられた。評価されたモデルは、単純な検索課題では高い性能を示しても、入力が長くなり、課題が複雑になるほど性能を落とした。

つまり、公称されるコンテキスト長と、実際の課題で有効に利用できる長さは、必ずしも一致しない。

AIは本当に「先頭と最後しか読まない」のか

長い入力では、情報の位置によって利用性能が変わることもある。

Liuらの「Lost in the Middle」は、複数文書から答える課題と、長い入力から対応する値を取り出す課題で、正解に必要な情報の位置を変えて性能を比較した。

調査されたモデルでは、関連情報が入力の先頭または末尾にあるときに性能が高く、中央付近にあるときに低くなる場合が多かった。

ただし、この結果から「AIは先頭と最後しか読んでいない」とは言えない。

研究が確認したのは、関連情報を使って正解する性能が、その情報の位置によって変化したことだ。中央の情報が計算対象から除外されていたことを示したわけではない。

ここでも、二つを区別する必要がある。

  • 読んでいない、またはモデルへ渡されていない
  • モデルへ渡されているが、適切に使えていない

「Lost in the Middle」が主に示しているのは、後者である。

なぜ、コンテキスト内に「ある」のに使えないのか

情報がモデルへ渡されていても、利用に失敗する理由はいくつか考えられる。

必要な情報とノイズが競合する

長いコンテキストには、必要な情報だけでなく、さまざまな情報が混ざる。

  • 過去に検討した案
  • 後から棄却した案
  • AI自身が以前に出した回答
  • 実行ログ
  • 重複した説明
  • 古くなったファイル内容
  • 現在の目的とは関係のない指示

たとえば、一つのファイルに次の内容が並んでいたとする。

初期案Aを主張
途中案AとBを併記する
確定案Bだけを主張として残す

人間は「確定案」という見出しや作業の経緯から、Bを現在の正本だと判断できる。

しかしモデルは、入力された文章から、どれが過去の案で、どれが現在の正本なのかを推定しなければならない。区別が明示されていなければ、AもBも同じ入力内の情報として影響し得る。

その結果、古い案を再び採用したり、棄却済みの説明を残したりする可能性がある。

抽象的な指示では、判断基準をモデルが補う

私が出した「不要な部分を削除してほしい」という指示にも問題があった可能性がある。

「不要」には複数の意味がある。

  • 最終結論に使わない
  • 読者の理解に役立たない
  • 内容が重複している
  • 証拠が弱い
  • 過去の検討過程である
  • 今回の提出物には載せない
  • 事実として誤っている

判定基準を示さなければ、モデルは対話履歴やファイル内容から「不要」の意味を補う。

しかも、過去の対話でAI自身がある段落を提案し、その必要性を説明していた場合、その採用理由もコンテキストに残っている。短い削除指示と、過去に積み上げられた採用理由が競合することになる。

この場合、問題は単純な記憶力ではない。何を残し、何を削除するかという判断基準が曖昧なのである。

指示するなら、たとえば次のように書いた方がよい。

以下の基準のいずれかに該当する段落を削除してください。
1. 最終結論の根拠として使われていない
2. 棄却済みの案や検討履歴である
3. 同じ内容を別の段落で説明している
4. 読者に見せる完成稿ではなく、作業メモに当たる
「確定骨子」以降を現在の正本とし、それ以前の案は判断材料にしないでください。

「不要」という言葉を具体的な判定条件へ分解することで、モデルが独自に意味を補う余地を減らせる。

長い出力では、AI自身の文章も次の判断材料になる

モデルは、完成した回答を一度に出力しているわけではない。トークンを順番に生成している。

したがって、長い文章の後半を生成するときには、元の指示やファイル内容だけでなく、すでに生成した回答前半もコンテキストの一部になる。

出力の前半で誤った前提を置くと、その前提と整合するように後半を生成することがある。その結果、文章全体には一貫性があるのに、依頼の意図から外れた回答が完成する。

一貫していることと、正しいことは別である。

対話履歴、外部ファイル、メモリ、プロジェクト指示は何が違うのか

これらはすべてモデルへ渡され得る情報だが、役割も保存方法も異なる。

種類主な役割モデルへの入り方主な弱点
対話履歴今回の作業経緯を引き継ぐ全文、要約、圧縮された履歴など廃案や訂正前の内容も残り得る
外部がファイル原稿、資料、データを保持する全文読込、部分読込、検索結果など保存されていても現在読まれるとは限らない
メモリセッションをまたぐ前提を残す保存情報の一部が選ばれて入力される全履歴ではなく、古くなる可能性もある
プロジェクト指示継続的なルールや作業方針を示すセッション開始時などに読み込まれる長すぎたり曖昧だったりすると適用が不安定になる
現在の依頼今回実行してほしい作業を示す現在の入力として直接渡される短く曖昧だと過去の情報との関係を誤られやすい

なお、実際の保存方法や読み込み方法は製品によって異なる。ここでの分類は、各情報の役割を理解するための概念整理である。

対話履歴

対話履歴には、ユーザーの過去の依頼だけでなく、AI自身の過去の回答、ツールの実行結果、途中で決めた方針なども含まれ得る。

そのため、「さっきの案を修正して」のように経緯を引き継げる一方で、廃案や誤った回答も次の応答へ影響する可能性がある。

長い対話では、履歴がそのまま保持されるとは限らない。Claude Codeの公式文書では、コンテキストが上限へ近づいた場合、過去の会話が圧縮され、要約された内容が引き継がれる仕組みが説明されている。

要約によって大筋は残っても、細かな条件や例外が落ちる可能性はある。

外部ファイル

外部ファイルは、原稿、PDF、コード、表、ログなどを保存する場所である。

重要なのは、ファイルが存在することと、その内容が現在のコンテキストへ入っていることは違うという点だ。

ファイルは、状況に応じて次のように扱われる。

  • ファイル全体を読み込む
  • 指定された範囲だけを読む
  • 質問に関連する箇所を検索して読む
  • 内容を要約し、要約だけを使う

大量のファイルを常に全文読み込めば、コンテキストを大きく消費する。そのため、AIエージェントや検索機能は、必要と判断した部分だけを読み込むことがある。

つまり、ファイルは資料の保管場所であり、現在の作業机そのものではない。倉庫に資料があっても、机の上に取り出されていなければ、その作業には使えない。

メモリ

メモリは、対話履歴そのものではない。

一般には、過去のやり取りから継続的に有用だと判断された情報や、ユーザーが明示的に保存した前提を、別のセッションでも利用するための仕組みである。

たとえば、対話履歴には次のような発言が残る。

ユーザー:説明は短くしてほしい

ユーザー:ただし技術的な根拠は省略しないでほしい

メモリには、これが次のように抽象化されて保存されるかもしれない。

ユーザーは、簡潔だが根拠のある説明を好む

メモリは過去の発言すべてをそのまま再現するものではない。情報が選択・要約されるため、一時的な条件や細かな例外は残らない可能性がある。

Claude Codeでは、セッションをまたいでプロジェクト情報を引き継ぐ方法として、`CLAUDE.md`とAuto Memoryが用意されている。ただし、これらはモデルへ与えられるコンテキストであり、プログラムの設定値のように必ず守られる強制規則ではない。

プロジェクト指示

プロジェクト指示は、その作業環境で継続的に適用したいルールである。

たとえば、次のような内容を置く。

  • 想定読者
  • 文体
  • 出力形式
  • 禁止事項
  • 使用する技術
  • 正本となるファイル
  • 作業手順

メモリが「過去から何を引き継ぐか」に近いのに対して、プロジェクト指示は「この作業をどのように進めるか」を明示するものだ。

ただし、指示を書けば必ず守られるわけではない。指示が長すぎる、抽象的である、相互に矛盾しているといった場合には、必要な規則が安定して反映されない可能性がある。

現在の依頼

現在の依頼は、そのターンで実行してほしい作業である。

しかし、最新の指示だからといって、それだけで過去の情報との関係が明確になるとは限らない。

たとえば、

不要部分を消して

という依頼では、何が不要で、どの案が最新版で、過去の方針をどこまで上書きするのかが分からない。

次のように書けば、過去情報との関係が明確になる。

過去の分析過程と棄却案はすべて削除してください。
「確定骨子」以降だけを現在の正本として残してください。
内容の追加や要約は行わず、削除だけを実行してください。

現在の依頼では、実行内容だけでなく、どの情報を正本とし、何を判断材料から除外するかまで示す必要がある。

私の削除指示は、どこで失敗したのか

ここまでの仕組みから、私の体験を考え直してみる。

原因を確定する再現実験は行っていないため、以下は仮説である。

第一に、「不要」の基準が曖昧だった可能性がある。中心の問いに答えない段落なのか、重複した説明なのか、棄却された案なのかを定義していなかった。

第二に、分析結果、途中の判断、過去の構成案、確定骨子が一つのファイルに混在していた。人間には履歴と完成版の違いが見えても、入力上で同列に並んでいれば、どれを現在の正本とするかは明瞭ではない。

第三に、対話履歴にも、AIが以前提案した構成や、その案を支持する説明が残っていた可能性がある。新しい削除指示が短い一文だったなら、それまでの構成を維持する情報の方が具体的で多かったかもしれない。

第四に、長文中の情報利用が不安定になった可能性がある。ただし、「Lost in the Middle」やRULERは、私が行った編集作業そのものを評価した研究ではない。研究結果だけから今回の原因を断定することはできない。

第五に、外部ファイルの最新版や必要な範囲が、そのターンで読み直されていなかった可能性も残る。

このように、「AIが忘れた」という一言では、複数の原因を区別できない。

失敗は、大きく二つの段階で起こり得る。

製品側で起きる失敗

  • 必要なファイルが読み込まれなかった
  • 過去の会話が要約され、重要な条件が落ちた
  • 最新版ではない情報が使われた
  • 必要な範囲が検索で取り出されなかった

モデル側で起きる失敗

  • 古い案と最新案の優先順位を誤った
  • 長文中の必要情報を十分に使えなかった
  • 無関係な情報を無視できなかった
  • 曖昧な削除基準を誤って補った
  • 複数の条件を統合できなかった

この二つを分けると、対策も変わる。

AIに覚えさせるより、現在の判断材料を作り直す

次に同じ編集作業を行うなら、私は新しいセッションを作り、現行原稿と確定骨子だけを渡す。分析ログや途中案は、判断材料から外す。

その上で、削除基準を次のように明示する。

  • 中心の問いに答えていない段落
  • 同じ根拠を繰り返す段落
  • 棄却済みの案や作業ログ
  • 出典のない一般化
  • 完成稿ではなく作業メモに当たる部分

さらに、「どのファイルが現在の正本か」「内容の追加を許可するか」「削除以外の編集を行うか」まで指定する。

これで改善しても、原因が一つに決まるわけではない。新しいセッション、入力する情報、ファイル構成、削除基準を同時に変えているからである。原因を厳密に知るには、条件を一つずつ変えて比較する必要がある。

それでも、実務上の問いは変わる。

「AIは私との対話を覚えているか」ではなく、

「次の判断に必要な何を、どの形で現在のコンテキストへ渡すか」

を考えられるようになる。

対話を長く続けることは、AIの中に一枚の完成した記憶を育てることではない。次の応答に使われる材料を積み上げているにすぎない。

だからこそ、何を残し、何を捨て、何を正本とするかは、AIの記憶力ではなく作業設計の問題になる。

後編では、この作業設計を、分析、構成、執筆、独立した編集チェックへどのように分けるかを考える。

参考資料

– [Attention Is All You Need(NeurIPS 2017)](https://papers.neurips.cc/paper_files/paper/2017/hash/3f5ee243547dee91fbd053c1c4a845aa-Abstract.html)

– [Lost in the Middle(TACL 2024)](https://aclanthology.org/2024.tacl-1.9/)

– [RULER(2024)](https://arxiv.org/abs/2404.06654)

– [Claude Code: Explore the context window](https://code.claude.com/docs/en/context-window)

– [Claude Code: How Claude remembers your project](https://code.claude.com/docs/en/memory)

– [OpenAI API: Conversation state](https://developers.openai.com/api/docs/guides/conversation-state)

よかったらシェアしてね!
  • URLをコピーしました!
目次