🙄

LLM に「覚えさせる」と「守らせる」は違う

に公開

「覚えている」と「守る」は同じではない

LLM を使っていると、前に伝えたルールを次の作業では守らないことがある。指摘すると、そのルール自体は正しく説明できる。それでも成果物には違反が残る。

この現象を単純に「忘れた」と考えると、対策も「もう一度強く指示する」「プロンプトの先頭に書く」「Memory に保存する」といった方向へ寄りやすい。しかし、情報を保持していることと、その情報が現在の処理を拘束することは別である。原典では、この違いを AI の記憶喪失ではなく、制約適用の失敗として整理した[1]。

たとえば、次の 2 つは同じではない。

  • 「出力には title と url を必ず含める」というルールを LLM が説明できる。
  • 実際に生成されたすべての出力で title と url の存在を検査し、欠落していれば失敗として扱う。

前者は自然言語による指示の理解であり、後者は検査である。LLM にルールを記憶させるだけでは、この 2 つは自動的にはつながらない。

ルール適用を 5 段階に分ける

「覚えていたか」という 1 個の問いでは、どこで失敗したのか分からない。実際には、少なくとも次の 5 段階に分けて考えられる[1]。

段階 確認すること 失敗したときの見え方
存在 ルールが利用可能な情報として存在するか そもそも知らないように見える
想起 現在の作業に関係する条件として取り出されるか 知っているはずの規則が出力に現れない
適用 取り出した規則を対象へ正しく当てはめるか 説明はできるのに成果物では守られない
検査 成果物全体が規則を満たすか確認するか 整った出力だが条件違反が残る
修正 違反だけを直し、別の条件を壊さないか 修正で無関係な箇所まで変わる

この分解が必要なのは、各段階で対策が異なるからである。

情報そのものが存在しないなら、必要な文脈を渡さなければならない。想起されないなら、現在の作業に関係する条件として明示する必要がある。適用が曖昧なら、対象範囲や例外を具体化する。それでも違反を許容できない条件は、生成後に別の仕組みで検査したほうがよい。

ここで特に分けたいのは、適用と検査である。「この形式で書く」と理解することと、生成済みの成果物全体を走査して違反が 0 件であることを確認することは、同じ仕事ではない。

文脈にあるルールは固定された状態ではない

通常のプログラムでは、守るべき条件を状態や処理として明示できる。設定値を読み、条件分岐を通し、違反ならエラーにして停止する、といった実装である。

一方、LLM に自然言語で渡したルールは、現在の依頼、会話履歴、作業対象、出力形式などとともに文脈を構成する。ルールは出力へ影響するが、それだけで if 文や validator のような固定された検査処理になるわけではない。

ChatGPT の Memory も、この区別で考えると分かりやすい。OpenAI は現在の Memory を、過去の会話から好み、プロジェクト、制約などを引き継ぎ、将来の会話で関連する文脈として利用する仕組みとして説明している[2]。また、評価目標として「好みや制約に従うこと」も挙げている[2]。

これは Memory が有効でないという話ではない。毎回同じ前提を説明し直さずに済むこと自体が大きな利点である。ただし、「過去の制約を将来の応答へ持ち越すこと」と「違反した出力を機械的に拒否すること」は別の機構である。

プログラムでいえば、設定ファイルに値があることと、すべての実行経路でその値を検査していることは別である。LLM でも同様に、文脈へ入っていることだけをもって固定制約とみなすことはできない。

長いコンテキストに入れば守られるわけではない

では、すべてのルールを長いコンテキストへ入れておけばよいのか。

Lost in the Middle は、長い入力を扱える言語モデルでも、関連情報の位置によって性能が変化することを 複数文書質問応答とキー・バリュー検索 で調べている。実験では、関連情報が入力の先頭または末尾にある場合に比べ、中央付近にある場合に性能が大きく低下するケースが報告された[3]。

この研究から直接言えるのは、長い文脈へ情報を入れられることと、その情報を位置にかかわらず同じ信頼性で利用できることは同義ではない、という点である。「古い指示は必ず忘れる」「中央にあるルールは必ず無視される」という一般則を示した研究ではない。

それでも設計上の示唆は明確である。コンテキストウィンドウの大きさは、入力可能な情報量を示す。重要な条件が必ず適用され、違反が必ず検出されることまでは保証しない。

そのため、次の 3 つは区別して扱う必要がある。

  • ルールを会話や Memory から参照できること
  • 現在の生成でルールが適用されること
  • 生成結果がルールを満たしていると検査できること

1 番目を改善しても、2 番目と 3 番目が自動的に保証されるわけではない。

守らせたい条件は検査可能な形にする

違反を許容できない条件は、自然言語だけに残さず、可能な範囲で検査可能な形へ変換する。

条件 LLM への指示 検査へ外出しする例
JSON の型 「JSON で出力する」 JSON パーサー、JSON Schema
必須項目 「title と url を必ず含める」 JSON Schema の required
コードの動作 「既存動作を壊さない」 自動テスト
変更範囲 「指定箇所以外を変更しない」 git diff による差分確認
実行可否 「確認なしで実行しない」 承認処理や権限制御

JSON Schema は JSON データに対する制約をスキーマとして表現し、インスタンスが条件を満たすか検証できる。2020-12 の検証語彙では type や required などの検証キーワードが定義されている[4]。

たとえば、「title と url を必ず含める」という条件なら、最低限でも次のように表現できる。

{
  "type": "object",
  "required": ["title", "url"]
}

LLM に同じ条件を自然言語で伝えることにも意味はある。生成時点で正しい形式へ寄せられるからである。しかしスキーマを使えば、生成結果が条件を満たしたかどうかを LLM 自身の自己申告とは別に判定できる。

コード変更でも考え方は同じである。「この関数だけを直す」「無関係な整形をしない」と指示しても、最終的に何が変わったかは差分を見なければ確定しない。

git diff

人間が差分を読むならこれでよい。単に「差分が存在するか」を終了コードで判定したい場合は、--exit-code も使える。Git 2.55.0 の git-diff 文書では、差分がある場合は終了コード 1、ない場合は 0 と定義されている[5]。

git diff --exit-code

もちろん、このコマンドだけで変更内容の正しさを判定できるわけではない。ここで示したいのは、自然言語で「余計な変更をするな」と指示することと、実際の変更を観測可能な形にすることを分離する設計である。

テストも同様である。「既存動作を壊さない」という文は意図を伝えるが、それ自体は既存動作を検査しない。再現可能なテストがあるなら、LLM に既存動作を推測させるより、変更後にテストを実行して結果を見るほうが強い。

生成と検査を同じ仕事にしない

LLM に成果物を生成させ、その直後に「条件をすべて確認したか」と聞くと、「確認した」と答えることがある。しかし、その文章が生成されたことと、全条件が独立に走査されたことは同じではない。

原典でいう「存在→想起→適用→検査→修正」の分解は、この場面で効く[1]。生成が成功していても、検査が抜けることはある。検査で違反を見つけても、修正時に別の箇所を変えることもある。

そこで、役割を分ける。

役割 適した仕組みの例
文章やコードの生成 LLM
構造の検査 パーサー、JSON Schema バリデーター
動作の検査 テストランナー
変更内容の確認 git diff
採用・実行の判断 人間または明示的な承認処理

これは LLM を信用するかどうかという話ではない。生成と検査では、必要な性質が違うからである。

生成には、曖昧な要求を解釈し、複数の条件をまとめ、自然な成果物へ変換する柔軟さが必要になる。一方、検査には「条件を満たすか」「満たさないか」を同じ規則で繰り返し判定できることが重要になる。後者を通常のコードで決定的に実装できるなら、同じ判定を毎回 LLM の自然言語処理へ戻す理由は薄い。

実務では、すべてを機械検査できるわけではない。文章の妥当性、設計判断、要件の解釈など、人間や LLM による評価が必要な条件も残る。それでも、JSON の必須項目、構文、テスト結果、差分の有無のように固定できる部分まで自然言語だけで管理する必要はない。

LLM に任せる範囲を広げるほど、この分離は効いてくる。ルールが 1 個なら再指示でも間に合う。数十個の条件、複数ファイル、既存仕様、出力形式が同時に絡むと、すべての条件を毎回同じ強度で適用し、さらに自己検査まで完結させることを期待するのは設計として弱い。

ルールは記憶させるだけでは足りない

LLM の Memory、長いコンテキスト、詳細なプロンプトはいずれも有用である。必要な情報を参照できなければ、そもそも正しい生成は難しい。

ただし、参照できることと、固定制約として強制できることは分けて考えたほうがよい。

自然言語のルールは、生成を正しい方向へ導く。そのうえで、違反を許容できない条件は パーサー、スキーマ、テスト、差分確認、承認処理などへ移す。すると、LLM がルールを「覚えていたか」という曖昧な問いを減らし、「成果物が条件を満たしたか」という観測可能な問いへ置き換えられる。

問題は、AI が人間のように物忘れするかどうかではない。守る必要があるルールが、どこで参照され、どこで適用され、どこで検査される設計になっているかである。

参考文献

  1. id774, AI はなぜ物忘れするのか(2026-07-28). https://blog.id774.net/entry/2026/07/28/4969/
  2. OpenAI, Dreaming: Better memory for a more helpful ChatGPT(2026-06-04). https://openai.com/index/chatgpt-memory-dreaming/
  3. Nelson F. Liu, Kevin Lin, John Hewitt, Ashwin Paranjape, Michele Bevilacqua, Fabio Petroni, Percy Liang, Lost in the Middle: How Language Models Use Long Contexts(2023-07-06). https://arxiv.org/abs/2307.03172
  4. A. Wright, H. Andrews, B. Hutton, JSON Schema Validation: A Vocabulary for Structural Validation of JSON(2022-06-16). https://json-schema.org/draft/2020-12/json-schema-validation
  5. Git Project, git-diff Documentation(2026-06-29). https://git-scm.com/docs/git-diff

Discussion