Jev(ジェブ)は Claude Code や Codex のモデルの代わりにはなりません。役に立つのは、エージェントの分かれ道で「どれを選ぶか」「はいかいいえか」を速く安く決める判定役としてです1 。この記事では、Claude Code と Codex の両方でそのまま動く hook スクリプトを書きます。プロンプトごとにスキルを 1 つ推薦する hook と、テストせずに「完了しました」と言ったら作業を続けさせる hook の 2 つです。あわせて、公開から 1 か月で出てきた使い方(許可確認の自動判定、fast-jev-compaction、Jev Router、Kev)を、どこに置くと効くかで整理します(内容は 2026 年 10 月時点)。
API の基本は「Jev API 入門 」に、Clef との違いは「Jev と Cloudflare Clef の違い 」にまとめています。
Jev を AI エージェントと組み合わせる方法は 2 つあります。エージェントに Jev を使うコードを書かせる 使い方と、エージェント自身のループの分かれ道に Jev を判定役として置く 使い方です。TypeSafe は、Jev は Claude Code・Cursor・Copilot などの LLM の代わりにはならず、エージェントを Jev で動かす設定も無いと書いています1 。
使い方 やること 入口 A. コードを書かせる 「LLM に JSON で答えさせている箇所」を Jev に置き換えさせる TypeSafe の agent skill2 B. 分かれ道に置く スキル選び・許可確認・コンパクション・完了チェックを判定させる hooks、mod、OpenRouter
A の入口は TypeSafe が配っているスキルです2 。
claude plugin marketplace add typesafe-ai/skills
claude plugin install typesafe@typesafe-ai
npx skills add typesafe-ai/skills --skill typesafe-ai
TypeSafe は、質問としきい値を 1 つのファイルにまとめて人がレビューするよう勧めています2 。この記事の残りは B の使い方です。
Claude Code や Codex のループの 5 つの段階(プロンプト・モデル選び・コマンド実行・コンパクション・完了)と、それぞれで Jev に聞くことの対応 図: 筆者作成(各社の公式ドキュメントと GitHub リポジトリをもとに作図)
Jev の検索は、日本でも公開の週に急に増えました。Google トレンド(日本・過去 90 日、2026-10-14 取得)では、「Jev」は 9/16 の週に 55 まで上がりました。それまでの 9 週はずっと 0 です3 。直近 4 週の平均は 29.1 で、同じ期間の「GitHub Copilot」(7.5)の約 4 倍でした3 。
「Jev」と「GitHub Copilot」の検索関心度(日本・週ごと) データを表で見る 「Jev」と「GitHub Copilot」の検索関心度(日本・週ごと) 週 Jev GitHub Copilot 07/15 0 13 07/22 0 11 07/29 0 13 08/05 0 9 08/12 0 7 08/19 0 11 08/26 0 12 09/02 0 12 09/09 0 10 09/16 55 5 09/23 37 8 09/30 15 10 10/07 8 8
出典: Google トレンド(日本、2026/07/15〜2026/10/07 の週、2026-10-14 取得。同じ回で比べた語の最大を 100 とした相対値)
ピークのあとは下がり、10/07 の週は 8 でした。急上昇の関連語は「jev model」「jev api」「typesafe ai」です3 。
エージェントとの組み合わせが目立つのは、GitHub で Jev を使う公開リポジトリが短期間に増えたからです。次のグラフは、筆者が 2026-10-14 に GitHub の API で取得したスター数です4 。
Jev 関連の GitHub リポジトリのスター数(2026-10-14 時点) データを表で見る Jev 関連の GitHub リポジトリのスター数(2026-10-14 時点) リポジトリ スター数 browser-use/jev-ultrafast(Web 操作エージェント) 22,850 jaredpalmer/kev(Jev 互換の自前モデル) 9,087 jev-chat/jev-chat-jarvis(チャット返信の判定アプリ) 7,718 tamaratran/fast-jev-compaction(Claude Code プラグイン) 7,619
出典: 筆者集計(元データ: GitHub REST API の stargazers_count、2026-10-14 取得)。リポジトリの作成日は 2026-09-16〜09-21
4 つとも、作成日は 2026-09-16〜09-21 です4 。このうち 3 つは、エージェントの判定に Jev を使うか、Jev の代わりを自前で動かすためのものです。たとえば jev-ultrafast は、ブラウザ操作エージェントの次の操作(クリック・入力など)と対象の要素を、Jev の 1 回のリクエストで選びます5 。
Jev が効くのは、選択肢が決まっていて、答えを確率で受け取りたい分かれ道です。Claude Code と Codex には、そこに自分のスクリプトを差し込む hooks があります6 7 。
場所(仕組み) Jev に聞くこと ① プロンプト(UserPromptSubmit hook) どのスキルが合うか。この記事の実践 18 ② モデル選び(OpenRouter の Jev Router) どのモデル・推論の深さで解くか9 ③ コマンド実行(PermissionRequest hook) 元に戻せるか・作業に沿うか10 ④ コンパクション(Claude Code の mod) このツール結果はまだ要るか11 ⑤ 完了の報告(Stop hook) テスト結果を書いたか。この記事の実践 2
どの場所でも、設計の考え方は同じです。
事実はコードで調べる : ファイルが変わったか、などは Jev に聞きません。Jev は計算や数え上げが苦手だと TypeSafe 自身が書いています12
言葉の判断だけを Jev に聞く : 1 問で 1 つのことを聞きます
失敗したら何もしない : キーが無い・通信に失敗したときは何も出さず、エージェントにいつもどおり動いてもらいます
hook から Jev を呼ぶ入口は 2 つあります。送る JSON({"model": …, "state": …, "questions": …})の形は同じです。
TypeSafe の System One API : POST https:/ / api.typesafe.ai/ v1/ systemone。モデル名は jev-1.13.0(別名 jev-latest)。TypeSafe のキーを使います13
OpenRouter の Decisions API : POST https:/ / openrouter.ai/ api/ alpha/ decisions。モデル名は typesafe/ jev-1.13。OpenRouter のキーだけで呼べます。名前のとおり alpha(試験提供)です14
料金は入力トークンにだけかかり、TypeSafe の単価は入力 100 万トークンあたり 0.042 ドルです(2026 年 10 月時点)13 。OpenRouter 経由では、レスポンスの usage.cost に 1 回の費用が入ります。チュートリアルの例では 476 トークンで 0.000019992 ドルでした15 。
API キーには注意が 1 つあります。OpenRouter のクックブックによると、Codex CLI 0.155.1(2026-09-22 時点)では、名前に KEY を含む環境変数が hook に渡りませんでした10 。そのため、この記事のスクリプトはプロジェクトの .env も読みます。.env は必ず .gitignore に入れてください。
スキルが増えると、エージェントは名前と短い説明だけを見て、どれを読み込むか決めることになります。Codex のドキュメントも、最初のスキル一覧はコンテキストの 2% までに収め、スキルが多いと説明から短くすると書いています16 。ここに Jev を置き、「この依頼に合うスキル」を 1 行だけ渡します。
TypeSafe はクックブックで、182 個のスキルを持つエージェント(Nous Research の Hermes)に Jev の推薦を足す実験をしています。488 件の依頼で、モデルは claude-haiku-4-5、Jev は jev-1.12 です8 。
スキル選びの誤りの割合(488 件、エージェントのモデルは claude-haiku-4-5) データを表で見る スキル選びの誤りの割合(488 件、エージェントのモデルは claude-haiku-4-5) 条件 違うスキルを読み込んだ(%) 不要なのに読み込んだ(%) エージェントだけ 16.8 9.8 Jev の推薦あり 7.3 4 正解を渡した場合 2.5 1.2
出典: TypeSafe Docs「Skill suggestion」クックブック(jev-1.12、2026-07-31 実行)。TypeSafe による計測
違うスキルの読み込みは 16.8% から 7.3% に減りました8 。ただし TypeSafe 自身の計測で、推薦を足したことで逆に間違えた依頼もあったと書かれています8 。
スクリプトは Python 3.10 以上の標準ライブラリだけで書き、prompt と stop の 2 つのモードを持たせました。Claude Code と Codex で同じファイルを使います。スキル推薦の部分は次のとおりです。
SUGGEST_AT = 0.5
GATE_AT = 0.3
GATE_QUESTIONS = {
"acts_on_user_system" : "Is the assistant being asked to act on the user's files, accounts, devices, or online services, rather than only to explain or advise?" ,
"would_follow_documented_procedure" : "Would a careful expert answering this consult a specific documented procedure or set of commands, rather than answering from general understanding?" ,
"prose_suffices" : "Could a knowledgeable generalist fully satisfy this request in prose, with no tools, no documentation, and no access to the user's files or accounts?" ,
}
INVERTED = {"prose_suffices" }
def suggest_skill (event: dict ) -> dict | None :
skills = read_skills(event.get("cwd" , "." ))
if len (skills) < 2 :
return None
questions = {
"which" : {
"type" : "choice" ,
"instructions" : "Which of these skills, if any, is the right one to load to help with `request`?" ,
"criteria" : skills,
},
**{f"gate_{k} " : {"type" : "noul" , "instructions" : v} for k, v in GATE_QUESTIONS.items()},
}
answers = ask_jev({"request" : event.get("prompt" , "" )[:4000 ]}, questions)
if answers is None :
return None
gate = [answers[f"gate_{k} " ]["noul" ] for k in GATE_QUESTIONS]
gate = [1 - v if k in INVERTED else v for k, v in zip (GATE_QUESTIONS, gate)]
best, p = max (answers["which" ]["probabilities" ].items(), key=lambda kv: kv[1 ])
if sum (gate) / len (gate) < GATE_AT or p < SUGGEST_AT:
return None
return {
"hookSpecificOutput" : {
"hookEventName" : "UserPromptSubmit" ,
"additionalContext" : f"Relevant skill for this request: {best} . Ignore this if it does not fit what the user actually asked for." ,
}
}
1 回のリクエストで聞く : スキルの Choice と、「スキルが要る依頼か」の Noul 3 問を一緒に送ります。3 問はクックブックの文をそのまま使い、平均が 0.30 未満なら推薦しません8
推薦は 1 行だけ : スキルの一覧は変えず、「合わなければ無視して」と添えて足すだけです8
しきい値は例 : SUGGEST_AT = 0.5 は筆者が決めた値です。クックブックは 2 回目のリクエストで上位 3 つを確かめ直しますが、ここでは 1 回に減らしました
additionalContext は、どちらのエージェントでも追加の文脈として渡ります6 7 。Claude Code の UserPromptSubmit は既定で 30 秒のタイムアウトがあり、時間切れなら文脈を足さずにプロンプトが進みます6 。
.claude/ hooks/ jev_hooks.py に保存し、.claude/ settings.json に登録します。Stop の登録は実践 2 で使います6 。
{
"hooks" : {
"UserPromptSubmit" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "python3 \"${CLAUDE_PROJECT_DIR}\"/.claude/hooks/jev_hooks.py prompt" ,
"timeout" : 15
}
]
}
] ,
"Stop" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "python3 \"${CLAUDE_PROJECT_DIR}\"/.claude/hooks/jev_hooks.py stop" ,
"timeout" : 15
}
]
}
]
}
}
hooks の基本は「Claude Code hooks 入門 」で解説しています。
Codex では .codex/ hooks.json に登録します。パスは、サブディレクトリから起動してもずれないよう git のルートから組み立てます7 。
{
"hooks" : {
"UserPromptSubmit" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "python3 \"$(git rev-parse --show-toplevel)/.claude/hooks/jev_hooks.py\" prompt" ,
"statusMessage" : "Jev でスキルを確認中" ,
"timeout" : 15
}
]
}
] ,
"Stop" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "python3 \"$(git rev-parse --show-toplevel)/.claude/hooks/jev_hooks.py\" stop" ,
"timeout" : 15
}
]
}
]
}
}
Codex では、さらに 2 つの手順が要ります7 。
hook を信頼する : CLI で / hooks を開いて信頼します。hook を変えると、もう一度確認が要ります
プロジェクトの .codex/ を信頼する : 信頼されていないと、プロジェクトの hook は読み込まれません
Codex のスキルは .agents/ skills に置きます16 。スクリプトは .claude/ skills と .agents/ skills の両方を読むので、どちらでも同じ一覧で判定できます。
Stop hook は、エージェントが返答を終えるときに動きます。どちらのエージェントでも、入力の last_assistant_message に最後の返答が入ります6 7 。hook が {"decision": "block", "reason": "…"} を返すと、エージェントは止まらずに作業を続けます。
Stop hook が、git で変更の有無を確かめてから Jev に 2 問だけ聞き、しきい値で作業を続けさせるかを決める流れ 図: 筆者作成(Claude Code と Codex の hooks ドキュメントをもとに作図)
CLAIMS_DONE_AT = 0.8
REPORTS_TESTS_BELOW = 0.2
STOP_QUESTIONS = {
"claims_done" : {
"type" : "noul" ,
"instructions" : "`message` says that the requested code change is finished." ,
},
"reports_test_run" : {
"type" : "noul" ,
"instructions" : "`message` reports that tests, a type check, or a build were actually run after the change, and states their result." ,
},
}
def check_stop (event: dict ) -> dict | None :
if event.get("stop_hook_active" ):
return None
message = event.get("last_assistant_message" ) or ""
files = changed_files(event.get("cwd" , "." ))
if not message or not files:
return None
answers = ask_jev({"message" : message[-6000 :], "changed_files" : files[:50 ]}, STOP_QUESTIONS)
if answers is None :
return None
done, tested = answers["claims_done" ]["noul" ], answers["reports_test_run" ]["noul" ]
if done >= CLAIMS_DONE_AT and tested < REPORTS_TESTS_BELOW:
return {"decision" : "block" , "reason" : STOP_REASON}
return None
STOP_REASON には「テストや型チェックを実行して結果を書いてから終えて」という指示を入れています。違いは次のとおりです。
Claude Code Codex block の意味 reason を理由として続ける6 reason を新しいプロンプトとして続ける7 続ける回数 連続 8 回で打ち切り6 上限の記載なし。stop_hook_active で判定7
Codex の Stop は、終了コード 0 でプレーンテキストを出すと不正になります7 。そのためスクリプトは、止めないときは何も出さず、止めるときだけ JSON を 1 行出します。
筆者は、決まった確率を返すモックのサーバーを立てて 2 つのモードを実行しました。API キーが無いため実際の Jev は呼んでおらず、GIF の確率はモックの値です。
スキル推薦では db-migration が推薦され、Stop ではテスト結果が無いため block が返り、2 回目と API キーが無いときは何も出ない様子 筆者の環境(macOS、Python 3.14)で実行した出力。Jev の応答はモック
推薦の JSON が出ること、テスト結果の無い「完了」で block が出ること、stop_hook_active が true のときと API キーが無いときは何も出さないことを確かめました。
実際の Jev でしきい値を決めるときは、過去の返答を 30〜50 件集めて確率の分布を見てください。Jev の学習は英語が中心で、日本語は同じ精度ではないとされています12 。そのため質問文は英語にし、返答本文は日本語のまま渡しています。
上に載せていない部分は、次の 4 つの関数です。
ask_jev(state, questions): OPENROUTER_API_KEY があれば Decisions API、無ければ TYPESAFE_API_KEY で System One API に送ります。タイムアウトは 8 秒です。失敗や答えの欠けがあれば None を返します
load_dotenv(cwd): 環境変数が無いときだけ、プロジェクトの .env から 2 つのキーを読みます
read_skills(cwd): SKILL.md の frontmatter から name と description を集めます
changed_files(cwd): git status --porcelain で変更ファイルの一覧を返します
API の呼び出し部分の抜粋です。
def ask_jev (state: dict , questions: dict ) -> dict | None :
if os.environ.get("OPENROUTER_API_KEY" ):
url, key, model = "https://openrouter.ai/api/alpha/decisions" , os.environ["OPENROUTER_API_KEY" ], "typesafe/jev-1.13"
elif os.environ.get("TYPESAFE_API_KEY" ):
url, key, model = "https://api.typesafe.ai/v1/systemone" , os.environ["TYPESAFE_API_KEY" ], "jev-1.13.0"
else :
return None
req = urllib.request.Request(
url, method="POST" ,
data=json.dumps({"model" : model, "state" : state, "questions" : questions}).encode(),
headers={"Authorization" : f"Bearer {key} " , "Content-Type" : "application/json" },
)
try :
with urllib.request.urlopen(req, timeout=8 ) as res:
answers = json.load(res).get("answers" )
except Exception:
return None
if not isinstance (answers, dict ) or any (k not in answers for k in questions):
return None
return answers
エントリーポイントでは、標準入力の JSON を読んでモードの関数に渡し、結果があるときだけ json.dumps(out, ensure_ascii=False) を出力します。
コマンドの許可確認を Jev で仕分ける Claude Code 向けの hook は、「Jev API 入門 」で紹介しました。OpenRouter のクックブックは、同じスクリプトを Codex CLI・Cursor・OpenCode でも使う方法をまとめています10 。Codex での違いは 3 点です。
登録先 : .codex/ hooks.json の PermissionRequest に書きます。入出力の形は Claude Code と同じです10 7
description を作業として使わない : Codex はここに承認の質問文を入れます。クックブックの記録では、これを作業として渡すと serves_task が 0.54 にとどまりました。turn_id があるときは「元に戻せるか」の 1 問だけを聞きます10
返してはいけない項目 : updatedInput・updatedPermissions・interrupt を返すと、Codex は失敗として扱います10
git push・rm -rf・デプロイは、コードの危険リストで先に止めます。クックブックも、安全の境目は Jev のしきい値ではなく危険リストだと書いています10 。
fast-jev-compaction は、Claude Code のコンパクション(会話の圧縮)を Jev の判定に置き換えるプラグインです11 。普通のコンパクションは LLM に要約させるため、ファイルパスや正確なエラー文が消えることがあります。このプラグインは要約せず、Jev が「もう要らない」と判定したツール呼び出しと結果だけを削ります11 。
README による仕組みは次のとおりです11 。
ツール結果を 1 行のメモに置き換えた会話全体を state として送り、各ツール呼び出しに「呼び出しを残すか」「結果を残すか」の Noul を 2 問聞く(最初と直近 6 件は対象外)
確率 0.5 以上なら残す。呼び出しだけ残すときは、結果を先頭 300 文字に切り詰める
削れた量が 25% 未満のときや Jev が失敗したときは、通常のコンパクションに戻る
claude plugin marketplace add tamaratran/fast-jev-compaction
claude plugin install fast-jev-compaction@fast-jev-compaction
このプラグインは Claude Code の mod の session.compact イベントを使います11 17 。README は早期アクセス期の 2.1.274 を前提に CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 を設定する手順を書いています。現在の公式ドキュメントでは、mod は v2.1.287 以降で既定で有効になり、この環境変数は無視されます18 。筆者はキーが無いため実際の圧縮は試していません。mod の仕組みは「Claude Code の mod 」で解説しています。
OpenRouter の Jev Router(typesafe/ jev-router)は、リクエストごとに Jev が「どのモデルと推論の深さで解くか」を決めるルーターです。Chat Completions・Responses・Messages のどの API でも、モデル名を変えるだけで使えます9 。
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY " \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-router",
"plugins": [{"id": "jev-router", "cost_tier": "medium"}],
"messages": [{"role": "user", "content": "Summarize this incident report."}]
}'
cost_tier は low・medium・high から選び、models と excluded_models で候補を絞れます。レスポンスの model に、実際に答えたモデルが入ります9 。
向いているのは自作のエージェントです。Claude Code を OpenRouter 経由で使う場合、動作が保証されるのは Anthropic 自身のプロバイダー(1P)だけとされています19 。筆者は Claude Code と Jev Router の組み合わせを確かめていないので、ここでは勧めません。
会話やコードを社外の API に送れない場合は、Kev が候補になります。Kev は Qwen3.5 / Qwen3.8 をもとにした、Jev に似た判定モデルの系列です20 。サーバーは System One API と同じ形で答えるので、この記事のスクリプトもエンドポイントを差し替えれば同じリクエストを送れます(筆者は Kev では試していません)。
モデル 動く環境(README) 新しいデータでの正解率 Kev-0.8B 4GB の GPU、Apple Silicon の Mac 0.648 Kev-4B L40S / H100、32GB の Mac 0.817 Kev-27B 80GB の GPU 0.851 Jev(参考) TypeSafe の API 0.857
出典: jaredpalmer/kev の README20 (開発セットの値、2026-10-14 参照)。Jev の学習データは不明なため、README も同じ条件の比較ではないと書いています。
README は Kev-4B から始めるよう勧めています。自分のデータで微調整するスキル(npx skills add jaredpalmer/ kev@kev-finetune)もあります。PyPI の kev は別のパッケージなので、Kev はソースから入れます20 。
エージェントが遅くなる : UserPromptSubmit はプロンプトのたびに動き、終わるまで処理を止めます6 。通信のタイムアウト(8 秒)は hook の timeout(15 秒)より短くします
Codex で hook が動かない : / hooks での信頼と、.codex/ の信頼を確かめます7 。キーが渡っていなければ .env を確かめます10
Stop が止まらない : stop_hook_active を見ずに block を返すと、同じ理由で続けさせ続けます6
しきい値が合わない : 確率は同じリクエストでも少し動きます。クックブックは 0.9 から始めて、必要なら 0.8 に下げるよう書いています10
jev-latest が動く : 新しい版で答えが変わりえます。しきい値を決めたら jev-1.13.0 のように版を固定します13
Jev はエージェントのモデルにはならない。分かれ道で型付きの答えと確率を返す判定役として使う
Claude Code と Codex は hook の入出力がほぼ同じなので、1 本のスクリプトを両方に登録できる。Codex は / hooks での信頼が要る
事実はコードで調べ、言葉の判断だけを Jev に聞く。失敗したら何も出さない
コンパクションは fast-jev-compaction、モデル選びは Jev Router、社外に出せないデータは Kev が候補
次にやること: 実践 1 の hook を自分のスキル一覧で動かし、1 週間分の推薦をログに残して SUGGEST_AT を決めましょう
Jev は TypeSafe AI の判定モデルで、TypeSafe が「System One モデル」と呼ぶ種類の最初の 1 つです1 。状態(state)と型付きの質問を受け取り、Choice・Score・Noul の答えを確率つきで返します。文章やコードは生成しません。
使えません。TypeSafe は、Jev はコーディングエージェントの LLM の代わりにはならず、エージェントを Jev で動かす設定も無いと明記しています1 。この記事のように、hook や mod から判定の部品として呼びます。
TypeSafe の System One API(https:/ / api.typesafe.ai/ v1/ systemone)か、OpenRouter の Decisions API(https:/ / openrouter.ai/ api/ alpha/ decisions)です13 14 。送る JSON の形は同じです。OpenRouter なら TypeSafe のアカウントは要らず、OpenRouter のキーだけで呼べます14 。
Claude Code や Codex が、Jev の API・質問の型・設計パターンを理解したうえでコードを書けるようになります2 。Claude Code では claude plugin install typesafe@typesafe-ai、ほかのエージェントでは npx skills add typesafe-ai/ skills --skill typesafe-ai で入れます2 。