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 比引一整套路由与授权流程轻得多——那样的话,先看你更适合哪种,再决定要不要它。

AI 创业方法论:把工具装进六层流程的判断标准(六层蓝图总纲)

AI 创业方法论:把工具装进六层流程的判断标准(六层蓝图总纲)

收藏夹里躺着十几个 AI 工具,测评存了几十篇,新模型发布当天必看热搜——三个月过去,能稳定用进工作流的还是原来那一两个。问题通常不在于没找到好工具,手里缺的是一把尺子:不知道什么值得学、学到哪一步、什么时候该换。装进流程的才值得学,装不进的再热门也不学。这篇是持久方法论轨的总纲:一张六层蓝图、一组判断标准、一张带日期的插槽表。

一、「是什么」的内容活不过一周,「为什么/怎么做」可以放十年

新闻与评测有明确半衰期:一次发布、一轮价格调整、一个版本号,热度在几天内起落,本仓台账里的时效文章皆是如此。商业模式、产品原则、避坑经验、决策框架则不随模型升级失效——变的是插槽里的工具,不变的是每层要回答的问题和判断依据。

写与读各有一个便宜的自检法:主语是事件还是体系?「某模型发布了什么」会过期,「怎么判断一个新工具值不值得投入学习成本」不会。本轨所有选题都要过六道闸(半衰期、挂载、一手、受众、空档、视角),今天先把体系本身交代清楚。

顺带把写作建议落成自检:写完每一段,先问这段是在描述一个事件,还是在交付一个可以照做的动作。事件段落删掉不心疼,动作段落才是文章留得住的部分——这套自检与六道闸同源:事件型内容服务今天,动作型内容服务明天。读者这边同理,看到「新东西很厉害」的说法,先等它长成判断标准再决定投入;等不到标准的,让它留在时间线上即可。

二、六层蓝图:每层回答一个问题,判据说明为什么这么判

这层回答什么 判据(为什么是这个)
L1 需求层 谁、痛到什么程度、愿意付什么 已有人在为替代方案付钱
L2 定位层 交付什么形态、和谁竞争 说得出不选竞品的那一个理由
L3 生产层 用什么把交付做出来(模型/Agent/人力) 单位交付成本可算、可复现
L4 分发层 怎么持续触达目标人群 至少一条渠道有可复利资产(订阅/搜索/名单)
L5 变现层 怎么收钱:按量/订阅/按结果 单位毛利为正,账单能对上
L6 复利层 沉淀什么会随时间增值 数据、内容、关系任一在复利
LOOP 验证循环 上面的假设何时被证伪 30 天一个节拍,至少一个读数
X 合规红线 隐私/版权/合同/IP 出事代价 × 概率,一票否决

层与判据是体系,按年级稳定;工具插槽是耗材,月级换。合规(X)不是第七层,是横切的红线:任一层都可能被它一票否决。

三、四条判断标准:新工具到底值不值得学

判断标准要能直接拿去用,顺序不能反:

  1. 挂载在哪一层:它替换 L1 到 L6 加 LOOP 加 X 里的哪一层、哪个插槽?挂不上就不要学,那是兴趣不是生产资料。
  1. 30 天窗口:插槽级收益能否在 30 天内被验证?验证不了就降级为「了解」,不进生产流。
  1. 替换成本:有没有替换判据和回退路径?绑死且无回退的,只放非关键位。
  1. 单位成本:按一手账单算(每任务、每百万 token),宣传页的数字不算数。

四问全答得上来,再谈学习投入;任何一问答不上来,它就还只是收藏品。

四、三个一手例证:这套判据在本仓怎么落地

例一(成本,L3):Jev Ultrafast 端到端实测-延迟 p50 382 毫秒、问题加到 60 个延迟只涨 14%、255 个 choices 是硬边界,全部实验花不到一毛钱,单任务成本压在 1 美分以内;同一轮也抓到三种静默假成功。判据对应:算到任务级,才知道便宜在哪、风险在哪。

例二(复现,L3):CUA-S1-FORMS 全量复核-模型卡宣称 99.95%,本仓用手移植的 numpy 前向加自写 ONNX 解释器全量跑 24,370 条,复现到 99.9549%;同时发现域外字段 23 个只填对 2 个。不看宣称,看复现——这是 L3 插槽替换判据的原型。

例三(账单,L5):CommandCode GOAT 档实测-10 美元换 70 美元额度,MiMo-V2.6 每百万 token 实测约 6 美分,缓存读、长上下文、批量半价在账单里一一拆开算单位成本。判据对应:L5 变现层先算单位经济,再谈规模。

五、30 天验证法与更新承诺

怎么做,三段节拍(对应 LOOP 循环):

  • 第 1 到 7 天:给工具定挂载层与插槽位,写下它的判据和预期读数,判据没写下来的工具不准开工。
  • 第 8 到 20 天:进真实任务,只记录插槽级读数——单位成本、成功率、返工率;顺手过一遍 X 红线四查(数据来源、素材版权、合同边界、敏感信息)。
  • 第 21 到 30 天:对照判据决定去留。通过则留在插槽,不通过则回退,记录留下作下一轮基线。

当前插槽填充(2026-09-23 快照,这就是「当前填充 + 日期」两行约定):

插槽 当前填充 替换判据
L3 强推理模型 CommandCode GOAT 档 MiMo-V2.6(6 美分/百万,账单实测) 同题单位成本与成功率
L3 端到端 Agent runtime 暂缓(假成功风险,见例一) 假成功率降到可接受
L4 分发渠道 geeyo 与微信双端 长尾阅读占比
L5 定价参照 按量与订阅对照,批量半价 单位毛利为正
LOOP 验证节拍 30 天 每个插槽至少一个读数
X 合规检查 发布前四查 出事代价 × 概率

更新承诺:插槽漂移会原地更新本文并改更新日期,体系层按年修订才另发新文;文中一手数据全部来自本仓可复现评测,上文三例均带链接回原评测。

收束成一句话:先挂层、再定判据、30 天见数——见不了数的工具,不配占用学习预算。

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-proxiaomi/mimo-v2.6-flashxiaomi/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),得按块切;TransformerEncoderLayernorm_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_systemtinyx 分支不读这个字段,仓库自己的单元测试还断言这种字段配 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 解释器与全部结果都已留档。

ZCode 开源后我拆了 4 个官方安装包:上传链路确实删了,那个开关却从没管过它

ZCode 开源后我拆了 4 个官方安装包:上传链路确实删了,那个开关却从没管过它

5600 颗星、1600 次 fork、两天——这是智谱把 ZCode 开源之后,GitHub 上给出的数字。而这款工具一周前被开发者抓包:登录状态下,它会把你本地整个代码仓库打包、加密、传到云端。

9 月 21 日,智谱在开源公告里说得很具体:v3.14.0 客户端已移除 Repo Wiki 功能,已切断本地仓库快照的生成与上传链路,并公布了信通院与绿盟的审计结论。

声明可以写得很干净,安装包不会。我把四个版本的 ZCode 从官方 CDN 下下来,解开内部的 app.asar,逐符号比了一遍。

一、三天之内发生了什么

时间 事件
9 月 18 日 开发者抓包:登录后 ZCode 静默打包本地工作区(含完整 .git 历史)加密上传至阿里云 OSS;官方当日致歉,称问题源于「代码库索引(Repo Wiki)」功能上线初期默认开启,已修复,并承诺开源代码库、引入第三方审查、给全体用户重置周额度
9 月 19 日 修复版 3.14.0 客户端发布
9 月 20 日 zai-org/ZCode 仓库建立
9 月 21 日 正式开源(Apache-2.0);公布信通院、绿盟审计结论;创始人唐杰实名投诉小红书网友「偷代码」传闻;社区发现开源版与官网版「不完全一致」

从曝光到开源,三天。速度值得肯定,但三天的信任重建只等于一份声明加一个仓库——能不能自证,要看你愿不愿意把安装包拆开看。

二、我把四个版本的安装包拆开比了一遍

官方说 v3.14.0 切断,我就把这条当假设去验。四个版本全部来自官方 CDN(cdn-zcode.z.ai),Linux arm64 的 AppImage,每个约 200 MB,解开 squashfs 后取出 resources/app.asar,再抽取桌面主进程的打包产物 out/host/index.js 逐符号计数。

符号(主机进程包内出现次数) 3.12.3(9/17 构建) 3.14.0(9/19) 3.14.1(9/20) 3.14.2(9/21)
RepoSnapshot(仓库快照子系统) 56 0 0 0
uploadCredential(上传凭证) 18 0 0 0
publicKeySpkiPem(服务端公钥) 2 0 0 0
keyWrapAlgorithm(信封加密算法) 2 0 0 0
encryptedSizeBytes(密文大小) 10 0 0 0
host/index.js 体积 2,588,119 B 1,496,653 B 1,497,846 B 1,497,917 B

结论与官方口径完全一致:事发前最后一版 3.12.3 里有一整套带 RepoSnapshot 前缀的代码,含 53 个具名函数;从 3.14.0 起,这些名字在客户端里一个都不剩,主进程包一次性瘦了约 42%(1.09 MB)。

同一套代码在命令行运行时里也被删了:3.12.3 的 zcode.cjs 有 3 处 RepoSnapshot,3.14.2 是 0。

服务端一侧也能对上一个便宜的证据。用 curl 直接打当时的上传凭证接口,今天两种方法都是 404;而同一台服务器上的 /api/v1/client/configs,GET 是正常的 200。这不是「全站 404」,是那条路由没了:

curl -s -o /dev/null -w '%{http_code}\n' https://zcode.z.ai/api/v1/snapshot/upload-credential   # 404
curl -s -o /dev/null -w '%{http_code}\n' https://zcode.z.ai/api/v1/client/configs              # 200

三、那段被删掉的代码,到底做了什么

更值得写清楚的是它原来的样子。废掉的 3.12.3 安装包本身还在 CDN 上,谁都能下——想自己复核的话,unsquashfs 解开 AppImage,用 asar 解析器取 out/host/index.js,搜 publicKeySpkiPem 就能看到这段代码。

流程和早先开发者还原的一致,但代码里还有几处此前没被提到的东西:

密钥由服务端掌控。客户端用随机 32 字节密钥 + 16 字节 nonce 走 AES-256-CTR 加密打包好的 tar.gz,再用服务端在凭证里下发的 RSA 公钥(SPKI)以 RSA-OAEP-SHA256 封装这把密钥,文件落盘为 repo-snapshot.tar.gz.enc。私钥从不出现在客户端,本地密文你自己解不开。

上传走 OSS 表单直传。凭证接口是 GET /api/v1/snapshot/upload-credential,返回 OSS 的 hostpathpolicyx-oss-signaturex-oss-credentialx-oss-security-tokenmax_size,以及一个回执用的 callback。客户端组 multipart 表单,把密文以字段名 repo-snapshot.tar.gz.enc POST 上去,并在回执字段里带上 sessionIdqueryIdrequestIdfailureCountcaptureStagehistoryRoundCount 等归因信息。

.git 被显式豁免了所有过滤规则。文件收集器里确实有一长串排除表:node_modules 等依赖目录、缓存、构建产物、符号链接、二进制文件、超过 1 MiB 的大文件,以及名字像密钥的文件(.env.npmrcid_rsa.pem.key.p12.pfx,以及文件名里含 tokensecret 的)。但只要路径里出现 .git,函数直接返回「包含」,大小、二进制、密钥名三道检查一道都不跑。所以历史上被删掉的配置文件、早年的测试密钥、内部域名,全都随 .git 目录一起进了压缩包——过滤器拦得住当前目录里的 .env,拦不住提交历史里的 .env

除了代码,还顺走了你的全局 Agent 配置。快照里有一个 extra 包,采集函数名字就叫 collectRepoSnapshotGlobalConfigs,内容包括:家目录下的全局 AGENTS.md(超过 20 MiB 才截断,截断标记写的是 ...[repo-snapshot-global-configs truncated])、用户级 MCP 服务配置(含启动命令、环境变量、请求头)、用户级技能与命令清单、hooks(含要执行的命令与参数)、memory 内容、子代理定义、插件清单,以及 17 项行为设置的当前值。

那个开关,从来没有管过它。客户端里有个设置项叫 repoSnapshotIndexingEnabled,界面上对应「仓库快照索引」。它在整个主进程包里只出现两次:一次是用户改动它时打个「用户已配置」的标记,一次是作为设置值被塞进上面那个 extra 包。没有一处代码读它来决定要不要采集、要不要上传。早先开发者说「没找到开关控制上传的逻辑」,我这次是从代码层面对上了。

它在你按回车之前就开始干活。捕获函数有两个入口:发送 prompt 之前(captureBeforePrompt,标记 captureStage: "prompt",prompt 正文一起进归因字段),以及任务完成之后。此外本地还有配额管理:单份密文上限默认 2 GiB,最多同时存在 3 份、保留 2 份,磁盘预算 6 GiB——这解释了为什么有人的 ~/.zcode 会悄悄涨到几百兆。

四、开源的那份,和你装的那份

开源当天,社区就发现 GitHub 上的代码和官网下载版不完全一样,「公关式开源」的质疑随之而来。这一条需要拆开说,因为两件事被混在了一起。

第一件,争议代码。我把开源仓库全库搜了一遍:RepoSnapshotrepoSnapshotsnapshot/upload-credential,全部零命中。开源版里唯一带 upload-credential 的地方是反馈附件的上传,那件事写在 NOTICE.md 的对外请求清单里,是用户主动提交工单才触发的。我又抽查了几个只可能来自同一份源码的字符串(例如主进程里那句「任务终态未读裁决」),开源仓库与线上 3.14.x 能对上——修复后的代码,两边是同源的。所以就「你审查的是哪一份 ZCode」这个问题,答案比社区猜测的更清楚:争议中的那段,两份里都没有。

第二件,商业功能。仓库自己的 NOTICE.md 第 70 行写得很直白:「受第三方版权、许可及再分发条件等约束,不承诺提供官方产品的全部功能及活动政策」。开源版少掉的是额度活动一类的商业化能力,官网仍在单独分发完整客户端。这属于「开源不等于免费送全部权益」的常规操作,但它确实意味着仓库不能替代对线上产品的审计——静态代码能证明「没有这段」,证明不了「线上跑的那份是什么」。

顺便说三个开源仓库的硬数据:6,973 个文件、14 个包、84.3 万行 TypeScript;NOTICE.md 27.7 KB,第三方声明 THIRD-PARTY-NOTICES.md 1.98 MB;2 个 commit、0 个 tag、0 个 release。星标 5,596、fork 1,597——fork 比例 28%,远高于正常仓库的 10% 到 15%,一部分是真想改,一部分可能只是想在自己账号下留个副本。

还有一个细节:仓库的 Issues 是关着的(GitHub API 返回 has_issues: false),PR 也是 0 条。官方在公告里说「把代码交给社区监督,欢迎开发者持续检查和反馈」——但反馈入口目前不在这个仓库里。

五、还没被验证的三件事

一、服务端的行为只能靠审计背书。信通院与绿盟的结论都指向同一个点:zcode-prod 的阿里云 OSS 存储桶「云端零数据」、全部对象与桶本身已删除。这对用户是好消息,但两份报告本身没有公开原文,外界看到的是官方转述的结论。国内机构做审计、三天出结论,效率和可信度都摆在那,唯一缺的是可复查的过程。

二、旧安装包还在。事发前的 3.12.3(9 月 17 日构建,199,710,914 字节)今天仍然能从官方 CDN 直接下载。这一点对想自己复核的人是便利,对没开自动更新的用户是风险——修复只在客户端,装了老版本的人不会因为服务端下线而变安全。

三、本地历史删不干净。无论客户端怎么改,已经被打包上传过的内容、以及 .git 里那些「以前删掉的密钥」,都不因为这次整改而变得不存在。涉及生产凭据的仓库,该轮换的密钥还是要轮换。

我的判断

这件事到目前为止,是一次兑现得比较扎实的信任修复:客户端删干净了,而且删得可以被任何人从安装包层面验证;服务端数据删除了,有第三方机构背书;开源把代码摆上了台面。

但信任重建有三条腿,现在只稳了一条。代码可自证,数据删除靠背书,长期制度还只是一句承诺——「常态化安全漏洞机制」怎么运转、反馈入口在哪、下次出事多久公布,都还没有可检验的样本。开源第一天就把 Issues 关掉,恰恰是这种落差最直观的注脚。

给正在用或者准备用的人三句话:

  1. 确认客户端版本不低于 3.14.0,这是官方口径里切断上传链路的分界,我的比对结果与之一致。
  1. 想自己复核,检查 ~/.zcode/v2/checkpoints 目录里有没有几百兆的密文文件;顺手看一眼 ~/.zcode 的总占用。
  1. 在用过老版本的机器上,把 .git 历史里出现过的密钥当作已泄露处理——文件名过滤挡不住提交历史。

相关阅读:

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

ChatGPT 跨站追踪实证:一枚 Cookie 挂满一年,936 个广告像素把你在别处买的东西送回 OpenAI

ChatGPT 跨站追踪实证:一枚 Cookie 挂满一年,936 个广告像素把你在别处买的东西送回 OpenAI

一枚 Cookie,名字叫 __obi,挂在 .openai.com 域下,有效期整整一年。它的响应头里写着 SameSite=None——这是让浏览器在跨站请求里也把它带上的配置。而在同一批请求里,OpenAI 的其他 Cookie 全被浏览器拦了下来,只有它被放行。

9 月 20 日,独立研究者 Buchodi 发布了一份逆向分析:任何在 ChatGPT 上投过广告的公司,只要在自己站点装上 OpenAI 的追踪代码,你在这家网站上看过的商品、读过的文章、填过的表单,就会连着一枚能对上你 ChatGPT 账号的标识,回到 OpenAI 手里。这份分析当天冲上 Hacker News 头版,我记录到的数据是 698 分、371 条评论。

三步:从你的 ChatGPT 账号,到别人家的网站

第一步发生在你打开 chatgpt.com 的那一刻。浏览器生成 16 字节随机数,调用 POST /backend-api/bazaar/obi/sync-token;后端签回一枚 RS256 的 JWT,60 秒后过期,里面把 sub(账号标识)和 obi(22 字符标识)钉在一起。bzr 是 bazaar 的缩写,OpenAI 内部对广告平台的叫法。

第二步是换 Cookie。客户端拿着这枚令牌,跨站 POST 给 bzr.openai.com/v1/obi/sync,服务器回种 __obi:域为 .openai.com、HttpOnly、Secure、有效期一年、SameSite=None。研究者贴出的响应头原文如此。

第三步发生在广告主的网站上。装了 OpenAI 测量像素的页面,会把 __obi 随请求一起送回 OpenAI——包括加载 bzrcdn.openai.com/sdk/oaiq.min.js 这个脚本本身的请求。也就是说,页面一打开、OpenAI 的代码还没运行,标识就已经送出去了。

环节 具体动作 关键参数
发证 chatgpt.com 调 backend-api/bazaar/obi/sync-token JWT,60 秒过期
换 Cookie 跨站 POST bzr.openai.com/v1/obi/sync 一年有效期,SameSite=None
回传 广告主页面加载像素脚本、上报事件 请求自动带上 __obi

研究者给出的观测规模:几个月收集到的流量覆盖 936 个广告像素、1,029 个域名;在他自己手机上,同一个 __obi 被 Chewy、Wayfair、ThriftBooks、Eventbrite、HelloFresh、Coursera、SeatGeek 等 12 个商业站点送回 OpenAI,每一次都被服务端以 202 收下。他还解码了 932 枚同步令牌,其中 736 枚对应登录账号,196 枚是匿名主体——没登录也不影响,匿名标识同样能稳定存在 27 天以上。

我把那 82 KB 的追踪脚本下下来读了

不带 ChatGPT 账号,也能核验其中一大半。我从广告主被官方要求加载的那个地址把脚本抓了下来:bzrcdn.openai.com/sdk/oaiq.min.js82,799 字节,里面写死的版本号是 0.1.41、类型 oaiq-web。研究者文章里引用的行为,来自更早的 0.1.31 时代。

这段代码里有四件事值得单独说。

先说第一件:它不只会收广告主给的数据,还会自己去页面上找。身份来源被分成四类:in(广告主主动传入)、fm(表单字段)、ht(渲染出来的页面文字)、js(标签管理器总线)。代码会去读 window.dataLayeradobeDataLayer,甚至解析 gtm.js 的 URL 参数,找出改过名字的 GTM 容器。研究者统计的抓取记录里,从页面上扒来的身份比广告主主动交出来的更多——685 条对 255 条。

*姓名仍在自动采集清单里* 代码中的身份定义表写着:email、phone、firstName、lastName 四项都是 automatic: true,只有 externalId 是 false。地理字段 country、city、region、postal_code 不进哈希,直接明文发送。研究者称采集范围在 8 月 27 日收窄过一轮,但从 0.1.41 的代码看,姓和名依然在自动匹配集合中。

再往下看:它自己划的红线很细。代码里有一张排除名单正则:密码、一次性验证码、CVV、卡号、社保号、生日、病历、诊断、法院案件、罪名都不碰;同时排除的还有礼物收件人、捐赠人、第三方、客服、推荐人、卖家——也就是别人的身份信息。这份名单说明 OpenAI 清楚哪些字段是雷区,边界画得很明确。

最后一件,开关不在广告主手里。每个像素会去 bzrcdn.openai.com/pixel-config/v1/ 加像素 ID 取一份配置,其中有一个布尔字段 automatic_advanced_matching_enabled——自动匹配是否开启,由 OpenAI 的广告后台按账户下发。

我还直接对着端点发了请求。带 Origin: https://chatgpt.com 时,预检返回 204,响应头里 access-control-allow-origin 回显 chatgpt.com、access-control-allow-credentials: true,也就是允许带凭证的跨站调用;换成别的 Origin,直接返回 403 Origin is not allowed.。令牌不对时是 401 Invalid or expired sync token.,内容类型不对则提示必须是 text/plain。一个只对自家前端开放、还要求带凭证的绑定接口,正是把账号身份写进跨站 Cookie 所必需的那一环。

官方文档和 Cookie 政策,写的都是另一套

OpenAI 自己的测量像素文档里,「给用户数据」是广告主主动做的事:可选地在初始化时传入 user 对象,邮箱与手机号按规则规范化后做 SHA-256,用来提高转化匹配率。文档没有说这套 SDK 会自己从表单和页面文字里抓。

再看 Cookie 政策。OpenAI 官网中文版的 Cookie 列表里,「分析型 Cookie」一栏只有一行:来源 OpenAI、名称 __obi、时长一年、用途「分析」、域 chatgpt.com 与 openai.com。营销绩效那一栏里排的是 LinkedIn 等第三方。换句话说,这枚承担跨站身份绑定的 Cookie,官方登记的身份是「分析型」。

研究者 9 月 14 日给 OpenAI 的 press 与 privacy 邮箱发过邮件,问了两个问题:为什么 __obi 被归类为分析 Cookie;只同意分析、拒绝营销的用户,是不是依然会收到它。回复来自客服支持:已收到,会转内部复核。两个问题都没有正面回答。

广告业务比这套机制跑得更快

把时间线摊开,这套东西为什么存在就不难理解了:

时间 事件
2026 年 2 月 9 日 ChatGPT 面向美国 Free 与 Go 用户开始展示广告
2026 年 4 月 30 日 免费用户的营销 Cookie 默认开启,WIRED 实测两个账号均为默认开
2026 年 5 月 5 日 自助广告管理平台向全美企业开放,取消 20 万美元投放门槛
2026 年 8 月 31 日 OpenAI 宣布 ChatGPT Ads 年化收入运行率达 10 亿美元,上线不足 200 天

按 OpenAI 8 月 31 日官方公告的口径:数万家广告主在使用,业务覆盖 40 多个国家,ChatGPT 周活跃用户超过 10 亿;「Pixel 和转化 API 已成为衡量与优化的重要基础」;并强调广告主无权访问用户的私人对话。据投资人披露的口径,OpenAI 2026 年广告收入目标 25 亿美元,2030 年 1000 亿美元。

广告主确实拿不到你的对话,但「衡量转化」需要知道看过广告的人有没有在别处下单——__obi 就是这条链路里的中间件。它把「在 ChatGPT 里看过一则广告」和「在 Chewy 上买了一次狗粮」接在了同一个人身上。

它证明了什么,没证明什么

边界要说清楚,这决定了你该有多紧张。

已被独立核验的:机制与代码(我下载脚本逐段读的)、绑定端点的访问控制(我实测的)、Cookie 分类(OpenAI 官方政策页原文)。研究者实测、我未能复现的__obi 真的随广告主页面的请求回传。我没有登录态的 ChatGPT 账号和安卓 Chrome 环境,这一步没跑通。仍是推断的:OpenAI 服务端是否把回传落到你的账号上——观测到的只有 202(已接受),研究者本人在文末写明「这个 join 没有被观测到」。

受影响的人也没那么多:观测环境是安卓版 Chrome;iOS 上所有浏览器跑的都是 WebKit,Safari 的智能防跟踪拦第三方 Cookie,机制不生效;桌面 Chrome 未测;大约每 5 次 ChatGPT 会话才下发一次令牌。

放在广告行业里,这套机制与 Meta Pixel、Google 标签是同构的:登录态、第三方 Cookie、站外转化归因。不一样的地方在于它跑在一个 AI 对话产品上——人们会告诉 ChatGPT 一些不会发朋友圈的事,而这个产品正在越来越多地替人做决定。研究者的原话是:机制本身是标准广告技术,没有先例的是它跑在 AI 聊天产品上。

想关的话,路径在 ChatGPT 的设置 → 数据控制,那里有分析和营销两个独立开关,可以只留一个。另外,广告主自己也看不到 __obi,它在广告主脚本读不到的域上——所以别指望商家能替你把这件事关掉。

我的判断是:这不是漏洞,是选择。OpenAI 在 Cookie 政策里如实登记了这枚 Cookie,也在代码里划了红线,但它没有把「分析型 Cookie 会被用来做跨站身份绑定」这件事讲明白。在广告收入年化冲上 10 亿美元的当口,讲明白的代价,大概比划一条红线要高。

相关阅读:OpenAI推出自助广告管理工具:AI广告投放如何变现?OpenAI 与微软未删节文件曝光:Copilot 把纽约时报点击率打掉 93%,内部称抓取是「史上最大劳动盗窃」三人用 Claude 黑进 OpenAI 内部代码库:一个图片上传漏洞,72 小时打通到代码提交

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

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 的控件结构做的:出发站输入框旁边有一排联想行,用裸 divonclick 实现,没有任何 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 靠收窄触发来省,而不是靠拆目录。这个答案在「拷走就能用」的传播场景里是成立的,在「长期常驻、天天触发」的用法里就不成立——所以真正需要你自己判断的,不是他对不对,而是你打算怎么用它。

阿里达摩院 RADAR 深度拆解:一次腹部 CT 看 146 项发现,26 位放射科医生里赢 23 位,但权重禁止商用

阿里达摩院 RADAR 深度拆解:一次腹部 CT 看 146 项发现,26 位放射科医生里赢 23 位,但权重禁止商用

26 位放射科医生坐在同一场测试里,23 位的平均准确率输给了一个模型。

9 月 17 日,这篇研究登上了《Science》,题目是《An expert-level generalist AI for abdominal CT diagnosis》;9 月 18 日,阿里巴巴达摩院把模型权重放上 HuggingFace,宣布开源。国内媒体当天跟进的口径几乎一致:全球首个「专家级」通用医学影像 AI,一次腹部增强 CT 能识别超过 146 种病症。

我把代码仓库拉下来、把权重页面和许可证逐个点开之后,第一句话就卡在许可证那一行:权重写的是 CC BY-NC-SA 4.0,NC 是 NonCommercial,禁止商业使用。

数字先摆出来:这篇论文证明了什么

论文的核心是一个叫 RADAR 的模型(Rapid Abdominal Diagnosis with AI and Radiology)。它跟此前影像 AI 最大的区别是打法:过去一个模型对应一种病,RADAR 把一例腹部增强 CT 按解剖结构拆开,再对照放射科报告学「这个部位的这句话对应什么影像表现」,一次性输出整份发现清单。

官方新闻稿与论文摘要给出的数字如下:

项目 数字
训练数据 424,911 例腹部增强 CT、150 万图文对、1500 万解剖级配对
覆盖范围 18 个解剖结构、146 项影像发现
平均 AUC 0.913(同批对比中最好的同类视觉语言模型为 0.776)
急诊场景 27,000 例以上急诊 CT 上 AUC 0.904,且训练未使用急诊数据
外部泛化 8 家外部中心,AUC 0.895
读者研究 26 位放射科医生,AI 辅助下诊断敏感度提升约 10%
作者与机构 40 位作者,达摩院与多家医院合作,含浙江大学医学院附属第一医院

AUC 是区分有病与没病的能力指标,1.0 是完美,0.9 以上在影像 AI 里属于可用的高水平。论文摘要的结论句是:通用型 AI 已经能在常规与复杂阅片任务上达到人类专家水平。

数据之外还有一段传播更广的说法:模型的平均准确率超过了 26 位参与者中的 23 位。这句话来自达摩院对研究的转述,被南华早报等媒体引用后,变成了中文标题里的「AI 赢了 23 位医生」。它和摘要里那句「辅助提升敏感度 10%」其实是两组不同的实验。

开源清单:我把仓库逐个点了一遍

「开源」这个词在这件事里需要拆开看,因为同一项目在三个地方用了三种许可证。

内容 是否开放 口径
代码 开放 GitHub 仓库 alibaba-damo-academy/damo-radar,Apache-2.0,可商用
模型权重 开放下载 HuggingFace 上共 6.4 GB,许可证 CC BY-NC-SA 4.0,禁止商业使用
训练数据 不开放 424,911 例只存在于论文里,一例影像都没放出来
外部测试数据 部分开放 用的是斯坦福 MERLIN 数据集,需向斯坦福申请下载
处理后的掩膜与重采样图 开放下载 HuggingFace 数据集,960 次下载,同样是非商用许可
代码归档 开放 Zenodo 存档 379 MB,许可证又写成了 CC-BY-4.0

代码仓库本身 510 MB,89 个 Python 文件、18,718 行,其中 7,633 行是从 Salesforce 的 LAVIS 视觉语言框架搬来的底座,达摩院自己的工程量大约一万行上下。仓库 7 月 3 日就建好了,比论文上线早了两个半月,45 次提交,最后一次推送是 9 月 18 日。

权重文件也能看出这个模型的体量:RADAR+ 主检查点 1.65 GB,预训练版 1.57 GB,单独的 UNet 视觉分支 208 MB,另有中英文两个 BERT 文本编码器,分别 412 MB 与 440 MB。也就是说,它的文本端是 BERT-base,视觉端是 3D UNet 与 ResNet,不是大语言模型。

想真正跑起来,门槛写得挺实在:官方文档要求单张 A100 或 H20 显卡,演示用的一例原始腹部 CT 体积 98 MB,预处理还要装 TotalSegmentator 分割 104 个解剖结构,报告解析脚本则要填 DashScope 的 Qwen 接口密钥。仓库里附带的外部测试结果有 5,125 例样本,但只覆盖 20 项发现——那是斯坦福 MERLIN 数据集有标签的那部分;146 项的完整逐例结果并不在仓库里。

还有一个细节值得记一笔:两天过去,仓库 323 星、37 次 fork,两个 issue 都还开着没人回。一个问「会不会有在线 demo」,另一个来自苹果芯片用户,说自己花时间把推理路径改成 MPS 跑通,只需要改 3 个文件、14 处设备调用,推理链路里没有任何自定义 CUDA 算子、纯 fp32,并附上了数值等价的验证。这是一个挺客气的补丁,目前还挂着。

三个被标题盖住的细节

第一,146 是「发现」,不是「病」。 我把模型输出的 146 列标签导出来看了一遍,里面既有直肠癌、胆管癌、胰腺肿瘤这类疾病,也有大量描述性条目:主动脉钙化、肝脂肪肝、脾副脾、膀胱憩室、肾上腺钙化、肋骨骨折、肝内钙化灶。官方中文口径写的是「识别超过 146 种病症」,读者很容易理解成能查出 146 种独立疾病,实际清单里相当一部分是阅片时顺带记录的表现。

第二,「赢了 23 位医生」是另一组实验。 论文摘要里读者研究的原句是「RADAR 辅助把 26 位放射科医生的诊断敏感度提升了约 10%」;而「平均准确率超过 23 位参与者」是模型单独阅片与医生单独阅片的对比。前者说的是 AI 帮医生少漏诊,后者说的是 AI 与医生同台竞争,两者都会被引用,但混在一起说就成了「AI 取代医生」的标题。官方还提到,在 AI 辅助下医生用时减少 30% 以上。

第三,它只吃增强 CT。 腹部增强 CT 要注射造影剂,属于有创的诊断检查,不是体检筛查。达摩院自己那条更出名的产品线走的是相反路线:用最常见的平扫 CT 做「一扫多筛」。所以 RADAR 的定位是诊断环节里的读片助手,不是把体检变成 AI 初筛。

另外,从论文摘要和官方新闻稿看,所有评测都是在已有病例上完成的回顾性评估,公开材料里没有前瞻性临床试验的结果;同批对比中那个 AUC 0.776 的「最好的同类模型」也没有被点名。

达摩院的医疗 AI 已经走了四年,这是通用化那一步

把 RADAR 放回时间线,会更容易理解它为什么值得上《Science》:

  • 2023 年 11 月,胰腺癌平扫 CT 早筛研究登上《自然·医学》,在两万多例真实病例的回顾性试验里找出 31 例临床漏诊病变
  • 2025 年 4 月,胰腺癌筛查模型 DAMO PANDA 拿到美国 FDA 的「突破性医疗器械」认定
  • 2025 年 11 月,GE 医疗与达摩院签署合作框架意向书,把 CT 影像 AI 往设备侧推
  • 2026 年 3 月,「胰腺病变 CT 图像辅助分诊软件」进入 NMPA 创新医疗器械特别审查程序
  • 2026 年 4 月,肠癌「无感」筛查研究登上国际肿瘤学期刊

这条路线一直是「一个模型查一种病」,RADAR 则是把单病种模型收拢成一个通用底座,再靠解剖级对齐把泛化撑起来——外部 8 家中心 AUC 只掉 0.018,急诊场景没训练过也能到 0.904,这两个数字才是它进《Science》的理由。

对照物也很清楚。RADAR 的外部测试集就是斯坦福的 MERLIN 数据集,而 MERLIN 团队自己在 2024 年发布的 3D CT 视觉语言基础模型,走的正是同一条「通用模型」路线,并在 2026 年发在《自然》上。这一年里,通用影像模型这条线被两本顶级期刊各认可了一次。

但商业化的距离还摆在那:许可证禁止商业使用,模型也没有医疗器械注册证。对医院和厂商来说,短期内它只能当研究基座,不能直接变成产品。

结论:值得抄的是方法,不是权重

这件事最值得带走的不是 6.4 GB 的检查点,而是它证明了一条可复制的训练路径:用现成的分割工具把 CT 按解剖结构切开,用大模型解析临床报告拿到弱标签,再用解剖级对比学习把影像和文字对齐。 整条链路不依赖人工标注,这才是 42 万例数据能跑出结果的原因。国内做影像 AI 的团队真正能借鉴的,是这套「不靠人标注」的工程范式,以及官方在仓库里公开的预处理代码与报告解析脚本。

至于那份权重,科研可以下,产品化要谨慎:非商用许可加上没有注册证,决定了它在国内医院里暂时只能以研究合作的形式出现。

对普通读者,一句话判断:一次 CT 给出 146 项发现,这件事是真的,也是影像 AI 近年少见的硬进展;但它替代的是读片流程的第一步——把该看的地方全部标出来,而不是放射科医生。

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

相关阅读: