AIの出力をJSONとして受け取る場合は、構文だけでなく、必要な項目、型、選択肢を検査します。JSON Schemaは、その形式を定義して、受け入れられるデータかを判定するために使えます。
ただし、Schemaに合う値が事実として正しいとは限りません。「保守」という選択肢に収まっていても、入力が制作の相談なら分類は誤りです。形式の検査と、内容の確認を分けます。
小さなSchemaから作る
次は問い合わせ分類の説明用Schemaです。実際の顧客データは含みません。categoryとreasonを必須にし、定義していない項目は受け付けません。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"category": {"type": "string", "enum": ["制作", "保守", "判断保留"]},
"reason": {"type": "string", "minLength": 1}
},
"required": ["category", "reason"],
"additionalProperties": false
}
これはアプリ側の検査用です。APIへ同じSchemaをそのまま送れるかは、対応するモデルとSchemaの範囲で確認します。OpenAIの構造化出力とGeminiの構造化出力は、それぞれ対応範囲と制約が説明されています。
Pythonで検査する
以下はjsonschemaライブラリが導入されている環境で動かす例です。Schemaをschema.jsonとして保存してから使います。検査対象は架空のデータです。
import json
from pathlib import Path
from jsonschema import Draft202012Validator
schema = json.loads(Path("schema.json").read_text(encoding="utf-8"))
Draft202012Validator.check_schema(schema)
validator = Draft202012Validator(schema)
def validation_issues(value):
return [
{"path": list(error.absolute_path), "rule": error.validator}
for error in validator.iter_errors(value)
]
sample = {"category": "保守", "reason": "既存ページの修正相談"}
print(validation_issues(sample))
Schema自体をcheck_schemaで確認し、iter_errorsで入力の不一致を列挙しています。呼び方はjsonschemaの公式資料で確認できます。上の例では、不一致がなければ空のリストになります。
エラーの全文には検査した値が入る場合があるため、この例では場所と規則だけを返しています。ログへ残す情報は、利用するデータに合わせて決めます。
正常例だけで終わらせない
| 入力の違い | このSchemaで期待する判定 |
|---|---|
| categoryとreasonが正しい | 形式上は受け入れる |
| categoryが「その他」 | enumの不一致 |
| reasonが欠けている | 必須項目の不足 |
| reasonが空文字 | 長さの不一致 |
| extraという項目がある | 未定義の項目 |
| オブジェクトではなく配列 | 型の不一致 |
reasonが空白だけの場合、このSchemaのminLengthは通ります。文章として理由があるかを確認したいなら、業務用の検査も加えます。日時やメールなどのformatも、ライブラリの設定によって検証の方法が変わるため、名前を付けただけで確認済みにはしません。
不一致を自動で隠さない
余分な項目を黙って削除したり、不明な分類を適当な値へ直したりすると、AIがどこで失敗したか分からなくなります。元の処理IDとエラー区分を残し、再生成か人の確認へ回します。再生成の回数と費用にも上限を設けます。
形式検査を通った後は、入力と根拠を照合し、分類や要約の意味を点検します。APIの拒否や途中で終わった応答も、通常の結果として後続処理へ流さないようにします。
入力条件の伝え方は長文要約のプロンプト、人が確認する工程はAI文章の推敲手順も参考になります。
