背景

最近把一个 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 的真实能力——能不能从测试覆盖良好的代码里挖出真问题,才是分水岭。

目标

我作为裁判要做的是:

  1. 不偏袒:哪怕 Claude Opus 是我自己家的模型,发现假阳性也要扣分
  2. 可验证:每一条”高危”指控都要打开实际代码核对,不能只听 reviewer 一面之词
  3. 多维度:从准确性、深度、实用性、平衡性、结构 5 个维度量化评分
  4. 找出独家发现:去重后真正”只有我看到”的 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.messageNone(消息已被删除等),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 分而不是满分,扣的就是这部分。

解决方案:公正评分结果

经过实测验证后的最终排名:

排名模型总分评级一句话
🥇 1Claude Opus 4.796S最深最全,但自评有偏
🥈 2qwen3.7-max86A+平衡感最好的工程师视角
🥈 2Kimi-k2.686A+三件套最工程化
🥈 2GLM-5.185A+独家命中跨用户 prompt 泄漏
5mimo-v2.5-pro81A独家捕获 query.message=None 安全绕过
6DeepSeek-v4-pro78A简洁锐利,独家 log 轮转 bug
7MiniMax-M2.773B+中规中矩,1 处明显假阳性
8Gemini57C+几乎是软文级别的夸赞

各 AI 详细评语

Claude Opus 4.7(96 分)

  • 强项:唯一实测出 .env 0644 的;OWASP 完整映射;P0/P1/P2/P3 优先级清晰;修复代码可直接套用。
  • 短板:体量 36k 字符过大;某些”竞态”在 GIL 下严重程度被高估。

qwen3.7-max(86 分)

  • 独家发现 4 项:_read_pid PermissionError 误判、_drain_queue while 异常丢消息(比 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.75(.env 权限 / _process_message 竞态 / resume 跨 chat / stderr 死锁 / sanitizer 漏过 sk-ant/ghp/JWT/PEM)
mimo-v2.5-pro5(query.message=None / read_env_list / stderr 正常退出未读 / status.json 冗余 / logger f-string)
qwen3.7-max4(_read_pid 权限 / _drain_queue while 异常 / encode_project_path 碰撞 / .env.example 缺失)
GLM-5.13(_last_prompt 跨用户 / timeout=0 / cmd_restart 无间隔)
DeepSeek-v4-pro1(cmd_logs —follow 日志轮转)
Kimi-k2.61(注释/实现不一致)
MiniMax-M2.70.5(osascript 注入与 Claude Opus 同时)
Gemini0

经验总结与工具推荐

核心教训

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 之外、多模型对照独有的价值。