reverse-skill 实测:36.9k 星的技能路由包,它自己 178 条路由全绿,我出的 56 条错了 7 条

reverse-skill 实测:36.9k 星的技能路由包,它自己 178 条路由全绿,我出的 56 条错了 7 条

132 天 36,908 星,平均每天约 280 个 star——reverse-skill 是近期安全向 Agent 技能里涨得最快的一个。它的判断很简单:AI 不是不会用工具,是不知道该用哪个工具,于是把 44 条路由规则摆在最前面,让 jadx、IDA、Frida、Burp 先各归各位,再进入 45 个场景模块里的那一个。仓库自带 178 条路由回归用例,我在 Linux 上全量跑完,178 条全绿;随后自己出 56 条对抗用例,它错了 7 条,其中 3 类是真问题——最典型的一个 bug,会让「sandbox escape」这种标准提法被路由去分析恶意软件。

一个「先选剧本再动手」的技能路由包

拆开仓库,它由三层组成:单一事实源 skills/config/routing.json(15,089 字节,44 条规则按优先级排列,每条规则由 must 命中、mustAll 全中、exclude 一票否决三段组成)、45 个场景模块的 SKILL.md,以及一套 bootstrap 脚本负责探测本机工具链。路由产出 PRIMARY/SECONDARY 两档 skill 路径和置信度(high/medium/low),还附带 case-init 流程:授权范围与网络档没就绪之前,不许对真实目标动手。

项 我实测的数字
路由规则 44 条(R0–R45,R0 为兜底),优先级链单独列出
场景模块 45 个 + 根路由 SKILL.md,INDEX.md 由脚本自动生成
CTF 子技能 41 个 competition-* 目录、42 个 SKILL.md
SKILL.md 合计 46 个、324,983 字节,按 1.8 字节/token 约 18 万 token
首屏负担 主路由只读 routing.json + MASTER-ROUTING.md(7,435 字节),模块按需展开
提交与人力 181 次提交、15 位贡献者(前三名 42、36、36 次)

上手路径也是三条:给 Claude Code 装 reverse-skill 插件、复制仓库根的 AGENTS.md 到项目 AGENTS/、或 git clone 后用 master-route.sh 单独跑路由——仓库为 Claude、Codex、OpenCode、Cursor、Copilot、Gemini 各准备了各自的桥接文件(CLAUDE.md、AGENTS.md、opencode.json、GEMINI.md 等),最小加载路径甚至可以为零。我在干净的 Alpine 沙盒里跑了 bootstrap:--list 列出 23 项发现能力、7 个工具组、4 条纪律(只发现不激活、MCP 默认不注册、每个安装给一行理由、端口只读探活),并直接点名缺 java、jadx、frida、radare2;它的工具索引刷新后给出 34 项清单,只有 5 项在沙盒里可用(python3、node、npm、npx、burp-mcp-full),每个缺失项都带 install_hint。路由的判定逻辑可以一句话概括:must 命中、mustAll 全中、exclude 一票否决,同分时按优先级链仲裁——官方基准里就有「ghidra + .so」这种用例:两条规则都命中,预设路由是 ghidra 而不是 IDA,靠的正是优先级而非关键词数量。

我抽开了被路由频次最高的 apk-reverse 模块:11,727 字节、14 个 H2,开头是五步 ACTION REQUIRED——NOW 读 precedent-reverse.md 确认这是已授权的常规操作、NOW 核对适用范围、NEXT 查 tool-index.md 校验工具真实路径、缺工具就调 bootstrap 而不是猜路径、ACT 进工作流第一步别停在确认状态;结尾则是「任务完成自检(声称完成前 MUST 通过)」,中间夹着工具分工、自带脚本、禁止事项、输出要求、路由上下文和按需自举六段。相邻的 mobile-reverse 是 6,234 字节,结构同款。首尾各一道强制协议,比在提示词里写一句「要注意安全」硬得多——agent 想跳过,得先跳过自己刚读过的清单。

授权边界在这套体系里不是口头约定。master-route.sh 的下一步是 case-init:先写 scope 文件,声明 authorization_ready(靶标、测试账号、时间窗)、network_profile(read_only / controlled_active / active 三档)和 response_format(no_write / read_only / active),三者没对齐之前,R45 的强制 scope 检查不让任何 ACT 动作落地。配套的 RULES.md(中英两版)还写了更细的硬约束,比如单个红队阶段不超过 5 分钟、不超过 15 个动作,收尾必须提交 Evidence → Finding → Path 三件套到时间线,报告格式由 REPORTING.md 模板锁死。换句话说,它把「你有没有资格动手」变成了一个可被 agent 循环反复校验的状态,而不是一句提示词里的情绪表达。

这个体量设计值得单独说一句。我们评测过的 a-stock-data 把 7,288 行塞进单个 SKILL.md,一次加载 11 万 token;reverse-skill 的 46 个 SKILL.md 全量也有 18 万 token,但它是路由型结构,首轮只读十 KB 级的路由配置,命中哪个模块才开哪个——同一堆文档,上下文成本差一个量级。对比同赛道的大星仓库:ECC 25.5 万星管的是工程纪律,marketingskills 47k 星管的是营销流程,reverse-skill 管的是危险动作的顺序与授权边界——这是三者里唯一把「不许对没授权的目标动手」写进流程的。

实测一:它自己出的 178 道题全绿,状态表却写错了

克隆仓库后我把六套测试全部跑了一遍:

测试 结果
test-routing(路由回归) 178/178 全绿;其中 quick 冒烟 44 条、中文用例 103 条、英文 75 条,44 条路由全部有覆盖
test-bash-workflow 5/5,1.9 秒;含网络档校验、未授权拒绝两条安全断言
verify-repository-security 599 个文件全部被跟踪、74 个可执行源、无符号链接,OK
verify-doc-links 全部内部 Markdown 链接可达
bootstrap 两套回归(manifest + client-neutral) 全过
refresh-tool-index 34 项工具只探测到 5 项可用(python3/node/npm/npx/burp-mcp-full),java、jadx、frida、r2 全缺,每项附 install_hint

基准本身的质量高得超出预期:每条路由至少 2 条用例、44 条全覆盖、中英双语,还是跨平台 CI(Windows + Ubuntu)跑的。但README 的 Current status 表把回归基准写成 175 cases,实际文件里是 178 条(基准 meta 停在 2026-08-02)——文档和数据第一次对不上,就发生在最该对得上的那个数字上。治理面同样偏紧:15 位贡献者、18 个 open issue、7 个 closed,唯一的 PR 还挂着,0 个被合并,主线实际上仍是作者一人在推(最新提交 9 月 22 日)。文档滞后一两天不致命,但滞后偏偏发生在 README 首屏的状态表里——后来者第一眼看到的就是一个错数。

实测二:我出的 56 条对抗用例,49 过 7 错

官方基准的用例几乎都含规则里的字面关键词,等于命题人和考生共用一张表。我另出 56 条:口语化重述、中英混合、多个技能域竞争,全部走真实入口 master-route.sh。结果 49 过 7 错(中文 45/51、英文 4/5),单次路由延迟 min 304ms / p50 358ms / p90 683ms。7 条失败分三类:

类型 用例 → 实际路由 判定
子串误命中 docker sandbox escape → malware-analysis 真 bug
关键词不对称 redis 未授权访问安全评估 → R11 通用渗透 真洞
优先级平局 iOS APP 证书校验绕过 objection → apk-reverse 真错
平局取工具方 用 nmap 扫完出个报告 → R11;mysql 注入 → R35 可辩护
口语掉置信 抓一下 APP 的请求看看签名怎么算 → R0,confidence=low 标记正确

第一个是实锤 bug:R9 恶意软件规则的 mustAll 里有一项裸词 cape(指 CAPE 沙箱),没有词边界,于是 “escape” 直接命中。我补测了四个变体:「sandbox escape」「k8s sandbox escape」「escape from sandbox」全部被判给 malware-analysis,只有中文「容器逃逸」落到正确的 cloud-k8s——因为规则写的是 docker.?escape|container.?escape,中间插一个词就不匹配,而官方基准里 R23 的逃逸用例措辞恰好全都带字面 container/docker,所以 178 条自测全绿也测不出这个洞。第二个是规则不对称:mysql、postgres、mongodb 是裸词直达 R35 数据库安全,redis 却要求 redis.?secur 相邻出现,一句「redis 未授权访问」(渗透测试里最经典的一句话)就漏到了通用渗透。第三个是优先级设计:iOS 与 APK 两条规则同时命中时,R1 排在 R2 前面,于是带 objection 的 iOS 任务进了 APK 技能。

我又围绕这个洞补了四个探针:「sandbox escape」「k8s sandbox escape」「escape from sandbox」三条英文全部落进 malware-analysis,「sandbox 逃逸」因为没有 escape 字面、R9 的 mustAll 不成立,干脆跌到逆向工程兜底——同一个意思,换种说法就换来三种不同结局,路由表对英文子串的敏感和对中文语义的迟钝同时暴露。

值得肯定的是置信度机制真的在工作:中文口语「抓一下这个 APP 的请求看看签名」匹配不到任何字面关键词,路由退回兜底 R0 并标了 confidence=low——它知道自己没听懂,这比硬给一个 high 强得多。合起来看,官方基准考的是「关键词表内命题」,我的 56 条考的是「把同一件事换种说法再问一遍」——178/178 与 49/56 之间的差距,就是这套路由在真实对话里的安全边际。

生态、赞助与中文圈的数字滞后

项目挂了三家赞助(UCloud AstraFlow、AtlasCloud、Kite AI),自建了教程站与 star-history 图,并上了 Trendshift 榜。文档纪律倒是罕见地完整:REPORTING.md 约束证据格式(Finding 必须带 PoC、Path、Impact 三件套)、CHANGELOG 记录到最近一次提交(v1.0.1 是唯一正式 release)、RULES 有中英两版,甚至 burp-mcp-full/ 里嵌了完整的 MCP 服务端代码。中文圈已有教程向覆盖:知乎两篇、腾讯云一篇、CSDN 与 CodePass 各一篇,但口径明显滞后——8 月 20 日的知乎长文还写着「41 条路由规则 + 163 个回归用例」(现在是 44 + 178),Threads 上 20 小时前的热帖还在转「27.5k 星」,而我实测拿到的是 36,908,两天差了九千多。没有一篇做过实测复核——中文教程基本停在安装向,没人跑过一次 test-routing,也没人指出 README 状态表与实际文件差了 3 条用例。这也是本文只做一件事的原因:把它自己出的题和我出的题都跑一遍,让 36,908 这个星数落在可验证的地面上。

什么时候不适合用

它不是万能插件,四种场景建议绕开:任务不在 44 条规则覆盖域里(Web CRUD、数据分析、写作润色),每次请求都要先付一遍路由上下文再落到 R0 兜底,纯亏;中文口语描述容易掉出关键词覆盖,命中不了就得自己补一句术语(我实测中文场景 88% 通过,剩下基本败在口语重述上);越是关键任务,越不能只信那 178 条全绿——cape 这个洞证明自测基准有盲区,master-route 的输出要人眼过一遍再往下走;另外它的主线是 Windows(PowerShell 一等公民,bash 是对等移植),Linux/Kali 用户建议直接读 kali/ 平台文档。如果你只是想给 Agent 加一个单点能力,装个几百行的小 skill 比引一整套路由与授权流程轻得多——那样的话,先看你更适合哪种,再决定要不要它。

CommandCode 上的 MiMo-V2.6 实测:GOAT 订阅下每百万 token 约 6 美分,但 Flash 并不快

CommandCode 上的 MiMo-V2.6 实测:GOAT 订阅下每百万 token 约 6 美分,但 Flash 并不快

如果你每个月在 AI 编程上要花掉 10 美元以上,今天这条值得看完:CommandCode 把小米今天凌晨发布的 MiMo-V2.6 三个档位全部上架了,而且费率跟小米官网一分不差——Pro 输入每百万 token 0.435 美元、输出 0.87 美元,Flash 是 0.14 与 0.28。放在 GOAT 计划里,$10 换 $70 额度,折扣率 7 倍。

「7 倍额度」是数学还是话术,两周半前写过一次。这次换个问法:同一个活,交给四个模型做,谁把活干完、谁花得更少。我用账号里的 Provider API 跑了六组全自动判定的任务——没有一项靠人打分,对错由 pytest、JSON 解析和字符串匹配决定——把 MiMo V2.6 Pro、MiMo V2.6 Flash,和同平台上的 DeepSeek V4.1 Flash、GLM-5.3 Flash 放在同一张题卷上。

结论先说:MiMo V2.6 两档都能干活,端到端成本比直连小米官网便宜约 7 倍;但「Flash」这名字没带来速度,而最大的坑不在价格表上,在三个平台细节里。

它是什么,档位怎么选

CommandCode 是一套以开源模型为优先的编码 agent(CLI 加网页工作室),同时提供 OpenAI 与 Anthropic 双兼容的 Provider API,端点 https://api.commandcode.ai/provider/v1。MiMo V2.6 的三档今天上架,模型 ID 是 xiaomi/mimo-v2.6-pro、xiaomi/mimo-v2.6-flash、xiaomi/mimo-v2.6-pro-ultraspeed,都标 1M 上下文。

档位地图(价格截至 2026-09-22,另收支付手续费):

套餐 月费 额度 适合谁
Go $1 $10 只想试一下,约 1.5 万次请求
GOAT $10 $70 个人主力,约 7.5 万次请求
Pro $20 $80 需要闭源旗舰模型(Claude、GPT、Gemini)
Max 10× / 20× $100 / $200 $150 / $300 重度用户,额度上限更高
Provider $15 起 按量付费 自建脚本调 API,零加价、不限流

倍率从哪来,官方没有藏着:一是额度按模型独立分配($70 不是一个大池子,而是每个模型一份),二是缓存命中工程的差价,三是厂商 deal 补贴。第三条对 MiMo 用户特别现实——mimo-v2.6-flash 有个上架 deal,GOAT 上这个模型的额度临时提到 $67(平时 $30),9 月 24 日截止;上一代 V2.5 系列则挂着 -98% 与 -99% 的折扣。

对照一下直连:小米官方海外定价与 CommandCode 完全一致(Pro $0.435 / $0.87,缓存读 $0.0036),所以这里的「便宜 7 倍」纯粹来自订阅额度,不是平台压价。

先做纸面数学,再谈体验。官方给的「约 7.5 万次请求」是个容易误读的数字——它指的是轻量 agent 请求。按我下面实测里最便宜的动作(修一个 bug,账单 $0.00013)算,$70 足够跑 50 万次以上;换成最贵的动作(一次 12.9 万 token 的长上下文,账单 $0.0564),$70 只够 1,240 次。同样一笔钱,容量差 400 倍,取决于你每次让它读多少东西。所以「够不够一个月」这个问题,答案不在套餐页上,在你的使用姿势里:把复用前缀固定住、让缓存吃满,比换模型省钱得多。

实测:六组任务,四个模型

方法说明白:走 Provider API 直连,/chat/completions,温度与输出上限按任务固定;六个任务全部可机器判定——T1 是给一个预埋了 3 个 bug 的小仓库(6 个 pytest 用例,初始 3 失败 3 通过),模型交回完整文件,我应用后跑测试;T2 是两轮真实工具循环,看它会不会用 read_file 读完两个文件、再用 run_tests 带 -v 跑测试;T3 是把 23.7 万字符(实测 129,521 token)的合成代码库塞进去找一句藏起来的话;T4 是严格 JSON 指令遵循;T5 是一道可判定的多步概率题;T6 量时延与吞吐。

任务 MiMo V2.6 Pro MiMo V2.6 Flash DeepSeek V4.1 Flash GLM-5.3 Flash
T1 修 3 个 bug(6 用例) 通过 6/6 通过 6/6 通过 6/6 通过 6/6
T2 两轮工具调用 通过 通过 未跑完(网关超时) 未跑完(网关超时)
T3 12.9 万 token 藏针 答对 答对 未答出 未测
T4 严格 JSON + 枚举 通过 通过 通过 通过
T5 多步推理(0.65) 通过 通过 通过 通过
T6 时延中位 / 吞吐 7.60 秒 / 9.1 tok/s 6.29 秒 / 12.9 tok/s 7.84 秒 / 16.3 tok/s 9.51 秒 / 13.5 tok/s

三个可以直接用的观察。第一,能力层面四个模型打平——修 bug、工具调用、JSON、推理这四关谁都没掉队,MiMo V2.6 的「agentic coding」定位不是虚的,Pro 与 Flash 在这几关没有可见差距。第二,长上下文分开了档次:12.9 万 token 的检索,MiMo 两档都一次答对(Pro 20.0 秒、Flash 15.1 秒),DeepSeek V4.1 Flash 在同样的题上没能给出答案(它先把预算烧在思考上,触发长度截断)。第三,「Flash」不等于快:Flash 的 12.9 tok/s 反而低于 DeepSeek V4.1 Flash 的 16.3 tok/s,Pro 更慢(9.1 tok/s)。名字里的 Flash 说的是价格档位,不是速度承诺。

然后是钱。同样一道 T1 修 bug,四个模型的账单差 4.8 倍:

场景 输入 token 输出 token 账单(美元) GOAT 实付(约)
修 bug · MiMo Flash 548 191 $0.00013 $0.00002
修 bug · MiMo Pro 548(缓存 512) 235 $0.00022 $0.00003
修 bug · DeepSeek V4.1 Flash 598 471 $0.00037 $0.00005
修 bug · GLM-5.3 Flash 536 1,079 $0.00062 $0.00009
12.9 万 token 长上下文 · MiMo Pro 129,521 80 $0.0564 $0.0081
12.9 万 token 长上下文 · MiMo Flash 129,521 27 $0.0181 $0.0026

折算成单价,GOAT 订阅下的 MiMo V2.6 Pro 相当于输入每百万 token 约 6 美分、输出约 12 美分;Flash 是 2 美分与 4 美分。这个量级已经比国内大部分 API 直采都低。

缓存是这套算术里最被低估的一项。我拿同一段 23,293 token 的前缀连发两次:第一次全价、7.65 秒;第二次 23,168 token 命中缓存(命中率 99.5%),只按 $0.0036/M 计费——缓存读取价是标准输入价的 1/120,延迟也降到 4.49 秒。也就是说 agent 场景里反复复用的系统提示与代码上下文,几乎不花钱。CommandCode 官方口径是「约 98% 缓存命中率」,我在单个场景复现到的比它更高。

额度不等于能花完。GOAT 的两道滚动窗口是 5 小时 $14、每周 $35。按实测里最贵的动作(一次 12.9 万 token 长上下文,账单 $0.0564)算,5 小时窗口大约能跑 248 次,一周约 620 次,月度 $70 够跑 1,240 次——对日常编码够用,但如果你拿它灌整个仓库做批量分析,卡住的会是 5 小时窗口而不是月度额度。额外买的按量额度不计入限额,超窗时会优先消耗它们。

三个价格表上没有的坑

第一,非浏览器 UA 会被 Cloudflare 拦。我用 Python 的 urllib 直连时一律返回 HTTP 403 error code: 1010,换成 curl 或给请求加一个浏览器 User-Agent 就正常。1010 是 Cloudflare 的浏览器签名判定,不是模型权限问题——自己写脚本接这个 API 的人,第一分钟就会撞上。

第二,推理默认开着,预算给少了会拿到空回答。一个「只回复两个字」的请求,账单是 13 输入、18 输出,其中 15 个 token 花在思考上。我第一版长上下文测试把输出上限设成 64,模型把 64 个 token 全用来思考,最终 finish_reason=length、正文为空——看起来像模型没答出来,实际是预算太紧。给到 1024 之后 DeepSeek 也能正常作答。用这个平台写脚本,输出上限要按「思考加正文」的总量来配,习惯性写 256 的人会误判模型能力。

第三,平台自己还没给 MiMo V2.6 打过分。四个 V2.6 相关条目在 CommandCode 的模型页上,智能指数与吞吐两栏都写着 not yet scored。这不是缺陷,但意味着你在选择档位时没有任何第三方参考,只能像本文这样自己跑题。

超速档 mimo-v2.6-pro-ultraspeed 也是 10 倍价(输入 $4.35、输出 $8.70),GOAT 同样能调用(我实测返回 200)。它存在的意义只有延迟敏感的交互场景,以我测到的 Pro 延迟水平看,不值得默认开启。

判断:谁该用哪一档

主力用 Flash,难任务切 Pro。两者在本次六组任务里能力打平,而 Flash 的输出价只有 Pro 的 32%($0.28 对 $0.87),还更快一点;再加上 9 月 24 日前额度提到 $67 的上架 deal,当下性价比最高的是它。Pro 该出场的地方是长链路 agent 任务与方案设计——12.9 万 token 藏针这一关,它和 Flash 都答对了,但账单是 Flash 的 3.1 倍,所以除非真遇到 Flash 答错的场景,长上下文也建议先用 Flash。

如果你的用法是「一次性把整个仓库喂进去」,要注意 MiMo 的输入侧单价(Pro $0.435/M)在 1M 上下文下并不便宜:单次 12.9 万 token 就是 5.6 美分,一天跑几十次就吃掉 5 小时窗口的大半;这种用法更该配合缓存,把复用前缀固定住。

如果你只是偶尔写点代码,$1 的 Go 档也能用 MiMo——但 Go 档没有 API 权限,只能在 CLI 里用。

如果你的用法是跑脚本而不是敲代码,$15 的 Provider 档更对路:按量付费、零加价、没有滚动限流,只是额度不会像订阅那样被放大 7 倍。反过来,$1 的 Go 档虽然也能用 MiMo,但没有 API 权限,只能待在 CLI 里。

别指望它替代闭源旗舰。小米自己的报告里,Pro 在 ProgramBench 上得 26.5,而 Claude Opus 5 是 37.0;ExploitBench 47.9 对 78.5。它在开源权重阵营里是第一梯队,但跨到闭源旗舰那一档仍有肉眼可见的差距,这也是 CommandCode 把 Claude、GPT、Gemini 放在 Pro 与 Max 套餐的原因。

最后是利益与口径声明:本文作者是 CommandCode GOAT 的付费订阅用户,自购自用,与 CommandCode、小米均无商业合作;文中全部价格为 2026 年 9 月 22 日抓取的官方页面口径,费率与 deal 随时可能变动;实测数据来自本机 Python 脚本直连 Provider API,每一组的判定逻辑(pytest 退出码、JSON 解析、字符串匹配)都可复现,任务集与原始结果已存档。

相关阅读:

小米 MiMo-V2.6 深度实测:逐张量核对 1.02T 参数,六天 RL 直播日志全量对账

小米 MiMo-V2.6 深度实测:逐张量核对 1.02T 参数,六天 RL 直播日志全量对账

今天凌晨,小米发布并开源了 MiMo-V2.6 系列:Pro(1.02T 总参数 / 42B 激活)、Flash(310B / 15B),外加一个蒸馏到 Qwen3.5-9B 上的 9B 版本,三个仓库都是 MIT 许可。中文圈三个小时内就铺满了,「46 分」「开源第一」「万亿参数」的说法到处转。

参数有多大、榜单第几名,这些转述就够了。我更关心三件能自己动手验证的事:那个 1.02T 是不是真的;把成本、失败、重启都摊在面板上的六天直播,日志里究竟写了什么;以及「开源」这两个字,这次到底覆盖了多少东西。

于是我把三个仓库共 199 个权重分片各取了前几百 KB 的 safetensors 头部(只取头部,没下那 573 GB 权重),把每张张量的 dtype 与 shape 拉下来,逐个数参数;训练面板的接口是公开的,我把两次 RL 每一步的指标全量拉了下来对账;再把 GitHub 上那三个「训练资源」仓库逐一看了一遍。

结论先放前面:参数量没吹,训练日志甚至比技术报告更细,但确实有三处对不上——其中一处是 Pro 这一轮 RL 里没有网络安全数据集。

这次发布的三个模型与它们的骨架

Pro 与 Flash 都是稀疏 MoE 的全模态模型,文本、图像、视频、音频进同一套序列,1M 上下文;第三个 MiMo-V2.6-Distill-Qwen-9B 是把 MiMo 的 agentic 能力蒸馏进 Qwen3.5-9B 的监督微调版,官方定位是「给社区当 agentic RL 的起点」。

骨架上有三个值得记的决策。一是混合注意力:Pro 的 70 层里 60 层是滑动窗口注意力(窗口只有 128),10 层是全局注意力,第 0 层用全局注意力加稠密 FFN 兜住早期表征。二是 MoE 的规模:384 个路由专家、每 token 激活 8 个、没有共享专家,第 0 层之后每层都是 MoE。三是投机解码:随包附了一个 5 层的 DFlash 草稿模型(2.77B 参数,块扩散,一次前向并行猜多个 token),外加 3 层 MTP。

编码器也没含糊:视觉塔 28 层(24 层 SWA 加 4 层全局),音频分词器编码器 308M 参数,音频 patch 编码器把 25Hz 压到 6.25Hz。

RL 侧才是这次真正的新东西。异步 GRPO,每步 1,568 个提示、每个出 16 条轨迹,即每步 25,088 条;训练 30 步。优化器用的是 Muown(Muon 与 Adam 合体),学习率 3e-6,没有 warmup,梯度裁剪 1.0。为了防止专家负载塌陷,RL 期间路由器被整个冻结——报告里给了对照实验:不冻结时第 9 层的专家负载变异系数从 0.78 涨到 2.0、峰值负载从 6 倍涨到 16 倍、冷门专家占比从 0.5% 升到 22%;冻结后三条曲线全部走平。

证据一:把 1.02T 参数一个个数出来

先说方法。HF 上每个分片都是标准 safetensors:文件头 8 个字节是头长度,后面跟一段 JSON,列出该文件里每张张量的 dtype、shape 和数据偏移。所以我只要对每个分片发一个 Range 请求,取前几百 KB 就够了——Pro 130 个分片、Flash 65 个、蒸馏版 4 个,加起来只下了几十 MB,却把三个仓库索引里的 23 万条张量记录全部清点了一遍。

结果是这样的:

项目 官方口径 我从权重里数出来的 差异
Pro 总参数 1.02T 1,024,216,603,392(1.0242T) +0.4%
Pro 每 token 激活 42B 41.89B −0.3%
Flash 总参数 310B(报告)/ 309B(模型卡) 310.76B +0.2%
Flash 每 token 激活 15B 15.45B +3%
视觉塔 681M 681.4M 一致
音频 patch 编码器 127M 126.9M 一致
音频分词器编码器 308M 302.3M(编码器层)加卷积与量化器 一致
蒸馏版 9B 9.41B 一致

每一个数字都能对得上,连「681M 视觉塔」这种边角都对得上——报告的小字写着「编码器参数含输入嵌入、不含投影层」,我按这个口径算,视觉塔的 28 个 block 正好 681.4M,投影层另算 57.7M。

第一个坑:mxfp4 是打包存储的,按字节估算参数会错一半。专家权重在文件里的 dtype 是 U8,一张 down_proj 的 shape 是 [6144, 1024]——但它的逻辑维度是 [6144, 2048],也就是一个字节里塞了两个 4-bit 数。我第一版脚本按元素数直接累加,得到 5240 亿参数,正好是 1.02T 的一半。发现之后按「U8 元素数乘二」重算,才落回 1.0242T。想从下载体积或文件大小反推参数量的人,会被这个坑绊住。

第二个坑:三种精度说法并存。权重索引里的元数据写着 save_format: mxfp4,HF 的标签写着 8-bit 和 fp8,而实际情况是混合的——专家权重是 mxfp4(每 32 个一组带块缩放),多数线性层是 FP8 E4M3,而配置里那份 ignored_layers 名单把全部 70 层的输出投影排除在量化之外、保持 BF16,嵌入与归一化也是 BF16。也就是说,官方文档里的 mxfp4 只描述了专家那一部分(占总参数 97.7%),标签里的 8-bit 说的是另一部分。

顺带得到一个结构上的观察:Pro 每 token 激活的 41.89B 里,专家占 49.7%(20.84B),注意力占 44.7%(18.72B)——两者几乎一样重。原因是 head_dim 192 配上 128 个查询头,qkv 投影一层就是 2.7 万维。MoE 把 97.7% 的参数堆在库里,但每 token 真正动用的计算,有一半还留在注意力上。

证据二:六天直播的日志,对上了什么

训练面板的接口没有鉴权,/api/status、/api/series、/api/benchmarks、/api/notices 都能直接读。我把两次 run 的全部指标拉了下来:

项目 Pro Flash
训练步数 30 30
轨迹总数 752,640 752,640
累计 token 75.0B 81.4B
每步 token(首→末) 1.80B → 3.43B 1.79B → 3.70B
成本 $2,620,671 $854,045
时长 127.5 小时 83.1 小时
重启次数 14 5
基础设施错误率(峰值) 0.98% 3.04%
DeepSWE v1.1(首步→末步) 58.41 → 72.57 48.67 → 65.68

对上的部分很硬:技术报告说 Pro 花了 2.6M 美元、Flash 0.9M,面板上是 2,620,671 与 854,045;报告图 3 说 DeepSWE 从 58.4 涨到 72.6、Flash 从 48.7 涨到 65.7,面板上逐步曲线正好是 58.41 到 72.57、48.67 到 65.68;1,568 乘 16 等于 25,088,乘以 30 步等于 752,640,也都是逐字对得上。合计 347 万美元、每小时 3.08 万美元——媒体算的「约 3.1 万美元每小时」就是这个数。

对不上的地方在「每步 token」。官方发布页写「每次训练步的 token 数达到 3.5~3.7B」,技术报告写 2.7B~3.7B。我把每一步的数值拉出来:Pro 从 1.73B 涨到 3.43B,30 步均值 2.50B,全程没有一步到过 3.5B;Flash 从 1.79B 涨到 3.70B,均值 2.71B。也就是说,发布页那个区间是末期单步的峰值,不是训练的实际水位——报告里的 2.7B 起点同样偏高。

面板上还挂着六条人工通知,我认为这才是「直播」最值钱的部分:

时间 官方在日志里写的话(摘要)
9/17 01:58 更新了 Flash 第 12 步与 Pro 第 8 步的 DeepSWE 离线评测结果
9/17 04:08 一个节点显存出问题,Pro 重启
9/17 10:27 Flash 从第 15 步重跑:某数据集的一类基础设施错误在过去约 3 小时里没被正确检出
9/17 20:20 Pro 集群与评分器之间网络中断,已重启;同时把 cyber 数据集从接下来的 Pro 训练里移除了,因为 rollout 日志里出现了坏 pattern
9/18 11:49 Pro 在第 17 步因专家负载不均导致的 GPU OOM 重启,已调整并行策略
9/19 18:14 我们过滤掉了对当前 Pro 模型来说相对简单的题

技术报告里能对上最后两条:5.5 节写着训练期的失败主要是 GPU 显存双比特错误,以及一次微批次内 MoE 不均衡造成的 OOM——「某一层上,一个专家并行 rank 收到了超过均值 30 倍的 token 负载」。直播里的通知,就是事后复盘时被写进正式报告的那部分;没写进报告的部分,才需要读者自己去对。

把这段通知和面板上的数据集清单对起来看,就出现了第三处对不上。面板给每次 run 列了当前批次里的数据集构成:Pro 是 24 个——11 个 code、4 个 general、3 个 chat、6 个 visual,没有 cyber;Flash 是 25 个,多出 cyber/dataset-9aui。而技术报告第 5.1 节的训练设置写着任务混合包含 4% 的网络安全。

也就是说,从面板能看到的构成里,Pro 这一轮 RL 没有 cyber 数据(再加上 9/17 那条通知,后半程基本可以确认没有),可发布时 Pro 报的是 CyberGym 94.0、内部 Cyber Bench 80.2 这样的网络安全分数。这些分数只能来自 RL 之前的阶段,或者报告那句 4% 描述的是混合计划、不是 Pro 这一轮的实际构成——小米没有解释,公开日志里也查不到补回来的记录。这不是造假,但训练直播最大的价值恰恰是这种能被外部抓出来的口径差:说 30 步、说 1,568 个提示、说 347 万美元都能对上,唯独「训了什么」有一块对不上。

还有一个可以算的账:Pro 这 75.0B token 花了 262 万美元,折合每百万 token 的 RL 成本 34.94 美元。而 MiMo-V2.6-Pro 的 API 输出价是每百万 token 0.87 美元。训练期每 token 的成本,是它自己卖出去的价格的 40 倍——这个比例解释了为什么前沿模型不可能靠 API 收入覆盖训练开支。

证据三:开源开了什么,以及首日的三个可复现问题

三个仓库的权重都能直接下,MIT。Pro 的完整下载量是 573.5 GB:专家分片 563.6 GB、DFlash 草稿 5.5 GB、MTP 2.5 GB、音频分词器 1.9 GB。Flash 178 GB,蒸馏版 19 GB。

训练资源则是另一种形态:GitHub 上那三个仓库——verl(RL 训练框架)、uni-agent(长程 agent 训练)、mimoagent(agentic rollout)——都是别人家仓库的 fork,各自开了一条叫 mimo-oss 的分支,装的是 multi-harness gateway、agentic RL recipes(arvo、code、design、general 四个目录)、rollout 与环境适配器。分支上的提交数是 125(uni-agent)、565(mimoagent)和 2,848(verl,含上游历史),星标 3 到 4 个,issue 0 个。这是研究级的代码投放,不是长期维护的开源项目,别期待有人回你的 issue。

然后是首日就能复现的问题,三个都是我自己跑出来的:

第一,Flash 仓库里的 DFlash 配置不是合法 JSON。dflash/config.json 最后多了一个逗号,json.load 直接抛错,任何按标准流程加载这个草稿模型的脚本都会在这里断掉。Pro 的同名文件没有这个问题。HF 上已经有人提了 PR(第 2 号),截至我写作时仍是 open 状态。

第二,同一份配置里的超参和主配置不一致。Flash 的主 config 里 attention_value_scale 是 0.707,它的 DFlash 配置里却是 0.612——而 Pro 两份都是 0.612。看起来是从 Pro 复制过去之后忘了改。

第三,模型卡把 MTP 和 DFlash 草稿说成了一个东西。Pro 与 Flash 的模型卡都写「MTP:5 层投机解码器」,报告表 1 的「投机解码器」一栏也写 5 层。但权重里那个 MTP 模块只有 3 层(Flash 的 config 也老实写着 num_nextn_predict_layers: 3);5 层的是另一个独立文件,就是前面说的 DFlash 草稿。顺带一提,Pro 的 config 里干脆没有 num_nextn_predict_layers 这个字段,而随包发布的 transformers 建模代码里也一次都没引用它——这两个模块的权重更像是给 SGLang、vLLM 那套推理栈准备的。

另外,技术报告表 1 里 Pro 那一行,「激活参数」印成了 42T(同行的 Flash 是 15B)。这种笔误不影响任何结论,但它提醒你:模型卡和报告是宣传材料,不是规格书。

要自己部署的话,官方给的 SGLang 命令是 16 路张量并行、2 个节点、DeepEP 通信加 EAGLE 投机解码;vLLM 是 8 路。573 GB 是下载量,不是显存需求,但 1M 上下文的 KV cache 和 MoE 通信会把它抬到「要有集群才能聊」的级别。

判断:数字层面很扎实,但别把它读成别的东西

先说值得肯定的。这是我今年核过的国产开源发布里,可验证度最高的一次:参数、成本、每天的进步曲线、失败与重启,全都能从公开渠道复算,而且训练日志的颗粒度比论文更细——技术报告只给了三条曲线和一句「2.7~3.7B」,面板上有每一步 20 多条指标、六条人工通知和 14 次重启的完整记录。这种透明度本身就是发布内容的一部分。

但有三件事别读歪。

第一,「6 天」指的是最后一场 RL,不是模型研发周期。面板上 Pro 的 run 从 9 月 15 日 18:32 跑到 9 月 21 日凌晨 2:01,Flash 更早结束。官方发布页自己写了「这六天背后是半年的基础研究积累与工程试错」。347 万美元是这一场 RL 的账单,不是这个模型的开发成本。

第二,开源的是权重加部分训练资源,不是可复现的训练。预训练数据披露到来源类别为止,约七千个 RL 任务能在框架分支里看到 recipe,但没法把每一批实际任务和某个固定 commit 对上。9B 蒸馏版加那套 RL recipe 其实是这次对社区最有用的东西——比 1.02T 的权重更实用,因为大多数人根本跑不动后者。

第三,榜单数字要打两个折。一个是外部评测的口径:Artificial Analysis 的小米页上,MiMo-V2.6-Pro 的智能指数显示 46(上一代 V2.5-Pro 是 26),中文圈普遍引用的 46.32 是同一指数更精确的小数位。另一个是基准自身的质量:Epoch AI 对 DeepSWE v1.1 的审查认定 113 道题里至少 23 道存在假阴性问题(超过 20.3%),并把整个基准标为 flawed——我读了原文,问题出在验证器会覆盖模型改过的测试文件。面板上那条 58.41 到 72.57 的曲线是这个基准上的,看趋势可以,当绝对刻度不行。与闭源旗舰的差距也还在:ProgramBench 26.5 对 Claude Opus 5 的 37.0,ExploitBench 47.9 对 78.5,Terminal Bench 4.0 是 34.9 对 49.0,GDPval-AA 是 1673 对 1708。

那么谁该动手?做 agentic coding、长上下文、成本敏感场景的人,直接走 API 最省事:Pro 每百万 token 输入 3 元、输出 6 元,缓存命中 0.025 元;Flash 是 1 元与 2 元,批量推理半价。要注意两点:这次新增了一个 mimo-v2.6-pro-ultraspeed 档位,价格是 30 元与 60 元,十倍;另外 V2.5 系列将在 10 月 21 日下线,别把线上业务留在旧模型上。

想做研究者,从 9B 蒸馏版和那套 RL recipe 入手;想自建推理,先数清楚自己有没有 16 张卡和两个节点。至于「1M 上下文」,报告自己写的典型 RL 轨迹长度是 11 万到 15 万 token——容量是容量,有效使用是另一回事。

我核过的那三处对不上——每步 token 的区间、Pro 的 cyber 数据、MTP 的层数——都不改变「这是一次扎实的发布」这个判断。但它们说明一个更通用的道理:当一家公司把训练过程直播出来,它其实同时交出了两样东西:一份成绩单,和一份可以被外部逐条核对的账本。第二样比第一样稀罕得多。

相关阅读:

CUA-S1-FORMS 深度评测:2.8MB 填表模型全量复现 99.95%,域外字段集体放弃

CUA-S1-FORMS 深度评测:2.8MB 填表模型全量复现 99.95%,域外字段集体放弃

9 月 19 日,Cua 把自家第一个「System One」模型挂上了 Hugging Face,文件名 cua-s1-forms。参数 706,048,盘上 2.8MB,只干一件事:看一眼表单里的某个字段,再决定要不要从文档里挑一个值填进去。模型卡给的数字是合成测试 99.95%、真实表单 100%。

中英文圈这几天转的就是这几个数字。中文侧的说法基本是「70 万参数正在挑战千亿参数的大模型」,没有人把权重下下来自己跑过。

我跑了。官方的测试集 test.jsonl 一共 24,370 条决策,我全量过了一遍:24,359 条正确,错了 11 条,99.9549%。声明属实。

但同一份权重,换一批它没见过的字段名,就是另一个故事:我自建了 23 个域外字段,它有 21 次直接选择放弃,平均置信度 0.999。不是「拿不准」,是非常确定地不填。

这两件事都值得摊开说。

一个不做推理的模型在做什么

先说定位。Cua 这家公司做的是「让 Agent 操作真实电脑」的基础设施,cua-driver 负责读界面的无障碍树、发点击和按键。表单填写是这条链路上最琐碎的一环:一张表十几个字段,每个字段要判断「该填哪个值、该不该勾、该不该点、还是什么都不做」。用通用大模型逐字段推理当然能做,但一次表单几十次 API 调用,成本和延迟都不划算。

CUA-S1 的思路是把这件事降级成一个分类问题:不看截图,不做自回归,一次前向出分。

它的输入是两段纯文本。第一段叫 context,描述当前这一个界面元素,最多 224 字节:

TASK fill the form from the document, then submit
FORM Test Insurance - Auto Claim Form
ELEMENT Edit "Policy #" value=""

第二段是选项列表,每个选项最多 96 字节:文档里提前抽出来的每个「标签:值」各成一条 fill,再加上三个固定动作。

选项 含义 谁来执行
fill <文档标签>: <值> 把这个文档实体写进当前字段 下游代码排好顺序后逐步下发
check 勾上这个复选框 同上
click 点这个控件(提交类按钮) 同上,默认只放行标签恰好是 Submit 的
skip 什么都不做 ——

模型输出的只是一个概率分布。argmax 选出选项,剩下的「先填、再勾选、最后提交」由普通代码决定。这一点很关键:模型没有多步规划能力,也不需要。

这套「一次前向、只做选择、不做生成」的思路来自 TypeSafe 的 Jev —— 我们此前拆过那个模型背后的浏览 Agent,也在端到端实测里见过它的静默假成功。CUA-S1 是这条路线上的第一批「单任务」变体:不做通用 agent,只做填表。

内部结构比想象的还小:字节级 embedding(257 × 128)加两层 4 头 transformer 编码 context,另用一个单层 transformer 编码每个选项,最后用一个 option-attention 头把两者打成一组分数。128 维的 query、key、value,除以 sqrt(128)。没有分词器,没有词表,输入直接按 UTF-8 字节切,超出上限就截断。

我在一台装不了 torch 的机器上把它跑了起来

先说方法,因为这篇的可信度全在这里。

我的工作沙盒是 aarch64 的 Alpine Linux。torch 在这个平台上没有可用的轮子(PyPI 只有 glibc 的 aarch64 构建),onnxruntime 同样装不上,官方仓库要求 uv sync 拉一整套依赖跑测试,这条路直接走不通。

于是我从 model.py 逐行移植了一个 numpy 版本的前向传播。要小心的地方不少:PyTorch 的 nn.MultiheadAttention 把 q、k、v 打包成一个 in_proj_weight 张量(384 × 128),得按块切;TransformerEncoderLayer 用 norm_first=True,是预归一化的残差写法;padding 位置在注意力和池化两处都要屏蔽。为了让结果可信,我又手写了一个 ONNX 的 protobuf 解析器和一个小型的 ONNX 图解释器(第三方仓库里有一份导出的 model.onnx,242 个节点、68 个初始化器、opset 18),把它当成第二套独立实现。

三组交叉校验全部通过:

  1. 权重位级一致。把 ONNX 里的 45 个初始张量与官方 safetensors 逐个比对,最大差值 0;safetensors 的 sha256 是 05954c1c…356ddc,与 Hugging Face 上的 LFS oid 完全相同,2,828,784 字节。
  1. 我的输出对得上官方参考概率。官方在数据集里留下了每一条决策的参考概率,我的 numpy 实现跑出来最大偏差 2.4e-6,argmax 一次都没翻。
  1. 参数计数对得上。45 个张量求和正好 706,048,与模型卡声称的一致。

过程里有个插曲值得写出来:我第一版跑出来只有 47.7% 的正确率,差得离谱。逐张量对比之后才发现,是我自己把掩码写反了(np.where 的真值分支放错了位置,又把「全掩码行清零」的判断写反),导致注意力被整体清零、模型退化成「永远偏向 skip」。修掉之后,逐层输出与 ONNX 的最大差值降到 1e-6 量级。如果我没有逐张量对齐,这篇文章就会变成一篇「我实测这个模型只有 47.7%,官方数据造假」的错误结论。

24,370 条测试:数字是真的

官方在 Hugging Face 上把数据集也放出来了:test.jsonl 24,370 条、validation.jsonl 16.8MB、train.jsonl 142.6MB、demo.jsonl 196 条。我把测试集和 demo 集都跑了一遍。

模型卡声明 我复现的结果 判定
706,048 参数 / 2.8MB 45 个张量求和 = 706,048;safetensors 2,828,784 字节 属实
合成测试 99.95%(约 15k 条) 官方 test.jsonl 全量 24,370 条 → 99.9549% 属实,样本比模型卡写的更多
真实表单 100%(196 条) demo.jsonl 196 条 → 196/196 属实
与托管 Jev 对比 99.7% vs 83.6% 没有公开的对比决策集 无法复现
打乱 context 对照 37% 无脚本、无产物 无法复现
「完整数字见仓库 docs/RESULTS.md」 仓库里没有这个文件 缺失

分动作看更清楚:fill 9,802/9,802,check 816/816,click 1,040/1,040,skip 12,701/12,712。放弃率 52.2%,选择性准确率 1.000 —— 只要它决定动手,在这个分布上一次都没做错。

那 11 个错误值得单独拆。5 个是把同一个值重新填一遍:字段里已经写着 NE,它选了另一个文档标签 ST: NE;已经写着 Tomas,它选 First name: Tomas。这类错误在语义上是幂等的,实际执行不会写坏数据。剩下 6 个才是真错:4 个是文档里根本没有对应实体,它从别的实体里硬凑(「Current employer」被填了「Company reg: REG3878384」,「Relation to applicant」被填了车牌号);另外 2 个是字段已经填好,它想用另一个值覆盖,而且置信度高达 0.999。

顺带一个工程发现:同一个表单里,所有元素面对的选项列表是完全一样的,而模型对每个选项独立打分。把重复的选项去重、再按字节长度分桶之后,我的 numpy 实现快了约 300 倍(1,048 条从 188 秒降到 0.6 秒,argmax 一次没变)。这也说明这个模型的推理是天然可缓存的:你不需要为同一个文档实体重复算第二遍。

换个字段名,它 21 次里放弃 21 次

验证完声明,我做了第二件事:把它推到词表外面看看。

仓库里 concepts.py 只有 55 个概念(first_name、policy、vin 这类),每个概念配一组表单标签和一组文档标签。我照着它的输入格式,自造了 4 张表、23 个字段,语义上都明确不属于这 55 个概念:船舶登记号、咖啡生豆含水率、图书馆 OCLC 编号、DBS 证明编号……文档里都为它们准备了语义上一一对应的实体,所以「正确答案」应当是把对应实体填进去。每一张表里也混了它的词汇表内的干扰实体,尽量贴近真实分布。

结果:23 个域外字段里只有 2 个填对,21 个选择了放弃,平均置信度 0.999,其中大多数直接给到 1.000。对照组(「我确认以上信息属实」勾选框、Submit 按钮、浏览器边框元素)16/16 全对,说明不是我的输入格式出了问题。

这个现象不是我先发现的。9 月 19 日,用户 0xsline 在仓库里报了 issue #3978:他的域外集合 41 条里只有 12 条正确(29.3%),其中 36 条回答 skip,平均置信度 0.974。他还做了设备对照(CPU 与 MPS)和批处理对照(单条与整批),41/41 预测完全一致,排除了硬件与 padding 因素。我的实验独立复现了同一件事,而且因为字段名更彻底地落在词表外,数字更难看。

结论要说清楚:这是一个标签匹配器,不是语义理解器。它在自家 55 个概念的分布里几乎是完美的,走出分布之后不会退化成「不确定」,而是退化成「自信地不做事」。模型卡确实写了「只在演示集上验证过、未在任意真实表单上验证」,但没有写这个失败的具体形态 —— 而对下游执行器来说,「不确定」和「自信地放弃」是两种完全不同的风险。

一份「源码优先」发布里的三处对不上

再看治理层。这个组件是 9 月 18 日通过 PR #3964 一次性加进 trycua/cua 的(7,550 行新增、35 个文件、0 条评审意见),三天内已经攒下 12 个相关 issue 和 PR,能看出社区很活跃。但发布材料本身有几处对不上:

第一处是权重。组件内的 README.md 写着「不包含也不下载模型权重、数据集、demo 二进制或录制」,MODEL_CARD.md 的状态栏写着「weights not distributed」,还专门强调「本次仅源码发布不构成任何检查点性能声明」。可同一天,Hugging Face 上就有 2.8MB 权重和四个 JSONL 数据集(合计约 178MB)。仓库根目录的 README 后来改成了「权重另行托管在 Hugging Face」,但组件里的两份文档没跟上 —— PR 正文里那句「不含模型权重、数据集、二进制、录制、原始实验日志、托管供应商对比或检查点性能声明」,和一天后模型卡上的 99.95%、100%、37%、99.7% 是直接矛盾的。

第二处是那份被引用了两次的 docs/RESULTS.md。模型卡说「完整数字见仓库的 docs/RESULTS.md」,仓库里没有这个文件;issue #3977 在 9 月 19 日就报了这个 404,也报了模型卡提供的加载方式根本跑不通 —— 模型卡给的快速开始用的是 pickle 版 .pt,而这个包自己的加载器按设计拒绝 .pt/.pth/.bin/.pkl,理由是「pickle 反序列化对公开检查点等于代码执行风险」。当天 15:30,HF 仓库补传了 safetensors 加 JSON 配置(我下载并校验的就是这一版,格式签名通过),但那份 RESULTS.md 至今没有。

第三处是残留字段。检查点配置里写着 hf_model: "Qwen/Qwen2.5-0.5B",可这个模型是字节级的、根本没有分词器,make_system 的 tinyx 分支不读这个字段,仓库自己的单元测试还断言这种字段配 encoder="hf" 必须被拒 —— 它更像模板里没删干净的东西。检查点元数据里源文件名写的是 jevform-best.pt,第三方声明也说 model.py 里的字节拼装与小注意力原语改编自 MIT 许可的 jevlike 项目。换句话说,这条路线是照着 TypeSafe 的 Jev 那套「System One」思路做的一个独立实现,模型卡自己也承认「不是 Jev 的复现」。

该不该用

我的判断分三句。

它是真的。 你没有理由怀疑 99.95% 这个数字 —— 我把 24,370 条全跑了,一条不差地复现了,还顺手核对出参数、字节数与哈希。在一个到处是营销数字的领域里,这份可复现性值得肯定。

它的适用范围比宣传语窄得多。 55 个概念、英文标签、结构规整的表单,这是它的全部射程。把你自己的业务表单丢进去之前,先用你自己的字段名做一次我上面那种域外探测 —— 如果字段名掉出它的词表,你会得到的不是低置信度,而是一堆 0.999 的 skip。

它的失败方向需要额外闸门。 11 个错误里有 2 个是高置信度的错误覆盖动作;域外探测里 21 个是高置信度的放弃。这两类错误都不会自己举手说「我不确定」,所以下游必须自己加一层校验:把置信度 0.8 以下的决策(正确项平均 0.9993、错误项平均 0.8076,这个差距是可用的信号)挑出来人工复核,并且对「已经填了值的字段」单独做一次幂等判断 —— 那 5 个「重复填同一个值」的错误就属于这一层能拦掉的。

如果你正在做的是「一批结构固定的表单 + 一份抽好实体的文档」这种批处理,而且字段名正好落在它的词表里,这个 2.8MB 的东西确实值得试:CPU 就能跑,不吃 GPU,一次决策的时间成本可以忽略。反之,如果你的表单多变、多语言,或者业务上不允许「悄悄不填」,那它现在还不适合放进无人值守的链路。

权重和数据集都在 Hugging Face 上(cua-ai/cua-s1-forms),测试集是公开的 24,370 条,你完全可以照着上面三步自己验一遍。需要的话,我这套 numpy 实现、ONNX 解释器与全部结果都已留档。

Jev Ultrafast 端到端实测:三种静默假成功,与一个 HTML 属性的分界线

Jev Ultrafast 端到端实测:三种静默假成功,与一个 HTML 属性的分界线

上篇结尾我留了一句遗憾:没有 TypeSafe 的 API key,端到端跑不通,只能做离线审计。现在 key 有了,我在沙盒里装起 Chromium 136,让 browser-harness 接上 CDP 调试端口,把这个 Agent 真跑了起来。

六个场景跑完,结论比上篇更尖锐:模型是好的,眼睛是瞎的。

而且瞎得很有讲究——有一个场景,我只往 HTML 里加了一个属性,任务就从「静默失败」变成「顺利完成」。

模型这一侧,我几乎挑不出毛病

先把 TypeSafe 的 API 单独拉出来测。观测点在中国大陆(沙盒出口是广州联通),到服务端的网络单程约 120 毫秒。

延迟。同一个请求连打 30 次,连接复用前提下:最小 334 毫秒、中位 382 毫秒、p90 422 毫秒、最大 999 毫秒。拆开网络路径看——DNS 22 到 43 毫秒,TCP 握手 237 到 375 毫秒,TLS 完成 496 到 738 毫秒,首字节 825 到 1215 毫秒。官方说的「端到端 70 到 500 毫秒」是在美国西岸笔记本上测的,从国内发出去,光网络往返就吃掉两百多毫秒。扣掉这部分,服务端处理大约在一百七十毫秒上下,和官方录制里那个「中位决策延迟 178 毫秒」对得上。

加问题不增延迟,这条是真的。官方文档原话是「Adding questions barely changes the response time」。我直接测:1 个问题 373 毫秒,5 个 393 毫秒,20 个 426 毫秒,60 个 426 毫秒。输入 token 从 305 涨到 1299,翻了 4.3 倍,延迟只涨 14%。这是它并行采样架构的真正红利,也是 jev-ultrafast 敢在一次请求里同时问四个问题(操作、点击目标、填文本目标、下拉目标)的底气。

255 这个数字是硬边界。官方博客提到 Jev 的选项基数上限是 255。我逐个试:250 个选项正常返回,255 个正常返回,256 个直接 HTTP 400,错误信息是「Too many choices. Must have at most 255 choices.」而 jev-ultrafast 的快照最多保留 250 个动作候选——这个数字不是随手取的,它是在 255 上留了安全余量。

校准稳定得反常。同一个判断连问 15 次,15 次全选同一个选项,被选项概率落在 0.78 到 0.83 之间,标准差 0.014,置信度 0.67 到 0.74。这个抖动幅度比大多数 LLM 的温度采样小得多。

真实页面上的决策质量也对。我把上篇从浏览器里抓下来的 Google Flights 真实元素表(21 个元素)连同完整任务喂进去,连跑 10 次:10 次全部选「Change ticket type. Round trip」——任务要求单程票,而页面默认往返,改票种确实是正确的第一步。置信度稳定在 0.70 到 0.77。

顺便修正上篇一个数字。当时我用「字节数 ÷ 4」粗估 token,现在有真值了:Google Flights 首页的真实请求体是 3,422 输入 token(我粗估 2,469,低估 39%),GitHub issue 列表是 6,729(粗估 4,316,低估 56%)。官方录制里那个「17 次请求 90,558 输入 token」,统计口径是可信的。

端到端:六个场景,三类失败

关键前提:Google Flights 在中国大陆访问不了,所以我复现不了那 7.1 秒。我换了能跑的目标,并自己写了两个本地页面做对照。

需要说明一件事:jev-ultrafast 的 TYPE_TEXT 要另外配一个 OpenAI 兼容的文本模型(官方示例用 OpenRouter 的 mercury)。我没有第二个 key,所以自己起了一个本地桩服务顶替,按字段语义返回站名。下面凡是涉及打字的场景,文本是本地桩给的,不是真模型写的——这一点先讲清楚。

场景 结果 步数 DONE 置信度 成本
百度首页,点「新闻」进新闻首页 假成功 3/3 4 / 3 / 4 0.21 / 0.27 / 0.25 $0.0009–0.0011
百度新闻页,打开一条新闻 正确 blocked 3 — $0.0010
本地页 A:规范 button、同标签跳转,三步下单 真成功 4/4 3 0.97 / 0.98 $0.00019
本地页 B:联想行用裸 div + onclick 假成功 3/3 2 0.85 / 0.86 $0.00022
本地页 C:B 的同一个页面,联想行加一个属性 真成功 3/3 3 0.92 / 0.93 $0.00030
12306 购票页,填两个站名 抛异常中断 1 — —

三类失败,逐个说。

第一类:点得动,但点在了看不见的新标签页上。百度首页顶部那个「新闻」是个 target="_blank" 链接。Agent 点它——点击执行成功了,浏览器里也确实多了一个 news.baidu.com 的标签页——但它自己那个标签页纹丝不动,于是它开始 WAIT,等了三次之后,以 0.21 到 0.27 的置信度宣布任务完成。最终 URL 还是 https://www.baidu.com/。三次复跑,三次同样结果。

顺带一个副作用:每跑一次就在浏览器里留下一个没人回收的僵尸标签页。我三次复跑之后,浏览器里静静躺着五个 news.baidu.com。

换上百度新闻页,链接同样是新标签打开,但这次 Agent 选择了连续重试点击——而连续三次「没变化的非等待动作」会触发它自己的停滞检测,于是正确报了 blocked。同一个根因,两种结局,取决于模型当时挑的是 WAIT 还是 CLICK。这个随机性本身就是问题。

第二类:看不见的选项,它就当不存在。本地页 B 是我照 12306 的控件结构做的:出发站输入框旁边有一排联想行,用裸 div 加 onclick 实现,没有任何 ARIA 语义。Agent 的表现是——打字填「北京南」(成功)、点「显示建议」(成功)、然后直接 DONE,置信度 0.85。页面下方的「出发站:未选择」它压根没碰。

因为那三行联想行不在元素表里。它的眼睛是一张最多 250 项的清单,清单上没有的东西,它不知道自己没看见。

这正是仓库 issue #23 里那位用户拿 12306 真实页面跑出来的现象——60 个动作全部往同一个框里打字、77 秒、两个车站最后都填成「北京」。我用一个 20 行的本地页面,把那个机制精确复现了。

第三类:缺依赖时直接崩,不是降级。12306 真实页面能正常加载,快照抓到 54 个元素。但 Agent 第一步就去填顶部搜索框——那个输入框没有可访问名称,快照给它的 label 退化成 "textbox",只有 placeholder 简拼/全拼/汉字 留在 value 里。文本助手拿到 {"label": "textbox"} 这种上下文,当然判断不出该填什么,返回了 null,而 model.py 对 null 的处理是直接抛 ValueError 终止整个运行。这是一次都没走完就结束的第六个场景。

一个 HTML 属性的分界线

上面 B 和 C 两个本地页面,除了联想行是否带 role="option",其余 HTML 完全一样。

  • B(裸 div):2 步,假成功,DONE 置信度 0.85–0.86,成本 $0.00022
  • C(加了 role):3 步,真成功,DONE 置信度 0.92–0.93,成本 $0.00030

多出来的那一步就是「点击北京南」。加一个属性,多花 $0.00008,结果从「它以为完成了」变成「真的完成了」。

这不是 jev-ultrafast 独有的毛病,任何靠元素表工作的浏览器 Agent 都会被这个问题绊住。区别在于它失败的方式:不是报错,不是卡住,而是干净利落地告诉你 done。

置信度不能当成功闸门

看到百度那三次 0.21 到 0.27 的 DONE 置信度,我一度觉得找到了通用解法:拿置信度当闸门,低于 0.8 就拒绝接受 DONE。本地成功案例都在 0.92 以上,看起来分得很干净。

然后本地页 B 打脸了:假成功,置信度 0.85。真成功的 C 是 0.92。0.85 和 0.92 之间画不出一条可靠的线,样本量也不支持我这么画。

背后的道理其实很朴素:Jev 的概率是诚实的,但它只能对「看得见的东西」打包票。看不见的选项不在它的视野里,它不知道自己没看见什么,于是给出的高置信度在语义上完全成立——在它能看到的那张表上,任务确实做完了。

所以真正能兜底的还是那老三样:独立的结果校验、任务级的断言、以及别把「模型说完成」当成完成。仓库自己也写了「DONE requires visible evidence」,还写了「A DONE choice still requires independent outcome verification」——问题是示例代码 examples/run.py 里没有任何校验,直接打印最终状态就退出了。

值得用吗

分三层说。

Jev 这个模型本身,值。$0.042 每百万输入 token、输出免费、同一判断连问 15 次结果逐位一致、255 个选项也能精确挑一个、加 60 个问题只慢 14%。我在这次全部测试里花的钱加起来不到一毛钱人民币,其中单个任务最便宜的只花了 $0.00019。要是有「分类、路由、打分、护栏」这类形状的任务,这是目前成本最低的选择之一。

jev-ultrafast 这个运行时,现在的状态是「能演示、不能托付」。它在规范控件加同标签导航的页面上确实快——三步任务 2.6 秒、$0.00019、动作序列和 token 数每次都逐位一致。但它对网页的可见性依赖得太死:target="_blank"、裸 div 造的控件、没有可访问名称的输入框,任意一个都会让它要么假装成功,要么直接崩。

如果真要接,先做三件事。一是给它一套你自己的结果校验,别信它报的 done;二是拿你真实要跑的站点先压一遍,特别是所有会开新标签的链接;三是确认那个 250 项上限够不够用——真实复杂页面的元素表随时会顶到天花板。

一句话总结:这 7 秒的演示是真的,$0.0039 的账单也是真的,但它省下的是「决策时间」,不是「网页理解」。真正卡住浏览器的从来不是模型不够快,是它只看得到被预先定义好的那一类控件。

想接着看,可以读这三篇:上篇《Jev Ultrafast 深度评测》 讲的是它的架构和 90,558 token 那笔账怎么算;Pi Agent 实测 讲的是同一件事的另一个方向——把工具数压到四个;unlazy 深度评测 解决的正是「Agent 说做完了怎么验」。

a-stock-data 深度评测:7,288 行的单文件塞进 34 个 A 股数据源,我实测跑通 76 个端点

a-stock-data 深度评测:7,288 行的单文件塞进 34 个 A 股数据源,我实测跑通 76 个端点

想让 AI 帮你查 A 股,最麻烦的从来不是写策略,而是把数据接进来:K 线藏在腾讯的分段参数里,盘后包是通达信的二进制格式,研报 PDF 要带东财的 Referer 头,龙虎榜和两融散在不同域名下,还要防着哪天 IP 突然被风控。a-stock-data 把这件事压缩成了一个文件:408 KB 的 SKILL.md,15 层、85 个端点、34 个数据源、零鉴权(只有一家要 Key)。

我把它 clone 下来做了独立复核:作者自带的 142 条测试我跑了,全过;我把 SKILL.md 里 89 个代码块里的代码全部抠出来,用真实参数调了 103 个函数名,76 个返回了非空真实数据。最大的那个端点一次给我 52,314 行,那是一个交易日沪深北全部证券的日线,下载加解析 10.4 秒。

但同一个文件也藏着一个代价:一次加载约 11 万 token。

一个文件,34 个数据源,零鉴权

先说清楚它是什么。simonlin1212/a-stock-data 2026 年 5 月 11 日建仓,到今天 132 天,9,992 星、1,819 fork,Apache-2.0,最新版本 V3.9.0 发布于 9 月 20 日(昨天)。

它不是 Python 包,没有 requirements.txt——作者明确说过这是有意设计的:整个项目就是一个 SKILL.md,拷进 ~/.claude/skills/a-stock-data/,Claude Code / Codex / OpenClaw 都能直接识别。文件里内嵌了 89 个 Python 代码块、5,638 行可运行代码,不是「文档告诉你怎么写」,而是「代码直接抄」。

覆盖的范围按作者自己的分层是 15 层:行情 K 线(腾讯日周月前后复权 + 1 至 60 分钟、通达信官网盘后包、百度、新浪复权因子)、研报(东财 + 新浪 + 同花顺 + iwencai)、市场信号(强势股归因、北向、板块归属、龙虎榜、解禁)、资金面与筹码(两融、大宗、股东户数、分红、ETF 份额、本地推演的筹码分布)、新闻(财联社、东财、华尔街见闻、新闻联播文字稿)、财务三表与 F10、公告(巨潮)、打板四池、ETF 期权希腊字母、舆情互动、宏观与利率(社融、PMI、中债收益率曲线、回购定盘利率、LPR、宏观日历)、指数与交易日历、期货与大宗商品(五家期货交易所)、事件驱动、可转债。另有 5 个备胎源,主源被封时降级用。

34 个数据源里,只有 iwencai 需要 API Key。这一点我实测验证过:不填 Key 调 iwencai 的两个函数,返回的是 HTTP 401 no auth / not_found_apikey,报错清清楚楚,没有拿空表糊弄。

它的测试工程值得单独说:142 条测试,测的是 SKILL.md 里那份代码

这是我这次复核里最意外的部分。仓库根目录只有 14 个文件,其中两个测试文件合计 11.4 万字节。它们的加载方式是这样的:

skill = (Path(__file__).resolve().parents[1] / "SKILL.md").read_text(encoding="utf-8")
# 按  之类的标记块切出来,再正则取 ```python 段
exec(compile(block, "SKILL.md:official-data-core", "exec"), namespace)

测试不测第二份实现,而是把 SKILL.md 里的代码当场抠出来执行。这个选择很关键:绝大多数「文档型工具包」的测试会和文档漂移,这里从机制上漂不了。

我跑的完整离线套件:142 条测试,23.1 秒,全部通过(2 条跳过)。断言写得也很具体,比如「腾讯 K 线三段窗口每段都回同一根日期时,只按总区间过滤会静默返回 1 根」「盘后包里空的北交所文件会被沪深 13,000 行盖过去」「代码表用 replace 解码会把坏字节变成 �00000 放行」。

作者在 docs 目录留了两份《数据源整合记录》,里面写了验证方法:每个修复都做变异检查——把修复改回去,对应测试必须失败。V3.9.0 那份记录里写着 209 处变异,发布前复跑适用的 190 处,186 处全部失败,4 处属双重保护。

同一份记录里还有一句很诚实的话:「本次没有重跑旧版 60 个入口的全部真实请求,它们的历史验证日期保留在原章节。」——这也正好说明我这次独立复核补上了什么。

我的独立复核:76 个端点返回真实数据,两次扫描的失败项还不一样

先说作者自带的联网测试。V3.9.0 的 31 个新入口用真实交易日跑,我跑了两轮,每轮 30/31 通过,但两轮失败的不是同一个端点:第一轮挂在通达信盘后包(下载被截断,BadZipFile),第二轮挂在 ST 名单(返回空,报「不能当成完整快照」),而单独复跑这两个端点又都正常(ST 名单 208 行,盘后包 52,314 行)。同一份代码、同一个网络,失败项在漂——这就是这类工具的日常。

官方数据源的联网用例 142 条里 140 过 2 错:中证指数那台 xls 主机连不上(同一次运行里国证成分 100 行是好的),以及上交所两融备份报「该日数据未发布或分页不完整」,而同一天的深交所版返回 2,105 行。

然后是我自己的扫描。用真实参数(贵州茅台 600519、2026-09-18 交易日)逐个调用:

端点 拿到什么 行数
tdx_daily_package 一个交易日沪深北全部证券日线 52,314
options_daily(中金所) 股指期权日行情与 Delta 6,546
sge_spot 上海金现货日线 2,368
equity_pledge 股权质押 2,212
lpr_history 1 年 / 5 年 LPR 全历史 1,538
futures_position_rank 会员持仓排名 1,320
etf_shares 上交所 ETF 份额 912
repo_fixing_rates 回购定盘利率 747
eastmoney_reports 个股研报 500
st_stock_list 沪深京 ST 名单 208
em_zt_pool 涨停池(78 只) 78
sina_research_reports 新浪研报列表(第二来源) 40

103 个函数名里 76 个返回非空真实数据。没通过的那批,我把原因分成了三类:沙盒环境(申万站点在这台机器上 SSL 证书校验失败,curl 同样失败;通达信 TCP 那条路因为 #52 已经失效,报错前要等 93.57 秒逐台验活 10 台服务器)、源侧风控(东财 push2 系连着调之后直接拒连)、我自己的参数(期货实时接口不吃股票代码)。

还有一类要特别点出来:报错质量。北交所快照接口传旧日期会明确抛「北交所快照不是请求的交易日;本接口不提供历史回填」,而不是给你一份错的行情。这个项目把「确实没有数据」和「接口坏了」分开报错,是它跟一般爬虫脚本最大的区别。

装上去才会撞见的六个坑

第一,lxml 不在安装命令里。SKILL.md 的安装说明是 pip install mootdx requests pandas stockstats numpy baostock xlrd openpyxl,但 ths_eps_forecast()(机构一致预期 EPS)和 full_valuation() 走的是 pd.read_html,缺 lxml 就直接 ImportError: Missing optional dependency 'lxml'。我补装后,这两个端点分别返回 3 行和 12 行。有意思的是,被拒的社区 PR #22 里恰好有一条改动就是「ths_eps_forecast() 增加 lxml 依赖说明」。

第二,baostock 是硬依赖。估值历史(PE/PB/PS/PCF + 换手率 + 停牌 + ST)和上市退市日这两个端点只走 baostock,装上才有数据(6 行标的信息、14 行估值历史)。作者在 CHANGELOG 里承认过:「零第三方封装依赖」这句话现在只适用于其余端点。

第三,日期格式是 YYYYMMDD,填错不报错。em_zt_pool("2026-09-18") 返回 0 行、没有任何提示;em_zt_pool("20260918") 返回 78 行。同一个库里多数端点的日期参数是 YYYY-MM-DD,只有打板层这几个要紧凑格式,是很容易踩的静默空。

第四,东财风控是真的,而且表现为「静默空表」。作者的对策做得很扎实:所有东财请求统一走 em_get()——串行、最小间隔 1 秒加随机抖动、复用 Keep-Alive 会话、403 不重试(重试反而加重)、带正常 UA 与 Referer。但我连着扫了一百多次调用之后,push2 系端点开始连接被拒;更麻烦的是同一组参数在两次扫描里,资金流端点第一次返回 100 行、第二次返回 0 行。调用方拿到的不是报错,是空表。

第五,通达信那条路已经半废。tdx_client() 依赖的 mootdx 库 2024 年就停更了,2026 年 9 月起通达信公开服务器的 K 线、盘口、逐笔全部返回 0 行(issue #52,作者自己开的)。现在只剩财务快照和 F10 能用,K 线改走腾讯和通达信官网盘后包。作者没有删掉这个端点,而是让报错直接指路——这个处理是对的,但你要是照抄了半年前的教程,会先浪费 90 秒等它失败。

第六,SKILL.md 里没有免责声明。README 的最后有「本项目仅提供数据获取工具,不构成任何投资建议」,但这份 408 KB、真正被 AI 读进上下文的文件里,一个字都没有。它面对的是「帮我看看这只股票」这类问题,而投资建议的边界只写在不会进模型上下文的那个文件里。

争议:社区要拆四次,作者的原话是「有意产品决策,长期保持」

a-stock-data 最有意思的地方不是它写了什么,是它长成了什么形状。

SKILL.md 现在是 408,549 字节、7,289 行,其中 41,945 个汉字、89 个代码块、5,772 行代码。Anthropic 官方《Skill 编写最佳实践》里有一句:「将 SKILL.md 正文保持在 500 行以内以获得最佳性能;接近此限制时将内容拆分为单独的文件。」这里是那个数的 14.6 倍。

它不是一天长成的。我把每个提交点的文件大小拉了出来:5 月 30 日的 v3.2.1 是 2,090 行 / 78 KB,7 月 10 日 2,648 行,8 月 19 日 4,137 行,9 月 20 日的 v3.9.0 一步从 4,552 行加到 7,288 行——113 天里行数涨了 3.5 倍,字节数涨了 5.2 倍。

社区不是没看见。6 月 2 日 issue #21 的原话是「当前 skill 巨大,读一次 token 就没好多」;6 月 3 日有人交了 PR #22,一份完整的渐进式披露重构:把 SKILL.md 改成轻量路由入口,端点实现拆进 scripts/,说明拆进 references/,连 agents/openai.yaml 和 smoke test 脚本都写了;6 月 17 日 #27 建议用 Anthropic 的 skill-creator 重新 review;6 月 22 日 #29 逐条给出了拆分方案,包括统一 JSON 输出契约。

作者 7 月 10 日给了最终答复,并把理由摊开:单文件自包含是有意产品决策,长期保持,不做目录化拆分。三条理由——① 「形态即卖点」,拷一个文件就能用,过去两周有 3,000+ 人 clone、1,400+ 人直接在 GitHub 上读 SKILL.md,拆分换不来这种可携性;② 单人维护下「拆分版 + 单文件版」双形态必然漂移,漂移比 token 成本更伤用户;③ token 痛点用不改形态的方式缓解——把 description 收窄,因为「误触发才是最大的浪费」,当时的口径是「此前任何 A 股话题都可能误触发加载 50K token」。

第 ③ 条是真的落地了:现在的 description 明确写着「仅在需要调用数据接口取数时使用」,并且点名排除「A 股概念解释、投资观点讨论、策略问答」;文首还有一张「端点路由速查」总表,鼓励按需局部读取。

但数字也摆在明面上:他当时说「误触发一次 5 万 token」的时候,文件是 2,177 行;现在是 7,289 行。按常见分词器粗算,一次完整加载约 11 万 token(我的算法:4.2 万个汉字约 1 token 一个,26 万字符的代码与英文按约 3.5 字符一个 token,实际数字取决于分词器,但量级没有争议)。他自己在 #21 里留了后门:「如果未来端点规模翻倍、单文件确实不可持续,会重新评估」——v3.2 到 v3.9,端点从大约 30 个走到 85 个。

还有一个数字值得一起看:这个仓库 12 个 PR,一个都没合并。作者在 issue 里承认过 PR 里的问题,然后自己重写一遍进 CHANGELOG(比如 PR #20 的巨潮 orgId 动态化,v3.2.2 里以作者自己的改动落地)。这不一定是坏事——issue #27 里一位用户让 GLM 跑 review,报的五条里最重的一条被作者核对后确认并修掉:full_valuation() 按列位置 iloc[2] 取 EPS,实际取到的是同花顺的「最小值」列而不是「均值」,导致 PE 与 PEG 长期系统性偏差。作者改成了按列名取。但你也该知道,这个仓库的演进节奏完全由一个人决定。

顺带一句:这类工具的地基一直在动。CHANGELOG 的 FAQ 里有一节叫「已死透别用」——网易财经整站下线、和讯、凤凰行情、腾讯资金流接口、雪球免登录数据,全死了;mootdx 库 2024 年停更;2026 年 9 月通达信公开服务器的行情命令集体返回 0 行。「34 个数据源」不是一个稳定数字,而是一份随时会过期、需要有人持续跟进的快照。

判断:什么时候该拷这个文件

它值得用的场景很明确:你要让 AI 或者脚本以最低的安装摩擦拿到 A 股数据,能接受「一个人维护、会随版本跟进」;你在国内网络(我这台机器出口是广州联通的 IP,实测 76 个端点直接返回真实数据);你需要的是单次或低频取数,认可它把数据边界写清楚的做法——每个端点标注数据来源、口径、实测日期,连「大商所官网有 JS 反爬、HTTP 返回 412 所以没接」都写在文档里。这种诚实度在国内数据接口项目里并不多见。

不该用的场景也一样明确:别把它装成常驻自动触发的 skill,除非你已经想好每次触发 11 万 token 的代价,更划算的做法是把它当一个手册放在项目目录里,让 agent 按层局部读——这也正是作者推荐的用法;别拿它做高频批量,东财的风控会以「空表」而不是报错的形式找上你;别指望回测,作者的 FAQ 里写明了本 skill 不带回测;也别指望所有源永远活着,你真正买到的是「源死了有人改」这条流水线。

类似的取舍在其他评测里也出现过:零密钥的方案往往要靠轮换多个不稳定的公开源来换取免注册(Wigolo,18 个搜索源实测只剩 1 个在干活);而当一个生态由单人维护时,社区贡献会以「被采纳但不合并」的方式落地,这一点在 Spec Kit 那份评测里也能看到同一个规律。

至于「单文件还是渐进式披露」,这不是一个非黑即白的工程问题。作者用 113 天和一个 408 KB 的文件给出了他的答案:可携性优先,token 靠收窄触发来省,而不是靠拆目录。这个答案在「拷走就能用」的传播场景里是成立的,在「长期常驻、天天触发」的用法里就不成立——所以真正需要你自己判断的,不是他对不对,而是你打算怎么用它。

Jev Ultrafast 深度评测:7 秒搜完机票的浏览器 Agent,一次决策只发一个请求

Jev Ultrafast 深度评测:7 秒搜完机票的浏览器 Agent,一次决策只发一个请求

7.1 秒,从一句自然语言,到 Google Flights 上列出苏黎世飞伦敦的航班,全程 1 倍速录屏,包含文本生成、模型调用和加载等待。Browser Use 与 TypeSafe 合作的开源 Agent 仓库 jev-ultrafast 靠这个数字刷屏,9 月 16 日创建,三天冲到 8,346 星。

我把它 clone 到本地,跑了官方全部离线测试,审计了它「一次决策要发几次网络请求」,把两个真实页面的动作表重放成请求体算了账,还独立复核了那段 7.1 秒视频和 $0.0039 的账单。

先说清楚一件事:我没有 TypeSafe 的 API key,没能跑通端到端任务。TypeSafe 目前是 waitlist 制,仓库 issue 里有人直接问「怎么拿到 TYPESAFE_API_KEY」。所以下面所有结论来自三处可独立验证的材料:官方 31 个离线测试与源码、官方公布的录制数据、以及我用真实网页 DOM 做的重放。跑不通的部分我会标出来。

7.1 秒是真的,但计时器是后开的

官方性能文档写得很直白:计时起点是「初始首页观察之后的第一次预测」,终点是「被接受的 DONE 选择」。浏览器启动、初始导航、以及任务结束后的独立结果校验,全部在计时之外。

这不是注水,是常规口径,但读者该知道这 7.1 秒买的是什么:页面已经打开、正文已经渲染完之后,Agent 从「看第一眼」到「确认结果正确」的耗时。

视频我也复核了。ffprobe 读出来 7.566 秒、227 帧、恒定 30fps;7.566 秒 = 公布的 7.073 秒运行 + 0.5 秒结尾停留,时间轴对得上。把浏览器画面区域单独裁出来逐帧比对,227 帧里有 224 帧互不相同——它不是靠重复帧把时长凑出来的。

有一处对不上:测量文件里写 video/source_frames = 187,而视频实际是 227 帧。这更可能是渲染脚本重跑之后元数据没同步,但可以确定的是,视频右下角那个跳动的秒表是渲染时按帧序号算出来的,不是硬件计时器。所以「1 倍速」这件事,外部无法只靠看视频证明,它依赖录屏时间戳被忠实映射。

还有一点值得给作者加分:官方在性能文档里保留了匹配对照的完整数据,三对样本,中位耗时 9.450 秒降到 7.092 秒,然后自己写了一句「三对样本太少,做不了强统计声明(双尾符号检验 p = 0.25)」。同一份文档里还留着自己失败的开发尝试——有一次跑到 8.697 秒更快,但独立校验没通过,被毙了。愿意把推翻自己的数据留在仓库里,这在爆款项目里不多见。

它把「决策」从字符串生成里抠了出来

jev-ultrafast 不是一个模型,是 Browser Use 给 TypeSafe 的 Jev 模型写的一层浏览器运行时。

Jev 是 TypeSafe 9 月 15 日发布的 System One 模型。它的输出不是文本,而是类型安全的决策值加校准概率——你事先定义好问题和选项,它一次查询并行吐出所有选项的概率,不做逐 token 自回归。官方定价 $0.042 每百万输入 token,输出 token 免费,端到端 70 到 500 毫秒。名字取自杰文斯(William Stanley Jevons),那位提出「效率提升反而推高总消耗」的经济学家。

这套东西落到浏览器里,做法是这样的:每次观察页面,运行时生成一张带编号的元素表,每个可见控件占一个索引(同一个 DOM 节点即使既能点又能填,也只占一个索引)。然后把整个目标、页面正文、元素表、最近十步动作打包,一次请求里同时问四个问题:下一步做哪个操作、如果点那么点哪个、如果填那么填哪个、如果下拉那么选哪项。

只有被选中的那个操作对应的目标头会被读取,其余的即使模型答了也不执行。这样一来,过去「先问该做什么,再问点哪里」的两次往返被压成一次,同时保证了不会拿一个 TYPE_TEXT 的目标去执行点击。

整个 Agent 主循环 agent.py 是 174 行。快照逻辑 snapshot.js 107 行。

我把它的每一步都拆开算了

离线部分全部通过。官方测试 31 个断言 1.04 秒跑完,一个不挂;ruff 静态检查干净;两个前端脚本 node --check 通过;uv build 能正常打出 wheel。代码总量 1,681 行 Python(其中测试 320 行),对一个需要驱动真实浏览器的项目来说小得反常。

一次决策确实只有一次网络往返。 我替换掉 HTTP 客户端做拦截,捕获到的请求体里同时挂着四个问题头:operation、click_target、type_text_target、select_target。返回的答案里,目标头带着完整的概率分布,但代码只取与所选操作匹配的那一个。README 里「两个决策,一次网络往返」的说法成立。

真实页面的账单我也算了。我用浏览器在目标站点上原样跑了一遍官方的快照脚本,拿到真实的动作表,再喂回官方 Python 的 action_space() 和 choose() 生成请求体:

页面(1120×780 视口) 可点元素 请求体 粗估 token
Google Flights 首页 21 个元素 / 24 个动作候选 9,935 字节 2,483
GitHub issue 列表页 57 个元素 / 60 个动作候选 17,395 字节 4,348

拿这个数字去对官方录制:那次跑动用 17 次请求消耗 90,558 输入 token,均摊每次 5,327 token。我的重放是 2,483 到 4,348,量级一致——说明 90,558 这个统计可信,而且后续步骤因为要带上历史动作和更满的结果页,单次开销还会涨。

账单也算得回来。90,558 × $0.042/百万 = $0.0038,官方宣传的任务成本是 $0.0039,差 2.6%,基本就是四舍五入。输出 token 不收费。折算下来一次跨境航班搜索不到 3 分钱人民币,而且这个数字里还不含浏览器和文本助手的开销(那部分官方实测是 $0.00006272)。Doom 那个演示跑 10 次决策每秒,作者说约合 $7 每小时。

安全边界经得起打。README 声明「模型输出永远不会变成选择器、坐标、shell 命令或可执行 JavaScript」。我构造了六种畸形响应去打它:把 choice 换成 document.querySelector('#x')、换成一段 script 标签、概率之和只有 0.5、概率里塞 NaN、选了个不是最大概率的选项、概率集合和候选对不上。六种全部被拦,一行动作都不会执行。

顺带发现一个代码里没写的原因:快照最多保留 250 个动作候选,而 TypeSafe 官方博客明确说 Jev 的选项基数上限是 255。250 这个数字大概不是随手取的。

视频、代理,和两个 AI 编出来的 issue

代理这一条,中文用户几乎必踩。issue #16 报告:httpx 在模块导入时就建了连接池且不处理代理,只要环境变量里有 ALL_PROXY=socks5://,程序在 import 阶段直接崩,报 ImportError: Using SOCKS proxy, but the 'socksio' package is not installed。我在沙盒里原样复现了。Clash、v2ray、xray 的默认配置都会导出这个变量。

代码默认值里还埋了一个坑。文本助手的 base URL 在代码里的默认值是 https://api.deepseek.com/v1,而 .env.example 和 README 写的是 OpenRouter。也就是说,一个人照着 README 只填了 TEXT_MODEL_API_KEY 就运行,他填进去的 OpenRouter 密钥连同页面文本会被发到 DeepSeek 的接口上。这条是 issue #36,我核对源码 164 行属实。

生态侧的数据就不那么好看了。仓库三天收了 40 个 PR,39 个没合并,唯一合掉的是作者自己改 README 的一条。16 个 issue 全部处于 open,一个都没关闭。三位贡献者里只有一位(作者本人),3 个 commit。

更麻烦的是信噪比。这里面混着明显是 AI 生成的幻觉报告,其中一条标着 HIGH:声称 README 的 clone 地址指向了错误的仓库——我 clone 过了,地址是对的;另一条说 agent.py 被压缩成了一行行的超长代码、违反项目自己的 120 字符行宽——实际文件 174 行、格式正常、ruff 检查干净。两条出自同一个账号,前后相隔 7 分钟。

也有真材实料的报告。issue #23 里,一位用户拿中国铁路 12306 的购票页去跑,结果是:60 个动作全部是往同一个输入框里打字,跑了 77 秒,120 次决策预算耗尽,出发站和到达站最后都被填成了「北京」。原因是快照只收集原生控件(a[href]、button、input 等)和固定清单里的 ARIA 角色,而 12306 的站点联想行是用裸 li/div 自己绑点击事件做的,模型根本看不见,只能反复重试它唯一看得见的那个框。

这暴露了动态索引动作空间的真实边界:它不是「看得懂网页」,而是「只看得见被预先定义好的那一类控件」。Google Flights 能用,是因为 Google 老老实实写 ARIA 标注。

值得看,但现在别急着拿它当脚手架

把结论分三层说。

方法层面,这个 demo 真的有价值。它证明了一件事:把「决策」从 LLM 的字符串生成里抠出来,换成一次并行的概率输出,是 Agent 提速最直接的一刀——不需要换更强的模型,不需要减少步骤,只是把「生成一段话再解析」改成「直接给答案」。这和 Pi Agent 砍工具数、unlazy 给完成状态装闸门是同一个方向:约束模型能做什么,比让它更聪明更有效。

工程层面,代码值得读。1,681 行、31 个测试、零运行时依赖、主循环 174 行,还能把「模型输出不变成选择器」这条安全不变量守住。想自己写浏览器 Agent 的人,这个仓库一小时能读完,比啃框架文档快得多。

产品层面,别急着接。三点:TypeSafe 还是 waitlist,拿不到 key 的话开源代码只能跑离线测试;中文站点上表现堪忧,12306 那种非标准控件直接崩;官方自己承认这不是基准测试,只是「一个任务在一个已有浏览器配置上跑三次」,而且性能对照的 p 值只有 0.25。

一句话:7.1 秒是真的,$0.0039 也是真的,但这两个数字测量的是「决策够快」,不是「网页够懂」。

想继续往下看,可以读这三篇:Pi Agent 实测 讲的是同一件事的另一个解法——默认只给模型四个工具;unlazy 深度评测 解决的是「Agent 说做完了怎么验」;OpenRouter 免费大模型全量拆解 里则有 Jev 上架 OpenRouter 之后的路由逻辑。

OpenRouter 免费大模型全量拆解:447 个模型里 25 个免费,最贵的三笔账不在价格表上

OpenRouter 免费大模型全量拆解:447 个模型里 25 个免费,最贵的三笔账不在价格表上

OpenRouter 上的「免费大模型」,价格是 0,但从来不是没有代价。今天官方模型接口返回 447 条记录,输入与输出价格同时为 0 的只有 25 条,占 5.6%。我把这 25 个逐条拉了下来——模型页、端点、延迟、吞吐、供应商数量、数据条款——结论是:免费池真正的成本,写在三张不在价格表上的账单里。(文中价格、额度与性能数据截至 2026-09-19,下单前请以官网为准)

免费额度怎么算:20 次/分钟、50 次/天,充值 10 美元换 1000 次/天

OpenRouter 做的是模型路由:一个 key、一份账单,覆盖 447 个模型、88 家供应商。2026 年 8 月它被 Stripe 以 70 亿美元收购,成为支付巨头押注的「模型路由入口」。

免费模型在这套体系里的位置,官方规则一共三档:

档位 每分钟 每天 条件
免费变体(累计充值少于 10 美元) 20 次 50 次 注册即可
免费变体(累计充值至少 10 美元) 20 次 1000 次 一次性充值 10 美元
付费变体 无平台级请求上限 不适用 按 token 计费

这 25 条免费记录里,22 个是带 :free 后缀的文本变体,2 个是 Google Lyria 音乐生成模型,1 个是随机路由。三个细节决定了这套规则的真实手感。第一,:free 不是一个开关,而是模型目录里单独的一行,有自己的定价、上下文长度和端点。第二,开小号没有意义——官方原文是「额外账号或 API key 不会改变限流,容量按全局治理」。第三,免费额度不花 OpenRouter 的钱,端点由供应商自己挂:NVIDIA 5 个、Google AI Studio 4 个、Novita 3 个,其余 9 家各 1 到 2 个,一共 24 个免费端点,外加一个随机路由的 openrouter/free。

换句话说,免费池是供应商拿算力换曝光、换数据、换榜位的地方。这直接决定了下面三张账单。

账单之一:8 个免费模型,由「可能拿你的数据训练」的供应商托管

OpenRouter 给 88 家供应商都标了数据条款。整张表里,承认可能用提示词训练模型的只有 4 家:DeepSeek、Liquid、Thinking Machines、NVIDIA。除 DeepSeek 之外的 3 家正是免费池主力,一共托管了 8 个免费模型,占免费池的三分之一。

另外 10 个免费端点属于「保留提示词但不训练」:Google AI Studio 保留 55 天、Nex AGI 保留 30 天、Cohere 保留 30 天,Poolside 与 AtlasCloud 没有给出天数。真正零保留的只有 6 个:Novita 的 3 个 Ling、ModelRun 托管的小参数 Qwen、OpenInference 托管的是 DeepSeek V4 Flash、以及 Decart 托管的 GLM-5.2。

这里有个容易被忽略的开关:账户设置里,付费模型与免费模型的「允许训练」是两套独立设置。你关掉它,那 8 个免费模型会直接从可用列表里消失——免费档的「免费」,一部分就是用数据条款换来的。

账单之二:免费版只有一个供应商,付费版最多 26 个

这是全量拉取后最扎眼的一组数字。24 个免费端点,每一个都只有单一供应商;同一个模型的付费版本却动辄十几二十个源:DeepSeek V4 Flash 有 26 个、GLM-5.2 有 23 个、Qwen3.8 27B 有 16 个、Gemma 4 31B 有 12 个。付费端点的多源意味着挂了会自动切到别家,免费端点没有 fallback,供应商一抖就整个不可用。

还有 7 个免费模型在 OpenRouter 上根本没有付费版本:Nex-N2.5 的大小两档、Ling 3.0 Flash Sante、Dots3-Note Preview、LFM 2.5、Cohere North Mini Code、Nemotron 3 Nano。对它们来说,免费是唯一入口。

规格也不是同一份。免费的 GLM-5.2 上下文只有 32768,付费版是 1048576,相差 32 倍;免费的 Qwen3.8 27B 是 262144,付费 1000000;反过来 Nemotron 3 Ultra 的免费端点上下文 100 万,比付费版的 262144 还大。免费端点不是付费端点的打折通道,而是另一套参数完全不同的部署。

可用率同样不均匀。24 个端点里有 3 个状态异常;过去三天,Nemotron 3 Nano 的日可用率是 80.1%、83.8%、83.8%,Inkling 最低 88.2%,DeepSeek V4 Flash 最低 94.0%。72 个「模型乘日期」的样本里,19 个低于 99%。

账单之三:免费最强只有旗舰的 64.6%,而且用量榜第一并不是分数第一

模型接口自带 Artificial Analysis 的智能指数,全部 447 个模型里有 145 个给出了分数。把这 25 个免费模型放进去排序是这样的:

免费模型 上下文 智能指数 p50 往返延迟 吞吐 免费端点数据条款
DeepSeek V4 Flash 0731 1.05M 34.5 2064 ms 25 tok/s 零保留
GLM-5.2 32768 34.0 1164 ms 37 tok/s 零保留
Qwen3.8 27B 262K 33.9 626 ms 28 tok/s 零保留
Inkling 1.05M 25.5 1840 ms 35 tok/s 可能训练
Ling 3.0 Flash VL 262K 25.0 2361 ms 60 tok/s 零保留
Nemotron 3 Ultra 1M 23.4 3143 ms 19 tok/s 可能训练
Ling 3.0 Flash Fin 262K 23.0 1342 ms 136 tok/s 零保留
Gemma 4 31B 262K 15.4 1291 ms 22 tok/s 保留 55 天
Nemotron 3.5 Lightning 1M 13.6 5134 ms 16 tok/s 可能训练
Cohere North Mini Code 256K 9.9 601 ms 80 tok/s 保留 30 天

三个结论。免费最强 34.5 分,在 145 个有分模型里排第 40,只有付费旗舰 53.4 分的 64.6%——免费档够做事,但够不到第一梯队。用量榜第一不等于能力榜第一:官方按近 7 天真实 token 用量排的免费榜,第一是 Nemotron 3 Ultra(4.32T tokens),智能指数只有 23.4;分数第一的 DeepSeek V4 Flash 用量排第 4;分数第二的 GLM-5.2 连前 16 都没进。延迟与吞吐也和分数无关,最快的 LFM 2.5(2.6B 参数)吞吐 185 tok/s,最慢的 Lyria 只有 4 tok/s。

延迟高有一半要怪拥挤:官方 30 分钟统计窗口里,免费池一共处理了约 50.1 万次请求,其中 Nemotron 3 Ultra 一家 10.96 万次、DeepSeek V4 Flash 9.83 万次。这些请求共享 20 次/分钟的平台限流。

该不该用:三种用法可以,三种用法别碰

先说额度值多少钱。额度按请求数计,不按 token 计。以一次请求 800 输入加 300 输出 token 估算,同样是每天 1000 次,按各自最便宜的付费端点价折算:

免费模型 付费价(每百万 token 输入/输出) 1000 次折算 一个月折算
Inkling 0.95 / 4.05 美元 1.98 美元 59.2 美元
Nemotron 3 Ultra 0.50 / 2.20 美元 1.06 美元 31.8 美元
GLM-5.2 0.554 / 1.742 美元 0.97 美元 29.0 美元
Qwen3.8 27B 0.10 / 1.80 美元 0.62 美元 18.6 美元
Gemma 4 31B 0.09 / 0.34 美元 0.17 美元 5.2 美元
DeepSeek V4 Flash 0731 0.04 / 0.08 美元 0.06 美元 1.7 美元

同样是一次性充 10 美元解锁每天 1000 次,选错模型,一个月的额度只值 1.7 美元;选对模型值 59.2 美元,差 34 倍。这个换算的口径是请求数不是 token 数,长上下文任务的实际价值会更高。

还要留意免费池的周转速度:这 25 个免费模型里,14 个是最近 90 天上线的,23 个在半年内上线,最早的一个也只到 2026 年 2 月。名单变得很快,今天能用不代表下个月还在——官方 FAQ 的原话是「这些模型限额低,通常不适合生产使用」。

横向看,Google AI Studio 的免费层是按项目、按模型分别限额,官方文档已经把逐模型的免费额度移出文档页;Groq 的免费层是另一套独立限流。OpenRouter 免费档的独特点在于覆盖面:一个 key 能试到 NVIDIA、Google、Cohere、DeepSeek、Qwen、GLM 全家共 24 个模型,代价就是上面那三张账单。

三种用法可以:一是原型验证与选型,一个 key 横评多个实验室的模型;二是非实时批处理,每天 50 到 1000 次足够跑小批量实验,慢一点不影响结果;三是学习与风格对比,openrouter/free 随机路由反而适合感受不同模型的差异。

三种用法别碰:一是生产环境,单源、20 次/分钟、可用率最低到 80%;二是隐私敏感内容,三分之一的免费端点来自可能保留训练权的供应商;三是需要一致性的 agent 长链,额度按请求数计,一次 agent 任务动辄几十次请求,而随机路由每次换模型,行为无法复现。

判断很明确:OpenRouter 免费档值得开,但要把定位从「省钱的生产方案」改成「低成本试模型加非敏感批处理」。它是目前最便宜的横评 24 个模型的方式;把它当生产环境用,或者把敏感代码贴进 NVIDIA、Thinking Machines、Liquid 托管的模型里,那就是在拿另一样东西付费。

相关阅读:

unlazy 深度评测:3,462 星的反摆烂验收闸门,把「做完了」变成一条能跑的命令

unlazy 深度评测:3,462 星的反摆烂验收闸门,把「做完了」变成一条能跑的命令

你让 AI 改 80 个文件里的 bug,它交回一份自信的完工报告,每个文件都打了勾。你抽查一遍,发现它实际只打开了 11 个。

unlazy 的作者把这件事写在仓库最显眼的位置。这个 2026 年 8 月 9 日建仓、40 天涨到 3,462 星的 skill,只做一件事:把「做完了」这句话变成一条能跑的命令。

它不劝模型努力,不写更长的提示词,也不骂模型。它要求 agent 在动手之前先写一份验收台账 GATES.md,每条闸门必须配一条命令和一句成功标记;跑完之后,检查器把「定义摘要、退出码、输出指纹」写回台账,agent 只能报告检查器认可的结果。

我在 Alpine 沙盒里把它拆开,跑了 6 组对抗实验,包括我自己伪造证据去骗它。结论比宣传语复杂:它能识破手写的假报告,但挡不住会算哈希的骗子——而作者自己承认了这一点。

它是一段代码,不是一段话术

反摆烂这个赛道里,unlazy 算是最冷的一条路。

它没有一句「你必须在放弃前再试 3 次」这类施压话术,核心是一个 960 行的 Node 脚本 gate-check.mjs,配套 953 行的解析库。整个仓库的运行时依赖是零:只用 node:fs、node:crypto 这些内置模块,没有 node_modules,Node 16 以上直接跑。SKILL.md 常驻上下文只有 10,520 字符,占整个技能包 114,606 字符的 9.2%,其余方法论、编排、安全说明都靠按需加载。

它给三种场景配了三档模式:

  • solo:一个 GATES.md 管一个任务,适合一个会话能干完的活。
  • orchestrated:先写 PLAN.md 定义契约和树结构,每个叶子和分支各自带台账。
  • parallel:多个叶子并行时,靠 OWNS: 声明文件所有权,先声明再开工,出错时能知道谁动了哪块。

闸门本身长这样,CHECK: 后面是可以执行的 shell 代码,EXPECT: 是只有成功才会打印的那句话:

- [ ] G1: pricing fixtures render the expected tiers
  CHECK: node scripts/verify-pricing.mjs
  EXPECT: pricing verification passed
  EVIDENCE: pending

判定规则只有两条:进程退出 0 + EXPECT 命中输出。两条都满足,检查器才会写回一条自动证据,长这样:

automatic-evidence=v1; definition-sha256=5f9ebdcc…; exit=0; EXPECT=matched;
output-sha256=67265cd5…; output-bytes=9; shell=/bin/sh; cwd=…; path=2da0e2f6c375/7 entries

这条 346 字符的证据,是整篇文章最值得注意的地方:它不是人写的,是检查器写的,而且和这条闸门的 CHECK:、EXPECT:、CWD: 三个字段的 SHA-256 绑定。你只要改动其中任何一个字,证据立刻作废。

实测:6 组对抗实验

我把测试分两类:它能不能识破别人撒谎,以及它自己会不会被糊弄。

实验 我做的事 结果
手写假证据 给一条命令实际会 exit 1 的闸门打勾,证据栏写「passed – independently verified」 --status 判 UNMET,理由是证据未绑定;加 --approve 真跑一遍后,勾被取消,证据回到 pending
未审批直接跑 不带任何参数运行检查器 只打印 CHECK、EXPECT、CWD、SHELL、PATH,一行命令都不执行
输出超限 让闸门打印 2 MiB 再退出 0 不是把输出截断成通过,而是直接 SIGKILL,报 output exceeded 1048576 bytes
定义漂移 把 CHECK 里的 ok.mjs 改成内容完全相同的 ok2.mjs 不执行任何 shell,--status 直接判 stale-unmet
台账畸形 空台账、重复 id、缩进写 ABANDON: 均 exit 2 并给出行号;顶格 ABANDON 判 exit 1 HANDOFF REQUIRED,不算成功
停止钩子 连续触发 6 次停止事件 前 6 次全部 decision: block,第 7 次主动释放,理由是「6 次无进展」,防止把 agent 卡死

有一组实验它没扛住。

它的证据绑定用的是无密钥的 SHA-256:摘要算法是公开的,仓库自己把 gateDefinitionDigest() 导出了。我把这个函数 import 进来,算出一条会失败闸门的定义摘要,然后手写一条声称 exit=0; EXPECT=matched 的证据,再打上勾——--status 立刻把它读成 MET,整份台账报「4 gates,UNMET 1」。一条命令实际退出码为 1 的闸门,就这样被判为通过。

README 里其实写着这件事:这种绑定能发现结构性漂移,但挡不住能编辑台账的人伪造看起来合法的证据。所以正确的用法是父层复核——加 --reverify 重跑所有可跑闸门。我试了,同样一份被我伪造过的台账,重跑 3 条闸门后,假的那条被判 FAIL,勾被取消,证据清空。输出里还有一行 reran: 3, previously met reverified: 3。

说白了:它防的是「不小心糊弄」,不是「故意撒谎」。

官方测试和自己承认的账

仓库自带 8 个测试文件,近 7,000 行。我在沙盒里逐个跑完:34/34、27/27、51/51、29/29、8/8、15/15,压力测试 24 条里通过 23 条,合计 187/188。

唯一挂掉的那条,是安装器拒绝硬链接文件的那组压力测试。我复现后发现失败发生在清理阶段,报的是 ENOTEMPTY。原因是我的沙盒对硬链接做了特殊模拟,ln 之后会留下 .l2s.* 临时副本,连 rm 都报 Operation not permitted——不是产品问题,是环境问题。产品那一侧的断言(拒绝写入、不改受害者文件)实际是通过的。

更有意思的是这个仓库对自己宣传数据的态度。

初版 README 写着深度树的算术:努力量等于 T 乘以 2 的 N 次方减 1,tree 3 就是 4 倍工作量,tree 7 是 64 倍。现在的版本把这句话改掉了,改成「深度树是分解与整合,而不是算术上的努力倍增器」。早期那组「六次运行对比」输出的 token 比例和自找缺陷数,也被明确标注为不可复现、不得当作 benchmark 承诺,仓库里专门放了一份 research/validation-protocol.md,给出预注册、隔离运行、操作化指标、盲评、发布计算过程、限定结论这 6 步可复现协议。

顺便说一句,它的引用是干净的:README 里列的 9 篇论文,我逐个打开 arXiv 核对,编号、标题、日期全部对得上;SlopCodeBench 摘要里那句「没有任何 agent 端到端解决问题,最好的 agent 通过 14.8% 的检查点」,和 README 的引用一字不差。

代价方面:--status 跑一次 206 毫秒,3 条闸门的 --reverify 934 毫秒,一条自动证据 346 字符。这个开销换来的是那句你不能反驳的交付报告。

三条反摆烂路线,选哪条

把已发过的几篇放在一起看,反摆烂目前有三条路线:

路线 代表 做法 你得到什么
话术施压 tanweai/pua(19.6k 星) 用压力话术和方法论约束 agent 的行为 模型行为的改变,无法验证
文件化计划 Planning-with-Files(26k 星) 用三个文件让 agent 不失忆 一份可读的计划和进度
可执行验收 unlazy(3.4k 星) 每条验收标准绑定一条命令 一份能被脚本复核的完成证据

适合谁:长任务、多部件交付、需要向别人交代证据的场景,或者你被 agent 的假完成坑过。它的 solo 模式上手成本很低,一份十来行的 GATES.md 加两条命令就能跑起来。

不适合谁:一次性的小改动别用,SKILL.md 自己写了——琐碎编辑和事实性回答不需要建台账。另外停止钩子只在 Claude Code 里生效,换别的宿主就只剩手动跑检查器这一半能力。最要紧的一条:如果你需要的是防作弊,它不行,它只是让作弊变得需要多写一行代码。

结论

值得放进工具箱,但别把它当防作弊工具。

我的建议是只用它的两个动作:开工前写 GATES.md,交付前跑 --reverify。第一条治的是「凭感觉觉得做完了」,第二条治的是「证据过期了还以为通过」。这两件事它做得比任何提示词都硬。

它现在的短板也很实在:仓库 0 release、0 tag,README 明确说 2.1.0 只是源码里的目标版本,你 npx skills add 装到的是未发布的源码树;11 个 issue 全部关闭、24 个 PR 合并 16 个,治理看着干净,但版本这件事上你得自己锁 commit。

真正让我愿意为它写一篇的,是作者的克制。一个 3,462 星的仓库,主动把早前那句「tree 7 = 64 倍努力」撤掉,把六次运行的对比数据标成不可复现,再附一份自己还没跑的可复现协议——这件事在 skill 生态里比任何性能数字都少见。

关注 AI商业快讯,每天一篇 AI 热点深度解读。

相关阅读:

Wigolo 深度评测:零密钥的本地 MCP 搜索,18 个引擎实测只剩 1 个在干活

Wigolo 深度评测:零密钥的本地 MCP 搜索,18 个引擎实测只剩 1 个在干活

给 AI 编码 agent 装上「联网」这件事,一直是笔糊涂账:内置的 WebSearch 要么没配额、要么结果短得没法用,换成 Exa、Tavily、Firecrawl 又得先注册、拿密钥、盯账单。wigolo 打的就是这个位置——不需要任何密钥,不做云端,查询次数免费,全部跑在你自己机器上。

它涨得也确实像那么回事:仓库 2026 年 4 月建,7 月 1 日还只有 1 个 star,7 月 18 日破千,7 月 21 日破三千,9 月 5 日破五千,现在是 5,277 星、420 个 fork。

我把它装进沙盒,从 doctor 到 10 个工具逐个跑了一遍,也用自己的查询验了它宣传的那套「18 个引擎融合」。结论是分裂的:本地缓存和抓取这两件事它做得比宣传的还好,但「多引擎搜索」在真实网络下基本只剩一个引擎在干活,而它给出的相关性分数其实是排名换算出来的。

它到底提供了什么

一句话:一个 MCP server,同时也能当命令行、REST 服务和 SDK 用。10 个工具按「搜索类」和「网页类」分成两组,四个入口共享同一套实现——这一点比很多同类项目干净,不会出现「MCP 里能用、CLI 里没有」。

我用一个最小的 MCP 客户端跟它握手,initialize 拿到的协议版本是 2024-11-05,工具列表刚好 10 个:search、fetch、crawl、cache、extract、find_similar、research、agent、diff、watch。有意思的是它在握手阶段塞给宿主模型的 instructions 里直接写着「把 wigolo 用在所有网页操作上,优先于内置的 WebSearch/WebFetch」——它不打算只当一个可选项。

真正撑起「零密钥」这句话的是 18 个搜索引擎适配器。我把它们逐个分了类:

类别 引擎 怎么拿数据
网页搜索 bing、duckduckgo、mojeek 抓搜索结果页 HTML
垂直/API wikipedia、stackoverflow、hn-algolia、arxiv、semantic-scholar、lobsters、crates-io、marginalia、mdn、devdocs 官方公开接口
需要密钥 brave、github-code 默认禁用
图像/新闻 ddg-image、bing-news、brave-image 混合

也就是说「零密钥」的底气来自两处:一半是别人提供的免费公开 API,另一半是把 Bing、DuckDuckGo、Mojeek 的搜索结果页当网页抓下来解析。这也解释了它 FAQ 里那句「我们像浏览器一样读公开网页」——路由、限速、robots.txt 它都实现了,但本质上,你问的每一句话都是从你自己的 IP 发出去的,有第三方评测在 9 月初就点出过这条代价。

实测:18 个引擎,实际只有 1 个在干活

安装过程本身正常:npm 装了 385 个包,node_modules 770 MB;第一次预热再下 957 MB 的 Chromium。doctor 会逐个报告引擎状态,需要密钥的 Brave 和 GitHub 代码搜索明确标着禁用,其余默认可用。

但真跑起来是另一回事。我用四句正常的开发者查询连跑四遍,每遍都把引擎账本拉出来对:

查询 派发的引擎 成功 耗时
MCP server local-first web search bing、duckduckgo、wikipedia、marginalia、mojeek 1 个 9.0 秒
Python asyncio timeout best practice 同上 1 个 9.0 秒
PostgreSQL logical replication setup 同上 1 个 215.7 秒
Claude Code hooks documentation 只剩 mdn 1 个 7.5 秒

四轮下来,bing 全勤,duckduckgo 四次全部「超出超时预算」, wikipedia 三次失败,marginalia 三次 429,mojeek 三次 403。返回体里那个 engine_pool 字段写得很清楚:healthy: 1, total: 5, degraded: true。

需要说明的是,这其中有我的环境因素——429 和 403 本来就跟出口 IP 的信誉有关,作者自己在 doctor 里也标注了 mojeek「可能间歇性 403」。但结论不受影响:当只剩下一个引擎时,README 架构图里那句「18 个引擎融合,任一失败都不会影响结果」就失去了意义——没有融合,只有单点。

更值得看的是第三行那个 215 秒。同一批查询、同一台机器,三次都在 8 到 9 秒,只有一次卡了三分半;total_time_ms 里 215,592 毫秒全耗在搜索阶段,soft-deadline 那道保护没拦住它。agent 在等这个调用的时候,用户看到的是「模型卡住了」。

结果正文的质量也跟着掉。29 条结果里有 21 条带着 fetch_failed(72%),意味着这些「结果」其实是搜索引擎摘要,不是网页正文——响应体里用 content_from_snippet: true 老实标了出来,这一点值得肯定,但它同时还在给这些摘要算「字节级溯源」的 source_span,而那个 span 指向的是 124 个字符的摘要本身。

一次彻底跑偏,和一套换算出来的分数

四轮里最难看的一轮是 Claude Code hooks documentation。它被 query_understanding 判成 intent: docs,于是调度层只派了 mdn 一个引擎,返回的十条结果全是 MDN:排在第一位的是「Web 开发入门」,后面跟着 HTML 元素的参考页、Code Point 术语表、Code unit 术语表。我用同一个函数名换成 React hooks documentation 再跑一次,react.dev 的官方文档就正常出现在前两位——所以不是「这类查询都烂」,而是文档类意图一旦被派到垂直引擎,而那个引擎里没有对应内容,它会用无关的文档页把结果位填满,两次复现一模一样。

比跑偏更值得警惕的,是它给这些结果打的分:

名次 展示的相关性分 实际是
第 1 名 1.000000 永远等于 1
第 2 名 0.983871 61/(61+1)
第 3 名 0.968254 61/(61+2)
第 8 名 0.884058 61/(61+6)

我把两次不同查询的十名分数拉出来对比,序列一模一样。翻源码能确认:orchestrator.ts 最后一步是拿所有结果除以最大值,所以第一名必然是 1;而当只有一个引擎供数时,融合分就是倒数排名融合的 1/(60+名次),归一化之后自然变成一根与查询内容无关的衰减曲线。

所以那些 MDN 无关文档,拿到的分数是 1.0 到 0.87。一个按「相关性分 > 0.7 就采信」办事的 agent,会把它们全部当真。它确实还提供了可解释的 evidence_score.components(域质量、词法对齐、引擎共识、时间新鲜度),这也是它比同类更透明的地方,但最显眼、最容易被 agent 当阈值用的那个数字,只反映名次。想让它真的有用,得读组件分而不是总分。

它自己的 benchmark 跑不起来

这个仓库带了完整的 benchmarks/ 目录,四个基准:搜索、抽取、agent、嵌入。我把 package.json 里的命令照抄执行,结果是:

  • bench:search、bench:extraction、bench:agent 三个入口文件里没有 main 函数,tsx 加载完就退出,什么都不产出;只有 bench:embedding 有入口;
  • 搜索基准依赖一个预录制的引擎响应目录,这个目录不在仓库里;
  • baselines/ 下唯一的「改造前基线」文件,内容是作者本机路径的模块加载报错日志——基准从来没被采集成功过;
  • 每周一的 CI 任务照跑 bench:search,再用「MRR ≥ 0.4」当门槛;它读的是那个不会生成的结果文件。

于是 README 里那段「Benchmark」,实际是一次单条查询的四路对比动图,由 agent 当场评判。它是好的产品演示,但不是基准,仓库里也没有任何 precision、nDCG 或 MRR 的数字被公布过。

治理:一个人的仓库,14 个外部 PR 零合并

这一项不是缺陷,但读者该知道自己在用什么。

我拉了全部 300 个 PR:286 个由作者本人提交,14 个来自外部贡献者,其中被合并的是 0 个。贡献者列表总共 11 人,作者一个人占 1,976 次提交(占全部 2,007 次的 98.5%)。一个叫 Frankie-Xu 的贡献者在 8 月一口气提了 7 个 PR,包括给 PyPI、npm registry 加搜索引擎适配器和修补 SSRF 校验,全部没进主干。

更实际的问题是节奏错位:npm 上的版本停在 0.2.1,2026 年 7 月 19 日,而仓库每天还在提交(最近一周还有 60 多次)。CHANGELOG 的最后一版也停在 v0.2.0。这意味着你 npx wigolo 装到的,是两个月前的构建,里面那些已知问题都还在。

我顺手复现了其中一个:issue #303 说 --search-engines 参数声明了但没人消费。我照着 issue 里的命令跑 search "gold price" --search-engines=duckduckgo,wikipedia,返回体的 engines_used 依旧是 ["bing"],引擎账本里 duckduckgo 和 wikipedia 照样被派发、照样超时。在源码里搜 searchEngines 有 41 处匹配,没有一处读取这个入参。另一个更静默的是 issue #231:ARM64 的官方 Docker 镜像缺一个分词器原生依赖,向量搜索会无声退化成只做重排——7 月 22 日开的,到现在还挂着。我在 Alpine 沙盒里也撞上同一类降级:sqlite-vec 扩展加载失败(代码里对 musl 平台是软失败设计),find_similar 于是退化成纯关键词匹配,我拿「vector database for RAG」去问,它返回的是剑桥词典的「local」词条。

省下的钱,没有想象中多

它最响的口号是「$0/query」。这句话是真的,但省钱这件事要看你一个月查多少次。按各家 2026 年 9 月的公开价,一家一口径算下来:

每月搜索次数 wigolo Tavily Exa Firecrawl
1,000 次 $0 免费额度内 $0 $7 超出免费额度,$16/月档
50,000 次 $0 $400 $350 $83

结论不算意外:一个人用,免费额度基本够覆盖,wigolo 省的是每月十几美元,换来的是 1.7 GB 磁盘、你自己的 IP 和时好时坏的延迟;真正拉开差距的是 agent 高频刷量,那才是它「不以查询计费」值钱的地方。

判断

它是一个工程密度很高、诚实度也不低的项目:四个入口共享一套实现、缓存命中后同一查询从 9.5 秒掉到 5 毫秒、失败和降级都写在返回体里而不是藏起来、AGPL 协议加社区赞助的路线也堵死了「先免费后收割」的想象。这些都比同类开源项目做得好。

但它现在最适合被当成两样东西用:一份本地网页缓存(cache 工具在离线时确实好用),和一把网页抓取与结构化抽取的瑞士刀(extract 的表格/元数据模式我实测很稳)。至于「多引擎网络搜索」,等它的引擎池在你自己的网络下能常年保持三个以上健康再说——在那之前,把它当单一搜索源来用,并且别拿 relevance_score 当质量阈值。

关注 AI商业快讯,每天一篇 AI 热点深度解读。

相关阅读

本文数据截至 2026 年 9 月 18 日:仓库 5,277 星、420 fork、AGPL-3.0、npm 版本 0.2.1;实测在 Alpine Linux 沙盒内完成,wigolo 版本 0.2.1,节点 22。