Jev Recipe / 出力契約比較
Jev vs JSON Mode:型付き意思決定と制約付き生成の比較
json_mode が保証するのは「有効な JSON」であって「正しい答え」ではありません。リトライコスト・レイテンシ・出力課金・較正済み信頼度を、Jev のゼロ生成型付き呼び出しと対比します。
JSON mode をやめる前の 6 つのチェック
{
"intent": {
"type": "choice",
"instructions": "この受信メッセージの種別を判定する",
"criteria": {
"billing": "支払い・請求・返金関連",
"technical": "製品の不具合やバグ",
"sales": "購入・アップグレード・価格の相談",
"abuse": "安全性または悪用の報告"
}
},
"is_actionable": {
"type": "noul",
"instructions": "このメッセージはチームの対応が必要か、それとも単なる情報共有か?"
},
"priority": {
"type": "score",
"instructions": "対応優先度を評価、1(空いたときで)から 5(手持ちを止めて即対応)"
}
}出力契約:Jev の型付き決定ヘッド vs json_mode / structured outputs
コード対照:制約付き生成 vs Jev 型付き呼び出し
import json
import time
from openai import OpenAI
client = OpenAI()
VALID_QUEUES = {"billing", "technical", "sales", "abuse"}
MAX_RETRIES = 3
def route_ticket(ticket_text: str) -> dict:
for attempt in range(MAX_RETRIES):
resp = client.chat.completions.create(
model="gpt-4o-mini",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": 'Reply as JSON: {"queue": "...", "urgent": true|false}'},
{"role": "user", "content": ticket_text},
],
)
payload = json.loads(resp.choices[0].message.content) # json_mode: 必ずパースできる
if payload.get("queue") in VALID_QUEUES: # 値の検証: json_mode はここに何も言えない
return payload
time.sleep(2 ** attempt) # 幻覚した列挙値 -> 生成全体を再請求
raise ValueError("queue never converged")
# 典型経路: 試行ごとに 500-1500ms、リトライのたびに 20-60 出力トークンを請求import requests
JEV_ENDPOINT = "https://api.typesafe.ai/v1/jev/evaluate"
AUTO_ROUTE_CONFIDENCE = 0.85
QUESTIONS = {
"intent": {
"type": "choice",
"instructions": "この受信メッセージの種別を判定する",
"criteria": {
"billing": "支払い・請求・返金関連",
"technical": "製品の不具合やバグ",
"sales": "購入・アップグレード・価格の相談",
"abuse": "安全性または悪用の報告",
},
},
"is_actionable": {
"type": "noul",
"instructions": "このメッセージはチームの対応が必要か?",
},
"priority": {
"type": "score",
"instructions": "対応優先度を評価、1(空いたときで)から 5(手持ちを止めて即対応)",
},
}
resp = requests.post(
JEV_ENDPOINT,
json={"state": {"message": "..."}, "questions": QUESTIONS},
timeout=5,
)
resp.raise_for_status()
data = resp.json()
if data["intent"]["confidence"] >= AUTO_ROUTE_CONFIDENCE:
lane = f"auto:{data['intent']['answer']}" # 約70-100ms、入力トークンのみ、ゼロリトライ
else:
lane = "review"import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const RouteDecision = z.object({
queue: z.enum(["billing", "technical", "sales", "abuse"]),
urgent: z.boolean(),
});
const client = new OpenAI();
const resp = await client.chat.completions.create({
model: "gpt-4o-mini",
response_format: zodResponseFormat(RouteDecision, "route_decision"),
messages: [{ role: "user", content: ticketText }],
});
const decision = RouteDecision.parse(
JSON.parse(resp.choices[0].message.content!),
);
// 形状は保証される。"queue" が正しいキューか——そしてモデルがどれだけ
// 確信しているか——は表現できない。手に入るのは推測であって、較正された判断ではない。const JEV_ENDPOINT = "https://api.typesafe.ai/v1/jev/evaluate";
const AUTO_ROUTE_CONFIDENCE = 0.85;
const QUESTIONS = {
intent: {
type: "choice",
instructions: "この受信メッセージの種別を判定する",
criteria: {
billing: "支払い・請求・返金関連",
technical: "製品の不具合やバグ",
sales: "購入・アップグレード・価格の相談",
abuse: "安全性または悪用の報告",
},
},
is_actionable: {
type: "noul",
instructions: "このメッセージはチームの対応が必要か?",
},
priority: {
type: "score",
instructions: "対応優先度を評価、1(空いたときで)から 5(手持ちを止めて即対応)",
},
} as const;
const resp = await fetch(JEV_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
state: { message: ticketText },
questions: QUESTIONS,
}),
});
const data = await resp.json();
const lane =
data.intent.confidence >= AUTO_ROUTE_CONFIDENCE
? `auto:${data.intent.answer}`
: "review"; // 低信頼帯・安全フラグ -> 同じレビューキューへJev vs JSON Mode FAQ
JSON mode とは何ですか?
OpenAI のチャット補完機能——response_format: {"type": "json_object"}——で、現在は主要プロバイダのほとんどが同等機能を提供しています。モデルを構文的に有効な JSON のみを出力するよう制約します:markdown のフェンスなし、前後の散文なし。ただし保証されるのはパース可能性だけです。キー、列挙値、そして答えの正しさはモデルの推測のまま——だから本番コードは今も json_mode 呼び出しをスキーマ検証とリトライループで包んでいるのです。
JSON mode と structured outputs は同じものですか?
いいえ。JSON mode(json_object)は有効な JSON 構文を保証します。structured outputs(json_schema)はさらに進んで、制約付きデコーディングによって schema に一致する形状を強制します。しかし両方ともペイロードをトークン単位で生成し続けます:レイテンシは出力長に比例し、出力トークンは課金され、値の正しさは保証されません。structured outputs は形状のギャップを埋めますが、判断品質のギャップは開いたままです。
JSON が有効なのに、なぜパイプラインは壊れ続けるのですか?
規模化したときに難しいのはパース可能性ではなく、値の正しさだからです。schema に適合しながら列挙値を幻覚した返答、「もっともらしいが誤った」ルーティング、欠落したフィールド——きれいにパースできてもアプリケーションは失敗する。そのたびに検証リトライが走り、生成全体を再請求される。実測の failure 率 × 1 呼び出しの出力コスト × QPS を掛け算してください。それが「較正なしの推測」の値札です。
json_mode や structured outputs から信頼度スコアを取得できますか?
判断に使える形では取得できません。logprob はサンプリング分布のもとで各トークンが生成されやすかった度合い——タイプする自信の尺度であり、判断の正確さの尺度ではありません。高いトークン確率で出力されたルーティングラベルでも、判断としては誤り得ます。Jev の確率は結果に対して RLCD 較正されており、0.85 のしきい値は精度の契約として振る舞います。この性質こそが、数値に対する自動化を安全にするものです。
Jev の代わりに JSON mode を使い続けるべきときは?
ペイロードに自由形式の生成コンテンツが必須のとき:要約、説明、可変長リスト、抽出した散文、テキストフィールドを含むネストしたオブジェクト。Jev の決定ヘッドは有界な値しか返せません——段落は書けません。本番のパターンは作業を分割することです:有界な質問(ルーティング・ゲート・スコアリング・yes/no)には Jev が約 95ms の1呼び出しで答え、制約付き生成の呼び出しが生成フィールドを埋める。
Instructor や OpenAI の Decision API(Luna)とはどう違いますか?
同じ問題の異なるレイヤーです。Instructor は生成を Pydantic 検証とリトライループで包むライブラリ——その軸は Jev vs Instructor 比較を。json_mode と structured outputs は API レベルでの生成への制約——このページです。OpenAI の GPT-6 Luna ベース Decisions API は別の非生成製品で、事前定義された回答集合から1つの答えと信頼度を返します——契約レベルの比較は Jev vs OpenAI Decision API を。どこでも矢印の向きは同じです:生成テキストのパースから離れ、型付き判断へ向かう。