プロンプトエンジニアリングと構造化出力
音声は3本です。
この章でできるようになること
何を報告し、何を捨てるかを、形容詞ではなく基準で書ける。出力の形がぶれるとき、少数の具体例で一般化させられる。構文はスキーマつきのツール使用で固定し、意味の矛盾は検証と、エラーを添えた再試行で扱う。待ち時間が許されない仕事を、遅延の保証が無いバッチへ置かない。レビューは、書いた会話から切り離し、ファイル単位と横断に分ける。
30秒で全体像
「慎重に」は、どの指摘を捨てるかを定義しません。バグは報告し、局所的なスタイルは捨てる、と例つきで書きます。詳しい指示だけでは形式が揃わないとき、二個から四個の具体例が、新しい入力への一般化を起します。JSONの構文を最も確実に消すのは、スキーマを入力にしたツール使用です。スキーマは、合計が合わないといった意味の誤りを消しません。文書に無い値を必須にすると、モデルは埋めます。再試行が効くのは形式と構造で、ソースに情報が無いときは効きません。Message Batches API は費用をおよそ半分にできますが、処理は最大二十四時間で遅延の保証は無く、一つの依頼の途中でツールを往復できません。同じ会話での自己レビューは、生成時の理由が残っているので、独立した実行と、ファイルごとのパスに負けます。
用語
| 用語 | 意味 |
|---|---|
| 明示的な基準 | 報告する欠陥と捨てる指摘を、種類とコード例で定義したもの |
| few-shot | 判断と出力の形を見せる少数の具体例 |
tool_use |
スキーマどおりの引数をツール呼び出しとして返させ、構文を固定する使い方 |
| nullable | 文書に無い値を、作らず空で返してよい欄 |
other と詳細 |
既知の分類に収まらないものを、その他と自由記述で受ける型 |
| strict | スキーマに厳密に従わせ、構文の破れを拒否する仕組み。意味の正しさは別 |
| 意味的な検証 | 合計の不一致など、スキーマを通過したあとに残る矛盾 |
detected_pattern |
指摘を生んだコードの形。却下の集計に使う |
| Message Batches API | 費用を抑えた非同期処理。最大二十四時間、遅延の保証は無い |
custom_id |
バッチの依頼と応答、失敗の再送を対応づける識別子 |
| セルフレビュー | 生成したのと同じ会話で、その出力を見直すこと。前提が残る |
| マルチパス | ファイル単位の局所パスと、横断の統合パスを分ける見方 |
本編
基準が無いレビューは、好みを欠陥として報告する
「コメントの正確さを確認して」は、文体の好みまで指摘します。開発者は二回目から、正しいバグ指摘まで読み飛ばします。境界は、こう書きます。主張している挙動が、コードの実際の分岐と矛盾するときだけ指摘する。命名、空行、局所的な書き癖は捨てる。
「保守的に」「確信度が高いものだけ」は、この境界を作りません。モデルの自己申告は、難しいケースで過大なままです。確信度の数値でフィルタする前に、種類で線を引きます。
誤検知が多い種類は、正確な種類への信頼まで壊します。その種類の基準を直すあいだ、指摘対象から外してよいです。外しているあいだに直すのは、形容詞ではなく、その種類の正例と反例です。重大度も、段階ごとのコード断片で定義します。「高」という語だけだと、同じ欠陥が人によって別の段階になります。
具体例は、一致表ではなく一般化の材料
指示が長いのに形式がぶれるとき、効くのは few-shot です。個数の目安は二から四です。十件に増やすと、モデルは列挙した文面への一致に寄り、新しいファイルで沈黙するか、例の文言をコピーします。
各例には、もっともらしい代替ではなく、こちらを選んだ理由を短く添えます。「この依頼は注文番号を含むので参照であり、表示名だけなので顧客取得ではない」。理由が無い例は、表面の語だけを真似します。
レビューでは、許容されるコードと、本当の欠陥を対にします。対が無いと、例に似た正しいコードまで指摘します。対があると、似て非なる新しいファイルへも線が移ります。
抽出では、体裁の違いを例にします。本文中の引用と、末尾の参考文献一覧。方法の節と、本文に埋め込まれた条件。どこを見れば同じ欄が埋まるかを見せると、必須欄が空で返る頻度が下がります。ただし、文書にその情報が無いのに欄が必須なのは、例では埋まりません。空のままが正しいのに、例が常に値を見せていると、モデルは無い文書でも値を作ります。例の一つは、該当なしで null を返すものです。
出力の形も例で見せます。ファイル、行、重大度、修正案。自由文の例を見せながらスキーマを要求すると、モデルは自由文に戻ります。
構文はツールとスキーマ、意味はまだ残る
「JSONだけを出力して」と文章で頼むと、前置きの一文や、末尾のカンマでパーサが死にます。スキーマをツールの入力にし、tool_use の引数として受け取ると、構文の破れはAPIの側で拒否されます。受け取るプログラムは、ツール引数のオブジェクトをそのまま検証します。strict は、この拒否をさらに厳密にする仕組みです。通ったオブジェクトは形としてはスキーマに合います。中身の合計が声明と一致する保証ではありません。
tool_choice を抽出に引き直します。auto は文章を返し得ます。スキーマが複数で文書種が不明なら any にして、どれかのツールで必ず返させます。メタデータをエンリッチの前に通すなら、extract_metadata をそのターンだけ強制し、結果を見た次のターンで続きを選ばせます。
スキーマ設計は三つです。
文書に無いかもしれない情報は、任意かつ null を許します。必須にすると、モデルは欄を埋めるために近傍の数字を入れます。請求書に税額の行が無いとき、合計を税額へコピーするのがこの失敗です。
曖昧さ自体を値にします。判別不能は unclear です。「不明」を空文字にすると、未抽出と、読んだが判別不能が同じになります。
分類が増えるなら、other と詳細文字列です。enum を毎回拡張して未知を既存のどれかへ押し込むと、新しい種類が古い種類の件数に混ざります。
ソースの表記がぶれるとき、スキーマは「どの文字列を許すか」であり、日付の方言を理解するわけではありません。「和暦は西暦のISO日付へ揃えてから入れよ」という正規化を、プロンプトにスキーマと並べて書きます。
再試行は、材料があるときだけ効く
検証に落ちたら、次の依頼に三つを含めます。元の文書、失敗した抽出、検証器の具体的なメッセージ。「合計が明細と一致しない。声明は1000、計算は800」です。メッセージが無い再実行は、同じ出力を繰り返します。
効くのは、桁区切りの違い、欄の取り違え、閉じ括弧のような構造です。効かないのは、必要な数が別の文書にしか無いときです。その再試行は、無いものを作る圧力になります。記録を分けます。形式は再試行、不在は null のまま人手、です。
意味の検証はスキーマの外に足します。声明の合計と、明細から計算した合計を両方抜き、一致しなければ再依頼します。ソース同士が矛盾するなら conflict_detected を立て、どちらかを静かに捨てさせません。
レビュー指摘には detected_pattern を残します。開発者が却下したとき、どの形(空の catch、特定のコメント様式)が誤検知を生んだかを集計できます。却下を件数だけ捨てると、基準の改善が勘になります。
Pydantic のような検証器は、スキーマと、その後の意味の検査をコードで行い、失敗メッセージを次のプロンプトへ戻すための道具です。言語の文法が主題ではありません。検証器が黙って値を補正すると、モデルは誤りを学びません。補正せず、メッセージを返します。
バッチは、人を待たせない仕事だけ
Message Batches API は、同期の呼び出しより費用がおよそ半分です。その代わり、処理の窓は最大二十四時間で、遅延の保証はありません。多くの場合は早い、は、マージボタンの前で待っている人の保証になりません。
向くのは、夜間の報告、週次の監査、夜間のテスト生成です。マージ前の危険物チェックのように、結果が来るまで次へ進めない仕事は、同期のAPIです。両方をバッチへ移す提案は、費用の半分と、待ちの上限を同時に見て否にします。
バッチの一つの依頼は、途中でツールを実行して結果を戻し、続きを生成する、という往復ができません。ツール往復が必要なエージェントループを、バッチの一行に押し込めません。抽出のように、文書を渡して構造が返る単発は置けます。
依頼と応答は custom_id で結びます。失敗した文書だけを、その識別子で再送します。成功分まで投げ直すと、半分になった費用が戻ります。文脈に入らなかった文書は、分割してから再送します。同じ識別子のまま再送すると、どの版の失敗かがログで混ざるので、再送は新しい識別子にし、元の識別子を欄に残します。
大量投入の前に、数十件の見本でプロンプトとスキーマを直します。初回の失敗率が高いまま一万件を送ると、再送が本実行より高くなります。
送信の間隔は、約束した時間から逆算します。処理が最大二十四時間なら、到着から次の送信までの最悪の待ちと二十四時間の和が、約束の内側に要ります。三十時間の約束に対して四時間ごとに送ると、四足す二十四は二十八で、内側に収まります。間隔を六時間に広げると、上限いっぱいの処理と重なったときに約束を割れます。間隔は、約束から最大処理を引いた残りより短く取ります。
誰が、何パスで見るか
同じ会話の自己レビューは、生成のとき「この境界でよい」と判断した文が履歴に残っています。見直せと言われると、その判断を擁護します。思考を長くする指定も、同じ履歴の上で起きます。差分と基準だけを渡した、別の実行のほうが、前提を持たないので矛盾を見つけます。
十四ファイルを一つのパスで見ると、注意が一部に寄ります。あるファイルは詳細で、別のファイルは表面的、同じパターンを片方では指摘し片方では通します。ファイルごとの局所パスと、ファイルをまたぐデータの流れのパスに分けます。より大きい窓のモデルへ取り替えても、一度に配る注意の偏りは残ります。開発者に小さいプルリクエストを義務づけるのは、レビューの構造を直していません。三回実行して二回以上出たものだけ残す多数決は、たまにしか出ない本物の欠陥を、合意が無いという理由で落とします。
各指摘に確信度を添えるパスは、人へ回す優先の材料にはなります。その数値を確率として閾値に使う前に、ラベルの付いた集合で校正します。校正は次の章です。未校正の数値で自動マージしてはいけません。
基準の書き方を、短い規約として置く
レビュー用の規約は、次の密度で足ります。報告するのは、分岐がコメントや名前と矛盾する欠陥、認証の抜け、入力が検証されずに外部へ出る箇所。捨てるのは、インポートの順序、一行の長さ、既存ファイルに既にある書き癖。重大度の高は、本番のデータが誤った相手へ出る、または例外が握りつぶされて呼び出し元が成功に見える、という断片つきで定義します。中は、特定の入力でだけ結果が違うがデータは漏れない。低は報告しない、と書き切ります。低を残すと、モデルは低を埋めるために好みを報告します。
この規約を「丁寧に」へ戻すと、翌日の指摘はスタイルに戻ります。規約の変更は、捨てるリストを増やすか、報告の種類の反例を足すか、のどちらかで行います。
例は、代替を捨てた理由まで書く
ツール選択の例なら、依頼「A-19 の状態は」に対して注文参照を選び、顧客取得を捨てた理由は、識別子が注文番号の形だから、です。依頼「山田の住所」は顧客取得で、注文参照を捨てます。三例目は「山田の A-19」で、確認が先で、番号があっても顧客が未確認なら返金へ進まない、です。この三例は、番号の有無という表面ではなく、確認という状態を一般化します。
抽出の例の一つは、税額の行が無い請求書で、税額を null にし、合計は本文の数字のまま、です。この例が無いと、他の例がすべて税額を埋めているので、無い文書でもモデルは合計の一割を税額として作ります。
再試行の二通目に何が並ぶか
一通目は文書とスキーマです。検証が「明細の和 800、声明 1000」で失敗します。二通目は、同じ文書、一通目のオブジェクト、その一文です。モデルは差額の行を探すか、矛盾フラグを立てます。二通目に文書を入れ忘れると、モデルは失敗オブジェクトだけを見て、数字を声明に合わせにいきます。ソースが無い補正です。文書があるときだけ、行の読み落としを復元できます。
三通目でも同じ矛盾なら、それ以上の再試行は止め、conflict_detected のまま人手へ回します。再試行の上限は、形式の誤り用の小さい回数です。矛盾は上限を待たずに人手へ回してよいです。上限まで自動で回すと、モデルは三通目で数字を作ります。
バッチの失敗だけを戻す
百件に doc-001 から識別子を振り、夜間に送ります。朝、四件が文脈長で失敗し、九十六件は成功です。再送は四件をページで分割し、doc-014-p1 のように新しい識別子を付け、元の doc-014 を参照欄に残します。九十六件を同じバッチへ混ぜると、成功分の費用がもう一度かかり、同じ抽出が二版できます。下流は識別子で「この文書の最新の成功」を一枚に決めます。
マージ前のチェックをこのバッチへ「とりあえず入れて、遅かったら同期に落とす」は、落ちるまでの待ちがマージの待ちです。最初から同期に置きます。
ファイル単位のパスで、矛盾が消える様子
三ファイルに同じ空の catch があります。一つのパスでは、最初のファイルだけを「例外を消している」と書き、三番目は「既存の様式」と書きます。ファイルごとに同じ基準文を渡すと、三ファイルとも同じ重大度になります。そのあと横断パスは、catch が呼ぶ先のエラーが別サービスへ伝わるかを見ます。局所パスは様式を揃え、横断パスは影響の到達を見ます。一つのパスに両方を頼むと、様式の判断と影響の判断が同じ注意の中で入れ替わります。
指摘の信頼は、種類を一つ外すと戻ることがある
レビューが、正しいバグと、インポート順の好みを同じ一覧に出します。開発者は二回目から、一覧の先頭しか読みません。正確なバグ指摘が、好みの隣にあるだけで無視されます。
直すあいだ、好みの種類は指摘対象から外します。外す条件は「インポートの順序、一行の長さ、既存ファイルに既にある書き癖は書くな」です。「慎重に」では、どの種類が外れたかが残りません。戻すときは、その種類の正例と反例を足してからにします。正例は、分岐がコメントと矛盾する空の catch。反例は、プロジェクトに既にある同じ空の catch で、呼び出し元が失敗を見ているもの。対が無い反例のない禁止は、翌日に好みが戻ります。
重大度は段階の定義です。高は、本番のデータが誤った相手へ出る、または例外が握りつぶされて呼び出し元が成功に見える、というコードの断片つきです。中は、特定の入力で結果が違うがデータは漏れない。低は報告しない、と書き切ります。低を残すと、モデルは低を埋めるために好みを報告します。「高」という語だけだと、同じ空の catch が人によって別の段階になります。
確信度の自己申告は、この線の代わりになりません。難しいファイルほど、誤って高い数字が出ます。数値で自動マージする前に、種類の線と、後の章の校正が要ります。
請求書で、スキーマが創作を止めるところと止めないところ
欄は、請求番号、明細、税額、声明の合計、計算した合計、矛盾フラグ、です。
税額は null を許します。必須にすると、税額の行が無い請求書で、モデルは合計の一部を税額へコピーします。例の一つは、税額の行が無い文書で税額を null、合計は本文の数字のまま、です。他の例がすべて税額を埋めていると、この例が無いだけで創作が戻ります。
判別できない通貨は空文字ではなく unclear です。空文字は、まだ読んでいない欄と区別できません。知らない費目は、既存の enum へ押し込めず、other と詳細文字列です。押し込むと、新しい種類が古い種類の件数に混ざります。
「JSONだけ」と文章で頼むと、前置きと末尾のカンマでパーサが死にます。スキーマをツールの入力にし、tool_use の引数として受け取ると、構文の破れは拒否されます。strict は、この形の拒否をより厳密にします。通ったオブジェクトの合計が、明細と一致する保証はありません。
意味の検査はスキーマの外です。声明の合計と、明細から足した合計を両方抜き、違えば conflict_detected を立てます。どちらかを静かに声明へ合わせるのは、検証器が値を補正しているのと同じです。Pydantic のような道具は、落ちた理由の文を次のプロンプトへ戻すために使います。黙って桁を直すと、モデルは誤りを知りません。
表記のゆれはスキーマが理解しません。「和暦は西暦のISO日付へ揃えてから入れよ」を、プロンプトにスキーマと並べて書きます。
再試行の二通目に、何が揃っていないと数字を作るか
一通目は文書とスキーマです。検証の文は「明細の和 800、声明 1000」です。
二通目に揃えるのは三つです。同じ文書、一通目のオブジェクト、その一文。モデルは差額の行を探すか、矛盾フラグを立てます。文書を入れ忘れると、失敗オブジェクトだけを見て、数字を声明に合わせます。ソースが無い補正です。メッセージを入れ忘れると、同じオブジェクトを繰り返します。
三通目でも同じ矛盾なら、再試行は止めます。形式の誤り(閉じ括弧、桁区切り)は小さい回数だけ自動で戻してよいです。矛盾は、回数を待たずに人手です。上限まで自動で回すと、三通目でモデルは無い行を作ります。
情報が別の文書にしか無いときも、再試行は創作の圧力です。記録を分けます。形式は再試行、不在は null のまま人手、です。
バッチの窓を、時刻で置く
処理の上限は二十四時間、約束は到着から三十時間以内に結果、です。最悪は、送信の直前に届いた文書が、処理の上限いっぱいを使う場合です。四時間ごとに送ると、待ちの四時間と処理の二十四時間で二十八時間になり、約束の内側です。六時間ごとに送ると、六と二十四で三十を超えます。間隔は、約束から最大処理を引いた残りより短く取ります。多くの場合は早い、は、この最悪の計算に入れません。
百件の識別子は doc-001 からです。朝、四件が文脈長で失敗し、九十六件は成功です。再送は四件をページで分割し、doc-014-p1 のような新しい識別子を付け、元の doc-014 を参照欄に残します。九十六件を混ぜると、成功分の費用がもう一度かかり、同じ抽出が二版できます。下流は、文書ごとに最新の成功を一枚に決めます。
大量の前に、数十件で失敗率を見ます。初回の失敗率が高いまま一万件を送ると、再送が本実行より高くなります。
マージの前に終わる必要がある危険チェックは、この窓に置きません。バッチは遅延の保証が無く、一つの依頼の途中でツールを往復できません。夜間の報告と週次の監査のように、人が待っておらず、文書を渡して構造が返る単発だけを置きます。遅いときだけ同期へ落とす切替は、用途を分ける前の複雑さです。最初から同期に置きます。
費用がおよそ半分になるのは、この制約を飲んだ仕事だけです。半分を先に見て、待ちの上限を見ない提案は、マージの待ちをバッチの待ちに変えます。
一つの空の catch が、パスを分けると判定が揃う
三つのファイルに、同じ空の catch があります。一つのパスに十四ファイルを渡すと、最初のファイルは「例外を消している」と書かれ、三番目は「既存の様式」と書かれます。モデルが怠慢なのではありません。一度に配れる注意が、先に読んだファイルへ寄ります。
ファイルごとに同じ基準文を渡すと、三ファイルとも同じ重大度になります。そのあと横断のパスは、その catch が別サービスの呼び出し元で成功に見えるかを見ます。局所は様式を揃え、横断は影響の到達を見ます。一つのパスに両方を頼むと、様式の判断と影響の判断が入れ替わります。
より大きい窓のモデルへ替えても、一度に配る偏りは残ります。提出を三ファイルに限る規則だけを足しても、レビューのパスは一つのままです。三回実行して二回以上出たものだけ残すと、たまにしか出ない本物の欠陥が、合意が無いという理由で落ちます。
指摘には detected_pattern を残します。開発者が却下したとき、空の catch が誤検知の源だと集計できます。却下を件数だけ捨てると、基準の改善が勘になります。
同じ会話でこのレビューをさせると、生成のとき「この catch は意図的」と書いた文が履歴に残っています。見直せと言われると、その文を擁護します。差分と基準だけを渡した別の実行は、その文を持っていません。
例は、捨てた代替が書いてあるときだけ一般化する
例が四を超えて十に近づくと、モデルは列挙した文面への一致に寄り、新しいファイルで沈黙するか、例の文言をコピーします。二から四に抑え、各例に、もっともらしい代替を捨てた理由を一行添えます。
依頼「A-19 の状態は」は注文参照で、顧客取得を捨てます。理由は、識別子が注文番号の形だからです。依頼「山田の住所」は顧客取得です。「山田の A-19」は、番号があっても確認が先で、未確認なら返金へ進まない、です。この三例は、番号の有無という表面ではなく、確認という状態を一般化します。理由の無い例は、表面の語だけを真似します。
出力の形も例で見せます。ファイル、行、重大度、修正案。自由文の例を見せながらスキーマを要求すると、モデルは自由文に戻ります。
どう判断するか
- 精度の第一手は、報告と非報告の種類と、段階ごとの例。自己申告の確信度や「慎重に」は境界の代わりにならない。
- 形式のぶれと曖昧な境界は、理由つきの例を二から四。例の一つは、情報が無いときの null。
- 構文はスキーマつき
tool_use。意味の矛盾は検証。無い欄は null。未知の分類はotherと詳細。 - 再試行に含めるのは文書、失敗結果、検証メッセージ。情報がソースに無い再試行はしない。
- バッチは、人を待たせず、ツール往復も不要な仕事。失敗は識別子単位。間隔は、約束から最大処理を引いた残りより短く。
- レビューは別実行。多数ファイルは、ファイル単位のあと横断。多数決と、より大きい窓は注意の偏りを直さない。
確認
問1
自動レビューの誤検知が多く、正しい指摘まで無視され始めています。最初に直すものはどれですか。
A. 「確信度が高いものだけ」と足す
B. 報告する欠陥と捨てる指摘を、種類とコード例で定義する
C. 文章の否定的な調子でレビュー対象を決める
D. 三回実行し、二回以上出た指摘だけ残す
解答
B。自己申告、感情、多数決は、何が欠陥かの定義を残したままです。
問2
文書種が事前に分からず、抽出スキーマが二つあります。構造で必ず受け取りたい。tool_choice はどれですか。
A. auto
B. any
C. ツールを定義せず、文章でJSONを依頼する
D. バッチの custom_id
解答
B。種が不明で、どれか構造で返すなら any です。特定の一段を先に通すなら強制です。auto は文章を返し得ます。
問3
合計欄が明細と一致しない抽出が、スキーマ検証は通過しています。次の一手はどれですか。
A. スキーマが通ったので採用する
B. 声明の合計と計算した合計を比べ、不一致のメッセージを添えて再依頼する
C. 同じプロンプトを、メッセージなしで再実行する
D. 必須欄を増やし、欠落を埋めさせる
解答
B。これは意味の誤りです。必須欄の追加は、無い値の創作を誘います。
問4
夜間の負債レポートと、マージの前に終わらせたい危険チェックがあります。費用を下げるために両方をバッチへ移す提案を、どう評価しますか。
A. 夜間のレポートだけバッチにし、危険チェックは同期のままにする
B. 両方をバッチにする。たいてい朝までに終わる
C. 識別子で対応づけられないので、夜間も同期にする
D. 遅いときだけ同期へ落とす切替を、用途を分ける前に作る
解答
A。バッチに遅延の保証はありません。対応づけは custom_id でできます。切替の複雑さは、用途を分けるより先ではありません。
問5
十四ファイルを一つのパスでレビューすると、深さがばらつき、同じパターンの判定が矛盾します。どう分けますか。
A. ファイルごとの局所パスと、横断のデータの流れを見る別パス
B. より大きい窓のモデルに替え、一つのパスを維持する
C. 提出を三ファイルに分割する規則だけを足し、レビューの構造は変えない
D. 独立に三回実行し、二回以上のものだけ採用する
解答
A。原因は一度に配れる注意の偏りです。窓の大きさ、提出の義務、多数決は、パスの入力を小さくしません。
自分で確かめる
欠けた欄がある文書と、欄が揃った文書を用意し、税額を必須にしたスキーマと、null を許したスキーマで、無い税額が創作されるかを比べてください。検証失敗の再依頼に、文書と失敗結果とメッセージを含めた場合と、プロンプトだけの再実行で、同じ誤りが残る回数を数えます。最後に、十四に分けたファイルを一つのプロンプトで読ませた指摘と、ファイル単位のあとに横断させた指摘で、同じパターンの判定が矛盾する箇所を数えます。