本番運用 — Logging Safety / Drift / Cost / Rollback で RAG を運用する

(更新: 2026-05-24) by ZeroZawa

2026-05-24 改訂: 本シリーズは Ollama + Qwen3 で完全ローカル再現できる構成に作り直しました。題材は架空企業「ナギサ・パートナーズ」(中堅 SIer、自社 SaaS「Mirage」を運用) の社内 wiki です。本記事は運用 runbook なので測定値の chart はありませんが、コスト節ではローカル経路 (API コスト 0 円) とクラウド経路の両方を併記します。

Part 1 で素朴な RAG、Part 2 で hybrid+filter、Part 3 で reranker + Citations、Part 4 で 30 件 golden set × RAGAs 4 指標。ここまでが offline の話でした。本記事 (Part 5、シリーズ完結) では online に持ち込んだ瞬間に立ち上がる別の課題群 — logging の設計PII の取扱いembedding drift古い文書の退役 (freshness)コスト構造ロールバック — を扱います。

RAG 本番運用の 6 つの観点 (logging / PII redaction / drift / re-index / cost / rollback) を 1 枚の運用 runbook として並べたインフォグラフィック

最初に強い警告を 1 つ置きます。個人情報を含むコーパスで default のまま retrieved chunks をログに出すと、それは即座に PII データレイクになります。Part 4 までの「動かす」「測る」と、Part 5 の「運用する」の間には、設計レベルの溝があります。本記事はその溝を埋める runbook です。

Offline で良かったものが Online で壊れる場所

Part 4 の最後で offline と online の対比表を出しました。改めて、online で 何が新しく壊れるか を観察します。

壊れる場所Offline ではOnline で起きること
Logging30 件の固定 query実 user query (PII / 機微情報含む) が大量に流れ込む
評価golden set 5pp 改善で勝ちA/B で 0.5pp の delta を信頼する必要
Retrieval固定 corpus文書改訂・新規追加で embedding drift が常に進行
Generation同じ judgeコスト構造 (embed / rerank / LLM tokens) を 常時 監視
障害sandbox で再現rollback 計画と postmortem が必須

ここからは各観点を順に runbook 化します。

Logging の設計 — 何を、どこに、どれだけ保持するか

最初の判断は 「何を記録するか」 ではなく 「何を記録しないか」 です。

記録対象の 4 層

機微度retention の標準
Requestquery, user_id (匿名化), timestamp90 日
Retrievalretrieved chunk_ids, scores90 日
Generationanswer text, model, tokens30 日
EvaluationRAGAs スコア, user feedback1 年

retrieved chunk の本文を保存しない のがポイントです。chunk_id だけ残せば、後から corpus を pin-point して再構築できます。本文をそのまま保存すると 検索結果がそのまま PII データセット になります1

OpenTelemetry semantic convention に乗せる

LLM 関連の telemetry には OpenTelemetry の gen_ai.* semantic convention2 が定着しつつあります。

from opentelemetry import trace
tracer = trace.get_tracer("rag-pipeline")
with tracer.start_as_current_span("rag.query") as span:
span.set_attribute("gen_ai.system", "anthropic")
span.set_attribute("gen_ai.request.model", "claude-opus-4-7")
span.set_attribute("rag.retrieved.chunk_ids", ",".join(chunk_ids)) # chunk 本文ではなく id
span.set_attribute("gen_ai.usage.input_tokens", usage.input_tokens)
span.set_attribute("gen_ai.usage.output_tokens", usage.output_tokens)

Datadog / Grafana / OneUptime いずれの可視化 backend も OTel convention を解釈するので、dashboard を作り直さずに backend を入れ替えられます3

Logging Safety — PII redaction を default に置く

ここからが本記事で最も強調したい節です。「個人情報を含むコーパスで default のまま retrieved chunks をログに出すと、それは即座に PII データレイクになる」。これを防ぐ設計を 3 箇所 で多重化します4

ナギサ corpus は教育用に無害化してありますが、現実の社内 wiki を想像してください。本シリーズの corpus でも、顧客 PJ 名 (Lumen / Tide / Marisol — 実在企業なら NDA 対象)、障害 post-mortem の担当者名、ボードゲーム同好会の参加者 initials のような 機微情報が業務文書に普通に混ざります。retrieved chunk 本文をそのままログに流せば、「障害対応フロー」を引いただけで担当者名と顧客名がログに焼き付きます。

3 箇所で redact する

箇所強み弱み
Ingest (embedding 前)最も強い保証、永続的corpus 再生成が必要、失われた情報は復元不可
Retrieval (取得後 / ログ書き込み前)柔軟、ホット pass で介入可hot-path 遅延 (数 ms) が乗る
Output (UI 表示 / API 返却前)最終安全網retrieved chunk 本文がすでに上流ログに出ていれば手遅れ

production では 3 箇所すべて に同じ regex / named entity 検出器を入れて多重化するのが標準です。1 箇所だけだと「redact 漏れの hop」が必ず生まれます。

検出粒度 — regex で取れるもの、取れないもの

regex で確実に取れるもの:

  • email (\S+@\S+\.\S+)
  • 電話番号 (国別)
  • クレジットカード (Luhn check 併用)
  • API key 風 token (sk-, xoxb- などの prefix)
  • IP アドレス

regex では取れず NER (named entity recognition) が要るもの:

  • 人名 (姓名独立も含む)
  • 住所
  • 組織名 (機微案件名)
  • 病名

軽量実装は presidio5pyap などのライブラリ。本シリーズの companion repo src/rag/pii_redactor.pyregex 6 種類 に絞った教育実装で、production では presidio に置き換えてください。

Opt-in sampling と retention

「全 query を保存」は legal/compliance リスクが大きすぎます。default で sampling rate 0.01 (1%) にし、debug 中だけ 1.0 に上げる運用が標準です:

import random
SAMPLE_RATE = float(os.getenv("RAG_LOG_SAMPLE_RATE", "0.01"))
if random.random() < SAMPLE_RATE:
logger.info("rag.query", extra={
"query": redact(query),
"retrieved_chunk_ids": chunk_ids,
"answer_summary": redact(answer[:200]), # 全文ではなく冒頭のみ
})

retention は 30 日 default、tenant 設定で 7 日まで短縮可、というのが GDPR / APPI の運用幅です6

知っておくべき法的制約 (極要約)

  • GDPR: EU 居住者の data subject 削除要求に 30 日以内 で応じる義務6。logger 側で query → user_id の逆引きが必須 (匿名化済みでも要紐付け)
  • APPI (日本): 利用目的の事前明示と保管期間制限。AI 学習目的を別枠で同意取得する潮流7
  • 米国 state laws (CCPA / CPRA): opt-out 権の即時反映。logger に削除フラグ伝播の経路が必要

詳細は法務と必ず合議してください。本記事は 「最小限の構造的安全」 を示すだけです。

Embedding Drift — 何がいつ壊れるか

corpus と query 分布が時間で変わると embedding が徐々にズレます。3 種類の drift があります8

Drift の 3 型

原因検出シグナル
Corpus drift文書の追加・改訂・削除retrieved chunk の age 分布変化 / hit rate 急落
Query driftuser の興味・語彙変化top query embedding の cluster 中心移動
Model driftembedding model のバージョン更新同じ chunk で異なる embedding (基本は再 index で対応)

検出の最小実装

import numpy as np
# 過去 7 日と直近 1 日の query embedding 分布の cosine 距離
def drift_score(recent_embeds: np.ndarray, baseline_embeds: np.ndarray) -> float:
recent_center = recent_embeds.mean(axis=0)
baseline_center = baseline_embeds.mean(axis=0)
return 1.0 - float(
np.dot(recent_center, baseline_center)
/ (np.linalg.norm(recent_center) * np.linalg.norm(baseline_center) + 1e-9)
)
# alert 閾値
if drift_score(recent, baseline) > 0.05:
notify("query drift detected — corpus 改訂 or 評価 set 更新を検討")

5pp の cosine 距離変化は経験上 「golden set を見直すべきタイミング」 の signal です。

Re-index のタイミング

トリガー頻度
文書改訂率 > 10%即時
embedding model major version up即時 (互換性ゼロ)
cold data (90 日以上アクセスなし) の再 embed四半期
全件再 embed半年〜年

Cold data の四半期再 embed は storage cost と冷えた retrieval 品質のバランス点 として広く採用されています9

古い「現行扱い」文書の退役 — Part 2 からの宿題

Part 2status filter を入れ、明示的に archive された旧版 (mirage-architecture-v2-archive など) を top-5 から追い出しました。けれどそこで宿題を 1 つ残しました。status=active のままだが、内容が古びていく文書」 です。現行 mirage-architecture-v3.md も、いつか v4 が出れば「active だが古い前提を語る文書」になります。誰も statusarchived に書き換えなければ、filter は素通りさせます。

これは static な metadata filter では解けず、運用の仕組み で退役させる必要があります:

仕組み内容
owner + 定期確認各 doc に owner (部署 / チーム) を持たせ、半年ごとに「まだ現行か」を確認するワークフロー。確認が切れた doc は statusstale に降格
updated_at の鮮度スコアretrieval スコアに freshness = exp(-age / τ) を掛け、古い doc を相対的に沈める (hard filter ではなく soft penalty)
参照グラフ「v3 が出たら v2 を自動 archive」のように、後継 doc の出現をトリガに前任を退役させる (corpus に 関連: リンクがあれば辿れる)

ナギサ corpus は各 doc に owner (例: プロダクト本部 / SRE 室) と 関連: リンクを持たせてあるので、この 3 つを乗せる素地があります。Part 2 の _extract_metadata で拾った updated_at / owner が、ここで効いてきます。「明示 archive は Part 2 で即除外、内容劣化は Part 5 で運用退役」という二段構えが、ドキュメンテーション劣化への完全な打ち手です。

コスト構造の分解 — どこに金が消えているか

「LLM が高い」とよく言いますが、production RAG では費用は 4 箇所 に分散しています。

費目単価感 (2026-05)月コスト試算 (10k query/day)
Embedding (query)$0.02 / 1M tokens〜数千円
Embedding (corpus 再構築)同上 × 文書総 token数万円 (年 4 回想定)
Vector DB (managed)$0.10 / GB / 月数千〜数万円
Reranker (cross-encoder local)CPU/GPU 償却数千円
LLM generation$3-15 / 1M output tokens数万〜数十万円

LLM generation が dominant ですが、hidden cost が 2 つあります:

  • Corpus 再 embedding: 文書 100k 件 × 1k tokens で 100M tokens = $2. 半年に 1 度なら年 $4 だが、毎週やると年 $200
  • Vector DB egress: managed DB の network 課金は traffic 量で別建て

ローカル経路 (Ollama) のコスト: 本シリーズの再現に使った qwen3-embedding:0.6b + qwen3:8b 経路は API コストが 0 円 です。費用は電気代と、何より 自分の時間 に乗ります。embedding と単発生成は数秒ですが、Part 4 の RAGAs 一括評価 (30 件 × 3 pipeline) は Apple Silicon で 1 時間強かかります。「無料」と「高速」は別物で、ローカル LLM は 金銭コストを計算時間に付け替えている だけ、という理解が運用判断には重要です。本番のスループットが要るなら、generation だけクラウド API に出して embedding/rerank はローカル、のような hybrid 構成が現実解になります。

直接効くコスト最適化 (Part 1-3 でやったこと)

打ち手効くコスト効果
Part 2 hybrid (BM25 で fallback)LLM input tokensretrieved の精度 ↑ で k を絞れる
Part 3 cross-encoder rerankLLM input tokenstop-20 → top-3 で input -85%
Prompt caching (Anthropic) 10LLM input tokens同一 corpus で input 90% off
Part 4 evaluation (offline)judge LLM tokens全 query では走らせない

Anthropic prompt caching は Part 3 の Citations API と 併用可能10、社内ナレッジボットのように コーパス + system prompt がほぼ固定 な構成では大きく効きます。

インシデント対応とロールバック

「LLM が壊れた」と「データが壊れた」は責任分界点が違います。

Fault model の 4 分類

分類rollback 単位
Model regression新モデルが回答品質低下model version pin
Index corruptionre-embed 途中で部分破損index snapshot 切替
Prompt regressionsystem prompt 変更で hallucinate 増prompt version pin
Corpus poisoning悪意ある doc 混入corpus diff revert

Rollback のための前提

  • Index は version 管理する (timestamp 付きで複数 snapshot 保持、N=3 が標準)
  • Prompt と model は version 文字列で pin する (v=2026-05-15 のような明示的 tag)
  • Corpus 改訂は git で diff 可能にする (companion repo の corpus/ 構造を参考)

Incident playbook (5 ステップ)

  1. 検知: dashboard alert (RAGAs スコア降下 / latency 上昇 / cost 急増)
  2. 隔離: traffic を baseline pipeline に戻す (canary 5% で導入していれば即座)
  3. 計測: golden set の re-run で regression 範囲を特定
  4. 修復: 該当 component を rollback または hotfix
  5. postmortem: blameless で golden set に該当ケースを追加 (Part 4 の golden を厚くする)

5 番目が最重要です。インシデントが起きるたびに golden が太り、同じ事故は二度と起きません。

シリーズ総括 — 次の入口

5 部にわたって 「動く RAG」から「使える RAG」へ の橋を架けてきました。最後に、本シリーズが意図的にスコープ外にした 3 つの方向を、次の入口として置きます。

Fine-tuning — domain-specific reranker / embedding

Part 3 で off-the-shelf cross-encoder の domain mismatch を観察しました。法務 / 医療 / 専門 jargon が密な領域では sentence-transformers の fine-tuning パイプラインで domain-specific reranker を作る価値があります11。golden set が 30 → 500 件に育った段階で検討するタイミングです。

Multimodal RAG — 画像 / 表 / 音声を含むコーパス

PDF の図表、議事録の音声、技術ドキュメントの diagram — 「テキストだけの corpus」は実世界の半分以下です。Anthropic Claude や GPT-4o の vision 入力を combine する multimodal RAG が 2026 以降の標準になりつつあります12

Agentic RAG — query 自体を LLM に分解させる

「複数 doc を統合して比較」「時系列で集約」のような複雑な query は、1 度の retrieve + generate では解けません。LLM 自身に 「どの retrieve を、どの順序で投げるか」 を計画させる agentic な構造が登場しています13。本シリーズの Part 2 で導入した hybrid retrieval + Part 3 の Citations API + Part 4 の評価ループは、agentic な系の 基盤 として機能します。


5 部完結です。Part 1 で 100 行 RAG を動かしたところから、Part 5 で本番運用 runbook を組むところまで来ました。「使える RAG」は遠くなさそうで、本気でやると 5 部かかります。けれど 5 部分の積み上げが終われば、PoC で止まらないシステムが作れます。

シリーズ全体: 今更聞けない RAG の作り方、評価の仕方

companion repo: zawazawa5809/rag-fundamentals-companionpart-05 tag で本記事の examples/ops/run.py / src/rag/pii_redactor.py / src/rag/logger.py / tests/ を再現できます。

参考文献

Footnotes

  1. RAG Pipeline Security Best Practices for 2026: Protecting Sensitive Data — retrieved chunks ログのリスクと 3 箇所 redact 戦略

  2. OpenTelemetry semantic conventions for GenAIgen_ai.* attribute 標準

  3. How to Implement RAG Pipeline Tracing with OpenTelemetry — backend 中立な OTel pipeline 設計

  4. Safe Observability: A Framework for Automated PII Redaction from LLM Prompts in OpenTelemetry Pipelines — 3 箇所多重化の根拠

  5. Microsoft Presidio — 産業実装の PII detection / anonymization SDK (regex + NER + custom recognizer)

  6. GDPR Article 17 — Right to erasure — 削除要求への 30 日以内対応の根拠条文 2

  7. 個人情報保護委員会 — 改正 APPI 解釈通知 — AI 学習目的の同意取得に関する 2024 改正解釈

  8. Drift Detection in Production RAG Systems — 3 型 drift と alert 閾値の実務観

  9. Cold-data re-embedding cadence in production RAG — 四半期再 embed の cost / quality バランス

  10. Prompt Caching - Anthropic API Docs — Citations API との併用と input token 90% 削減 2

  11. Fine-tuning Cross-Encoders for Reranking — sentence-transformers — domain-specific reranker の学習レシピ

  12. Multimodal RAG with Anthropic Claude — 画像入力を含む RAG パターン

  13. Agentic RAG: A Survey — 2025 サーベイ。multi-hop / query decomposition / tool-use RAG の体系化