JevCode ドキュメント · モデルは clavue-jev
LLM構造化出力: JSONモード、関数呼び出し、および型付き判断
LLMアプリ向けの構造化出力オプションの比較 — JSONモード、スキーマ制約デコーディング、関数呼び出し、TypeSafe型付き質問 — 失敗モード、コスト、およびモデルにJSONを出力させるよう求めるよりも、クローズドセットの意思決定プリミティブが優位となるケース。
本文はenからの機械翻訳です。校正は未実施で、参考情報としてのみご利用ください。

全てのLLMアプリが直面する問題
LLMは文章を返す。あなたのアプリケーションが必要とするのはデータだ:カテゴリ、数値、ブール値、構造体。それ以降のすべて——ルーティング、ストレージ、ダッシュボード、リトライ——は、その文章が毎回確実にパース可能で有効な出力になることに依存している。
業界におけるこの名称は構造化出力であり、現在それを取得する方法は4つの主流なものが存在します。これらは、保証内容、コスト、および失敗する要因において異なります。
4つの選択肢を一覧で
| 手法 | 仕組み | 保証 | 失敗モード | 相対コスト |
|---|---|---|---|---|
| JSON 用のプロンプト | モデルに「JSON で返信してください」と指示する | なし — 単なる提案 | 末尾のコンマ、JSON 周辺の散文、発明されたフィールド | 1x 生成(長くなる可能性がある) |
| JSON モード / response_format | 出力を有効な JSON に制限する API フラグ | 有効な JSON 構文 | 形状や型が異なる有効な JSON;スキーマの乖離 | 1x 生成 |
| スキーマ制約付きデコーディング | トークンサンプリング時に文法/正規表現制約を適用 | 構文 および 形状がスキーマに一致 | 意味的に誤っているが妥当なフィールドの埋め込み;サーバーサポートが必要 | 1x 生成 + サービングの複雑さ |
| 関数呼び出し | モデルが宣言された関数と引数を選択 | 引数があなたのシグネチャに対して検証される | 列挙型外の幻覚的な引数値;マルチステップの脆弱性 | 1x 生成 |
| 型付き質問 (TypeSafe) | あなたの状態に対する閉集合の選択 / 評価 / Noul 質問 | 型付き回答 + 確率分布全体 + 信頼度、ワンパスで | 質問していないことのみ — 質問されていない質問は幻覚を起こせない | トークン入力のみ;出力は無料 |
最初の4つは、正直に述べる価値のある一つの性質を共有しています:モデルは依然としてトークンを一つずつ生成しています。 上記のすべての保証は、生成を置き換えるものではなく、生成を取り巻くガードレールです。5つ目は、定義した閉じた集合に対する分布を出力する単一の順伝播パスによって生成を置き換えます。
クローズド集合が失敗プロファイルを変える理由
JSONモードでは、"priority": "high"のようなフィールドが"High"、"HIGH"、
"priority_high"、または2として返されることがあります。バリデーター、リトライループ、およびフォールバックはあなたが実装します。
スキーマ制約付きデコーディングでは、構造は正しいものの、値が
正しい判断であるかどうかを検証する手段がありません。完全にフォーマットされた構造体であっても、誤った回答を含んでいる可能性があり、
モデルがどの程度確信を持っていたかを示す信号はありません。
型付き質問は逆のアプローチを採用する:回答空間はリクエストが存在する前に固定される。
from typesafe_sdk import AsyncTypeSafeClient, Choice
async def main() -> None:
async with AsyncTypeSafeClient() as client:
response = await client.system_one(
state=ticket_text,
questions={
"priority": Choice(
instructions="Which priority does this ticket have?",
criteria={
"p0": "Outage or data loss, all users affected",
"p1": "Major feature broken, workaround exists",
"p2": "Minor issue, scheduled work",
},
)
},
)
answer = response.answers["priority"]
print(answer.choice) # "p1"
print(answer.confidence) # 0.93 — route on it directly
返ってくるのは解析すべき文字列ではありません。それは、宣言した選択肢のみに対して確率分布を持つ型付き値 — p0: 0.02, p1: 0.93, p2: 0.05 —
と、信頼度スコアです。検証すべきJSONも、正規化する列挙型も、不正な出力に対する再試行ループもありません。不正な出力は生成できないからです。
実際にはどのようなものか
列挙型引数を用いた関数呼び出し。 関数のシグネチャですでにLiteral型を使用している場合、それらの閉じた集合はChoiceの質問に1対1でマッピングされます — 自然言語が引数ごとの信頼度を備えた型付き呼び出しに変換される、完全なトレーディングアシスタントの例については、関数呼び出しのクックブックをご覧ください。
抽出パイプライン。 ドキュメントから値を取り出す際、質問マップ は スキーマそのものであり、フィールドごとに1つのエントリを持ち、セマンティクスは正確に1回だけ定義されます。 構造化データ抽出カスケードは、検証パスを含む2段階版を示しています。
ガードルールと分類。 はい/いいえのチェック(これはジャイルブレイクか?、これはPIIを含むか?)はNoulの質問である——確率であり、構文解析された文字列ではない。LLMのガードルールを参照。
不確実性の扱い。 確率分布は、JSON モードでは提供できない部分です。信頼度を用いた分類 および信頼度ゲート型ルーティングは、それが可能にするもの、すなわち、閾値以上では自動承認、閾値以下では人間のレビューという、独自データ上で測定された処理を示しています。
正直なトレードオフ表
| JSON mode / function calling | Typed questions | |
|---|---|---|
| Open-ended text generation | はい — スキーマには自由な文字列を含められます | いいえ — 回答は閉じた集合から取得されます |
| Output validity | 生成後に検証されます | 構築によって保証されます |
| Confidence signal | 場合による(logprobs、公開されている場合) | 常に — 質問ごとに完全な分布を提供 |
| Cost driver | 生成された出力トークン | 入力トークンのみ(出力は無料) |
| Schema changes | JSON スキーマを編集し、再プロンプト | 質問マップを編集し、リクエスト形状はそのまま |
| Best for | 構造を含むドラフト、要約、クリエイティブテキスト | 判断:分類、ルーティング、スコアリング、検証 |
2つのアプローチは競合ではなく補完関係にある。生成された概要 と ルーティング判断の両方を必要とするパイプラインでは、生成には1回しかコストがかからず、同じJSONから解析して判断するのではなく、型付きの質問で判断を下す。
はじめに
- プリミティブの概要 — 選択、スコアリング、Noul、およびそれぞれの適用場面
- HTTP API リファレンス — リクエスト/レスポンスの形状
- クイックスタート — 5分で最初の型付き質問を行う
- プレイグラウンド — 登録不要でライブ状態に対して質問を試す
Related
- 関数呼び出し — 自然言語から型付き関数呼び出しへ
- 構造化データ抽出カスケード — 検証を伴う二段階抽出
- 信頼度ゲート付きルーティング — 分布が可能にするパターン
- ユースケースマップ — 各プリミティブが本番環境で登場する場所