1. 为什么需要给 AI 编程助手配一个“裁判”
1.1 从两个真实场景说起
用 Claude Code 写一个 Express 中间件,它给你返回了一段代码,逻辑看起来没问题,但跑起来就是 500。你盯着屏幕看了十分钟,最后发现是async函数里漏了await。Codex 帮你重构一个 React 组件,改完之后 props 类型对不上,TypeScript 报了一堆红,但它信誓旦旦地说“已经修复”。这种场景,我相信每个深度使用 AI 编程助手的人都遇到过。
问题出在哪?出在AI 自己写、自己检查、自己说没问题。这就像让一个学生自己出题、自己答题、自己判卷,他当然觉得自己全对。我们需要的是一个独立的第三方,在 AI 提交代码之后、你合并之前,站出来说一句:“这段代码有问题,第 7 行的错误处理逻辑不完整。”
Jev 就是干这个的。它本质上是一个AI 裁判层,通过 MCP 协议挂载到 Claude Code 或 Codex 的工作流里,在代码生成之后自动触发一轮独立审查。注意,这里的“独立”很关键——它不是让同一个模型换个 prompt 再问一遍,而是走一套独立的审查逻辑和规则集。
1.2 Jev 到底解决了什么问题
我把 Jev 的价值拆成三个层面:
第一层,拦截低级错误。未处理的 Promise rejection、边界条件缺失、类型不匹配、资源未释放——这些错误人眼容易漏,AI 生成时也容易犯。Jev 的规则引擎会针对这些高频问题做定向扫描。
第二层,统一代码规范。团队里每个人用 AI 助手的习惯不同,有人喜欢让 Claude Code 生成完整文件,有人习惯让它改几行。Jev 可以在审查阶段统一执行团队的 lint 规则和架构约束,比如“所有 API 调用必须走统一的 request 封装”“禁止在组件里直接写 fetch”。
第三层,留下审查记录。每次 Jev 的审查结果都会生成结构化输出,谁在什么时候改了什么、裁判给出了什么意见、最终是否采纳,这些记录在排查线上问题时非常有用。
1.3 谁适合用这套方案
如果你只是偶尔用 AI 写个脚本,那 Jev 可能有点重。但如果你符合以下任一条件,这套方案值得花时间搭起来:
- 每天有超过 2 小时在和 Claude Code 或 Codex 协作写代码
- 团队多人共用 AI 助手,代码风格开始失控
- 项目对代码质量有硬性要求,不能接受“AI 写完直接合”
- 你在做 MCP 相关的开发,想看看一个真实的 MCP Server 是怎么设计的
我自己的情况是第二种和第四种的混合——团队里五个人都在用 Claude Code,代码 review 的时候经常发现 AI 生成的代码有相似的问题,与其每次人工指出来,不如让 Jev 在提交前就拦一道。
2. Jev 的核心机制与 MCP 协议拆解
2.1 MCP 协议到底是个什么东西
MCP 全称 Model Context Protocol,你可以把它理解成AI 助手和外部工具之间的 USB 接口。以前 Claude Code 只能用它内置的能力,你想让它调用一个外部的代码审查服务,得自己写插件、改配置,每个 AI 助手的方式还不一样。MCP 出现之后,只要你的服务实现了 MCP 协议,Claude Code、Codex 以及其他支持 MCP 的客户端都能直接挂载使用。
MCP 的核心概念只有三个:
- Server:提供能力的一方,比如 Jev 就是一个 MCP Server,它暴露了“审查代码”这个能力
- Client:消费能力的一方,Claude Code 和 Codex 都是 MCP Client
- Tool:Server 暴露的具体功能单元,一个 Server 可以有多个 Tool
通信方式上,MCP 支持 stdio(标准输入输出)和 SSE(Server-Sent Events)两种。本地开发用 stdio 最方便,Jev 跑在你本机,Claude Code 通过管道和它通信,不需要网络端口。如果要把 Jev 部署到团队服务器上共享,那就用 SSE 模式。
2.2 Jev 的审查逻辑是怎么设计的
Jev 不是简单地“再问一遍 AI”。它的审查流程分三步:
第一步,静态规则扫描。这一步不涉及大模型,纯粹是规则匹配。Jev 内置了一套针对常见 AI 生成代码问题的规则集,比如检测console.log残留、检测空的 catch 块、检测硬编码的密钥、检测未使用的 import。这一步速度快,误报率低,能拦下大概 40% 的问题。
第二步,上下文感知审查。这一步会调用大模型,但和生成代码时的 prompt 完全不同。Jev 会把代码变更的 diff、相关的文件上下文、项目的技术栈信息一起打包,发给一个专门调优过的审查 prompt。这个 prompt 的核心指令是“找出问题,而不是赞美代码”,和生成时的“帮我实现功能”是两种完全不同的思维模式。
第三步,规则与模型结果合并。静态扫描的结果和模型审查的结果会做去重和优先级排序,最终输出一个结构化的审查报告。报告里每条问题都有严重等级(blocker、warning、info)、具体位置、修改建议。
2.3 为什么选择 Jev 而不是自己写脚本
你可能会想,我自己写个 pre-commit hook 调一下 ESLint 不就行了?区别在于:
| 对比维度 | 自写脚本 | Jev |
|---|---|---|
| 审查范围 | 仅语法和风格 | 语法、逻辑、架构、安全 |
| 上下文理解 | 无 | 有,能理解 diff 和项目结构 |
| 与 AI 助手集成 | 需要手动触发 | 通过 MCP 自动挂载 |
| 审查记录 | 需要自己存 | 内置结构化输出 |
| 维护成本 | 规则要自己写 | 规则集持续更新 |
最关键的是集成方式。自写脚本你得记住在提交前跑一下,而 Jev 挂在 MCP 上之后,Claude Code 在完成代码生成后会主动调用它,不需要你额外操作。这个“自动”两个字,决定了它能不能真正融入工作流。
3. 从零搭建 Jev 审查环境的完整实操
3.1 前置准备:确认你的 AI 助手支持 MCP
不是所有版本的 Claude Code 和 Codex 都支持 MCP。先确认版本:
# 查看 Claude Code 版本 claude --version # 查看 Codex 版本 codex --versionClaude Code 需要 1.0.0 以上版本才内置 MCP 支持。Codex 的情况稍微复杂一些,它的 MCP 支持是通过配置文件启用的,需要确认你的版本号在 0.9.0 以上。
如果版本不够,先升级:
# 升级 Claude Code npm update -g @anthropic-ai/claude-code # 升级 Codex npm update -g @openai/codex注意:升级之前先备份你的配置文件,特别是
~/.claude/和~/.codex/目录下的内容。我有一次升级完发现自定义的 MCP 配置被覆盖了,重新配了半小时。
3.2 获取 Jev 并完成基础配置
Jev 目前提供了两种获取方式:npm 包和源码编译。推荐用 npm 包,省事:
# 全局安装 Jev npm install -g @jev/mcp-server # 验证安装 jev --version安装完成后,需要初始化配置。Jev 的配置文件默认在~/.jev/config.json,首次运行时会自动生成一个模板:
jev init生成的配置文件长这样:
{ "server": { "mode": "stdio", "port": 3456 }, "review": { "level": "standard", "rules": { "static": true, "contextual": true, "security": true }, "ignorePatterns": [ "**/*.test.ts", "**/*.spec.ts", "**/node_modules/**" ] }, "model": { "provider": "openai", "modelName": "gpt-4o", "apiKeyEnv": "JEV_MODEL_API_KEY" } }这里有几个关键配置需要根据你的实际情况调整:
review.level有三个档位:light、standard、strict。light只跑静态规则,速度快但漏报多;standard是默认值,静态加上下文审查;strict会额外开启安全扫描和架构合规检查,适合对质量要求极高的项目。
model.provider支持openai、anthropic和local。如果你用本地模型,把 provider 改成local,然后配置localEndpoint指向你的推理服务地址。
model.apiKeyEnv指定从哪个环境变量读取 API Key。不要把 Key 直接写在配置文件里,用环境变量更安全:
# 在 ~/.bashrc 或 ~/.zshrc 中添加 export JEV_MODEL_API_KEY="your-api-key-here"3.3 把 Jev 挂载到 Claude Code
Claude Code 的 MCP 配置在~/.claude/mcp.json。如果文件不存在就新建一个:
{ "mcpServers": { "jev": { "command": "jev", "args": ["serve", "--stdio"], "env": { "JEV_MODEL_API_KEY": "${JEV_MODEL_API_KEY}" } } } }配置完成后重启 Claude Code,然后在对话里输入:
/mcp list如果看到jev出现在列表里,说明挂载成功。接下来测试一下审查功能:
请帮我写一个 Python 函数,读取 CSV 文件并返回字典列表。写完后用 jev 审查一下。Claude Code 会先调用自己的生成能力写出代码,然后自动调用 Jev 的审查工具。你会看到类似这样的输出:
[Jev Review Report] File: read_csv.py Severity: warning Issues found: 2 1. [WARNING] Line 8: 文件打开后未使用 with 语句,存在资源泄漏风险 建议: 使用 with open(...) as f: 替代直接 open() 2. [INFO] Line 12: 未处理 CSV 解析异常 建议: 添加 try-except 捕获 csv.Error3.4 把 Jev 挂载到 Codex
Codex 的 MCP 配置方式和 Claude Code 略有不同。它的配置文件在~/.codex/config.toml,用的是 TOML 格式:
[mcp_servers.jev] command = "jev" args = ["serve", "--stdio"] [mcp_servers.jev.env] JEV_MODEL_API_KEY = "${JEV_MODEL_API_KEY}"Codex 对 MCP Server 的启动超时比较敏感,默认是 5 秒。如果你的机器比较慢,Jev 启动超过 5 秒,Codex 会认为挂载失败。可以在配置里加一个超时设置:
[mcp_servers.jev] command = "jev" args = ["serve", "--stdio"] startup_timeout_sec = 15配置完成后,在 Codex 里用/mcp命令查看挂载状态。Codex 的 MCP 工具调用语法和 Claude Code 不同,需要显式指定:
@jev review --file=./src/utils.ts或者在对话中直接说“用 jev 审查这段代码”,Codex 会自动识别并调用。
3.5 验证整套流程是否跑通
挂载完成之后,用一个真实的代码变更来验证。我建议用一个包含已知问题的文件来测试,比如:
# test_jev.py import os import sys def process_data(filepath): f = open(filepath, 'r') data = f.read() result = [] for line in data.split('\n'): if line.strip(): parts = line.split(',') result.append({ 'name': parts[0], 'value': int(parts[1]) }) return result这段代码至少有四个问题:文件未关闭、未处理文件不存在的情况、未处理 int 转换失败、未处理 parts 长度不足。让 Claude Code 或 Codex 调用 Jev 审查这个文件,如果 Jev 能报出其中至少三个问题,说明整套流程是通的。
4. 实操中踩过的坑与排查手册
4.1 MCP 挂载失败的常见原因
这是最高频的问题。Claude Code 或 Codex 报MCP server failed to start,原因通常有这几类:
第一类,路径问题。command字段写的是jev,但系统 PATH 里找不到这个命令。解决办法是用绝对路径:
{ "command": "/usr/local/bin/jev", "args": ["serve", "--stdio"] }用which jev命令可以查到绝对路径。
第二类,环境变量未传递。Jev 启动时需要读取JEV_MODEL_API_KEY,但 Claude Code 启动 MCP Server 时的环境变量和你的 shell 环境是隔离的。必须在配置里显式传递:
"env": { "JEV_MODEL_API_KEY": "sk-xxxx" }或者用${JEV_MODEL_API_KEY}引用,但前提是这个变量在 Claude Code 启动时就已经存在。
第三类,stdio 通信阻塞。Jev 在 stdio 模式下,如果启动过程中往 stdout 打印了日志,会干扰 MCP 的协议通信。检查 Jev 的日志输出配置,确保日志走 stderr 而不是 stdout:
{ "server": { "mode": "stdio", "logOutput": "stderr" } }4.2 审查结果误报太多怎么办
Jev 的standard模式在大型项目上可能会产生较多误报,特别是info级别的问题。我的处理方式是分两步:
第一步,调整 ignorePatterns。把测试文件、生成代码、第三方库目录都排除掉:
"ignorePatterns": [ "**/*.test.*", "**/*.spec.*", "**/dist/**", "**/build/**", "**/generated/**", "**/migrations/**" ]第二步,调整严重等级阈值。如果info级别的问题对你没价值,可以在配置里关掉:
"review": { "minSeverity": "warning" }这样只有warning和blocker会被报告出来。我自己的经验是,新项目用standard加minSeverity: warning,老项目迁移时先用light模式跑一段时间,等规则调优后再升级。
4.3 审查速度太慢的优化思路
Jev 的上下文审查需要调用大模型,每次审查大概 3-8 秒。如果每次代码变更都触发,确实会影响开发节奏。几个优化方向:
方向一,只审查变更部分。Jev 支持 diff 模式,只把本次变更的代码发给模型,而不是整个文件:
"review": { "diffOnly": true }方向二,缓存审查结果。如果同一个文件的同一段代码已经被审查过且没有变化,直接复用上次的结果:
"review": { "cache": { "enabled": true, "ttl": 3600 } }方向三,异步审查。让 Jev 在后台跑审查,不阻塞 AI 助手的响应。审查完成后通过通知的方式告知结果:
"review": { "async": true, "notifyOnComplete": true }我自己的配置是diffOnly: true加cache: true,日常开发基本感觉不到延迟。
4.4 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| MCP server failed to start | 命令路径错误 | which jev确认路径 | 配置中使用绝对路径 |
| 审查无输出 | API Key 未配置 | 检查环境变量 | 在 env 中显式传递 Key |
| 审查结果为空 | ignorePatterns 误匹配 | 检查文件是否被排除 | 调整 ignorePatterns |
| 审查超时 | 模型响应慢 | 查看 Jev 日志 | 切换更快的模型或开启缓存 |
| 重复报告同一问题 | 缓存未生效 | 检查 cache 配置 | 开启 cache 并设置合理 TTL |
| Codex 挂载失败 | 启动超时 | 查看 Codex 日志 | 增加 startup_timeout_sec |
4.5 几个我踩过的坑
坑一:不要在生产环境的 CI 里用 strict 模式。我一开始把 Jev 的 strict 模式接入了 CI,结果每次 PR 都被拦下来,因为 strict 模式会把所有console.log都标为 blocker。后来改成 CI 里用standard加minSeverity: warning,本地开发用strict,才找到平衡。
坑二:Jev 的审查结果需要人工确认。它毕竟是一个 AI 裁判,不是绝对真理。我有一次遇到 Jev 报了一个“安全漏洞”,仔细一看是误报——它把一段正常的字符串拼接当成了 SQL 注入。所以 blocker 级别的问题一定要人工复核,不要盲目相信。
坑三:模型选择影响审查质量。我试过用本地的小模型跑 Jev,速度快但漏报严重。后来换成 GPT-4o 级别的模型,审查质量明显提升。如果预算允许,审查用的模型不要比生成用的模型差太多。
坑四:配置文件不要提交到 Git。Jev 的配置文件里可能包含 API Key 的引用路径,虽然不直接暴露 Key,但不同开发者的环境变量名可能不同。把~/.jev/config.json加入全局 gitignore,团队共享的配置放在项目根目录的.jev/config.json里,用环境变量引用 Key。
5. 进阶玩法:让 Jev 融入团队工作流
5.1 团队共享的 Jev 配置方案
个人用 Jev 很简单,但团队用就需要考虑配置同步的问题。我的做法是分两层:
项目层配置放在项目根目录的.jev/config.json,包含团队统一的审查规则、ignorePatterns、严重等级阈值。这个文件提交到 Git,所有人共享。
个人层配置放在~/.jev/config.json,包含个人的 API Key、模型偏好、缓存设置。这个文件不提交,每个人自己维护。
Jev 启动时会先读个人层配置,再用项目层配置覆盖。这样既保证了团队规则统一,又保留了个人的灵活性。
5.2 把 Jev 接入 CI 流水线
在 CI 里跑 Jev 有两种方式:
方式一,作为独立的审查步骤。在代码提交后、合并前,CI 调用 Jev 的 CLI 模式审查变更:
# 在 CI 脚本中 jev review --diff=origin/main...HEAD --output=json > jev-report.json # 检查是否有 blocker 级别的问题 if jq '.issues[] | select(.severity == "blocker")' jev-report.json | grep -q .; then echo "发现 blocker 级别问题,阻止合并" exit 1 fi方式二,作为 PR 评论机器人。Jev 支持输出 Markdown 格式的报告,可以直接作为 PR 评论发布:
jev review --diff=origin/main...HEAD --output=markdown > jev-comment.md # 然后用 GitHub API 把内容发到 PR 评论我推荐方式二,因为审查结果直接展示在 PR 里,reviewer 能看到 Jev 的意见,讨论起来更方便。
5.3 自定义审查规则
Jev 内置的规则集覆盖了通用场景,但每个团队都有自己的特殊规范。Jev 支持自定义规则,规则文件放在.jev/rules/目录下,用 YAML 格式编写:
# .jev/rules/no-direct-fetch.yaml name: no-direct-fetch description: 禁止在组件中直接使用 fetch,必须走统一的 request 封装 severity: warning pattern: "fetch\\(" excludePaths: - "src/utils/request.ts" message: "请使用 request 封装替代直接 fetch 调用"这个规则会扫描所有包含fetch(的文件,除了src/utils/request.ts本身。自定义规则的 pattern 支持正则表达式,可以覆盖大部分场景。
5.4 审查结果的数据分析
Jev 每次审查的结果都会记录在~/.jev/history/目录下,按日期分文件存储。积累一段时间后,可以做数据分析:
# 统计最近 30 天各类问题的出现次数 jev stats --days=30 --group-by=severity # 输出示例 # blocker: 12 # warning: 87 # info: 234 # 查看最常出问题的文件 jev stats --days=30 --group-by=file --top=10这个数据对团队改进很有价值。比如发现某个文件反复出问题,可能是这个文件的代码结构本身有问题,需要重构。或者发现某类 warning 特别多,可以考虑把它加入自定义规则,在生成阶段就避免。
5.5 和其他 MCP 工具的配合
Jev 不是孤立的,它可以和其他 MCP 工具配合使用。比如:
- Playwright MCP:Jev 审查完前端代码后,Playwright 自动跑一遍 E2E 测试,双重验证
- 蓝湖 MCP:设计稿变更后,蓝湖 MCP 同步设计规范,Jev 审查代码是否符合最新设计规范
- BurpSuite MCP:安全扫描工具的输出可以作为 Jev 安全审查的补充输入
我目前的配置是 Jev 加 Playwright MCP,代码审查通过后自动触发 E2E 测试。如果测试失败,Jev 会重新审查相关代码,形成一个闭环。
6. 一些个人体会和后续扩展方向
6.1 关于 AI 裁判的边界
用了几个月 Jev 之后,我最大的体会是:AI 裁判不能替代人工 review,但能让人工 review 更聚焦。以前 review 代码,一半时间花在找低级错误上,另一半时间才用来讨论架构和逻辑。现在低级错误被 Jev 拦掉了,review 的时候可以直接讨论“这个抽象是否合理”“这个接口设计是否可扩展”,效率提升很明显。
但也要清楚 Jev 的局限。它擅长发现“代码和规则不符”的问题,不擅长判断“这个需求本身是否合理”。它能看到“这个函数没有错误处理”,但看不到“这个函数根本不应该存在”。所以人工 review 的价值不会消失,只是重心转移了。
6.2 后续可以怎么扩展
如果你已经把 Jev 跑起来了,可以考虑这几个扩展方向:
方向一,多模型交叉审查。用两个不同的模型分别审查同一段代码,对比结果。如果两个模型都报同一个问题,可信度就很高;如果一个报一个不报,就需要人工判断。Jev 的配置支持配置多个 model provider,按顺序调用。
方向二,审查结果反馈到生成阶段。把 Jev 的历史审查结果作为 few-shot 示例,注入到 Claude Code 或 Codex 的生成 prompt 里。这样 AI 在生成代码时就知道“上次这类问题被裁判拦过”,从源头减少问题。
方向三,自定义规则的市场化。如果你在某个特定领域(比如金融、医疗、游戏)积累了大量的审查规则,可以把这些规则打包成 Jev 的规则集分享给社区。Jev 的规则格式是开放的,社区已经有一些针对特定框架的规则集在流传。
6.3 最后分享一个小技巧
如果你觉得每次都要手动说“用 jev 审查一下”太麻烦,可以在 Claude Code 的CLAUDE.md或 Codex 的AGENTS.md里加一条指令:
每次生成或修改代码后,自动调用 jev 进行审查,并在回复中附上审查结果摘要。这样 AI 助手会在每次代码操作后自动触发 Jev,不需要你额外提醒。我加了这个指令之后,基本上就忘了 Jev 的存在——它变成了工作流里一个透明的环节,该拦的问题一个不落,不该打扰的时候一声不吭。这大概就是一个工具最好的状态。