背景
最近把一个 4500 行的 Python 项目(claude-code-tg,一个把 Claude Code CLI 桥接到 Telegram 的 Bot)丢给了 8 个不同的大模型做 Code Review,想看看在同样的代码、同样的上下文下,各家模型的”代码嗅觉”差距究竟有多大。
参评模型:
- Claude Opus 4.7(1M context)
- Kimi-k2.6(提交 3 份文件:综合 + 安全专项 + 任务清单)
- GLM-5.1
- DeepSeek-v4-pro
- Gemini CLI
- MiniMax-M2.7
- qwen3.7-max
- mimo-v2.5-pro
被审项目特点:197 个测试全绿、ruff 零告警,看起来很”干净”。但越是这种代码,越能考验 reviewer 的真实能力——能不能从测试覆盖良好的代码里挖出真问题,才是分水岭。
目标
我作为裁判要做的是:
- 不偏袒:哪怕 Claude Opus 是我自己家的模型,发现假阳性也要扣分
- 可验证:每一条”高危”指控都要打开实际代码核对,不能只听 reviewer 一面之词
- 多维度:从准确性、深度、实用性、平衡性、结构 5 个维度量化评分
- 找出独家发现:去重后真正”只有我看到”的 bug 才是模型能力的硬指标
遇到的问题
跑完 8 份 review 一对照,发现的”高危”问题严重打架:
- Claude Opus 标红
.env权限 0644 可被本机任何用户读 Bot Token - GLM 独家指出
_last_prompt单实例变量造成跨用户 prompt 泄漏 - DeepSeek 唯一抓到
cmd_logs --follow在日志轮转后会丢内容 - mimo 独家捕获
query.message=None时 stop callback 安全检查被绕过 - MiniMax 把已经用
with os.fdopen上下文管理的 status.json 写入误判为 fd 泄漏(假阳性) - Gemini 把
--dangerously-skip-permissions当成”YOLO 模式优势”夸赞(真高危被反向理解)
同一段代码,8 个模型给出了 6 种不同的”最严重问题”。这种分歧本身就是评测的价值。
排查过程与踩坑
验证方法
不能直接相信 review 文档里说的”高危”——必须用 Read/Bash 实地核对。每条指控都做一次”实测验证”:
实测一:.env 文件权限
ls -la *.env
# -rw-r--r-- ... a.env
# -rw-r--r-- ... b.env
# ...
✅ Claude Opus 的指控成立——多个 .env 文件全部 0644,Bot Token 对本机任意用户可读。这是一条只有 Claude Opus 发现的真高危。
实测二:_last_prompt 跨用户泄漏
# bot.py:52
self._last_prompt: str = ""
# bot.py:276
self._last_prompt = prompt # 任何用户的消息都覆盖到全局
✅ GLM 的指控成立——单实例变量,多用户场景下 A 的消息可被 B 通过 /status 看到。
实测三:MiniMax 声称的 status.json fd 泄漏
# bot.py:77-81
fd = os.open(str(self.status_file), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
with os.fdopen(fd, "w") as f:
f.write(content)
❌ 假阳性——with 上下文管理器已经会在退出时关闭 fd。MiniMax 没看清代码就标红。
实测四:mimo 独家指出的 stop callback 绕过
# bot.py:380
if query.message and query.message.chat_id != chat_id:
return
✅ 真实——当 query.message 为 None(消息已被删除等),and 短路使整个表达式为 False,安全检查被跳过。8 个 review 里只有 mimo 看到了这个 corner case。
踩坑:评分体系的设计
尝试一:单一总分(失败)
最初想直接打个 1-100 的总分。问题:信噪比一团乱——Gemini 写得很流畅但全是软文,DeepSeek 简洁但只找到 1 个独家 bug,没法用单一维度公正区分。
尝试二:5 维加权评分(成功)
最终采用:
| 维度 | 权重 | 衡量什么 |
|---|---|---|
| 准确性 | 25 | 指控是否经得起实测,假阳性扣分 |
| 深度 | 25 | 是否触达架构/安全模型层面,独家发现是硬指标 |
| 实用性 | 20 | 修复建议能否直接套用 |
| 平衡性 | 15 | 优缺点比例是否得当 |
| 结构 | 15 | 章节组织、可读性 |
并要求每条”独家发现”必须先实测核对——最后筛掉了 3 个被多家声称但实际不存在或夸大的”高危”。
踩坑:自评利益冲突
Claude Opus 是我自己家的模型,又当裁判又当选手,怎么避免偏袒?
做法:在 Claude Opus 的评语里显式列出它的扣分项——体量过大(36k 字符冗余)、把 GIL 单线程 asyncio 下的”竞态”严重程度拔高、状态一致性论述偏理论。最后给 96 分而不是满分,扣的就是这部分。
解决方案:公正评分结果
经过实测验证后的最终排名:
| 排名 | 模型 | 总分 | 评级 | 一句话 |
|---|---|---|---|---|
| 🥇 1 | Claude Opus 4.7 | 96 | S | 最深最全,但自评有偏 |
| 🥈 2 | qwen3.7-max | 86 | A+ | 平衡感最好的工程师视角 |
| 🥈 2 | Kimi-k2.6 | 86 | A+ | 三件套最工程化 |
| 🥈 2 | GLM-5.1 | 85 | A+ | 独家命中跨用户 prompt 泄漏 |
| 5 | mimo-v2.5-pro | 81 | A | 独家捕获 query.message=None 安全绕过 |
| 6 | DeepSeek-v4-pro | 78 | A | 简洁锐利,独家 log 轮转 bug |
| 7 | MiniMax-M2.7 | 73 | B+ | 中规中矩,1 处明显假阳性 |
| 8 | Gemini | 57 | C+ | 几乎是软文级别的夸赞 |
各 AI 详细评语
Claude Opus 4.7(96 分)
- 强项:唯一实测出
.env0644 的;OWASP 完整映射;P0/P1/P2/P3 优先级清晰;修复代码可直接套用。 - 短板:体量 36k 字符过大;某些”竞态”在 GIL 下严重程度被高估。
qwen3.7-max(86 分)
- 独家发现 4 项:
_read_pidPermissionError 误判、_drain_queuewhile 异常丢消息(比 Claude Opus 的”竞态”判断更精确)、encode_project_path哈希碰撞、.env.example缺失。 - 自我审慎:M5 主动标注”当前用纯文本所以影响不大”,避免假阳性灌水。
- 信噪比最高,几乎无假阳性。
Kimi-k2.6(86 分)
- 三份文件结构最专业(综合 + 安全专项 + 任务清单含工作量预估)。
- 独家发现
encode_project_path注释/实现不一致。 - 漏掉
.env权限、_process_message竞态、resume 跨 chat 接管。
GLM-5.1(85 分)
- 独家命中
_last_prompt跨用户泄漏(真实高危,其他 7 家都没看到)。 - 独家发现
timeout=0禁用超时、cmd_restart无间隔。 - 模块级星级评分实用,测试覆盖盲区分析最具体。
mimo-v2.5-pro(81 分)
- 5 项独家发现:
query.message=None安全绕过(亮点)、read_env_list静默忽略非数字、stderr 正常退出时未读、status.json 字段冗余、logger f-string。 - H1 浮夸:把”prompt 在
-p后不会被当作 flag”误判为命令注入风险。 - “小处细致、大处失明”——独家发现细节但漏掉
.env权限。
DeepSeek-v4-pro(78 分)
- 独家发现
cmd_logs --follow日志轮转 bug(与 dashboard 的_read_log_lines做了对比,论证力强)。 - 安全审查”已做好”清单写得最好(建设性)。
- 体量精简,信噪比高。但深度不足,结论”可发布”过于乐观。
MiniMax-M2.7(73 分)
- 最大假阳性:把已用
with上下文管理器的 status.json 写入误判为 fd 泄漏。 CLAUDE_SKIP_PERMISSIONS论述存在事实错误。- 漏掉大多数高危。
Gemini(57 分)
- 几乎是软文级别的夸赞——没找出任何具体 bug、没识别任何高危。
- 4 条”优化建议”全是 nice-to-have(SQLite/多媒体/沙箱/日志轮转)。
- 把
--dangerously-skip-permissions当卖点夸赞而非风险,作为 code review 严重失职。
独家发现统计(去重后)
| 模型 | 真独家高/中危计数 |
|---|---|
| Claude Opus 4.7 | 5(.env 权限 / _process_message 竞态 / resume 跨 chat / stderr 死锁 / sanitizer 漏过 sk-ant/ghp/JWT/PEM) |
| mimo-v2.5-pro | 5(query.message=None / read_env_list / stderr 正常退出未读 / status.json 冗余 / logger f-string) |
| qwen3.7-max | 4(_read_pid 权限 / _drain_queue while 异常 / encode_project_path 碰撞 / .env.example 缺失) |
| GLM-5.1 | 3(_last_prompt 跨用户 / timeout=0 / cmd_restart 无间隔) |
| DeepSeek-v4-pro | 1(cmd_logs —follow 日志轮转) |
| Kimi-k2.6 | 1(注释/实现不一致) |
| MiniMax-M2.7 | 0.5(osascript 注入与 Claude Opus 同时) |
| Gemini | 0 |
经验总结与工具推荐
核心教训
1. “测试全绿 + lint 通过”≠ 没问题。
项目 197 个测试全绿、ruff 零告警,但仍藏着至少 5 个真高危:.env 0644、_last_prompt 跨用户、resume 跨 chat 接管、stderr 管道死锁、stop callback 绕过。测试覆盖率是地板,不是天花板。
2. 越像 “S 级 review” 的报告,越可能是软文。 Gemini 的报告语言流畅、有架构图、有”设计哲学解读”,但 0 个具体 bug。一份高质量 code review 应该让你不舒服——会指出你不愿面对的债务。读起来太爽的 review,反而要警惕。
3. 假阳性比漏报更坏。
MiniMax 把 with os.fdopen 误判为 fd 泄漏,会让用户去”修”一个不存在的问题,浪费时间还可能引入 regression。漏报只是少了一份保险,假阳性会主动制造伤害。
4. 独家发现是模型能力的硬指标。
跟风指出”.env.example 缺失”这种谁都能看到的没意义。真正分高下的是 8 家里只有 1 家看到的那条 bug——_last_prompt 跨用户泄漏(GLM 独家)、query.message=None 安全绕过(mimo 独家)、cmd_logs --follow 日志轮转(DeepSeek 独家)。这些是模型”代码侦探”能力的真实切片。
5. 自评必有偏,要主动扣分。 我作为 Claude,给 Claude Opus 打分时,最容易陷入”自家孩子最好”的偏袒。解决办法是先列扣分项再给分——逼自己说出对方哪里不好。
实用工具与命令
实测验证 review 指控:
# 验证文件权限指控
ls -la *.env
# 验证"竞态"指控前先看 GIL 模型
# Python asyncio 单线程内不会有真竞态,但 finally 时序问题真实存在
grep -n "busy.discard\|_drain_queue" bot.py
多模型并行 review 的高性价比组合:
如果只能选 3 家:Claude Opus(深度)+ qwen3.7-max(信噪比)+ GLM-5.1 或 mimo(独家细节)。三家组合的覆盖面已经接近 8 家全跑。
避坑清单:
- 看到 review 里”该项目可发布”或”工业级质量”,警觉是软文模式
- 看到只有架构图没有具体 bug 的 review,跳过不读
- 看到任何”高危”指控,先 grep + 实测,不要直接相信
值得关注的资源
- 项目本体:
claude-code-tg(一个把 Claude Code CLI 桥接到 Telegram 的 Bot) - review 评分维度的灵感来源于 OWASP Top 10 + 经典 code smell 分类
- 多模型对照本质上是”反对意见的市场”——参考 Karpathy 关于 LLM ensemble 的讨论
最后一句感想:让 8 个模型同台 review 一份代码,最大的收获不是评分本身,而是看到”同一段代码在不同视角下的呈现”——有人看到的是命令注入风险,有人看到的是架构债,有人看到的是文档过时。一个工程师在 review 自己的代码时,只能站在一个视角;而 8 个模型让你同时站在 8 个视角。这是单模型 ensemble 之外、多模型对照独有的价值。