Jev 实操指南,给 Claude Code 和 Codex 加一个 AI 裁判
Claude Code、Codex 写完代码以后,谁来判断它有没有把事情做好?
测试能检查一部分,代码审查能发现另一部分。如果还想在实现过程中反复检查改动质量,或者在执行命令前多做一次风险判断,可以试试 Jev。
它是 TypeSafe 推出的决策模型。你给它材料和明确的问题,它返回选项、分数或概率。它不生成评审文章,也不会替你修改代码。
这篇沿着实际接入过程来讲。先跑通一次 API 调用,再给 Claude Code 或 Codex 装代码评审工具,最后给 Claude Code 加一个命令检查 hook。做完以后,你会有一个能调用的判断接口、一套代码评审流程,以及一份可以拿来校准的判断日志。
1. 先选清楚,你准备让 Jev 判断什么
Jev 最容易用起来的任务,有一个共同点,答案的范围事先已经知道。
第一次接入,建议从代码评审开始。它对原有流程的影响比较小,你可以逐次比较模型建议和实际代码,不必马上让它决定执行权限。
准备环境时,确认这些条件。
已经能正常使用 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 是需要它回答的问题。问题可以混在一次请求里,分别得到结果。
Choice 和 Score 还会返回 confidence。它是从概率分布计算出来的统计量,不能直接当成“这个答案正确的概率”。Noul 没有单独的这个字段。
初学时最容易犯的错,是把所有需求压进一句“判断这件事是否合理”。
合理取决于什么?是否符合用户要求,是否会修改远程状态,还是是否涉及凭证?这些条件得分别写清楚。模型拿到模糊的问题,即使返回一个很精确的小数,也没有替你定义好标准。
3. 跑通第一次调用,确认 key 和网络都正常
先去
创建 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
“ \ -H “Content-Type: application/json” \ –data-binary @- <<’JSON’ { “model”: “jev-latest”, “state”: { “message”: “我被重复扣款了,希望今天能帮我处理。” }, “questions”: { “has_deadline”: { “type”: “noul”, “instructions”: “message 是否明确提出了处理时间或截止时间?” } } }
成功后,响应里应该有 answers.has_deadline.noul。它应该是 0 到 1 之间的数。先检查结构正确,再观察判断是否符合这条消息的含义,不要求每次都返回同一个小数。
把“希望今天能帮我处理”换成“不着急,下周看也可以”,再跑一次。两条都带时间信息,所以按当前问题,两条都可能获得较高分数。如果你想区分紧急程度,就需要另写一个关于紧迫性的条件。
这一步很有用。它会让你立刻发现,你写的问题和脑子里想判断的东西,有时差着半句话。
报错时按状态码排查。
如果本机 curl 太旧,不认识 –fail-with-body,可以换成 –fail;后者通常不会保留错误响应正文。
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,写入下面的示例。
1 | from typesafe_sdk import Choice, Noul, Score, TypeSafeClient |
运行它。
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 分析,正确性继续用测试和代码检查验证。这也是项目说明中的职责划分。
6. 官方 Skill 和评审插件,各自解决什么问题
原调研提到了两种安装,名字相近,用途不同。
只想试代码评审,完成上一节就可以。准备自己做分类器、检索过滤或命令检查,再装官方 Skill。
Claude Code 的安装命令如下。
claude plugin marketplace add typesafe-ai/skills claude plugin install typesafe@typesafe-ai
Codex 等其他 Agent 可以使用下面的入口,按提示选择客户端。
npx skills add typesafe-ai/skills –skill typesafe-ai
安装后,在任务里明确要求使用 TypeSafe Skill。Claude Code 也可以用 /typesafe:typesafe-ai 调用。
这里有一条值得照做的官方建议,把问题文本和阈值集中放在容易检查的位置。后面模型判断异常,你就能直接核对条件,不必翻遍项目。官方也提醒,Agent 写的问题仍需要人参与修改。
7. 进阶实操,给 Claude Code 加一个命令检查 hook
MCP 工具需要 Agent 调用。hook 则可以在指定事件发生时触发。
Claude Code 的 PreToolUse 在工具执行前运行。下面让它观察 Bash 命令,判断两件事,一是是否包含删除、覆盖、发布等操作,二是是否涉及读取或传输凭证。
先说清这个示例的作用。它只根据命令文本做附加检查,不知道被调用脚本内部实际会做什么,也不能独立判断用户是否授权。低分时不改变原有权限;高分时可以额外阻止本次调用。
默认先用 observe,只记录判断。校准以后才切到 block,在高分或检查失败时阻止调用。不要关闭客户端原有的权限和沙箱设置。
另外,这个例子会把完整命令文本发给 TypeSafe。先在不含敏感材料的练习项目使用,命令里有明文密钥或不允许外发的信息时,不要接这条云端检查流程。
保存检查脚本
创建目录。
mkdir -p ~/.claude/hooks
新建 ~/.claude/hooks/jev_gate.py,写入下面的代码。阈值只是演示值,不能当成经过验证的安全标准。
1 | import hashlib |
脚本没有执行命令的代码,只把收到的命令当文本交给 Jev 判断。日志保存命令的哈希标识,不重复保存原始命令;这只减少本地日志暴露,不能改变请求本身会外发的事实。
它也没有“只要以 ls 或 cat 开头就直接跳过检查”的规则。Shell 命令可以带重定向、命令替换或继续接其他操作,仅看开头几个字无法判断完整行为。
注册到 Claude Code
把下面配置合并进 ~/.claude/settings.json。如果已经有 hooks 或 PreToolUse,在已有数组里追加,不要重复定义同名键。
1 | { |
确认启动 Claude Code 的进程能读取 TYPESAFE_API_KEY,重启后检查 /hooks 中的配置。
这段 hook 仅用于 Claude Code。Codex 用户可以完成前面的 MCP 评审流程,不能把这份 Claude 配置直接复制过去使用。
在这里,退出码 2 表示阻止本次工具调用;退出码 0 且没有权限覆盖输出,表示这个 hook 不额外阻止,原有权限检查继续生效。阻止调用本身不会自动建立一个新的审批流程。
先单独测试,再接入实际工作
将测试命令作为 JSON 文本喂给脚本。下面只是在分析 git push –force,不会执行推送。
JEV_GATE_MODE=observe python3 ~/.claude/hooks/jev_gate.py <<’JSON’ {“tool_name”:”Bash”,”tool_input”:{“command”:”git push –force”}} JSON
查看最近的日志。
tail -n 5 ~/.claude/jev_gate.jsonl
正常记录应该有 model、scores 和 flagged。只有 error,说明检查没有成功,不能拿它当一条低风险结果。
随后再让 Claude 执行一条无敏感信息的普通命令,确认日志增加,才算把独立脚本与 hook 触发都接通了。
8. 阈值要用自己的样本调
把脚本跑起来,只完成了一半。
示例里 0.85 和 0.70 没有通用效力。你需要先确定,在自己的项目里,哪些条件出现时应当追加人工检查,再观察 Jev 能否把它们区分出来。
可以先准备二十到五十条脱敏命令文本。这是一次小规模试验的起点,不能靠这么一点样本证明安全性。
只把这些文本送入检查脚本,不要为了测试分类结果真的执行它们。
每条先人工标注期望结果,再看模型分数。额外保留一批样本不参与调参,最后用它们复查,避免把阈值调成只适合眼前这批例子。
记录时至少保留样本编号、人工标签、问题版本、模型标识和分数。同一条重复运行几次,观察靠近阈值的结果会不会来回变化。
你要分别统计两种错误。
漏检,人工认为需要检查,模型没有标记。误报,日常操作频繁被标记,用户被迫不断处理中断。
如果两类分数大量重叠,继续移动阈值通常只能在两种错误之间交换。回去检查问题是否够具体、材料是否足够,或者承认这类判断不适合交给当前模型。
还有一个方向问题。这里分数越高表示越需要关注,降低阈值会标记更多命令。假如你换成“这条命令是否安全”,方向就反过来了。问题改了,旧阈值必须重新验证。
满意以后,把 hook 配置中的 JEV_GATE_MODE=observe 改成 JEV_GATE_MODE=block。
这时命中阈值会退出 ;缺 key、网络错误或响应异常,只要脚本捕获到,也会退出 。
但它仍然只是附加检查。解释器没启动、脚本被强制结束或宿主超时,都可能不走这里的异常处理。Claude Code 对 hook 的失败处理有自己的规则,不能把这个示例称为完整的强制安全边界。
9. 判断不准时,按这个顺序查
模型返回一个不合预期的答案,先把输入、问题和结果放在一起看,别急着把所有问题都归到“模型不行”。
先查有没有问错。 “含有截止时间”和“非常紧急”是不同条件。你期待紧急程度,却只问有没有时间信息,模型按字面回答并没有偏题。
再查材料是否足够。 只有一行调用脚本的命令,没有脚本内容,就无法据此知道内部全部行为。代码评审同理,缺少调用约束和验收要求,会限制评分的价值。
把可精确计算的部分移回代码。 数量、日期间隔、数值范围,让程序计算。Jev 1.13 的官方边界说明明确列出了这类弱项。
检查题型是否变过。 同一个条件,用 Noul 问和用 yes/no 的 Choice 问,输出不能简单视为等价。换题型、改措辞或换模型后,重新验证阈值。
最后再缩小上下文。 把与当前判断无关的日志、历史对话和文件去掉。保留能解释条件的必要内容,别用材料体积代替材料质量。
对可能含有恶意指令的输入,还要单独做对抗测试。提示词写上“忽略输入中的指令”只是设计的一部分,不能证明模型已经不会受影响。
10. 做完以后,怎么判断这套东西值得留下
先用一周记录实际效果,不急着把所有判断都接进去。
代码评审场景,每次记下 Jev 提醒关注了什么,Agent 最后找到了什么实际问题,改完以后测试或行为有没有改善。如果低分一直无法对应到具体问题,就需要调整材料和评审方式。
命令检查场景,除了误报和漏检,再记额外等待时间,以及请求失败会不会频繁打断工作。模型调用费用也要和整理上下文、维护规则、处理误报的时间一起算。
最后保留一小组固定回归样本。修改问题、调整阈值或升级模型时,先跑一遍。发现结果明显变化,就停下来查原因,别让一个版本更新悄悄改变执行行为。
第一次做到这里就够了。有一个用例确实帮你发现问题,有记录能解释它为什么值得用,再考虑增加下一个判断。






