Jev - TypeSafe AI决策模型使用介绍

94 阅读9分钟

Jev是 TypeSafe 推出的决策模型。你给它材料和明确的问题,它返回选项、分数或概率。它不生成评审文章,也不会替你修改代码。它根据类型化问题评估共享状态,并返回选项、分数和布尔概率,支持分类、路由、基于评分标准的评估以及自动化验证。多个问题可以在单次请求中并行评估。

本篇沿着实际接入过程来讲。先跑通一次 API 调用,再给 Claude Code 或 Codex 装代码评审工具,做完以后,你会有一个能调用的判断接口、一套代码评审流程,以及一份可以拿来校准的判断日志。最后介绍JEV-MODEL-ROUTER插件使用。

image.png

1.先选清楚,你准备让 Jev 判断什么

Jev 最容易用起来的任务,有一个共同点,答案的范围事先已经知道。

HSgHwnQbYAAFaRI.jpg

第一次接入,建议从代码评审开始。它对原有流程的影响比较小,你可以逐次比较模型建议和实际代码,不必马上让它决定执行权限。

准备环境时,确认这些条件。

已经能正常使用 Claude Code 或 Codex。

有可用的 TypeSafe API key。没有拿到 key,先到控制台确认账号当前的开通状态。

使用社区评审插件需要 Node.js 20 或更新版本;后面的 Python 示例使用 Python 3.10 或更新版本。

示例终端命令按 macOS、Linux 或 WSL 编写。

可以先运行 node --version 和 python3 --version 检查环境。别等插件装完,才发现运行它的解释器版本不对。

2.看懂它的输入和三种题型

Jev 的一次请求可以拆成两部分。

state 是给它看的材料。评审代码时,可以放用户要求和相关改动;处理工单时,可以放客户的原始消息。

questions 是需要它回答的问题。问题可以混在一次请求里,分别得到结果

HSgH8lCboAANk_A.jpg

Choice 和 Score 还会返回 confidence。它是从概率分布计算出来的统计量,不能直接当成“这个答案正确的概率”。Noul 没有单独的这个字段。

初学时最容易犯的错,是把所有需求压进一句“判断这件事是否合理”。

合理取决于什么?是否符合用户要求,是否会修改远程状态,还是是否涉及凭证?这些条件得分别写清楚。模型拿到模糊的问题,即使返回一个很精确的小数,也没有替你定义好标准。

HSf2TJPbMAARiIN.jpg

3.跑通第一次调用,确认 key 和网络都正常

先去 TypeSafe 控制台 创建 API key,在本机终端设置环境变量。

export TYPESAFE_API_KEY="你的 API key"

检查时只确认有没有设置,不必把 key 打印出来。

test -n "$TYPESAFE_API_KEY" && echo "key 已设置"

接着发送一个简单的判断题。这个例子问的是消息中有没有明确的时间要求。

curl --fail-with-body --max-time 15 \  
<https://api.typesafe.ai/v1/systemone> \  
-H "Authorization: Bearer $TYPESAFE_API_KEY" \  
-H "Content-Type: application/json" \  
--data-binary @- <<'JSON'  
{  
  "model": "jev-latest",  
  "state": {  
  "message": "我被重复扣款了,希望今天能帮我处理。"  
  },  
  "questions": {  
    "has_deadline": {  
      "type": "noul",  
      "instructions": "message 是否明确提出了处理时间或截止时间?" 
    }  
  }  
}
heredoc> JSON
{"model":"jev-1.13.0","answers":{"has_deadline":{"type":"noul","noul":0.83}},"usage":{"input_tokens":310,"output_tokens":23}}%  

成功后,响应里应该有 answers.has_deadline.noul。它应该是 0 到 1 之间的数。先检查结构正确,再观察判断是否符合这条消息的含义,不要求每次都返回同一个小数。

把“希望今天能帮我处理”换成“时间不着急”,再跑一次。两条都带时间信息,所以按当前问题,两条都可能获得较高分数。如果你想区分紧急程度,就需要另写一个关于紧迫性的条件。

curl --fail-with-body --max-time 15 \
  https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "jev-latest",
  "state": {
    "message": "我被重复扣款了,时间不着急。"
  },
  "questions": {
    "has_deadline": {
      "type": "noul",
      "instructions": "message 是否明确提出了处理时间或截止时间?"
    }
  }
}
heredoc> JSON
{"model":"jev-1.13.0","answers":{"has_deadline":{"type":"noul","noul":0.16}},"usage":{"input_tokens":306,"output_tokens":23}}%  

这一步很有用。它会让你立刻发现,你写的问题和脑子里想判断的东西,有时差着半句话。

4.用 Python 一次问完选择题、评分题和判断题

API 通了,再安装 SDK。下面用独立虚拟环境,减少装错解释器的问题。

mkdir jev-demo  
cd jev-demo  
python3 -m venv .venv  
source .venv/bin/activate  
python -m pip install typesafe-sdk

新建 first_jev.py,写入下面的示例。

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()

response = client.system_one(
    state={
        "message": "我被重复扣款了,希望今天退回多扣的钱。"
    },
    questions={
        "intent": Choice(
            instructions="message 中客户的主要诉求是什么?",
            criteria={
                "refund": "要求退回已经支付的钱",
                "technical": "要求修复产品功能或连接问题",
                "information": "只咨询信息,没有要求退款或修复",
                "other": "以上类别均不适合,或缺少判断材料",
            },
        ),
        "urgency": Score(
            instructions="message 表达了多强的处理紧迫性?",
            criteria=[
                "没有要求尽快处理,也没有提出近期截止时间",
                "希望尽快处理,或提出当天等近期截止时间",
                "明确要求立即处理,并说明正在遭受严重影响",
            ],
        ),
        "has_deadline": Noul(
            instructions="message 是否明确提出了处理时间或截止时间?"
        ),
    },
)

print("model", response.model)
print("intent", response.answers["intent"].choice)
print("probabilities", response.answers["intent"].probabilities)
print("urgency", response.answers["urgency"].score)
print("has_deadline", response.answers["has_deadline"].noul)

运行它。

python first_jev.py

这段代码按官方 SDK 的调用形式编写,客户端会读取 TYPESAFE_API_KEY。如果你换了终端,需要重新设置环境变量。

读输出时,注意三个细节。

**Choice 留一个接不住的出口。 **示例中的 other 让无法归类的消息有地方可去。类别覆盖不全,却强迫模型必选一个业务部门,程序仍会拿到合法答案,只是业务分错了。

**Score 的含义来自你写的等级。 **这里有三个等级,对应 0、1、2。拿到 1.2,不能把它说成“紧急程度 1.2 分,满分 10 分”。你换了评分标准,旧分数也就失去了直接比较的基础。

**把模型标识留在记录里。 **同样的问题换了模型,分数分布可能变化。调阈值时,把请求使用的模型名和响应里的 model 一起记录;需要复现时,再按 Models 文档选择可固定的具体版本。

5.给 Claude Code 或 Codex 接上 jev-review

前面的调用帮你理解 Jev 怎么工作。接下来可以用现成的社区插件,让编码 Agent 在工作时调用它。

先给插件设置它需要的变量名。

export JEV_API_KEY="$TYPESAFE_API_KEY"

这里别混淆。前面的 SDK 读取 TYPESAFE_API_KEY,jev-review 读取 JEV_API_KEY。

Claude Code 用户运行这一条。

npx plugins add NiazMorshed2007/jev-review --target claude-code

Codex 用户用这一条。

npx plugins add NiazMorshed2007/jev-review --target codex

以上是项目给出的安装入口。安装完成后重启客户端,确认 MCP 连接状态。Claude Code 可以用 /mcp 检查;使用其他界面时,在相应的 MCP 管理入口查看。

如果采用手动方式,项目也给出了 Codex 配置。将这一段合并进 ~/.codex/config.toml,路径换成你实际保存并构建好项目的位置,别覆盖已有配置。

[mcp_servers.jev-review]
command = "node"
args = ["/绝对路径/jev-review/dist/server.js"]
env_vars = ["JEV_API_KEY"]

插件要能启动,配置中的文件必须存在,客户端进程也必须拿到 key。特别是从桌面图标启动的程序,不能假定它自动继承了终端里刚 export 的变量。

jev-review 在本机运行 MCP 服务,但评审内容会发给配置的 Jev API。任务说明和 diff 只提交本次评审必需的部分,排除密钥与无关私有代码。

第一次就用一项小改动验证

选一个你能看懂结果的任务,例如修复一个输入校验问题。把下面这段要求交给 Agent,方括号换成实际需求。

完成这项改动,并在实现过程中使用 jev-review。

本次需求为[填写需求及验收条件]。

完成第一版实现后,提交任务要求、相关代码差异和必要上下文进行评审。保存第一次结果,作为后续比较的起点。

对评分较低的维度,回到代码中检查原因。能找到具体问题再修改,不要为了提高分数扩大改动范围。

修改后运行相关测试,再使用相同要求和尽量一致的上下文重新评审。支持时传入 previousEvaluation 比较前后变化。

最后交代改了什么、测试结果,以及仍需人工判断的地方。

你要看到实际的 jev_review 调用和返回结果。Agent 只说一句“已经自查”,不能算接通了这个工具。

评审后也别只看总的感觉。某个维度变好了,就去看对应改动有没有实际价值;如果只是改了命名,不能据此认定逻辑错误已经消失。

Jev 返回质量信号,具体原因仍由 Agent 分析,正确性继续用测试和代码检查验证。这也是项目说明中的职责划分。

HSf2eC7aMAEXcNx.jpg

claude:
 使用jev-review分析最近的一次提交效果

⏺ jev-model-router: [jev-model-router] main loop → claude-sonnet-5: balanced (confidence 0.34)

  Thought for 25s, called pmb, ran 1 shell command

⏺ Skill(jev-review:jev-review)
Successfully loaded skill

  Thought for 2m 12s, read 1 file, ran 3 shell commands

我已通读该提交的完整差异。在调用 jev_review 之前,先核实一个关键事实:文档中引用的新增代码文件(CgalExactSolid.cs、CgalExactSolidStage0Probe.cs、CgalExactSolid.dll)是否确实在本仓库中存在。

评审完成。先说明:jev_review 返回的是标量分数与预定义类别提示,不是根因分析——以下是分数加上我对该提交逐行核查后的独立诊断。

提交概况

8fbc95823 是纯文档提交(11 个文件全在 Doc/plans/第三迭代总体分析/土方工程/,+2139/−52):建立 g4/OCCT/CGAL 三库分工、重排 AI 辅助工期(阶段0 4→6 日、阶段4 12→10 日,总基线维持 97/134 日)、新建实施路线图与完成跟踪体系(47 项任务、12 工作包、42 验收场景台账)。

Jev 基线评分

┌─────────────────┬──────┬────────┬───────────────────────────┐
│      维度       │ 分数 │ 置信度 │         类别提示          │
├─────────────────┼──────┼────────┼───────────────────────────┤
│ correctness     │ 4.7  │ 0.55   │ 依赖了不安全/不正确的假设 │
├─────────────────┼──────┼────────┼───────────────────────────┤
│ consistency     │ 4.9  │ 0.55   │ 相关部分约定不一致        │
├─────────────────┼──────┼────────┼───────────────────────────┤
│ documentation   │ 4.9  │ 0.53   │ 运行使用说明不足          │
├─────────────────┼──────┼────────┼───────────────────────────┤
│ maintainability │ 5.0  │ 0.54   │ 常规修改易出错            │
├─────────────────┼──────┼────────┼───────────────────────────┤
│ readability     │ 5.4  │ 0.37   │ 意图表达可更清晰          │
└─────────────────┴──────┴────────┴───────────────────────────┘
拉低分数的具体根因:

1. correctness 4.7 的主因——证据在版本库不可复核:新文档多处断言“脚本和 DLL 已加入项目”,但 Assets/Plugins/CgalExactSolid.dll、Assets/Editor/CgalExactSolidStage0Probe.cs、Wrappers/CgalExactSolid.cs 在 release 分支中不存在、无提交历史(工作区干净,也无忽略规则)。这些文件只存在于作者本机。跟踪文档的核心承诺(S0-07 待验证项、Unity 菜单入口)在任何其他 checkout 上都是死链接。
2. consistency/documentation:大量 /C:/YAO/... 本机绝对路径链接(如 DMeshAABBTree.cs:1554),仅作者机器可打开;1057 行生成 JSON 作为证据可以保留,但读者无法从中复跑。
3. maintainability:同一张“用库分工表”在 4 个文档中整表重复(设计方案 1.3、AI 计划 1.6、任务对照 §1、技术方案 §2)。文档已指定《后续功能用库与开发任务对照》为权威(“以……为准”),但整表复制仍会在后续 27 周的修订中漂移——这正是后续每次更新最容易出错的地方。

6.使用jev-model-router插件

jev-model-router是一种基于函数钩子构建的完整 Claude Code 插件(类似 Anthropic 的 mods/布局);在安装了 Claude Code 2.1.259 及更高版本,并设置 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 的环境下即可使用,不过 API接口仍可能在后续版本中发生变化。相关模块位于hooks/jev−model−router.ts。可选参数如:typesafeApiKey、routeMainModel、timeoutMs等(可通过用户设置或managedsettingspluginConfigs,或/config进行配置)。可在安装目录上运行claudepluginvalidate命令,查看该插件所触发的所有事件以及它发起的所有API 接口仍可能在后续版本中发生变化。相关模块位于 hooks/jev-model-router.ts。可选参数如:typesafeApiKey、routeMainModel、timeoutMs等(可通过用户设置或 managed settings pluginConfigs,或 /config 进行配置)。可在安装目录上运行 claude plugin validate 命令,查看该插件所触发的所有事件以及它发起的所有 API 调用.

安装

npx claude-code-templates@latest --mod productivity/jev-model-router

$ npx claude-code-templates@latest --mod productivity/jev-model-router


ƒ Installing mod: productivity/jev-model-router

⚠️ Early access: mods need CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1

📥 Downloading from GitHub (main branch)...

✓ .claude-plugin/plugin.json

✓ hooks/hooks.json

✅ Mod "productivity/jev-model-router" installed successfully!

📁 Installed to: .claude/skills/jev-model-router/ (5 files)


$ CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
Claude Code

~/projects/my-app


⏺ jev-model-router@skills-dir loaded

⎿ function hooks registered


❯ Continue with the task


⏺ Jev Model Router is now hooking engine events.

现在你可以在claude里发出任何prompt,一个请求,同时评估三个问题:

  • 层级——从三种工作描述中选择一种(机械与本地处理/普通工程/高难度或高风险任务)。决策模型不会看到具体的模型名称。
  • 复杂度——根据四级评分标准来衡量任务所需的逐步推理程度。
  • 风险性——判断任务是否涉及生产、资金、资质或一旦出错就无法挽回的情况。

模型以及需要重写的代码量是每个请求的参数,而非会话设置,因此无论路由器做出何种决定,状态行、标题栏和代码量显示框的内容都不会发生变化。只是会根据任务难度选择不同模型执行。

简单的问题,如:hello,jev返回评分fast 0.99,选择了最低能力,最省钱的模型:claude-haiku-4-5-20251001/low。

QQ_1790945238754.png

复杂问题,如:

 分析 DrawingEntity.cs + CadTypesetter.cs 现状,为「CAD 页面排布位置鼠标拖拽」新设计做准备(那句记忆中的表述可能需要作为新设计重新写)

jev评分deep 0.35,选择了能力最强的 claude-opus-5。

QQ_1790945421237.png

注意默认jev-model-router不对切换模型,如果需要jev自动根据评分自动切换模型,需要在.claude/setting.json中配置routeMainModel参数:

 "pluginConfigs": {                                           
    "jev-model-router@skills-dir": {                           
      "options": {                                             
        "typesafeApiKey": "apikey_2207848***b114eff91fff825$
        "timeoutMs": 3000,                                     
        "routeMainModel": true                                 
      }                                                        
    }                                                          
  },