マガジン

LLMの応答を保存して再利用してよいか:応答キャッシュの可否判断とキー設計

AIを使いこなす

Claudeで執筆し、GPTで自動校閲・修正しています。

無地のカードを共通分と個別分に手作業で仕分けている様子
記事の内容をもとに制作したAI生成イメージです。実際の製品画面や検証結果の写真ではありません。

結論から言うと、再利用してよいのは「回答が入力文だけで決まり、誰が・いつ聞いても同じで構わず、古くなっても被害が小さい」場面です。この3条件のどれかが崩れるなら、同じ質問でも同じ答えを返してはいけません。個人情報を含む入力は、そもそも応答を保存しない設計を第一候補にし、保存するなら下記のキー設計メモの条件を満たしてからにします。 この記事は、自分のアプリ側で応答を保存する「応答キャッシュ」の可否だけを扱います。判断表、キーに入れる要素、個人情報があるときの設計メモの順に進みます。

この記事の目次
  1. 先に区別する:プロバイダーのプロンプトキャッシュは応答を保存しない
  2. キャッシュ可否の判断表
  3. キーに入れる要素
  4. 個人情報を含む場合のキー設計メモ
  5. 運用で確認する項目

先に区別する:プロバイダーのプロンプトキャッシュは応答を保存しない

名前が似ているので混同しやすいのですが、APIの「プロンプトキャッシュ」は応答の再利用ではありません。

  • OpenAIのプロンプトキャッシュの解説は、再利用するのは入力の一致したプレフィックスであり、モデルが回答を新たに生成すると説明しています。キャッシュの照合・保持条件はモデルや設定により異なります。
  • Anthropicのプロンプトキャッシュの解説も、保存するのはリクエストのプレフィックスで、モデルの応答ではないとしています。標準の保持は5分で、組織単位(対応する提供形態ではワークスペース単位)で分離されます。

つまり、プロンプトキャッシュは料金や遅延を減らす仕組みで、毎回新しく生成された回答が返ります。「同じ質問に同じ答え」を実現するには、アプリ側で応答を保存する必要があります。その保存内容と鍵の管理は自分の責任範囲です。保持時間や対象モデルは更新されうるため、実装時に各ドキュメントを見直してください(本記事は2026年10月28日に上記ページを閲覧して確認しました)。

キャッシュ可否の判断表

次の表は編集上の整理で、公式仕様ではありません。判断軸は「入力だけで答えが決まるか」「利用者や権限で答えが変わるか」「時間で古くなるか」「外れたときの影響」です。

  • 固定の文章の翻訳、書式変換、要約、可否:可、条件・キーに足すもの:入力の正規化、モデル、プロンプト版
  • 公開FAQへの定型回答、可否:可、条件・キーに足すもの:上記+参照文書の版、TTL(保存期限)
  • 社内規程のRAG回答、可否:条件付き、条件・キーに足すもの:文書版、テナント、閲覧権限グループをキーに含める
  • 注文状況・契約内容など利用者固有の回答、可否:原則避ける、条件・キーに足すもの:保存するなら利用者単位に完全分離し、短いTTL
  • 問い合わせ本文(氏名・連絡先を含む)の要約、可否:原則避ける、条件・キーに足すもの:個人情報を除いた後の定型部分だけ別扱い(後述)
  • 価格、在庫、ニュースなど時間で変わる内容、可否:避ける/短TTL、条件・キーに足すもの:データ側の更新時刻をキーに含める
  • 企画案、キャッチコピーなど多様さが価値の生成、可否:避ける、条件・キーに足すもの:同じ案ばかり返ると価値が下がる
  • 与信、採用、医療など判断の影響が大きい用途、可否:避ける、条件・キーに足すもの:毎回の生成と人の確認を前提にする

迷ったときの4つの質問

  1. 別の利用者に同じ文面を見せても問題ないか。
  2. 参照データや規程が更新されたら、答えは変わるべきか。
  3. 保存した回答が誤っていたとき、誰が訂正し、どう消すか。
  4. 保存する入力や回答に、個人を特定できる情報が入りうるか。

1が「いいえ」なら権限・利用者をキーに入れるか、キャッシュをやめます。2が「はい」なら、更新を表す版番号を必ずキーに入れます。3に答えられないなら、運用手順ができるまで保存しません。4が「はい」なら次節に進みます。

キーに入れる要素

同じ文字列が来たから同じ答え、ではなく、「答えを変えうる要素がすべて同じか」で判定します。入れる要素の例です。

  • 入力:空白や全角半角を揃えた文字列。大文字小文字は意味が変わりうるので、安易に揃えません。
  • 呼び出し条件:モデル名、システムプロンプトの版、temperatureなどのパラメータ、ツール定義、出力形式の指定。
  • 参照データ:RAGの文書版や索引の更新時刻。
  • 範囲:テナントID、権限グループ、言語。

次は、これらからキーを作る説明用の例です(未実行のコードで、動作は確認していません)。

python
import hashlib, hmac, json, re, unicodedata

SECRET = b"replace-with-managed-secret"  # 実運用では秘密管理の仕組みから取得

def normalize(text: str) -> str:
    text = unicodedata.normalize("NFKC", text)
    return re.sub(r"\s+", " ", text).strip()

def cache_key(*, tenant, scope, model, prompt_version,
              params, kb_version, user_input) -> str:
    material = json.dumps({
        "tenant": tenant, "scope": scope, "model": model,
        "prompt_version": prompt_version, "params": params,
        "kb_version": kb_version, "input": normalize(user_input),
    }, sort_keys=True, ensure_ascii=False)
    digest = hmac.new(SECRET, material.encode(), hashlib.sha256).hexdigest()
    return f"llm:v1:{digest}"

prompt_version や kb_version を上げれば、古い項目に当たらなくなります。これが一番安全な「全消し」の手段です。保存時にはTTLを必ず付け、同じ入力でも毎回同じ文面になるとは限らない前提で、最初に保存した1件を正解として扱う運用にします。

個人情報を含む場合のキー設計メモ

個人情報保護委員会は、生成AIサービスの利用に関する注意喚起等を公表し、別添の注意喚起を案内しています。応答キャッシュは、入力や回答に含まれる個人情報をアプリ側にも残す行為です。利用目的の範囲に収まるか、保存期間や削除の手順をどうするかは、自社の法務・個人情報の担当者と確認してください。また、OWASPの機微情報の漏えいに関する解説は、入力の無害化とアクセス制御を対策として挙げています。

以下は、これらを踏まえた編集上の設計メモです。

1. まず保存しない設計を検討する個人情報を含む入力は、キャッシュ対象から外します。外す判定は、入力を送る前に行います(検出ルールや分類を通し、迷うものは対象外に倒します)。

2. 個人情報を取り除いた定型部分だけを再利用するたとえば「配送遅延のお詫びを書いて」という依頼のうち、氏名や注文番号を {顧客名}、{注文番号} に置き換えたテンプレート部分だけを生成・保存し、差し込みはアプリ側で行います。置き換え後の文面に個人情報が残っていないかの確認は、人またはルールで行います。

3. キーに生の個人情報を入れないキー名はログ、監視画面、障害調査でそのまま表示されます。上のコードのようにキー全体を鍵付きハッシュ(HMAC)にします。単純なSHA-256だけでは、氏名や電話番号のように候補が絞れる値は総当たりで復元されます。ただし、ハッシュ化したからといって個人情報でなくなる保証はありません。

4. 利用者単位に名前空間を分ける保存するなら、キーに利用者(またはテナント)を含め、他者の項目に当たらない構造にします。共有キャッシュにすると、別の利用者の情報が返る事故になります。

5. 削除できる形にするHMACのキーから利用者は逆引きできません。そのため、利用者ID→キー一覧の索引を別に持つか、利用者単位の名前空間ごと消せる構造にします。削除要求や退会時に、保存した応答を消せるかを先に確認します。

6. 保存値も保護するキーだけでなく、保存する回答本文に個人情報が入ります。暗号化、アクセス権限の限定、短いTTL、ログへの本文出力禁止を設定します。

運用で確認する項目

  • ヒット率ではなく「誤ヒット」を見ます。権限違いの回答が返っていないかを、別テナント・別権限のテスト入力で定期的に確認します。
  • プロンプトやモデルを変えたら、バージョン値を更新します。
  • 応答にキャッシュ由来かどうかをログで残し、苦情や誤回答の調査で追えるようにします。
  • キャッシュ対象の場面を増やすときは、判断表の4つの質問に戻って判定します。

出典・参考資料