1. はじめに
レバレジーズテクノロジー戦略室先端技術チームの永安です。普段はレバレジーズ内のAI関連の研究開発に携わっています。さて、皆さんはLLMの構造化出力を使っているでしょうか? LLMによる処理をシステムに組み込む上で構造化出力は必須ですが、確率的に失敗するため困ることも多いと思います。そこで、LLMによる出力をどのように構造化しているのか、なぜ失敗するのか調査してみました。
2. 構造化出力の方法
LLMの構造化出力は実装ごとに細かな違いがありますが、ここでは Lu et al. (2025)[1]の分類に従います。この論文は、JSON生成の主要な方法として direct prompting with a JSON schema, tool calls, constraint decoding methods を並べて説明しています。そこで本記事でも、この3分類に沿って整理します。
2.1 Direct prompting with a JSON schema
Direct prompting with a JSON schema は、プロンプトの中で「この schema に従って JSON を返して」と明示して、モデルにそのまま構造化データを出させる方法です。代表例としては Instructor が分かりやすく、公式ドキュメントでも JSON モードや MD_JSON モードを持ち、テキスト出力から JSON を扱う流れを明示しています。
2.2 Tool calls
Tool calls は、モデルに自然文ではなく「どの関数をどういう引数で呼ぶか」を返させる方法です。アプリケーション側では JSON を直接パースするというより、ツール呼び出しの引数を structured output として受け取る感覚に近いです。代表例は LangChainで、公式ドキュメントでも ToolStrategy が tool calling を使って structured output を生成する方式として説明されています。
2.3 Constraint decoding methods
Constraint decoding methods は、生成後に壊れた JSON を直すのではなく、生成中にトークンの出力確率をマスクし、無効なトークンを出しにくくする方法です。代表的なOSSとしてはOutlinesが挙げられます。
3. 各構造化の弱点となる入力
構造化の種類によって苦手な入力タイプも異なります。ここでは各構造化手法ごとに弱点となる入力の種類を解説します。具体的な入力文章の例は、後述の実験を行う際にサンプルを作成しているので、そちらを参照してください。
3.1 Direct prompting with a JSON schema の弱点
Direct prompting with a JSON schema は、条件分岐を含む複雑な schema、厳密なフォーマット制約がある値、引用符やバックスラッシュを多く含む文字列で壊れやすいです。出力の正しさをLLMそのものの確率的な
出力に全て委ねていることが原因になります。
3.2 Tool calls の弱点
Tool calls は、必須項目・条件依存の引数が細かく絡む入力で壊れやすいです。理由は、自然言語としては大筋が正しくても、関数引数ではschema仕様を厳密に一回で決めきる必要があり、ここで少しでも判断を誤ると呼び出し自体は成立しても引数仕様から外れやすいからです。
3.3 Constraint decoding methods の弱点
Constraint decoding methods は、深いネストや再帰構造、大きい配列で壊れやすいです。理由として、生成中ずっと「次に出せるトークン」を制約計算し続ける必要があるため、schema が複雑になるほど探索空間の管理が重くなるという点があります。
4. 実験
メール内容をスキーマで構造化させる実験を行いました。メールは通常の文面と各手法の弱点を織り込んだ文面をそれぞれ用意しています。また、以下の以下のメール文面とスキーマはchatgptで作成しています。Gemini 2.5 flashで処理を行い、返答文字列がjson.loadsで辞書型に変更できなかったものを失敗とみなし、100回の入力の成功率を見ます。これにより、Gemini 2.5 flashで採用されている構造化方法を推定することが、本実験の目的になります。
4.1 共通スキーマ
{
"type": "OBJECT",
"properties": {
"callback_time": {"type": "STRING", "format": "date-time", "nullable": true},
"customer_name": {"type": "STRING"},
"email": {"type": "STRING", "format": "email", "nullable": true},
"evidence": {"type": "ARRAY", "items": {"type": "STRING"}},
"issue_type": {"type": "STRING","enum": ["billing", "shipping", "technical", "account", "other"]},
"order_id": {"type": "STRING","nullable": true},
"phone": {"type": "STRING", "nullable": true},
"priority": {"type": "STRING","enum": ["low", "medium", "high"]},
"summary": {"type": "STRING"},
"wants_callback": {"type": "BOOLEAN"}
},
"required": ["customer_name", "evidence", "issue_type", "priority", "summary", "wants_callback"],
"propertyOrdering": ["customer_name", "email", "phone", "order_id", "issue_type", "priority", "wants_callback", "callback_time", "summary", "evidence"]
}
4.2 通常のメール文面
件名: 注文 ORD-1042-AB の配送遅延について 田中です。3月31日発送予定の注文 ORD-1042-AB がまだ届いていません。 配送状況ページには「倉庫で保留」と表示されています。 急ぎで確認したいです。連絡先は aya.tanaka@example.com です。 必要なら 2026-04-03T14:00:00+09:00 に電話できます。
4.3 Direct promptingが弱いメール文面
引用符やバックスラッシュを多く含む文字列を入れています。
件名: ログ込みで見てください(生ログそのまま貼ります)
田中です。注文 ORD-7781 の配送がおかしいです。まだ届いていません。
追跡画面には次のように表示されました:
{"status":"hold","retry":2,"detail":"carrier said \"address mismatch\"","raw":"{\"phase\":\"warehouse\",\"code\":\"HOLD\",\"note\":\"check \\\\shipping\\\\queue\"}"}
保存したログの場所は C:\logs\ship\2026\04\err.json です。
バックアップは \\nas01\ops\shipping\2026\04\ORD-7781\err-backup.json にあります。
画面に出ていた文言は "address mismatch"、別の箇所では "\"address mismatch\""、さらにログ上では "\\\"address mismatch\\\"" でした。
配送会社からは "invalid address / hold" と言われ、追跡メモには ["hold","retry","manual_check"] と書かれていました。
そのまま貼ると次です:
{
"order":"ORD-7781",
"events":[
{"at":"2026-04-01T09:12:33+09:00","msg":"label created"},
{"at":"2026-04-01T11:02:10+09:00","msg":"warehouse hold"},
{"at":"2026-04-01T11:05:44+09:00","msg":"carrier said \"address mismatch\""}
],
"debug":"path=C:\\logs\\ship\\2026\\04\\err.json; regex=^ORD-[0-9]+$; note=\"retry->manual_check\""
}
メモ欄には `/address\\s+mismatch/i` とも残っています。
引用元の本文には ```json {"carrier":"X","status":"hold"} ``` みたいな表示もありました。
連絡先は yama@example.com です。
必要なら 2026-04-03T19:30:00+09:00 に電話できます。
要約すると「配送遅延、倉庫保留、住所不一致扱いの可能性あり」です。
4.4 Tool callsが弱いメール文面
注文番号や時間といった構造化する内容に分岐が多く、最終的な構造を決めにくいです。
件名: どの問い合わせとして扱えばいいのか分かりません
山田です。たぶん注文は ORD-7781 だと思うのですが、古いメールを見ると ORD-778I にも見えていて、どちらが正しいか分かりません。
今回の問題も、単なる配送遅延なのか、住所の不一致なのか、アカウント画面の表示不具合なのか、あるいは請求のやり直しまで絡んでいるのか判断できません。
追跡画面には {"status":"hold","retry":2} と出ていますが、配送会社には "address mismatch" と言われ、マイページでは配送先が正しく見えている一方で、昨日は決済がやり直されたようにも見えました。
急ぎではあるのですが、今日中でなくてもよく、ただ明日の朝までに何か分かると助かります。
電話はできれば欲しいですが、出られないかもしれないのでメールでも構いませんし、電話するなら 2026-04-03T19:30:00+09:00 でもいいですし、20:00以降のほうが確実かもしれません。
連絡先は yama@example.com ですが、前回は別のアドレスを使った気もします。
保存したログの場所は C:\logs\ship\2026\04\err.json です。
4.5 Constraint decodingが弱いメール文面
分量が多く、制約計算が壊れやすいです。長いため一部省略しています。
田中です。これまでの経緯を全部まとめます。
過去メールの引用、配送会社とのやり取り、注文の関連情報、添付一覧を下に全部貼ります。
注文は1件ではなく、関連注文も含めて追跡してほしいです。
関連注文は ORD-2201 / ORD-2202 / ORD-2203 / ORD-2204 / ORD-2205 / ORD-2206 / ORD-2207 / ORD-2208 / ORD-2209 / ORD-2210 です。
添付は 40 枚あります。
時系列:
1. 3/28 注文を作成(ケースID: CASE-1001)
## 以下80件までの時系列
添付一覧:
1. attach_01_注文確認PDF
## 以下40件までの添付
関連注文メモ:
1. ORD-2201 - 本命
## 以下30件までのメモ
過去メールの引用:
1. 私: 「本日発送予定です」
## 以下100件までのメール引用
追跡ページからの生ログ:
1. {"event":"HOLD","order":"ORD-2201","retry":1,"seen_at":"2026-04-02T11:31:00+09:00"}
## 以下30件までのログ
補足:
1. 電話は平日18時以降なら可、ただし4/3・4/5・4/7は 19:30 以降のみ。
## 以下20件までの補足
4.6 結果
| プロンプト | 成功率 |
|---|---|
| 通常 | 100 / 100 |
| Direct prompting with a JSON schema | 100 / 100 |
| Tool calls | 100 / 100 |
| Constraint decoding methods | 96 / 100 |
Constraint decoding methodsに弱いプロンプトで100件中4件失敗するという結果になりました。GeminiはConstraint decoding methodsを使っていることを示唆する結果となりました。ただしこのケースのプロンプトは極端に長いのでDirect promptingであっても悪化する可能性はあります。
5. まとめ
LLMの構造化出力を行う方法について調査し、それぞれの方法に対して弱点になる入力を調査しました。そしてGeminiに対してテストを行ったところ、極端に長いプロンプトにおいて構造化に失敗する傾向が見られました。これはConstraint decodingの計算負荷やコンテキストの長大化が影響している可能性があります。構造化出力の失敗は無駄なAPI利用にも繋がるのでなるべく無くしていきたいですね。[1]の論文ではベンチマークも作成しているのでclosed modelで試すのも面白いかもしれません。
おわりに
レバレジーズでは、最先端AI技術の調査・研究開発を行う研究員のポジションで一緒に働くメンバーを募集しています。 「専門性を生かして新たなイノベーションを起こしたい」と考えている方は以下の求人もご確認ください!
https://hrmos.co/pages/leverages/jobs/A_c_00076
引用
- [1] Lu, Yaxi, et al. "Learning to generate structured output with schema reinforcement learning." Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers). 2025.