前回の記事ではコンテキストエンジニアリングのあるべき姿について語りました。今回はどうして、コンテキストエンジニアリングが必要なのか? ということをAIを活用する上で考慮すべき4つの現象の紹介とともに考察していきます。
コンテキストにまつわる4つの現象
1. コンテキスト汚染
原因:
不正確な情報や無関係な情報がプロンプト内に混入し、AIが誤った答えを生成すること。これは、AIが与えられた情報を、真偽を判断することなく、プロンプト内で最も関連性の高い情報として扱う性質に起因します。AIは、たとえその情報が嘘であっても、あたかも事実であるかのように自信を持って話し始めます。
また、プロンプトでの比喩表現や意図的な誤情報が、AIの応答に影響を与えることもあります。AIは、言葉の裏にある意図を完全に理解することが難しいため、それらの表現を文字通りに解釈し、本来は関係のない情報と結びつけてしまうことがあります。これは、AIがテキストをベクトルに変換し、類似性の度合いを示す「関連スコア」に基づいて情報を選択する過程で発生します。比喩表現や不明瞭な指示が、AIの応答生成に必要な文脈を歪め、意図しない解釈や不正確な回答を引き起こすことがあります。
対処法:
AIに外部の情報源を頼らせないよう、必要な情報を推測の余地なく、十分な信頼性をもって構成されたプロンプトを与えます。具体的には、ユーザー側で信頼できる情報を事前に精査(キュレーション)し、AIに追加調査が不要なようにします。これにより、AIが不確かな情報にアクセスする機会を減らし、コンテキスト汚染による応答の歪みを抑制します。
また、意図しない解釈を避けるため、比喩表現は極力避け、明確な言葉で指示を出すことが重要です。複雑なタスクや複数の情報源を扱う場合は、セッションを分けて行うことも有効です。
2. コンテキストの断片化
原因:
関連性の低い情報や、情報間の論理的な繋がりが不明瞭なプロンプトを与えることで、AIがそれらの情報を一つのまとまりとして効果的に利用できない状態です。AIは、プロンプトを単語の羅列としてではなく、意味的な関連性を持つベクトルの集合として捉えます。
例えば、ユーザーが「今日の天気は?」「最近のおすすめのゲーム動画教えて」「バッテリー50%しかないけど、3時間くらい外出しても大丈夫?」といった、関連性のない話を続けた場合を想像してください。これらの質問は意味的に互いに関連性が低く、ベクトル空間上でも互いに遠く離れた位置に存在します。 そのため、AIはプロンプト全体を一つのまとまりとして扱うことが難しくなります。その結果、各質問への回答を生成する際の探索が非効率になり、パフォーマンスが低下したり、不正確な応答を生成するリスクが高まります。
対処法:
情報の関連性を高め、高度に構造化されたプロンプトを作成します。これにより、情報が明確な一つのまとまりとして認識され、AIはより効率的かつ正確にその情報を利用できるようになります。具体的には、一つのプロンプト内で複数のタスクを扱う場合でも、それらを論理的な構造で繋げ、それぞれの情報が持つ目的と役割を明確にすることが重要です。
3. コンテキストの押し出し
原因:
AIモデルのコンテキストウィンドウ(一度に処理できるトークンの最大量)の制約により、古い情報が新しい情報によって「忘れられる」現象です。長時間の対話ではこの現象は不可避であり、AIが過去の重要な文脈を見失う原因となります。
対処法:
この問題に対処するためには、情報の圧縮が不可欠です。
現在では、AIエージェントが自律的に会話履歴を要約する技術も進化しています。しかし、この自動圧縮は、人間にとって重要な文脈を意図せず失ってしまうリスクを伴います。したがって、AIの自動処理に依存するのではなく、ユーザー自身がプロンプトに含める情報を厳選し、最適化することが最も効果的な対処法となります。
これにより、コンテキストの押し出しを遅らせ、AIとの対話をより効率的かつ正確にコントロールすることが可能になります。
ここまで説明した3つの現象は重要な文脈を見失うというリスクを伴いましたが、次に説明する現象はコンテキストを全て失うという非常に恐ろしいものです。
4. コンテキストの喪失
原因: ソフトウェアやシステムの内部的なエラーに起因する、アンコントローラブルな技術的問題です。APIリクエストの失敗、ネットワークの切断、前回の出力が正しく引き継がれないなどの理由でセッションの完全なリセットが発生し、ユーザーの努力だけでは解決できない事象を指します。
対処法: 残念ながら、この問題に対する根本的な解決策は存在しません。 これは、コンテキストエンジニアリングの限界を示す現象であり、ユーザーの努力だけでは解決できないAIとの対話における不可避的なリスクとして認識しておく必要があります。
解決策としてのAIロールとの協働
これらのコンテキストにまつわる課題は、単一のAIモデルにすべてを任せることの限界を示唆しています。上記で紹介した対処方法を人間が常に考えて手作業でプロンプトを組み立てていくことは現実的ではありません。私が以前投稿した記事において紹介したコンダクターというロールでも触れましたが、実行エージェントを活かすためのAIロールを作るという解決策があります。
事前準備として人間が最低限やっておくべきこと
- 必要な情報をキュレーションして、追加情報をRAGしないで済む様にしておく
- ルールを構造化して出来る限り小さく、矛盾や推測の余地が残らないものにする
- 最小限のルールだけに責務を負うロールを用意しておく
最低でも上記を実現した上でコンダクターには以下の方針でプロンプトを生成してもらいましょう
- 実行内容に対して適切な担当ロールやルール、もしくはその両方をプロンプトにマージする
- 生成するプロンプトはコンテキストウインドウに対して余裕のあるトークン(ex. 30%程度)に収める
- 上記を踏まえて必要であればサブタスクに収まるようにプロンプトをサブタスク毎に分割する
最小限の責務だけを負うロールやルールというのは以前にCascading Role Systemの提案で触れた様な構造化されたロール定義の様な形で実現出来ます。
セッションの寿命と断片化
実はコンテキストの断片化にはもう一つ原因があります。それは長すぎるセッションの寿命です。
複数のタスクを一度に任せる長時間の対話では、情報の関連性が薄れることで、AIの応答の精度が低下する傾向にあります。これは、タスクの切り替えによって、AIが以前のタスクのコンテキストから抜け出せず、新しいタスクに集中できなくなるためです。この問題を解決する方法は出来る限りセッションを一つのタスクに絞り込むことです。
結論
コンテキスト汚染や断片化といった本質的な課題を解決しないまま、AIの記憶を外部の記憶領域に丸投げするような記事を見かけます。特に、RAG(Retrieval-Augmented Generation)のように、外部のブラックボックス化された記憶装置にコンテキストを依存させるアプローチは、コンテキストの押し出し問題を解決する画期的な方法に見えるかもしれません。しかし、これは根本的な解決ではなく、問題を先延ばしにしているに過ぎません。なぜなら、外部にコンテキストを移管したとしても、その情報自体に「汚染」や「断片化」といった問題があれば、AIの応答は依然として不正確になるからです。もちろん、情報のフィルタリングや最適化を高度に行う外部記憶システムが実現すれば、この状況は変わるでしょう。
AIとの対話において不可避的に発生する様々な課題から目をそらすのではなく、それらを根本から解決するシステム設計を追求する必要があるのは、だけでなく、日々のエンジニアリング領域の作業と何ら変わりはありません。
私が構想したAIによる自律型ソフトウェア開発システム構想も、この設計思想に基づいています。単一のLLMの限界を根本的に解決し、各々が最高品質の結果を残すマルチエージェントを組む必要があるという結論に至ったのは、他でもない、今回考察したような問題群を克服するためです。
コンテキストエンジニアリングとは小手先のテクニックでなく、AIを効率的に使うための設計とも言えるでしょう。