LLM Output Parser(エルエルエム アウトプットパーサー)
LLM の生テキスト出力を構造化データに変換するコンポーネント。JSON、リスト、キー値ペアなどのフォーマットを解析し、アプリケーションが扱えるデータ構造に変換する。
LLM Output Parser とは
LLM Output Parser は、大規模言語モデルが生成した生テキスト出力を、アプリケーションが処理可能な構造化データに変換するコンポーネントです。LLM の出力は基本的に文字列であり、そのままではプログラムで扱いにくい場合があります。Output Parser は、この文字列から必要な情報を抽出し、辞書、リスト、カスタムオブジェクトなどに変換します。
なぜ Output Parser が必要か
LLM をアプリケーションに組み込む際、モデルの出力をそのまま表示するだけでなく、後続の処理に渡すケースが増えています。例えば、LLM に商品レビューの感情分析を依頼した場合、「ポジティブ」という文字列ではなく { sentiment: "positive", confidence: 0.92 } というオブジェクトが欲しいのです。
Output Parser は以下の課題を解決します。
- フォーマットの不安定性: LLM は同じプロンプトでも異なるフォーマットで回答する場合がある
- 型変換: 文字列として出力された数値や日付を適切な型に変換する
- 抽出と整形: 長い説明文から必要なフィールドだけを取り出す
- エラー回復: パース失敗時のフォールバック処理
主要な Output Parser パターン
正規表現ベースパーサー
最もシンプルなアプローチです。LLM の出力から特定のパターン(JSON ブロック、キー値ペア等)を正規表現で抽出します。
| パターン | 正規表現例 | 用途 |
|---|---|---|
| JSON 抽出 | \\{[^{}]*\\} | マークダウンコードブロック内の JSON |
| キー値ペア | ^(\\w+):\\s*(.+)$ | 「カテゴリ: 電子機器」形式 |
| リスト抽出 | ^[\\-\\*]\\s*(.+)$ | 箇条書きリスト |
| 数値抽出 | (\\d+\\.?\\d*) | スコアや評価値 |
軽量で依存関係がない利点がありますが、複雑な構造や入れ子のパースには限界があります。
LangChain Output Parsers
LangChain は複数の Output Parser クラスを提供しています。
StructuredOutputParser: JSON Schema に基づいてパースします。プロンプトにフォーマット指示を自動挿入し、出力を辞書に変換します。
PydanticOutputParser: Pydantic モデルを使ってパースと型検証を同時に行います。バリデーションエラー時にはエラー内容をモデルにフィードバックして再生成を促す自動修正機能も備えています。
CommaSeparatedListOutputParser: カンマ区切りの出力をリストに変換します。タグや選択肢のリストを取得する際に便利です。
Instructor パターン
Instructor ライブラリは、Output Parser の概念をさらに進化させたアプローチです。Pydantic モデルを直接 LLM に渡し、Function Calling や JSON Mode を通じてモデル側で構造化出力を生成させます。パーサーがモデルの外にあるのではなく、モデルの生成プロセスに組み込まれている点が特徴です。
実装のベストプラクティス
プロンプトとパーサーの整合性: パーサーが期待するフォーマットをプロンプトで明示的に指示します。LangChain の get_format_instructions() メソッドが好例で、パーサーの期待値をプロンプトに自動挿入します。
段階的なフォールバック: 厳密なパース → 緩いパース → 生テキスト保持の段階でフォールバックします。例: Pydantic パース失敗 → 正規表現で JSON 抽出 → 手動パース → エラーログと生出力保存。
デバッグ可能性: パース前の生出力を必ずログに記録します。パース失敗時にモデル出力を確認できないと、プロンプト改善ができません。
冪等性: 同じ入力に対して同じ出力を返すパーサーを設計します。パース結果が入力以外の状態に依存すると、テストとデバッグが困難になります。
Output Parser の進化と今後
Response Format (JSON Mode / Structured Outputs) の普及により、Output Parser の必要性は減少傾向にあります。モデル側で構造化出力が保証されれば、アプリケーション側のパースロジックは単純な JSON.parse() で済みます。
ただし以下のケースでは依然として Output Parser が有効です。
- Response Format をサポートしないモデル(古いバージョン、一部のオープンソースモデル)を使う場合
- テキスト出力から複数の情報を段階的に抽出する場合
- 非 JSON フォーマット(CSV、YAML、カスタムフォーマット)をパースする場合
- レガシーシステムとの統合で特定の出力形式が必要な場合
FAQ
Q: Output Parser と JSON Mode はどう使い分けますか?
JSON Mode がサポートされているプロバイダでは JSON Mode を優先してください。Output Parser は JSON Mode 非対応の環境や、非 JSON フォーマットの処理に使用します。両方を組み合わせること(JSON Mode + Pydantic バリデーション)も一般的で、二重の安全性を確保できます。
Q: パース失敗が頻発する場合の対処法は?
まずプロンプトを改善します。具体的な出力例をプロンプトに含める(Few-shot)、XML タグでフィールドを囲む指示を追加する、temperature を下げるなどの手法が効果的です。それでも改善しない場合は、Response Format (JSON Mode / Structured Outputs) への移行を検討してください。
Q: 独自の Output Parser を作るべきですか?
シンプルなケース(1-2 フィールドの抽出)では正規表現で十分です。複雑なケースでは LangChain や Instructor 等の既存ライブラリの使用を推奨します。独自パーサーはメンテナンスコストが高く、エッジケースの処理が不十分になりがちです。