LLMから狙った通りの構造化データ(JSON)を打率高く抽出するためのTips備忘録
LLMから狙い通りの構造化データを最も打率高く(確実かつ低レイテンシで)抽出するためのアプローチとTipsを整理してメモしておきます。
LLMに「綺麗なJSON」を吐かせる難しさ
LLMを使ったアプリケーション開発(特にエージェントやバックエンドの自動化パイプライン)において、出力を綺麗な構造化データ(JSON)として受け取ることは必須要件です。
しかし、プロンプトで「JSONで出力して」と頼むだけでは、不要な解説テキストが混ざったり、スキーマが微妙にズレたりしてパースエラーになるのが日常茶飯事。 今回は、LLMから狙い通りの構造化データを最も打率高く(確実かつ低レイテンシで)抽出するためのアプローチとTipsを整理してメモしておきます。
1. 構造化データ抽出の「3つのアプローチ」
現在、主要なLLM APIで構造化データを取得する方法は大きく分けて3つあります。
| 手法 | 特徴と使い所 |
|---|---|
| Structured Outputs |
(OpenAI等) | 最強の選択肢。 モデルの出力自体をJSON Schemaに強制的に固定するため、スキーマ違反が原則100%発生しない。 |
| JSON Mode | 出力フォーマットをJSONに縛る。ただし、プロンプト側でも「JSONで返せ」と明示する必要があり、キーの型や構成までは完全強制できないため、パース後のバリデーション(Zod等)が必須。 |
| Tool Calling(関数呼び出し) | 本来は外部ツール連携用だが、「ツール(関数)の引数」として構造化データを定義できるため、間接的に確実なJSON抽出手段として機能する。 |
💡 結論: スキーマの完全性を担保したい、かつ対応モデルであるなら**Structured Outputs(またはTool Callingのハック)**の一択。
2. 精度を高めるためのスキーマ定義・プロンプトのTips
ただ仕組み(Structured Outputsなど)を使うだけでなく、「LLMが迷わないスキーマ」を設計することが、ハルシネーションの抑制や抽出精度の向上に直結します。
① description(説明文)をサボらない
JSON SchemaやZodでオブジェクトを定義する際、各プロパティ(キー)に必ず具体的な description を付与します。
LLMはこの説明文を強力な指示(プロンプト)として読み解くため、「何を、どういう基準で抽出してほしいか」をここに言語化するのが最も効果的です。
② あいまいな「自由記述」を減らし、enum(列挙型)を活用する
例えば、テキストの感情分析をさせる場合、string で自由に返させるのではなく、['positive', 'negative', 'neutral'] のように enum で選択肢を制限します。
これにより、LLMの思考のブレ(「ポジティブ」「高評価」などの表記揺れ)を完全に防ぐことができます。
③ 思考フェーズ(Chain of Thought)をスキーマに内包させる
「思考プロセスを踏んでから結論を出させたいが、最終出力はJSONにしたい」という場合、スキーマの中に reasoning(思考・理由)というフィールドをあらかじめ用意しておくテクニックが有効です。
LLMはJSONを上から順に出力していくため、先に reasoning で推論を行わせることで、最終的な result(結論)の精度が劇的に向上します。
// スキーマ構造のイメージ
{
"reasoning": "なぜその結論に至ったかの思考プロセス(ここに先に書かせる)",
"final_answer": "最終的な抽出結果・判定"
}
3. 実装・運用時の注意点(LLM Opsの視点)
- トークン消費量とレイテンシのトレードオフ:
思考フェーズ(
reasoning)をJSONに含めると、出力トークン数が大幅に増えるため、その分レスポンスが遅くなり、APIコストも上がります。リアルタイム性が求められる画面では、あえて思考を省くか、軽量モデル(Flash系など)を叩くといった割り切りが必要です。 - スキーマ変更時の互換性: アプリケーション側のコード(Zod定義など)を変更した際、LLM側に渡すスキーマ定義も追従させないと、本番環境で予期せぬパースエラーを吐く原因になります。スキーマのロジックは一元管理するのが安全。
まとめ
LLMからの構造化データ抽出は、プロンプトの工夫(泥臭いアプローチ)から、APIの機能(堅牢なシステム)へと完全にシフトしています。
description の記述や enum の固定といった基本を徹底しつつ、用途に応じて「速度重視か」「精度重視か」を切り替えていくのが良さそうです。
参考元記事
- [元記事のタイトルやリンクなどをここに記載]