Jev Recipe / アーキテクチャ比較

Jev vs Instructor:構造化出力の 2 つの設計

最終更新日: 2026-11-12

判断という有限の意思決定には Jev、豊かな構造の生成・抽出入力には Instructor。エンドポイント、公式 SDK のコード、トレードオフを 2026-11-12 に確認した内容で並べます。

広告

Instructor から Jev への移行 3 ステップ

01Instructor の Pydantic / Zod モデルを、等価な Jev の契約に翻訳します。キューは Choice、度合いは Score、はい/いいえは Noul です。
02「生成 → パース → 検証 → 再試行」のループを 1 回の client.systemOne() に置き換えます。単一のフォワードパスで、設問ごとの型付き答案と確率が返ります。
03confidence のしきい値は業務コード側に置いて分岐させます。指数バックオフの再試行でフォーマットエラーを覆い隠すのではなく、です。
schema / 共通意思決定コントラクト
{
  "routing": {
    "type": "choice",
    "instructions": "チケットを正しいキューへ振り分ける",
    "criteria": {
      "billing": "決済、返金、インボイス",
      "technical": "製品不具合や設定トラブル",
      "sales": "購入相談や見積もり"
    }
  }
}
このスキーマは Instructor Pydantic モデルと等価であり、Playground でゼロリトライ判定を検証できます。

アーキテクチャ:契約優先 vs 生成してから検証

METRIC
Jev
Instructor / Guardrails
何を生成するか
テキストを生成しません。宣言した選択肢を採点し、設問ごとに型付き答案を 1 つ返します。
JSON テキストを生成し、Pydantic / Zod モデルで検証します。
出力トークン費用
なし。TypeSafe は入力トークンのみ課金(2026-11-12 時点 $0.042/M)。
フル生成課金:捨てられた再試行分も含め、出力トークンすべてに支払います。
レイテンシ
単一フォワードパスで自己回帰デコードなし。TypeSafe は SLA を公開していないため自分の経路で実測してください。
モデルと応答長に完全に依存します。自分の schema とプロバイダーで実測してください。
失敗の形
答案は必ず宣言した選択肢のいずれか。設計すべき失敗は「信頼度が低い」ことです。
検証が失敗すると再試行ループに入ります。出力長と入れ子の深さが失敗率を左右します。
信頼度
設問ごとの確率分布と confidence。ただし自分のラベルでの較正は別途必要です。
モデルの自己申告(ある場合)。そのままゲートに使える確率ではありません。
Schema 表現力
Choice(最大 255 選択肢)、Score、Noul、画像領域の Box。答案はフラットな値で、入れ子文書ではありません。
任意の入れ子 schema、長い文字列、オブジェクト配列——それが存在理由です。

コード対照:リトライループ vs ゼロリトライ型呼び出し

python / instructor リトライループ
import instructor
from openai import OpenAI
from pydantic import BaseModel

class RouteDecision(BaseModel):
    queue: str

client = instructor.from_openai(OpenAI())

def route_ticket(ticket: str) -> RouteDecision:
    return client.chat.completions.create(
        model="gpt-4o-mini",
        response_model=RouteDecision,
        max_retries=3,
        messages=[{"role": "user", "content": ticket}],
    )
python / typesafe-sdk による型付き判定
from typesafe_sdk import Choice, TypeSafeClient

client = TypeSafeClient(model="jev-latest")

def route_ticket(ticket: str) -> dict:
    response = client.system_one(
        state=ticket,
        questions={
            "routing": Choice(
                instructions="チケットを正しいキューへ振り分ける",
                criteria={
                    "billing": "決済、返金、インボイス",
                    "technical": "製品不具合や設定トラブル",
                    "sales": "購入相談や見積もり",
                },
            ),
        },
    )

    routing = response.choices["routing"]
    return {
        "queue": routing.choice,           # 必ず宣言した選択肢のいずれか
        "confidence": routing.confidence,  # ゲートに使う前に較正する
        "probabilities": routing.probabilities,
    }
typescript / @typesafe-ai/sdk による型付き判定
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient({ defaultModel: "jev-latest" });

export async function routeTicket(ticket: string) {
  const { answers } = await client.systemOne({
    state: ticket,
    questions: {
      routing: choice("チケットを正しいキューへ振り分ける", {
        billing: "決済、返金、インボイス",
        technical: "製品不具合や設定トラブル",
        sales: "購入相談や見積もり",
      }),
    },
  });

  return {
    queue: answers.routing.choice,           // 必ず宣言した選択肢のいずれか
    confidence: answers.routing.confidence,  // ゲートに使う前に較正する
  };
}

コストと統合の継続評価