7月3日、Techstrong.AIが「Three Ways LLM Pipelines Fail in Production That Staging Will Not Catch」と題した記事を公開した。LLMを本番投入したチームが直面する本当の問題は、プロンプトの質やモデルの性能ではなく、インフラレベルの構造的障害だ。たとえば、新しい必須フィールドがスキーマに追加されたその瞬間から、誰も気づかないまま不正データが積み上がっていく——そうした障害は、ステージングのテストでは決して表面化しない。記事の筆者は10万回超の生成サイクルを経たAIドキュメント処理パイプラインの運用経験から、学術ベンチマークでは露出しない3つの障害パターンを体系化した。
Failure Mode 1: スキーマ進化によるプロンプトドリフト
3つの中で最も静かに、そして最も広範に被害をもたらすのがこれだ。
構造化出力(JSON)を返すLLM機能を実装し、Pydanticモデルとプロンプトをセットで本番投入する。数週間後、プロダクトの要件変更で出力スキーマに新しい必須フィールドが追加される。開発者はPydanticモデルを更新し、DBマイグレーションを走らせる。しかし、プロンプトは誰も更新しない。
LLMは引き続き「有効なJSON」を返し続ける。ただしそれは古いスキーマに準拠したJSONだ。新しい必須フィールドは欠落しているか、ハルシネーションで埋められている。ダウンストリームのパーサーはクラッシュしない。不正データは静かに伝播し、気づいた頃には汚染が広がっている。
検出策: すべてのプロンプトにスキーマバージョンフィールドを埋め込む。推論実行前にプロンプト内のスキーマバージョンと現行バージョンを照合し、不一致ならアラートを上げる。
対策: プロンプトをDBマイグレーションと同等の「バージョン管理されたアーティファクト」として扱う。スキーマ変更のPRには、対応するプロンプト変更を必須として含める。問題の根本は、プロンプトがバージョン管理外のconfigファイルやDBテーブルに置かれ、スキーマ定義との関係がコードレビューで見えないことにある。
Failure Mode 2: 検索コンテキストの汚染(Retrieval-Context Poisoning)
RAG(Retrieval-Augmented Generation)システムでは、ドキュメントをチャンクに分割・埋め込みし、推論時に関連チャンクをベクトルストアから取得する。この設計には暗黙の前提がある——「チャンクの関連性は時間が経っても変わらない」という前提だ。
ソースドキュメントが更新されると、この前提は崩れる。新しいチャンクをベクトルストアに投入しても、古いチャンクの削除が不完全だった場合、あるいはキャッシュが古いままの場合、検索結果に新旧混在のチャンクが返ってくる。生成されたテキストはどちらのバージョンも正確に反映しない。外見上は一貫した文章に見えるが、内容は誤っている。
検出策: 埋め込み時に各チャンクへドキュメントハッシュを付与する。検索時にチャンクのハッシュとライブドキュメントの現行ハッシュを比較し、不一致のチャンクをコンテキストウィンドウに入れる前に「stale」としてフラグを立てる。
対策: チャンクの削除をドキュメントライフサイクルの一等市民として扱う。古いチャンクの削除と新しいチャンクの挿入はアトミックに行い、削除の確認なしに挿入だけ完了した状態は「部分的成功」ではなく「失敗した更新」とみなす。
Failure Mode 3: パイプライン途中失敗からの回復
LLMパイプラインは「コンテキスト取得→要約→構造化→バリデーション→後処理」のような逐次ステップで構成されることが多い。ステップ3が失敗したとき、大抵は次のどちらかが起きる——パイプライン全体がクラッシュするか、失敗ステップをスキップして劣化した出力を返すかだ。どちらも受け入れられない。
筆者が指摘するのはグラニュラーなチェックポイント機能の欠如だ。「ステップ1・2は成功、ステップ3で失敗、ステップ4は未実行」という状態を記録しておけば、リトライ時にステップ3からのみ再実行できる。ステップ1・2が高コストなLLM呼び出しや検索処理を含む場合、これは単なる効率化ではなく、出力の再現性を保つためにも必要だ(リトライのたびにステップ2が異なる出力を返す可能性がある)。
検出策: セッションIDとステップシーケンス番号を持つ「ステップ開始/終了」イベントをログに記録する。障害発生時にログを照会し、最後に成功したステップを特定する。
対策: 各ステップが次のステップ開始前に、セッションID + ステップ番号 をキーとする永続ストアに出力を書き込む設計にする。リトライ時はストアを確認し、完了済みのステップをスキップする。分散コンピューティングでは標準的なチェックポイント・リスタートパターンだが、LLMアプリケーションでは公式なパイプライン抽象が後付けになりがちなため、導入が遅れている。
3つの障害に共通する構造
これら3つの障害はいずれも、既存のテスト戦略では検出できないという共通点を持つ。
- ユニットテストは個々のプロンプトをテストするが、時間経過によるスキーマ進化は対象外
- RAGの統合テストは特定時点の検索品質を検証するが、ベクトルストアの更新時挙動は対象外
- エンドツーエンドテストはハッピーパスを検証するが、途中失敗のケースは対象外
本番LLMシステムには、静的なテストではなくオペレーショナルなモニタリングが必要な障害クラスが存在する。これらの障害は、負荷の下で、変化の中で、時間をかけて表面化する。
未解決課題:筆者自身が認める「まだ答えのない問題」
筆者は「これらの問題に対するクリーンな解決策をすべて持っているわけではない」と率直に述べており、以下の3点を未解決の課題として明示している。
- 分岐・並列パイプラインでのチェックポイント: 逐次ステップであれば状態管理は比較的シンプルだが、複数の処理が並行・分岐する構造では、どのステップまで完了したかを正確に記録・再現することが難しくなる
- ストリーミングデータでのハッシュベース検出: ドキュメントが静的なバッチではなくリアルタイムで更新され続ける場合、ハッシュの比較タイミングや粒度の設計が複雑になる
- ランタイム生成プロンプトのバージョン管理: プロンプトが実行時に動的に組み立てられる設計では、「どのバージョンのプロンプトが使われたか」を事後的に再現・追跡することが困難になる
いずれも、LLMパイプラインの運用がより複雑なユースケースに拡張されるにつれて重要性が増す論点だ。現時点では業界全体として確立した解法がなく、各チームが個別に対処しているのが実情といえる。
詳細はThree Ways LLM Pipelines Fail in Production That Staging Will Not Catchを参照していただきたい。