LLMの構造化出力とは|JSON出力とFunction Callingの使い分け
最終更新日:2026/10/08
LLMの構造化出力とは、JSON Schemaなどで出力の形をあらかじめ定義し、モデルの生成をその形に拘束する仕組みです。「プロンプトでJSONを頼んでいるのに、たまに前置きが混ざってパースが落ちる」という詰まり方をしているエンジニアに向けて、JSONモード・スキーマ強制・Function Callingの違いと選び方、そして形が守られても壊れるケースの対処まで整理します。
先に結論
構造化出力は「返答の形式を固定する機能」、Function Callingは「実行する処理を選ばせる機能」です。この一点でまず切り分けます
なお本記事では、JSON形式で返させる方法全般を広義の構造化出力として扱い、狭義の「構造化出力」はスキーマ準拠を保証する方式を指します
プロンプトでJSONを依頼するだけの方式は、フィールド名や型が実行ごとにブレます。本番バッチに載せるなら最低でもスキーマ強制まで上げます
主要3サービス(OpenAI・Anthropic・Google)はいずれも、対応モデルではスキーマ準拠を目指す構造化出力機能を提供しています。ただし指定方法とサポートされるスキーマの範囲が各社で違うため、移植時はここが最初の落とし穴になります
スキーマが守られても壊れる経路は3つ。トークン上限での打ち切り・安全性による拒否・形は正しいが中身が誤っている、の順に対策します
構造化出力は「形の保証」であって「内容の保証」ではありません。値の妥当性は別レイヤーの検証で担保します
この記事でわかること
構造化出力の3つの実現方式(プロンプト指示・JSONモード・スキーマ強制)の違いと、どこから本番品質になるか
Function Callingとの役割分担と、ツール呼び出しを「構造化出力の代用」にしたときの限界
OpenAI・Anthropic・Googleそれぞれのスキーマ制約の差と、移植で詰まりやすい箇所
スキーマ準拠が保証されていても出力が壊れる3経路と、その検知・リカバリ方法
対象は、LLM APIを使ったアプリケーションやバッチ処理を実装した経験があるエンジニアです。Python・TypeScriptいずれかでAPIを叩いたことがあれば読み進められます。
なお、安全性フィルタや権限制御まで含めた出力制御の全体像は「LLMのガードレールとは|出力制御の実装パターンとツール選定」で扱っています。本記事はそのうち「フォーマットを拘束する」部分に範囲を絞り、実装の中身に踏み込みます。
目次
LLMの構造化出力とは|3つの実現方式
Function Callingとの違い|「形を固定する」と「行動を選ばせる」
使い分けの判断フロー
主要3サービスの対応状況
スキーマ設計の実務ポイント
構造化出力でも壊れるケースと対策
ケース別の実装パターンと導入チェックリスト
フリーランス案件における構造化出力のスキル評価
まとめ
よくある質問
LLMの構造化出力とは|3つの実現方式
構造化出力とは、モデルの出力を決められたデータ構造に従わせる仕組みの総称です。実現方式は拘束の強さで3層に分かれ、層が上がるほど形の保証は強くなり、代わりに表現の自由度と対応モデルが狭まります。
構造化出力が必要になる場面
LLMの出力を人間が読むだけなら、構造化は不要です。必要になるのは、出力が次の処理の入力になるときです。
典型的なのは、請求書PDFから項目を抜いてDBに入れる抽出処理、問い合わせ本文を優先度とカテゴリに振り分ける分類処理、そして複数ステップを自動で回すエージェントの中間データです。いずれも後続がプログラムなので、形が崩れた瞬間に処理が止まります。
厄介なのは失敗の頻度です。プロンプトでJSONを依頼する方式でも、9割以上は正しく返ってきます。だからこそ検証段階では気づかず、本番で数千件回したときに数十件が落ちる。この「たまに落ちる」が運用コストを押し上げます。
プロンプト指示・JSONモード・スキーマ強制の3層
3つの方式の違いを整理します。
方式 | 保証される範囲 | 実装コスト | 本番適性 |
|---|---|---|---|
プロンプト指示のみ | なし(お願いベース) | 最小 | 低。リトライ前提の設計が必要 |
JSONモード | パース可能なJSONであること | 小(パラメータ1つ) | 中。キー名・型はブレうる |
スキーマ強制(構造化出力) | 定義したJSON Schemaへの準拠 | 中(スキーマ設計が要る) | 高 |
OpenAIの公式ガイドでは、JSONモードと構造化出力を「どちらも有効なJSONを生成するが、スキーマへの準拠を保証するのは構造化出力だけ」と区別しています(Structured model outputs)。この整理に従えば、JSONモードで返ってきたオブジェクトのキーが前回と同じ名前である保証はありません。
実務では、プロンプト指示とJSONモードの間より、JSONモードとスキーマ強制の間のほうが段差が大きいと感じます。前者はどちらも「パースしてみるまで分からない」のに対し、後者は「パースは通る前提でコードが書ける」ため、例外処理の設計が根本から変わります。
なぜ制約付きデコーディングで形が保証されるのか
スキーマ強制が効く理由は、生成のしかた自体を変えているからです。
通常のLLMは、各ステップで語彙全体から次のトークンを確率的に選びます。制約付きデコーディング(constrained decoding)では、定義したスキーマを文法に変換したうえで、その文法上あり得ないトークンの確率をゼロに潰してから選ばせます。閉じ括弧が必要な位置では閉じ括弧しか選べないため、構造が崩れようがない、という仕組みです。
この前処理にはコストがかかります。OpenAIのドキュメントでは、新しいスキーマでの初回リクエストはスキーマを文脈自由文法に変換する処理が入るため遅くなり、そのレイテンシを避けたい場合はstrictを有効にしない選択肢もある、と説明されています(Structured model outputs)。スキーマを動的に組み立てる設計だと毎回この初回コストを踏むため、スキーマは可能な限り静的に固定しておくほうが有利です。
ミニFAQ:JSONモードはもう使わなくていいですか?
スキーマ強制が使えるモデルなら、基本はそちらで問題ありません。ただしスキーマ強制は対応モデルが限られ、使えるJSON Schemaの機能にも制限があります。出力の形が毎回変わる探索的な用途や、未対応モデルを使う場合はJSONモードが現実的な選択肢として残ります。
Function Callingとの違い|「形を固定する」と「行動を選ばせる」
結論から言うと、両者は競合する選択肢ではなく、目的が別の機能です。OpenAIのドキュメントは、モデルをツールや関数・データに接続するならFunction Calling、ユーザーへの応答そのものを構造化したいなら出力フォーマット指定、と用途で使い分けを示しています。
Function Callingの本来の役割
Function Callingは、モデルに「どの関数を、どの引数で呼ぶべきか」を判断させる仕組みです。開発者は呼べる関数の一覧とそれぞれの引数スキーマを渡し、モデルは文脈を見て呼ぶ関数を選び、引数を埋めて返します。
標準的な使い方では、モデルに関数を呼ぶかどうかの選択権を持たせます。関数を呼ばずに通常の文章で答えてもいいし、複数の関数を順に呼んでもいい。この「選ばせる」性質こそがFunction Callingの価値であり、単に決まった形のデータが欲しいだけの用途には過剰です。なお、APIや設定によっては特定ツールの使用を強制することもできます。
ツールとモデルの接続を標準化する動きとしては、Model Context Protocolのようなプロトコル層の整備も進んでいます。接続の仕組み自体は「Model Context Protocolとは|MCPの仕組み・活用事例をエンジニア視点で解説」で解説しているため、本記事ではモデルAPIレベルの出力制御に話を限定します。
Function Callingを構造化出力として流用する手法と限界
スキーマ強制が一般提供される前から広く使われてきたのが、ツールを1つだけ定義し、そのツールを必ず呼ぶよう強制して、引数オブジェクトを戻り値代わりに受け取るという手法です。ツールの入力スキーマがそのまま出力スキーマとして機能します。
この方法は今でも動きますが、注意点があります。厳密なスキーマ拘束(strict指定など)を伴わないツール呼び出しでは、スキーマ準拠はベストエフォートです。必須フィールドが欠ける、スキーマにないフィールドが増える、整数を期待した箇所に文字列が入る、といったズレが発生しえます。
Anthropicは現在、この2つを明確に分けています。公式ドキュメントでは「JSON outputsはClaudeの応答フォーマットを制御するもの、strict tool useはツールの引数を検証するもの」と役割が整理されており、両者は併用できる設計になっています(Structured outputs - Claude Platform Docs)。
両方を併用する構成
エージェントを実装すると、両方が同時に要る場面が出てきます。
たとえば旅程を組むエージェントなら、途中でフライト検索ツールを呼ぶ際の引数はツール側のスキーマで検証し、最終的にユーザーへ返す旅程データは出力フォーマット側のスキーマで固定する。入口(ツール引数)と出口(最終応答)を別々に縛るのが素直な設計です。
エージェント全体の設計パターンについては「AIエージェントとは?仕組み・種類・活用事例をわかりやすく解説」や「AIエージェント開発フレームワーク比較|LangGraph・CrewAI・AutoGen」が参考になります。
使い分けの判断フロー
判断は4つの軸で決まります。迷ったら上から順に当てはめてください。
判断軸 | スキーマ強制の構造化出力 | Function Calling |
|---|---|---|
モデルに選択権を渡すか | 渡さない(形は固定) | 渡す(呼ぶ/呼ばないを判断させる) |
出力の用途 | 後続処理に流すデータ | 外部システムの実行 |
分岐の有無 | 単一の形で足りる | 複数の処理先から選ぶ |
実行後の継続 | 1回で完結 | 結果を受けて会話を続ける |
実務的な原則として、まずスキーマ強制で形を固定しておき、処理の分岐が必要になった段階でFunction Callingへ広げると、設計の後戻りが少なく済みます。逆順(最初からツール定義で組んで、あとから出力形式だけ欲しくなる)だと、ツール定義とスキーマ定義が二重管理になりやすいためです。
ユースケース別に落とすと、次のようになります。
文書からの項目抽出、要約の構造化、分類・スコアリング → スキーマ強制
DB検索、API実行、ファイル操作を伴う処理 → Function Calling
抽出結果をもとに外部APIを叩き、その結果を整形して返す → 両方を併用
主要3サービスの対応状況
結論として、3社とも制約付きデコーディングによるスキーマ準拠を提供していますが、使えるJSON Schemaの範囲とパラメータ名が異なります。以下は執筆時点(2026年10月)で各社の公式ドキュメントから確認できる内容です。仕様の更新が速い領域のため、実装前に必ず公式ページで最新を確認してください。
項目 | OpenAI | Anthropic Claude | Google Gemini |
|---|---|---|---|
指定方法 | json_schema形式のフォーマット指定+strict | output_config.formatでjson_schemaを指定 | generationConfigでresponseMimeTypeとresponseSchemaを指定 |
スキーマなしのJSON強制 | JSONモードあり | 出力フォーマット指定が中心 | responseMimeTypeのみ指定で可 |
ツール引数の厳密化 | Function Callingのstrict | toolsのstrict指定 | Function Calling |
スキーマの土台 | JSON Schemaのサブセット | JSON Schemaのサブセット | OpenAPI 3.0 Schemaのサブセット |
OpenAIの場合
json_schema形式でスキーマを渡し、strictを有効にすると準拠が保証されます。strict有効時の制約が実装上いちばん引っかかる箇所です。
執筆時点のstrict利用では、すべてのプロパティをrequiredに列挙する前提で扱う必要があり、任意項目は「requiredから外す」のではなく「型にnullを含めたunionにする」という表現に変えます。オブジェクトにはadditionalPropertiesをfalseで明示します。この2点を知らずにPydanticやZodのスキーマをそのまま投げると、バリデーションエラーで弾かれます。
Anthropic Claudeの場合
出力フォーマット指定とツールのstrict指定が別機能として用意されており、併用できます。PythonではPydanticモデル、TypeScriptではZodスキーマをそのまま渡せるSDKサポートがあります。
制限として、再帰的なスキーマは非対応、minimumやmaxLengthといった数値・文字列の範囲制約も非対応です。ドキュメントによれば、SDK側がAPI非対応の制約を自動的に取り除き、その内容をdescriptionに書き戻す処理を行います。つまり範囲制約はモデルへの「お願い」に格下げされるため、値の範囲チェックはアプリ側で別途行う前提で設計します。あわせて、1リクエストあたりのstrictツール数や任意パラメータ数にも上限が設けられています。
Google Geminiの場合
generationConfigでresponseMimeTypeをapplication/jsonにし、responseSchemaにスキーマを渡します。ベースがJSON SchemaではなくOpenAPI 3.0 Schemaのサブセットである点が他2社と異なり、propertyOrderingという独自フィールドで出力順を指定できるため、順序依存の後続処理や差分ログの比較を扱いやすくできます。分類タスク向けにenumを使った出力指定もサポートされています。
一方で、公式ドキュメントは非常に大きなスキーマや深くネストしたスキーマは拒否される場合があると明示しています(Generate structured output using the Gemini API)。
各APIの料金やモデル選定については「OpenAI APIの使い方|料金・モデル選定・Claude/Geminiとの違いをフリーランスエンジニア向けに解説」「Claude APIの使い方|料金・モデル選定・実装例をフリーランスエンジニア向けに解説」「Gemini APIの使い方|料金・モデル選定・OpenAI APIとの違いを解説」にまとめています。
ミニFAQ:3社に対応したマルチプロバイダ構成は現実的ですか?
スキーマを共通の内部表現(PydanticやZod)で1本持ち、各プロバイダ向けに変換層をかませる構成なら現実的です。ただし非対応制約の落ち方がプロバイダごとに違うため、変換で落ちた制約を必ずアプリ側のバリデーションで拾い直す設計にしないと、プロバイダを切り替えた瞬間にチェックが素通りします。
スキーマ設計の実務ポイント
スキーマは「厳しくすれば安全」ではありません。モデルが埋めやすい形に設計するほうが、結果的にデータ品質が上がります。
必須フィールドと任意フィールドの扱い
strictモードでは任意フィールドをnull許容で表現するのが基本です。ここで注意したいのは、モデルは「そのフィールドを埋めなければならない」という圧力を受ける点です。
抽出元の文書に書いていない項目でも、required扱いにするとそれらしい値をでっち上げるリスクが上がります。「文書に記載がない場合はnullを返す」とdescriptionに明記し、型をnull許容にしておくのが安全です。この挙動は誤情報の混入経路のひとつで、対策の考え方は「ハルシネーション対策|LLMの誤回答を減らす実装と運用設計」と共通します。
enumは分類タスクの精度を底上げする
分類やルーティングの用途では、自由記述よりenumでの列挙が確実です。制約付きデコーディングが効いていれば、定義した候補以外は構造上出力できなくなります。
ただしAnthropicのドキュメントは、条件によってはenum値の大文字・小文字が揺れる可能性に注意を促しており、比較は大文字小文字を区別しない形で実装することを推奨しています。候補値は短く、記号やスペースを含まない形にしておくと事故が減ります。
ネストと配列の深さは浅く保つ
深いネストは、スキーマが拒否されるリスクとレイテンシの両方を押し上げます。3階層を超えそうなら、フラットな構造に組み替えてアプリ側で再構成するほうが安定します。
配列の要素数も同様です。1回の呼び出しで100件返させるより、20件ずつ5回に分けるほうがトークン上限での打ち切りを避けられます。トークン量の設計についてはコスト面にも直結するため、「LLMコスト最適化案件の単価相場|トークン削減・推論設計のフリーランス実務」の観点も参考になります。
非対応の制約はdescriptionとアプリ側の二重で守る
minLength、maximum、パターンマッチの一部など、プロバイダが受け付けない制約があります。これらを「スキーマに書いたから大丈夫」と考えるのが典型的な事故です。
実務では、非対応制約は次の2段構えで守ります。
descriptionに自然言語で書く(モデルへのヒントとして機能する)
受信後にアプリ側のバリデータで再検証する(ここが本当の防波堤)
構造化出力でも壊れるケースと対策
スキーマ準拠が保証されていても、出力が使えない状態になる経路は残ります。保証が及ばない境界を知っておくことが、運用設計そのものです。
トークン上限での打ち切り
最も頻度が高い失敗です。生成が最大トークン数に達すると、JSONが途中で切れた状態で返ります。この場合、スキーマ準拠は成立しません。
検知は終了理由(stop_reason等)で行います。パースエラーをtry-catchで握りつぶす実装にしていると、この原因に気づけません。終了理由を見て、上限打ち切りなら「件数を減らして再実行」、通常終了なのにパースが落ちたなら「別の異常」と切り分けます。
安全性による拒否
モデルが安全性の観点で応答を拒否した場合も、スキーマから外れた形が返ります。OpenAIはrefusalという専用フィールドで、Anthropicは専用の終了理由で、それぞれ拒否を明示する設計になっています。
拒否はHTTPエラーではなく正常応答として返り、課金も発生します。ステータスコードだけを見ている実装では素通りするため、レスポンス本体の判定が必要です。入力側に起因する異常挙動への備えは「プロンプトインジェクション対策|LLMアプリのセキュリティ実装ガイド」とあわせて設計してください。
形は正しいが中身が誤っている
これがいちばん厄介です。スキーマ準拠100%でも、値が間違っていることはあります。日付フィールドに文書と違う日付が入る、金額の桁が1つずれる、カテゴリが微妙に不適切、といったズレは構造チェックでは検出できません。
対策は構造とは別レイヤーで組みます。参照元テキストに該当値が存在するかの照合、数値の範囲・合計の突き合わせ、サンプリングによる人手レビュー。こうした品質担保の進め方は「LLM評価(Evals)とは|LLM-as-a-Judgeと品質保証の実務まで解説」で体系的に扱っています。
レイテンシとコストへの影響
スキーマ強制には固定費がかかります。新しいスキーマの初回リクエストは文法への前処理が入るぶん遅くなり、スキーマ定義そのものも入力トークンを消費します。
影響を抑える実務的な手当ては3つです。スキーマを静的に固定して初回コストの再発を防ぐ、フィールド名を短くしてトークンを節約する、そしてdescriptionは効果のある箇所に絞って書く。descriptionを全フィールドに丁寧に書くと、スキーマだけで数百トークンを超えることがあります。
ケース別の実装パターンと導入チェックリスト
ケース1:文書からの項目抽出バッチ
契約書や請求書から決まった項目を抜く処理です。スキーマ強制が最も素直に効く用途で、任意項目はすべてnull許容にし、「記載がなければnull」をdescriptionで明示するのが要点になります。
1回の呼び出しで処理する文書は1件に絞ります。複数文書をまとめて投げると、トークン上限での打ち切りと、文書間での項目の取り違えが同時に起きやすくなります。
ケース2:分類・ルーティング
問い合わせを優先度とカテゴリに振り分ける処理です。enumで候補を列挙し、合わせて判断理由のフィールドを1つ持たせます。
理由フィールドは一見冗長ですが、分類精度の改善時にログを読むコストが大きく下がります。精度を追う運用をするなら、最初から入れておくほうが安上がりです。
ケース3:エージェントのツール呼び出し
ツール引数はツール側のstrict指定で縛り、最終応答は出力フォーマット側で縛ります。ツールの数が増えるほど、モデルが選択を誤る余地も増えるため、用途の近いツールは統合して総数を抑えるのが基本方針です。
RAGと組み合わせる場合、検索結果の整形に構造化出力を挟むと後続の扱いが楽になります。検索側の設計は「RAGとは?仕組み・活用事例・導入メリットをわかりやすく解説」を参照してください。
導入チェックリスト
本番投入前に、次の項目を確認してください。
任意フィールドをnull許容で表現し、「不明ならnull」をdescriptionに書いたか
オブジェクトのadditionalPropertiesをfalseにしたか(OpenAI strict利用時は必須)
ネストを3階層以内に抑えたか
1回の出力件数を、トークン上限に対して余裕のある数に制限したか
終了理由(上限打ち切り・拒否)をレスポンス本体で判定しているか
プロバイダ非対応の範囲制約を、アプリ側のバリデータで再検証しているか
enumの比較を大文字小文字非依存で実装したか
スキーマを静的に固定し、リクエストごとの動的生成を避けたか
値の正しさを構造チェックとは別レイヤーで検証する仕組みを用意したか
フリーランス案件における構造化出力のスキル評価
結論として、構造化出力そのものが単独の案件になることはほとんどありませんが、LLMアプリ開発案件の実装品質を分ける要素として評価されます。
主要フリーランスエージェント数社の公開案件ページを2026年10月時点で確認した範囲では、構造化出力を単体のスキルとして明示する募集はほとんど見られず、「LLM APIを用いた機能開発」「生成AIの業務システム組み込み」といった要件の一部として含まれる形が中心でした。公開案件のみを対象にした観測であり、非公開案件の傾向は含みません。
面談でアピールしやすいのは、スキーマを書けること自体よりも、上限打ち切り・拒否・値の誤りという3経路を踏まえた運用設計まで話せることです。プロトタイプ止まりの経験と本番運用の経験は、この一点で見分けられやすくなります。
関連領域の案件相場や参画ルートは「RAG構築案件の実情|単価相場・必要スキル・獲得方法」に整理しています。自分の経験でどのくらいの単価を狙えるか確認したい方は、無料のフリーランスエンジニア単価診断で市場単価の目安を把握できます。実際の募集内容はフリコンの案件一覧から確認してください。
まとめ
構造化出力は「形の保証」、Function Callingは「行動の選択」。この役割分担を押さえれば、設計判断の8割は決まります。
本番バッチに載せるなら、プロンプト指示やJSONモードではなくスキーマ強制まで上げる
3社とも準拠保証を提供しているが、サポートされるスキーマ範囲とパラメータ名が異なる。移植時はここを最初に確認する
任意フィールドはnull許容で表現し、「不明ならnull」をdescriptionに明記して捏造を防ぐ
壊れる経路はトークン上限・拒否・値の誤りの3つ。終了理由をレスポンス本体で判定する実装にする
プロバイダ非対応の範囲制約は、アプリ側のバリデータで必ず再検証する
値の正しさは構造チェックでは守れない。評価・照合の仕組みを別レイヤーで持つ
迷ったら、まず構造化出力で形式を固定し、外部処理の分岐が必要になった段階でFunction Callingへ広げる。この順で考えると判断がぶれません。
次のステップとしては、手元の既存処理のうち「LLMの出力をパースしている箇所」を洗い出し、終了理由の判定が入っているかを確認するところから始めるのが確実です。上限打ち切りの見落としは、本番で最初に顕在化する不具合です。
参照した一次情報は以下のとおりです。
よくある質問
構造化出力を使うと精度は落ちますか?
形式を縛ることで推論の自由度が下がり、複雑な推論を要するタスクでは品質が落ちる場合があります。対策としては、理由や根拠を別フィールドで返させる設計が有効なケースがあります。JSONの出力順を活用して理由フィールドを結論より前に置く構成も選択肢ですが、思考過程の詳細出力はコストや運用方針に応じて慎重に判断してください。
スキーマが大きすぎてエラーになります。どう分割しますか?
1回の呼び出しで全項目を埋めるのをやめ、関連する項目ごとにスキーマを分けて複数回に分割します。抽出系なら「基本情報」「金額情報」「当事者情報」のようにグループ化すると、スキーマサイズとトークン上限の両方が同時に緩みます。
ローカルLLMでも構造化出力は使えますか?
推論ランタイム側が制約付きデコーディングに対応していれば使えます。ランタイムによってサポートするスキーマ機能の範囲が異なるため、クラウドAPIで動いたスキーマがそのまま通るとは限りません。移行時はスキーマの簡素化を前提に見積もってください。
ストリーミングと構造化出力は併用できますか?
併用自体は可能です。ただし途中のチャンクは不完全なJSONであるため、逐次パースには部分JSONパーサーが必要になります。実装コストに見合うのは、長い出力をUIに段階表示するケースに限られます。バッチ処理なら完了を待つほうが単純です。
スキーマのdescriptionはどこまで書くべきですか?
フィールド名から意味が自明なものは省略し、判断基準が必要なフィールドにだけ書くのが費用対効果の良い書き方です。「記載がなければnull」「日付はYYYY-MM-DD形式」「複数該当する場合は最も金額の大きいもの」のような、モデルが迷う分岐に絞ります。
出力が毎回微妙に違うのを完全に固定できますか?
構造は固定できますが、値は固定できません。温度パラメータを下げると揺れは小さくなりますが、ゼロにはなりません。完全な再現性が必要な処理は、LLMではなくルールベースで実装する判断も検討してください。
Function Callingで複数ツールを定義すると選択を誤ります。どうすれば?
ツール名と説明文の書き分けが不十分なケースが大半です。説明文に「いつ使うか」だけでなく「いつ使わないか」を書くと改善します。それでも誤る場合は、ツールを階層化して先に大分類を選ばせる2段構成に変えます。
構造化出力があればガードレールは不要ですか?
別物なので両方必要です。構造化出力はフォーマットを保証するだけで、中身が不適切な内容でないかは判定しません。安全性の判定や入力側の検査を含む全体設計は「LLMのガードレールとは|出力制御の実装パターンとツール選定」を参照してください。
Pydanticのバリデーションはもう要らなくなりますか?
必要です。スキーマ強制が保証するのは型と構造であり、ビジネスルール上の妥当性は別です。加えて、プロバイダが受け付けずに落とされた範囲制約は、受信後の検証でしか守れません。
出力が拒否されたときのリトライはどう設計しますか?
同じ入力で単純リトライしても結果は変わりにくいため、回数は1回程度に抑えます。繰り返し拒否される入力は人手確認のキューに回すほうが、トークンを消費し続けるより安全です。拒否も課金対象である点を見落とさないでください。
