文章を書かずに判断だけ返すモデル Jev を Workers AI で動かす

  • Jev
  • LLM

問い合わせのメールを読んで、急ぎかどうかを判定する。どの部署に回すかを決める。この手の仕事を LLM にやらせると、返ってくるのは {"urgent": true} のような短い JSON になる。

ただ、その一行を作るためにモデルがやっていることは、文章を書くときと変わらない。LLM は文字や単語のかたまり(トークン)を、先頭から一つずつ予測して並べていく。{ の次は "、その次は u、というふうに。一つ前まで出した内容を見て次を決めるので、この方式を自己回帰と呼ぶ。

欲しいのが真偽値ひとつでも、道のりは同じである。出力が長いほど時間がかかり、多くのサービスでは出力トークンにも課金される。JSON schema で形式を縛っても、一つずつ並べていること自体は変わらない。

Jev には、この並べる部分がない。

何を受け取って何を返すのか

TypeSafe が2026年9月に公開したモデルで、同社はこれを System One model と呼んでいる。名前は Kahneman の言うシステム1、速くて直感的なほうの思考から取っている。考え込まずに即答する側の役割、という位置づけになる。

渡すものは2つある。判断の材料になる文章(state)と、それについて何を聞きたいかの定義(questions)だ。返ってくるのは、質問ごとの数値だけ。文章は一文字も出てこない。

質問は3種類ある。

  • noul:そうである確率を 0 から 1 で返す。真偽を聞くときに使う
  • choice:用意した選択肢から一つ選び、どれがどれくらいの確率かも返す
  • score:「弱い、普通、強い」のような段階のどこに当たるかを、連続値で返す

noul は聞き慣れないが、TypeSafe が付けた名前で、真偽を確率で答える質問を指す。true か false ではなく 0.82 が返るので、boolean とは別物として名前を分けているのだと思う。

choice と score には confidence という数値も付く。これは「その答えがどれくらい確からしいか」を表す。選択肢の確率が 0.98 対 0.02 のように片方に寄っていれば高く、0.36 対 0.63 のように割れていれば低くなる。

Cloudflare には typesafe/jev というモデル ID で、他社製モデルとして組み込まれている。

Workers AI から呼ぶ

Cloudflare Workers でモデルを使うときは、設定ファイルに binding を1行書いておくと、コードから env.AI として触れるようになる(コード一式)。

{
  "name": "jev-eval-ja",
  "main": "src/index.ts",
  "compatibility_date": "2026-09-19",
  "ai": { "binding": "AI" }
}

呼び出しは、モデル ID と入力を渡すだけで終わる。

const response = await env.AI.run('typesafe/jev', { state, questions });

questions は、質問ごとに型と指示と判定基準を並べる。instructions が聞きたいこと、criteria がどう判断してほしいかの説明になる。

{
  is_urgent: {
    type: 'noul',
    instructions: 'Does this convey urgency?',
    criteria: { true: 'Explicitly time-sensitive', false: 'No urgency expressed' },
  },
  department: {
    type: 'choice',
    instructions: 'Which team should handle this?',
    criteria: {
      billing: 'Payments, invoicing, refunds',
      technical: 'Bugs, outages, integrations',
      sales: 'Pricing, upgrades, new accounts',
    },
  },
  frustration: {
    type: 'score',
    instructions: 'How frustrated is the customer?',
    criteria: ['Calm', 'Frustrated', 'Very angry'],
  },
}

state に Help! My payouts have been failing for 3 days. を入れて呼ぶと、こう返る。

{
  "is_urgent":   { "type": "noul", "noul": 0.95 },
  "department":  { "type": "choice", "choice": "billing",
                   "probabilities": { "billing": 0.98, "technical": 0.02 },
                   "confidence": 0.96 },
  "frustration": { "type": "score", "score": 0.65,
                   "probabilities": { "0": 0.36, "1": 0.63, "2": 0.01 },
                   "confidence": 0.43 }
}

score の 0.65 は、criteria に並べた3段階を 0、1、2 と見たときの位置を表す。0.65 なので「Calm」と「Frustrated」の間、やや後者寄りということになる。

confidence が付いているのは choice と score だけで、noul には付かない。二値なら 0.95 と答えた時点で確からしさも同時に言っているので、別の数値が要らないのだと思う。

ここまでは素直だった。

動かすまでに踏んだもの

一つめ。wrangler dev をそのまま起動しても動かない。

Workers AI のモデルは Cloudflare 側でしか実行できないので、ローカルで完結する開発モードでは呼べない。--remote を付けると、手元のコードを Cloudflare 上で動かす形になって通る。

npx wrangler dev --remote

二つめのほうが厄介で、最初の呼び出しがこれで落ちた。

AiGatewayError 2021: Insufficient AI Gateway credits

Workers AI には Cloudflare 自身が用意したモデルと、他社が提供するモデルの2種類がある。typesafe/jev は後者なので、Workers AI の無料枠には乗らない。AI Gateway に事前チャージしたクレジットから引かれる仕組みになっている。

ダッシュボードの AI Gateway で支払い方法を登録して Top-up したら通るようになった。購入額に5%の手数料が乗るが、モデルの利用料そのものへの上乗せはない。

値段と速さ

課金対象は入力トークンだけで、100万トークンあたり $0.042。出力は $0 と表示される。文章を書かないモデルなので、出力側で課金する根拠がない、ということだろう。

ただし応答の usage には output_tokens も入っていて、質問3つのときで63だった。テキストが一文字も出てこないのに何を数えた値なのかは分からない。料金表で出力側に値が付いていない、ということだけが確かである。

手元から Worker 経由で30回呼ぶと、応答の中央値は 261ms だった。最小は 210ms 前後で安定しているが、最大は実行ごとに 1.1 秒から 5.1 秒まで振れる。wrangler dev --remote 越しの測定なので、手元の開発セッションを一度通る分が乗っている。

一度に渡せる文章の長さは、Cloudflare の表記で 32,000 トークンまで。

日本語で使えるかどうか

TypeSafe の公式ドキュメントは、言語について「英語が主たる学習言語であり、精度もそこが一番よい」と書いている。日本語や中国語を含む他の言語も扱えるが同じようにはいかないので、自分のデータで試してから使い、確信度を見て振り分けること、という注意が付く。

ここまでの話は全部、動いたというだけの話でしかない。

なお、Jev の公開後、同じように文章を生成せず判断だけを返すモデルが、重みを公開する形でいくつか出ている。学習済みの重みが誰でも落とせるので、クラウドのAPIを経由せず手元のマシンで動かせる。Laya は Apache-2.0 で、Mac でも動く。

選択肢はあるわけだが、どれを選ぶにしても先に確かめることは同じである。実務で使うつもりなら、知りたいのは日本語でどれだけ当たるかのほうだ。