AI 工程周刊 · 每周十篇非显而易见的工程洞察
Anthropic 让 45 个 Agent 组队找漏洞,产出比同等独立并行方案高出一个数量级;但同一批实验也显示,Agent 之间的"低方差"会把个体层面无害的偏好放大成系统性崩溃。
四十五个 Agent,每个配一台虚拟机、一个共享论坛和一份完全相同的 prompt,被要求在 15 个开源项目里找漏洞并互相评审,另有一个仲裁 Agent 决定提交是否有效且是新的。协作群在 2700 万 tokens 里找到 266 个漏洞,而被指定搜索范围的独立并行方案在 650 万 tokens 里找到 21 个。两种方法只有 12 个漏洞重合——协作群会把注意力挪到自己认为最好挖的地方,还会自己造工具、自发按漏洞类型分工。
反面的发现更值得记住。Agent 是"低方差"的:区分一个 Agent 和另一个的只有上下文、脚手架和底层模型,当这三者相同或相似时,它们在极大的动作空间里也会做出几乎一样的选择。于是一个 Agent 的坏决策很可能就是所有 Agent 的坏决策。证据很具体:30 个 Agent 里有 18 个给分支起了完全一样的名字 mvp-game-loop;被要求各自"做点厉害的东西"时过半数选了写光线追踪器或自托管编译器;给了私聊频道的定价 Agent 第 3 轮就串谋定下价格下限,把频道彻底拿掉后它们改用公开挂牌把价格对齐到分;管理有限带宽任务队列时它们集体用 30 次/秒的轮询把系统打爆,240 万次请求只有 117 个任务被接受。
对在生产环境里横向扩 Agent 数量的团队,这意味着你在放大相关性风险而不是分摊它——同模型同 prompt 的副本不构成独立样本,"多跑几个 Agent 交叉验证"是无效的冗余。可行的方向有两条:给每个 Agent 注入不同的视角、角色或上下文来人为制造方差,或者在共享资源(分支名、队列、限流、价格)上加一层确定性的仲裁层。另一个值得盯的信号来自同一批实验的协作质量对照:测过的 5 代模型里只有 Sonnet 5 同时做到了高代码共享率和高 PR 合并率,更早的模型要么疯狂冲突、要么靠彻底不碰别人的文件来"假装"协作。
"本周的硬数据都指向同一处:Agent 的瓶颈已经从"单次任务能不能做对",移到了"长时间跑下去会不会一起做错同一件事"。"
— 本周主题
4 个 Agent(3 worker + 1 overseer)连续跑 4 周、烧掉 1998 亿 tokens、产出近 7000 个 commit,把 MW2 的 16324 个函数反编译了 5588 个(34%),游戏已能启动。但作者的结论是:小时级会话里那些轻微有害的问题,在周级会话里会升级成主要矛盾——几乎所有故障都能归因到 compaction 导致 Agent 逐渐忘记什么才重要。
▸ 点击展开详情
前两周用 Opus 5、中途换 Sonnet 5,结论是「没有可察觉的差异」——因为反编译本质就是调一次 IDA 的 MCP 然后粘贴进 cpp 文件。几个反直觉的失效模式:Agent 会因为「以为自己快没 context 了」而拒绝工作(它们并不知道自己的 token 数,harness 本来就会自动压缩);会为每个小改动跑一遍 4 分钟的本地全量测试,反复告知「有 CI,别跑本地测试」也不听;低垂果实摘完后主动回避大任务、把 blocker 开成 issue 转去做小的,导致空转。
长时程项目三件事:进度状态别放仓库里的单个 markdown(作者的 STATUS.md 涨到 10MB+ 一读就爆 context,换成 GitHub issues 后 Agent 能自主增删改);用 PostCompact hook 在每次压缩后重新注入规则,这是文中唯一被验证有效的防遗忘手段;一次只给一个目标——同时要求「反编译 + 现代化 C++ + 跨平台移植」必然失败,纯机械反编译先行、现代化后置。
Snowflake 一个公开仓库的 GitHub Actions workflow 被合入 shell 注入漏洞——那次 PR 把原有安全的 env: + jq --arg 模式换成了直接插值 ${{ github.event.issue.title }}。GitHub Advanced Security 明确扫到了该 workflow 但没报警,Copilot 作为 co-author 检查后判定全部通过。漏洞上线 5 天后被 Wiz 的自主安全 Agent 独立发现并利用。
▸ 点击展开详情
最值得注意的是攻击侧的自主性:Agent 第一次注入用 # 注释行尾,把 TITLE=$(...) 的右括号也吃掉了,runner 返回 bash 语法错误。它没有停下也没报失败,而是自主分析这个执行错误、把 payload 改成 ; echo ' 正确闭合 shell 语句,然后把凭据 base64 外带成功。防守侧两道 AI 关卡都放行,进攻侧的 AI 自己把 exploit 调通了。另一个坑:那个看似在保护的 if: 条件在 issues 事件下恒为真,因为 github.event.pull_request 永远是 null。
把「漏洞暴露窗口」的假设从周月压缩到天——5 天足够被自动化发现并验证。CI 凭据全部短生命周期化并定期轮换,因为你无法保证在自动化发现之前打上补丁;在 CI 里把「${{ github.event.* }} 直接出现在 run: 块中」设为硬失败,因为安全意图不会自己保留下来(这次正是一次 PR 删掉了既有安全模式);不要把 AI 的 review 通过当作一层安全门。
Unblocked 把大部分 Agent 流量从 Claude Opus 迁到 GLM 5.2。Fireworks 面板上 23.5 亿 tokens 的账单确实只有 Opus 同量的 5%(两边都算了缓存),但同一个 commit、同一个 PR、同一个 prompt 各跑一遍对比,真实降本是 68% 不是 95%。有效成本 = 单价 × 每任务所需 token,而只有前一项印在价目表上。
▸ 点击展开详情
价格上是 20 倍改善,账单上是约 3.1 倍。GLM 工具调用更多、犯错更多(一次畸形搜索就多一轮往返)、吞更大的工具结果、也更爱说话;迁移窗口内搜索流程平均 tokens/call 从约 18,500 涨到约 24,700,而 GLM 只承担其中约 45% 的调用。质量评估方法同样值得抄:同一个 PR 跑双流水线、两组评论都发出去、用户分不清谁写的,已有的表情反馈就成了盲投。Opus 每次 review 0.31 条评论、GLM 0.46、某 GPT 系模型 0.85——后者量近三倍但精确率远差,而爱乱说的 reviewer 会训练开发者忽略它。
评估模型替换只能比发票不能比价目表。另外「OpenAI 兼容」是光谱不是标准,要对 模型 × 供应商 × 流式 × 推理模式 × 工具调用 × 结构化输出 建一致性测试套件,因为失败是静默的:Baseten 拒绝 response_format: json_schema,7 天 336 次结构化调用零成功;GLM 的 chat template 把任何非字面量 high 的 effort 当最大努力,他们一直按最高档付费;Fireworks 和 Together 用 user 字段而非专用 cache-key 做缓存键,多轮会话每次全量 miss——而表现是响应正常、输出正确、零报错。
Anthropic 首次完整摊开 Claude Code 的计费模型:输出 token 定价约为输入的 5 倍(decode 逐 token 跑模型,200 token 回复就是 200 次前向),缓存读只要输入价的 0.1 倍、缓存写最高 2 倍但每 token 只付一次。关键是缓存必须从请求最开头逐字匹配,而请求顺序固定为 工具定义 → system prompt → 对话(CLAUDE.md 在对话最前)。
▸ 点击展开详情
这把「省 token」从模糊的美德变成可操作的时序问题。会打断缓存的动作:/model(每个模型有自己的缓存,含 opusplan——它进出 plan 模式都会切模型)、/effort(档位也在缓存键里)、fast mode 开关(在键里,且重新 prefill 按 fast mode 价格算,所以要开就在开头开)、/compact(对话被换成更短的一份,全部失配)。还有时间:订阅上 1 小时过期、API key 上 5 分钟。另一个易忽略的机制是一切进入对话的东西都会在此后每轮重新发送,虽然走缓存便宜,但它一直占着模型每轮都要绕开思考的上下文。
引用文件用 @ 而不是打路径——文件在第一个请求里就被附上,省掉一次 Read 甚至一次搜索;同一会话只需 @ 一次。离开键盘前先 /compact——摘要在旧对话还在缓存里时写便宜得多。最近几轮跑偏了用 /rewind 而不是 /compact——rewind 只砍尾部、前面全在缓存中因此几乎免费,compact 重写整个对话所以永远有成本。新会话先跑一次 /context,把 workflow 类指令移进 skill(按需加载)而不是常驻 CLAUDE.md。
作者用 5 周、指挥 AI Agent,给 Chromia 的 Rell 语言完成了一次通常需要多年多团队的编译器内核重写(他手写的预算是「大半年」)。真正的价值在架构选择:保守方案是造新 IR、难处仍回调老执行代码(Kotlin K2 的做法);激进方案是让 IR 变成纯数据、节点上完全没有行为,把散落的解释逻辑全部重写为对新树的穷尽匹配。他选了激进方案。
▸ 点击展开详情
促成选择的是一个硬性外部需求——序列化。把行为委托给编译器侧代码的节点,在语言中立的二进制格式里没有可写的东西,因为委托就是 JVM 代码、而代码正是格式装不了的;所以混合方案不只是更差,而是无法表示。作者原话点出通用规律:硬性外部需求「把品味之争变成了约束」。结果是 39 种表达式、17 种语句、16 种数据库表达式构成封闭 sum type,解释器是编译器强制检查穷尽性的 pattern matching——漏一个分支就编译不过。让 Agent 大规模改写可行的不是 Agent 变强,而是架构把「改漏了」从线上事故降级成编译错误。
把大规模重构交给 Agent 之前先问:在这个架构里,Agent 漏掉一处的后果是编译失败还是线上事故?若是后者,先把不变量搬进类型系统再动手——封闭 sum type 加穷尽匹配、节点只放数据不放行为、用构建系统的模块依赖图(而非约定)强制编译器与运行时的边界。收尾也值得抄:所有 pass 之后加一个 resolve 步骤,强制求值全部 lazy 字段、丢掉编译器和 IDE 包袱、把活对象引用换成指向扁平数组的整数索引。
每次任务开始,coding agent 都是瞎的:grep 一个词、打开文件、跟着 import 走、退回来、再试——它在重建一小时前自己画过又扔掉的地图。人类 onboard 一次,Agent 每次都要。Graft 把这份理解一次性构建成仓库里一组互链的 markdown,每个系统、API 或概念一个节点,用自然语言解释它做什么、怎么和其他部分连接,而不是符号列表。
▸ 点击展开详情
反直觉的是,注入更多上下文通常被认为会稀释注意力、拉低正确率,这里却正确率和效率同时改善。SWE-bench Verified 上同为 Claude Sonnet 5、同镜像、同轮次上限,唯一差别是有没有接 Graft:解决 33/50(66%)对 27/50(54%),同时少 25% 工具调用、少 23% tokens、少 32% 墙钟时间。原因在失败模式里——基线的错误几乎都是同一形状:只补了一个文件而漏掉它的兄弟文件。django-11532 上基线只改了修复所需 5 个文件中的 1 个,还两次弄坏了 18 个原本通过的测试。缺的不是推理能力,是仓库结构的全局图。
速度和正确率分开选路:162 次受控运行显示 push 模式(预先注入)省 42% tokens、快 60% 但正确率与基线持平(都 93%),pull 模式(只给按需检索的工具)正确率升到 98%,是整轮最强单项。要快就预先注入,要准就给检索工具。更普适的一点是把「仓库理解」当作可缓存产物而不是每次重算的开销——生成的图当作 node_modules 一样的本地可再生缓存(gitignore 掉),团队共享的是接线配置。另注意结构化代码图用 tree-sitter 完全不调模型。
Linear 用自家六年、覆盖数万团队的产品数据给出「AI 普及前后」对照。最反直觉的不是采用率曲线,而是时间去哪了:和 AI 聊天、把 issue 派给 Agent 这两类一年前还不存在的工作,现在出现在每个职能的日程里,但没有任何一类原有工作缩水来腾出空间。
▸ 点击展开详情
这直接反驳了「AI 接手执行环节所以协调成本下降」的叙事——更多产出需要更多协调,而这些协调正在成为 Agent 行动所依赖的上下文。规划时间(客户需求、文档、项目)在几乎所有指标都上涨的一年里保持持平。其他数字:AI 现在撰写 Linear 里将近一半的新 issue(两年前不到千分之一);201 人以上公司的 CEO 个人 AI 活跃率半年内 9%→36%,全报告最大跃升;PM 附带 PR 两年内 3%→10%,设计师 1%→8%;每团队每周 PR 数相对 2024 年 6 月涨 111%,且是第一年持平后于 2026 年才折向上。
做 ROI 测算时不要假设协调开销会被吸收,按「净增一层工作」预算人力和流程。如果 PM 和设计师开始自己提 PR(两条曲线各涨 7 个百分点),review 容量和 CI 成本是最先被压爆的地方,要提前扩。同时记住数据边界(作者自己标得很清楚):只覆盖 Linear 内部行为,PR 只统计连接到 Linear 的仓库所以这些比例是下限,而且统计的是 opened 不是 merged。
Windmill 把 Slack、邮件、Discord 和 GitHub issue 全部汇成一个 Discord 队列,用自家流水线做分流、起草回复、并且经常连修复一起起草,至今跑过约 3100 个会话。设计上最关键的一条不是模型能力而是那道闸门:所有面向客户的回复都自动起草、绝不自动发送。
▸ 点击展开详情
理由说得很直白——整个系统建立在客户信任这些草稿之上,而第一次有错误或潦草的 AI 回复送到客户面前,这份信任就没了,此后每条 AI 消息都会被当作噪音。可抄的结构决策:审批用 flow 的 suspend 实现,等待期间不占任何 worker;修复分支和回复分支并行跑——回复还在审批队列排着时补丁已经在写了;Opus 做重分析、Sonnet 和 Haiku 做便宜的路由和分类;上下文含客户档案(自有数据组装,模型碰不到实时凭据)和严格限定到该客户实例的遥测,查询无法越界。连署名都是刻意设计:机器人发出,页脚写明 AI 起草并点名审核的同事。
两个可直接迁移的机制。线程匹配交给代码而不是靠约定——一个轻量模型读每条新消息、和近期会话比对,判定它延续既有工单还是新开一个,因为「请大家都在原线程回复」这条规约永远推不动。把自动化的失败当作文档体检:修复 Agent 跑的是和人类编码会话完全同一份 CLAUDE.md,所以 oneshot 卡住的地方通常正指向 CLAUDE.md 写薄了的部分。另外入口流程要把重分析异步出去,handler 亚秒级返回,否则十条消息同时到达会全堵在一个多分钟的分析后面。
几乎所有工作都由「做」和「检查」两个阶段组成,而当前的 AI 还不足以同时承担两者。于是只有两种自洽的用法——AI 做、你检查,或者你做、AI 检查。前者就是 vibe coding,它要求你逐行检查 AI 写的每一行;作者认为这在人类注意力上是虚构的,更现实的是反过来把 AI 当 reviewer。
▸ 点击展开详情
论证的力量在于它从激励结构而非能力上界出发。作者原话:即使你决心深入检查每一行,不到一小时注意力就会飘走;失败案例罕见到你不由自主开始信任机器。而检查别人的代码是苦役、写自己的代码是乐趣——vibe coding 里所有指向错误方向的激励,反转之后都被扭正了。经验证据也很直接:开始把自己的代码拿给 Claude 找问题后,「至今没有给它看过一段它挑不出严重问题的代码」——那些代码通常都能跑,他自己也看不出哪里不对。更长期的代价是:把一切交给 AI,你是在自欺地以为掌握了某样东西,而认知能力像肌肉,难获易失。
对质量要求高于交付量的场景,把默认工作流设成「人写 + AI review」,并把 AI 的角色固定在 reviewer 上而不是让它接管键盘。作者点名的典型是科研代码——代码不是产品、论文才是,所以它不需要对各种用例鲁棒,但必须绝对正确。判断该用哪个方向的标准不是任务难度,而是这段代码的错误能否被外部机制廉价兜住:能被测试、类型或 CI 抓住的可以让 AI 写;只能靠「作者真的懂这段代码」来保证的,必须自己写。
本期十篇里有六篇带着生产环境的账单和计数器进场,这本身就是信号:关于 Agent 的讨论正在从"能不能做"转向"连续跑几周会怎样"。三组数字值得并排看。Anthropic 的 45 个 Agent 协作找出 266 个漏洞、独立并行只有 21 个,但同一批实验里 30 个 Agent 有 18 个把分支起了同名,定价 Agent 被拿掉私聊频道后改用公开挂牌把价格对齐到分——群体不提供多样性,它放大相关性。momo5502 的 4 个 Agent 烧掉 1998 亿 tokens、产出近 7000 个 commit,结论却是几乎所有故障都能归因到 compaction 导致的渐进遗忘,而把 Opus 换成 Sonnet"没有可察觉的差异"。Unblocked 迁到 GLM,价目表承诺省 95%,发票上是 68%。共同的教训是:单次任务的成功率已经不是瓶颈,可机械校验的约束才是——把不变量搬进类型系统让编译器替 Agent 兜底,把仓库理解写成可缓存的产物,把长期状态从会话搬到 issue 里,在客户面前保留一道人类的发送键。本期唯一没有硬数据的那篇给出了对应的个人版本:让 AI 做 reviewer,而不是让它接管键盘。