TypeSafe AIのJevは、文章を書かない判定特化モデルです。入力は state(判定材料)と typed な質問、出力は選択肢・スコア・確率だけ。料金は入力100万トークンあたり $0.042、出力は無料。応答はおおよそ70〜500msです。
発表直後から「LLMの100倍速い判定器」として語られがちですが、現場で効くかどうかはモデル名より 何を渡すか で決まります。この記事では、料金と比較の整理に加えて、state設計と質問(いわゆるプロンプト)の具体例まで落とします。
1. Jevがやること、やらないこと
やること:
- 与えられた状態について、事前に定義した質問に答える
-
Choice(N個から1つ)、Score(段階評価)、Noul(yesの確率)の3種だけ返す - 複数質問を同じstateに対して並列評価する
やらないこと:
- メール文、要約、理由説明、コード生成
- 画像入力
- 顧客データでのファインチューン
英語が主学習言語で、日本語は動くが英語ほど強くない、と公式が書いています。顧客リクエストは学習に使わず、ドメイン知識は毎回のstateとcriteriaに書け、という立場です。学習データ規模とパラメータ数は未公開です。
2. 料金感
| 使い方 | ざっくり費用 |
|---|---|
| 1回(入力500トークン程度) | 約 $0.000021 |
| サポート分類100万件(1件500トークン) | 約 $21 |
| チェス1局(実測報告) | 約 $0.0015 |
質問文と選択肢の説明も入力トークンに入ります。同じ本文を何度も送るより、1リクエストに質問をまとめた方が安く速いです。早期アクセスでは月$5クレジットの報告もあります。
他の判定手段と並べるとこうなります。
| ルール / 決定木 | 学習済み分類器 | 安価LLM | Jev | |
|---|---|---|---|---|
| ラベル変更 | コード | 再学習 | プロンプト | 質問を書き換える |
| 学習データ | 不要 | 必要 | 不要 | 不要 |
| 遅延 | μs〜ms | ms | 数百ms〜秒 | 70〜500ms |
| 単価 | ほぼ0 | ほぼ0 | 高め | 安いが0ではない |
| 説明文 | 強い | 中 | 出せる | 出せない |
「全部Jev」は過剰です。確定できることはコード、曖昧な文章判断だけJev、自信が低いものだけLLMか人、が基本形です。
3. 決定木で足りるなら、Jevは不要
金額閾値、ステータス分岐、正規表現、合法手生成は決定木とコードの勝ちです。Jevが必要なのは、入力が自然文で、ラベルをその場の文章で定義したいときです。
オセロや将棋も同じです。Jevはゲームエンジンではありません。盤面ASCIIだけ渡すと弱く、コードが計算した事実(取る、角、王手)をstateに書くと一気に上がります。チェスではFENだけだとランダムより悪い報告すらあります。探索が必要なら、Jevの確率をMCTSの方策にするのが筋です。
つまりJevは決定木の上位互換ではなく、決定木の手前に置く 文章用センサー です。
4. 設計原則: コードが主、Jevは部品
公式の建て付けも明確です。
- 制御フロー、確定ルール、副作用はコード
- 広い判断は狭い質問に分解する
- 関連する材料だけをstateに入れる
- 同じstateに質問をたくさん載せ、答えはコードで合成する
ルールで切れるもの
→ 残った曖昧さだけ Jev
→ 高自信: 自動
→ 低自信: LLM または人
コンテキスト上限は、リクエスト全体64kトークン、state + 最長の1質問 が32kです。関係ない履歴を積むと精度が落ちます(いわゆるcontext rot)。
5. state設計
stateは文字列でもJSONでも配列でもよいですが、実務では 名前付きオブジェクト が基本です。質問から `ticket.message` のようにパスで指せるからです。
載せるもの:
- 判定対象の本文
- 比較に必要なレコード(注文、契約、盤面)
- コードが既に計算した事実
- その判断に使うポリシーの該当箇所だけ
載せないもの:
- 全履歴、全社規定の全文、関係ないメタデータ
- モデルに数えさせたい生の表(先に集計する)
- 質問文そのもの(質問は
questions側)
悪いstate
{
"text": "二重課金されて返してほしい。注文A-104。あとパスワードもリセットしたい。"
}
本文だけだと、課金とアカウントが混ざります。ポリシーも注文事実もありません。
良いstate(返金トリアージ)
{
"ticket": {
"subject": "Duplicate charge",
"message": "I was charged twice for order A-104. Please refund the duplicate. Also reset my password."
},
"order": {
"id": "A-104",
"charges": [
{"amount_usd": 49, "status": "captured"},
{"amount_usd": 49, "status": "captured"}
],
"distinct_captured_count": 2,
"duplicate_same_amount": true
},
"customer": {
"plan": "pro",
"open_orders": ["A-104"]
},
"refund_policy": "Duplicate captured charges of the same amount on one order are refundable."
}
distinct_captured_count と duplicate_same_amount はコードが先に計算しています。Jevに「何件あるか数えて」と頼まない。
社内問い合わせ(日本語)
{
"subject": "PCの入れ替えについて",
"body": "来月の異動に合わせてPCとアカウントを移したいです。",
"requester_department": "営業部",
"known_facts": {
"mentions_transfer": true,
"mentions_outage": false,
"has_desired_date": false
}
}
日本語本文はそのまま載せつつ、正規表現やキーワードで取れる事実はフラグにします。Jevは「窓口はどこか」「情報不足か」だけ見ます。
オセロ(ゲーム)
{
"game": "othello",
"side": "black",
"board": "...ASCII...",
"legal_moves": ["c4", "d3", "e6"],
"facts": {
"c4": {"flips": 3, "is_corner": false, "is_edge": true, "gives_corner": false},
"d3": {"flips": 1, "is_corner": false, "is_edge": false, "gives_corner": true},
"e6": {"flips": 2, "is_corner": false, "is_edge": false, "gives_corner": false}
}
}
合法手と特徴はプログラム。Jevは Choice で1手選ぶだけ。将棋なら候補を255以下に切る必要があります。
6. 質問(プロンプト)の最適化
Jevの「プロンプト」はチャット文ではなく、instructions と criteria です。キー名はモデルに送られません。質問はそれぞれ独立で、互いの答えを文脈にしません。
型の使い分け
| 欲しいもの | 型 |
|---|---|
| 窓口・カテゴリ・次アクション | Choice(最大255) |
| 緊急度・影響度・品質 | Score(2〜10段階) |
| 返金希望か、PIIがあるか | Noul |
Noulの0.5は「中くらいの緊急」ではありません。yes/noが拮抗しているだけです。程度が欲しいならScoreにします。
Scoreの段階は「やや高い」ではなく、照合できる状況で書きます。「回避策がある機能障害」はよく、「中程度」は悪い。
悪い質問
{
"what_to_do": {
"type": "choice",
"instructions": "適切に対応して",
"criteria": {
"refund": null,
"reply": null,
"ignore": null
}
}
}
判断が1つに畳まれ、境界も例もありません。確率が均等に散ったら、モデルが弱いのではなく基準が重なっています。
良い質問(分解)
{
"refund_requested": {
"type": "noul",
"instructions": "Does `ticket.message` request a refund?",
"criteria": {
"true": "Asks to return money or reverse a charge",
"false": "Complains or asks options, but does not request money back"
}
},
"policy_supports_refund": {
"type": "noul",
"instructions": "Does `refund_policy` cover this case given `order.duplicate_same_amount`?"
},
"topic": {
"type": "choice",
"instructions": {
"question": "Which team should handle `ticket.message`?",
"focus": "Primary request only. Ignore secondary asides."
},
"criteria": {
"billing": {
"what": "Charges, invoices, refunds, subscriptions",
"not_for": "Password, login, or device setup",
"examples": ["I was charged twice", "Where is my refund?"]
},
"account": {
"what": "Password, login, access",
"not_for": "Money movement",
"examples": ["Reset my password"]
},
"orders": {
"what": "Delivery and tracking",
"not_for": "Refund of a captured charge"
}
}
},
"business_impact": {
"type": "score",
"instructions": "Impact on the customer's ability to use the product",
"criteria": [
"Can use the product normally",
"Workaround exists; some work is slower",
"Blocked; cannot complete a core action"
]
}
}
ポイント:
- 1質問1判断
-
`path`で参照先を固定する - Choiceは
what/not_for/examplesで隣のラベルと対比する - Noulは「yesが高い=起きてほしい事象」に揃える。エスカレーション検知なら「問題あり」を true にする
- 合成はコード。重みを変えるときにプロンプトを書き換えない
answers = res.answers
auto_refund = (
answers["refund_requested"].noul >= 0.85
and answers["policy_supports_refund"].noul >= 0.85
and answers["topic"].choice == "billing"
and answers["topic"].confidence >= 0.7
)
よく効く書き換え
- 「分類して」→「主目的はどれか。ついでに触れた話題は無視」
- ラベル名だけ → 対象外と具体例
- 長い1問 → 3つのNoul + コードのAND/OR
- Scoreで数値の精密な内挿を期待しない。閾値判定だけ使う(jev-1.13の既知の癖)
- Noulで取った閾値を、同じ内容のChoiceに流用しない。相対選択と絶対yes/noは別物
同じ質問を15回投げて分布が散るなら、基準が曖昧です。criteriaを先に直します。
7. 自信の使い方
ChoiceとScoreは confidence を返します。分布が尖っていれば高く、平坦なら低い。Noulは別のconfidenceを持たず、0か1に近いかで見ます。
実務の初期値:
- 高自信: 自動処理
- 中: 下書きだけ作って人へ
- 低: LLMか担当者
閾値は自前データで決める。公式の校正主張は、自分の分布では未検証として扱うのが安全です。
8. 最小の実装イメージ
def triage(ticket, order, policy):
if ticket["status"] == "closed":
return "no_action"
facts = {
"duplicate_same_amount": duplicate_charge(order),
}
state = {
"ticket": {"message": ticket["message"]},
"order": {**order, **facts},
"refund_policy": policy["refund_excerpt"],
}
res = client.system_one(state=state, questions=QUESTIONS)
a = res.answers
if a["topic"].confidence < 0.55:
return "human"
if a["topic"].choice == "billing" and facts["duplicate_same_amount"]:
if a["refund_requested"].noul > 0.85:
return "auto_refund"
return a["topic"].choice
QUESTIONSは設定ファイルとしてバージョン管理します。プロンプト変更はモデル変更と同じくらい本番影響があります。
9. 向き不向きのチェックリスト
向く:
- ラベルを先に列挙できる
- 呼び出し回数が多い
- ルールだけでは表現の揺れを拾えない
- 間違えても回収できる
向かない:
- 返信文や理由が必要
- ラベルが毎回変わる創造的な仕事
- すでにきれいな特徴量と教師データがある(分類器の方が安い)
- 計算そのもの(探索、集計、権限)
まとめ
Jevの本体は重みではなく、毎回のリクエストです。
- コードで確定させる
- 残った判断に必要な事実だけstateに載せる
- 質問を原子に分解し、基準で境界を書く
- 確率はコードで合成し、低い自信は逃がす
モデルを「賢く使う」より、判定仕様をデータ構造にする作業です。そこまでやると、決定木でもLLMでもなく、Jevを挟む意味が出ます。