把开源代码审查工具接上百炼:踩坑记录 + 一次 PR 账单
最近在搞
上周刷 GitHub 看到阿里开源的 open-code-review(CLI 名 ocr)冲上了 Trending 本周 #1,一周涨了 15,028 颗星。Apache-2.0,Go 原生二进制,内置 28 个 LLM provider,其中就包含百炼的 dashscope。装了一台机器想试试,顺手把接百炼的坑和 PR 的账单都记下来。
环境踩坑记录
坑一:非交互式配置没有 flag
网上能找到的教程不少写了 ocr config provider --name xxx --base-url xxx。实际上 ocr config provider 和 ocr config model 是纯交互式 TUI,cobra.NoArgs,没有任何 flag。grep Flags\(\)|StringVar|BoolVar|IntVar 零命中。
非交互式的唯一路径是 ocr config set <key> <value>:
ocr config set provider dashscope
ocr config set model qwen3.8-max
ocr config set providers.dashscope.api_key sk-你的key
交互式的好处是走完会自动跑一次 ocr llm test 验证连通性,非交互式要自己手动跑。
坑二:只 export DASHSCOPE_API_KEY 不够
环境变量只补 key 那一份。ocr 的 resolver(internal/llm/resolver.go:149)要求完整的(URL、token、model)三元组。光 export 环境变量,另外两份还得靠 config 文件。
我一开始也只 export 了,卡在 ocr llm test 上半天。config 文件路径是 ~/.opencodereview/config.json,字段名是 provider、model、providers.dashscope.api_key,写错一个就废。
配置字段名也容易搞混:url 不是 base_url,model 是字符串(生效的模型),models 是数组(仅供 TUI 选择器用)。内置 provider 的 URL 挂在 providers.<name>.url,自定义 provider 在 custom_providers.<name>.url,两个不同的 map。
坑三:Anthropic 兼容端点 + thinking 模式 → 400
社区 issue #1064 有人报了:走百炼的 Anthropic 兼容端点,开着 thinking 模式,ocr 调 tool_choice=required 时收到 400 Bad Request。报错信息是 "The tool_choice parameter does not support being set to required or object in thinking mode"。
这个 issue closed 了但没有维护者评论,我没法断言已经修了。目前最稳的路径是走内置的 OpenAI 兼容端点,别自己改 Anthropic 兼容端点。
坑四:--page-size 100 静默返空
用百炼 CLI 批量查价的时候发现的。bl model list --page-size 20 正常,--page-size 100 返回 items: [] 还不报错。--output 也是,只接受 text 和 json,写错静默回落 text。
写脚本查价要对返回条数做断言,不然得出"这个模型不存在"的错误结论。还有一个坑:bl model list 返回的模型族有 179 个,但 --page-size 超过内部上限就静默返空。
坑五:flash 名字不承诺快
qwen3.8-flash 单价 ¥0.8/2.7(输入/输出,元每百万 token),看着是便宜档。但它默认就在深度思考,实测一次审 64 行代码烧了 12,909 个输出 token、跑了 241 秒、花 ¥0.0353,是 qwen-plus 的 9 倍。
3.8 这一代的 flash,名字里那点"快"已经不作数了。选档要看它会不会思考、思考多少,别只看名字和单价。
坑六:跨地域的 401
百炼的 API Key 是按地域绑定的。北京地域创建的 Key,拿去调新加坡或弗吉尼亚端点,返回 401。各地域端点:
| 地域 | Base URL |
|---|---|
| 北京(旧) | https://dashscope.aliyuncs.com/compatible-mode/v1 |
| 北京(工作空间) | https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 |
| 弗吉尼亚 | https://dashscope-us.aliyuncs.com/compatible-mode/v1 |
| 新加坡 | https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1 |
如果已经迁移到工作空间专属域名,用 ocr config set providers.dashscope.url 覆盖。注意 Base URL 以 /compatible-mode/v1 结尾,不包含 /chat/completions。
关于 OCR 是什么
补充一点背景。alibaba/open-code-review 是 Go 原生的代码审查工具,Apache-2.0,通过 npm 分发(@alibaba-group/open-code-review),支持 macOS/ Linux/Windows 多平台。它不走静态分析路线,而是把代码变更喂给大模型,让模型通过 tool calling 来"读懂代码再挑刺"。
这意味着模型必须原生支持 function calling。不是"能在文本里描述工具调用",而是真的通过 function calling 协议完成交互。这也是为什么 FAQ 明确说了 deepseek-r1 不能用——它只在 <think> 块里假装调用,实际并没有。
另一个容易被忽略的工程事实:社区有人实测 1,400 个 PR 跑了十多个小时,几行改动的小 PR 也要几分钟。它不是 pre-commit 工具,适合挂在 PR 合并门禁或者离线批量跑。
模型硬要求:必须支持 function calling
OCR 的审查完全靠 tool calling 驱动。模型必须原生支持 function calling,否则不管怎么调 prompt 都跑不通。官方 FAQ 点名 qwen3 可用。
百炼侧可以通过 bl model list --model <模型名> --output json 查看 features 字段是否包含 function-calling,这条命令免登录。
内置的 dashscope provider 预置模型列表前 5 个全是 qwen:qwen3.8-max、qwen3.7-max、qwen3.7-plus、qwen3.6-plus、qwen3.6-flash。另外还有 deepseek-v4-pro、kimi-k2.7-code、glm-5.2 等第三方模型,function-calling 支持情况要逐一确认。
账单怎么算的
同一份 64 行 Python 订单服务代码(埋 4 个真缺陷 + 2 个诱饵),同一个 prompt,7 个 qwen 模型各审一遍。
单价取自 bl model list --model <模型> --output json,免登录就能查。token 是 API 原样返回的 usage,耗时是客户端墙钟。每组只跑一次,没有重复取样。得分 = 抓到数 − 误报数,满分 4。
这个实验的设计要点是只变一个变量:模型。prompt 逐字节相同,输入文件相同,max_tokens 固定。唯一变化的是不同模型的 tokenizer 会导致输入 token 数略有差异(464 到 540 之间),但这不影响结论方向。
值得提前说明的是 reasoning token 不计入 max_tokens 限制。所以设置了 4096 的 max_tokens,旗舰档还是返回了 11,064 个完成 token,其中 9,770 个是思考。这是平台行为,不是 bug。
| 模型 | 思考 token | 抓到/4 | 漏报 | 误报 | 得分 | 耗时 | 审一次 ¥ |
|---|---|---|---|---|---|---|---|
| qwen-turbo | 不思考 | 2/4 | 2 | 4 | -2.0 | 7.4 秒 | 0.0007 |
| qwen3-coder-plus | 不思考 | 3/4 | 1 | 1 | 2.0 | 10.1 秒 | 阶梯计费,见控制台 |
| qwen-plus | 不思考 | 2/4 | 1 | 1 | 1.5 | 39.3 秒 | 0.0039 |
| qwen3.7-plus | 1,182 | 4/4 | 0 | 0 | 4.0 | 23.4 秒 | 见控制台 |
| qwen3.6-flash | 4,258 | 4/4 | 0 | 1 | 3.0 | 42.6 秒 | 见控制台 |
| qwen3.8-flash | 9,517 | 4/4 | 0 | 0 | 4.0 | 241.0 秒 | 0.0353 |
| qwen3.8-max | 9,770 | 4/4 | 0 | 0 | 4.0 | 293.1 秒 | 0.4048 |
三处"见控制台"不是留白:qwen3-coder 系列官方文档写明"采取阶梯计费",qwen3.7-plus、qwen3.6-flash 在 bl model list 里没返回单价。查不到我就不编。
三条规律
第一条,满分不需要旗舰。qwen3.7-plus 用 23.4 秒拿满分,qwen3.8-max 也满分但花了 293 秒。多出来的 8,588 个思考 token 和 270 秒在这份代码上没换来分数,但多报了三个我没埋的真问题——包括 amount <= 0 拦不住 float('nan') 这个 corner case。
第二条,分水岭是会不会思考。三个不思考的模型全部有漏报(-2.0、2.0、1.5),四个会思考的零漏报。但思考量过了 1,182 就不再换分。
第三条,便宜档的行号不能信。
| 模型 | 行号对了几条 |
|---|---|
| qwen-turbo | 0 / 9 |
| qwen-plus | 0 / 4 |
| qwen3-coder-plus | 1 / 5 |
| qwen3.6-flash | 2 / 5 |
| qwen3.7-plus | 6 / 6(±1) |
| qwen3.8-flash | 全对 |
| qwen3.8-max | 全对 |
turbo 把 SQL 注入报在第 9 行(实际第 18 行),空指针报在第 10 行(实际第 13 行)。描述对,位置错。便宜档输出当线索清单用,拿着描述自己找。
有意思的一个观察:qwen-plus 漏了空指针,qwen3-coder-plus 漏了竞态,两个便宜档漏的正好不重叠。各跑一遍交叉看能补盲区,但误报也会叠加,得人复核。样本只有 7 组,这是观察不是结论。
换算成能感知的单位
| 模型 | 审一次 | 1 块钱能审 | 审 100 次 | 每天 10 次 × 22 天 |
|---|---|---|---|---|
| qwen-turbo | ¥0.0007 | ≈1,345 次 | ¥0.07 | ¥0.16 |
| qwen-plus | ¥0.0039 | ≈256 次 | ¥0.39 | ¥0.86 |
| qwen3.8-flash | ¥0.0353 | ≈28 次 | ¥3.53 | ¥7.76 |
| qwen3.8-max | ¥0.4048 | ≈2 次 | ¥40.48 | ¥89.05 |
单价差 40 倍(输入 ¥0.3 vs ¥12),单次总账差 545 倍。算钱用 Decimal,Python 的 round() 是银行家舍入,账单会对不上。
from decimal import Decimal, ROUND_HALF_UP
def cost(in_tok, out_tok, price_in, price_out):
c = (Decimal(in_tok) * Decimal(price_in) + Decimal(out_tok) * Decimal(price_out)) / Decimal(1000000)
return c.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
跑起来要几步
装工具(需要 Node.js 和 Git ≥ 2.41):
npm install -g @alibaba-group/open-code-review
领 API Key:控制台密钥管理页。
三行配置 + 验证:
ocr config set provider dashscope
ocr config set model qwen3.7-plus
ocr config set providers.dashscope.api_key sk-你的key
ocr llm test
然后 ocr review 审工作区变更,ocr scan --path 任意目录 扫文件。
免费额度可用于白跑一遍:每模型独立、通常 100 万 Token、90 天有效期、仅华北2(北京)地域、过期不补发、用尽不会自动切换。
想自己查模型目录和单价,装阿里云百炼 CLI(bl),bl model list 这条命令免登录。
适用边界
- 不适合 pre-commit:社区实测 1,400 个 PR 跑十多个小时,几行改动的小 PR 也要几分钟
- 不替代静态扫描:规则引擎报确定命中的模式,它报读懂代码后觉得不对的地方
- 已有 Copilot / CodeRabbit 且用得顺手的,不需要换
每组只跑一次的局限性也得说清,同一模型跑两次得分会变。以上结论限定在这一次实测、这一份代码上。

浙公网安备 33010602011771号