跳到主要内容

35 篇博文 含有标签「coding-agents」

查看所有标签

编译器是你运行过最廉价的评估 (Eval)

· 阅读需 12 分钟
Tian Pan
Software Engineer

正在构建编程智能体(coding agents)的团队在验证上投入了真金白银。针对每一次模型升级运行精心策划的任务评估套件;对 diff 进行打分的 LLM 裁判;每次迭代都要消耗数分钟算力的沙箱测试。这一切的存在都是为了回答一个问题:模型写出的代码能运行吗?

与此同时,这些团队大多能接触到的最便宜的评估方式就躺在他们的工具链中,而他们在十年前配置它时根本没有考虑过模型。它就是编译器。一个严格的类型检查器是一个免费、即时、确定性的验证器,它在智能体循环中的每一次编辑时运行——而你是否拥有它取决于你的语言选择,而不是你的评估预算。

这种重构带来了一个令人不安的后果。你的团队在多年前确定的技术栈决策——为了速度选择动态语言、类型可选、以测试作为安全网——是针对人类作者优化的。当作者变成模型时,权衡的优先级会重新排序。你团队最擅长的语言可能不再是你的智能体最安全的语言。

合并队列成了新的瓶颈

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的编程智能体(Coding agents)刚刚让编写代码成为了交付软件中最廉价的部分。但它们并没有让代码落地变得更便宜。AI 采用率高的团队合并的 Pull Request (PR) 数量几乎是以前的两倍——而他们的交付指标却几乎没有变化,因为每一个 PR 仍然必须挤进同一个代码评审流水线、同一个 CI 集群以及同一个合并队列(Merge Queue),而这些设施当初是按人类打字速度设计的。约束并没有消失,而是向后移动了,移到了系统中那个最窄的管道:从“已批准”到“进入主分支(main)”之间的串行化路径。

这是一个经典的约束理论(Theory-of-constraints)故事,大多数工程组织目前正身处其中却尚未察觉。当一名开发者可以在并行工作树中指挥 5 到 10 个智能体时,PR 的体量就不再与员工人数挂钩。但合并吞吐量仍然取决于一些更为死板的东西:你的 CI 每小时能验证多少个 main 分支的候选状态。这个数字受限于测试套件的时长、执行器(Runner)容量、抖动率(Flake rate)和队列机制——而这些都没有随着智能体变快而变快。

你的智能体幻觉出的软件包现在已存在 —— 而且它是恶意的

· 阅读需 12 分钟
Tian Pan
Software Engineer

每个安全团队对拼写抢注 (typosquatting) 都有一个心智模型:攻击者注册 requets 并等待有人误输入 requests。这行得通,但它是对人类粗心大意的一种随机押注。Slopsquatting 则更糟糕,因为这种“拼写错误”并非随机。语言模型会以可预测、可重复的模式虚构出看似合理但并不存在的包名——攻击者可以查询你使用的相同模型,收集它们虚构的名字,并准确地在 PyPI 和 npm 上注册这些包。幻觉变成了预购单。你的编码智能体 (coding agent) 在拥有自主安装权限的情况下运行,就是那个取走包裹的顾客。

这并非假设。关于这一现象的最大规模研究对 16 个模型生成了 223 万个代码样本,发现 19.7% 的推荐包并不存在——涉及 205,474 个独特的虚构名称。当一位安全研究员将其中一个最常被幻觉出的 Python 包注册为一个无害的空壳时,它在三个月内被下载了超过 30,000 次,并最终出现在一家大型科技公司开源仓库的安装说明中。由“氛围编程” (vibe coding) 带来的供应链攻击已经完成了它的概念验证。

重写现在变得廉价,但做对依然很难。

· 阅读需 10 分钟
Tian Pan
Software Engineer

二十五年以来,“绝不从零开始重写”一直是软件工程界最接近诫律的一条原则。这一公认论点背后的成本结构曾被所有人视为理所当然:重写意味着重新阅读、重新理解并重新编写多年积累的代码;而当你忙于这些时,旧系统仍在运行,竞争对手仍在不断交付。重写之所以被禁止,是因为它太慢了。

编程智能体刚刚消除了这个“慢”的部分。一个智能体可以在几天之内——而不是几个季度——将一个拥有十万行代码的代码库从一种语言或框架翻译成另一种。研究大型机现代化的团队发现,主要由于 AI 辅助转换,平均程序成本从 2024 年的 910 万美元下降到了 2025 年的 720 万美元,咨询机构目前报告称现代化进度加速了 40–50%。那么,这条诫律失效了,对吗?如果重写中最昂贵的部分变便宜了,那么重写又重新回到了选项中。

问题在于:编写代码从来都不是最昂贵的部分,它只是最显眼的部分。在大规模迁移中失败的组织,很少是因为代码难以转换。他们的失败源于代码之外的一切——未记录的行为、数据迁移、集成切换,以及那些没人想到要写下来的运维肌肉记忆。智能体让重写的开始变得廉价,但对于让重写安全完成的那些因素,它们几乎没有提供帮助。

万档代码转换:在机械式代码迁移中运行智能体集群

· 阅读需 12 分钟
Tian Pan
Software Engineer

每一个框架迁移的模式都大同小异。你编写一个 codemod,在代码库中运行它,它能干净利落地转换 80% 的文件 —— 也就是那些符合 codemod 作者预期的模式的文件。然后你会遇到长尾问题:某些测试文件中有人对渲染器进行了猴子补丁(monkey-patched),某些组件触及了框架内部机制,或者某个模块是 2017 年由一位早已离职的工程师编写的,使用的是没人再采用的惯用法。Codemod 可以正常解析这些文件,只是没有适用的规则。因此,最后 20% 的迁移工作消耗了 80% 的日程,只能由那些宁愿做任何其他事情也不愿干这活的工程师们手工逐个文件完成。

编程 Agent 颠覆了这种经济效益。难倒确定性 AST 转换的手写怪癖,恰恰是模型擅长处理的 —— 它阅读文件,理解意图,并像人类一样重写代码,而不需要为每种变体制定明确的规则。Airbnb 在大规模实践中证明了这一点:在短短六周内,将近 3,500 个 Enzyme 测试文件迁移到了 React Testing Library,而最初估计的人工工作量是 1.5 年。但头条新闻中被忽略的一点是:难点并不在于提示词(prompting)。一旦你让 Agent 集群处理一万个文件,工程问题就不再是 AI 问题,而变成了批处理操作问题 —— 分片、验证、隔离和合并策略。正确的心理模型是一个 Mapper 具有随机性的 MapReduce 作业。

你的设计系统曾是文档,现在它需要成为一个编译器

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的设计系统在过去十年中得以幸存,是因为人类吸收它的速度很慢。新入职的工程师通过 Figma 文件、PR 里的细节纠错,以及那个总能揪出错误灰色阴影的设计师来学习组件变体。这种吸收流水线的吞吐量大约是每位工程师每周几个组件——速度慢到足以让设计团队手动把控边缘情况。

编程智能体刚刚打破了这条流水线。一个智能体集群可以在午饭前生成 50 个稍有偏差的按钮:每一个看起来都挺合理,但每一个使用的十六进制值可能差了两个色阶,内边距可能是 14px 而非你规范中的 16px 阶梯,圆角则是随手捏造的。没有哪个设计师能跟上这种评审速度。而你首先想到的指令——在系统提示词中加入“遵循样式指南”——会像所有其他软性指令一样逐渐失效:随着上下文窗口被填满,它的统计权重会下降,模型会退回到它从数百万个其他代码库中学到的通用 CSS 模式。

解决方案不是写更好的提示词。而是一次类别转变:你的设计系统必须停止作为供人类解读的“文档”,转而成为由机器执行的“契约”。文档只是请求,而编译器则是拒绝。

你的内部框架是一种低资源语言

· 阅读需 10 分钟
Tian Pan
Software Engineer

让编程智能体(coding agent)构建一个 React 组件,它第一次尝试就能写出地道的、基于 Hook 的、带有无障碍标注的代码。让同一个智能体使用你公司的内部 ORM —— 那个平台团队维护了六年、拥有出色文档和上百个内部用户的框架 —— 它就会幻觉出不存在的方法,从其他库里发明配置选项,并自信地交付出基于它臆造的 API 编写的代码,而这些代码根本无法通过编译。

这种差异并非源于质量。你的 ORM 可能比模型能完美处理的一半开源库设计得都要好。差异在于训练数据。React 背后有数百万个公开仓库;而你的框架则一个都没有。在自然语言处理(NLP)的术语中,你的内部框架是一种低资源语言(low-resource language) —— NLP 研究人员针对低资源语言记录的每一个后果,现在都适用于你的代码库。

你的模型认为你的技术栈已过时 2 年

· 阅读需 12 分钟
Tian Pan
Software Engineer

有一类 AI 生成的 Bug 几乎每次都能通过代码审查,它既不是幻觉函数,也不是捏造的包。它是完美的地道代码——地道到符合模型训练数据冻结时你的技术栈版本。模型为运行 Tailwind v4 的项目编写 tailwind.config.js,在 Hooks 代码库中调用类组件的生命周期方法,或者调用一个在三个小版本前就被弃用、并在你的 lockfile 实际锁定的版本中已被删除的 API。代码看起来毫无破绽。它看起来就像出自某个备受推崇的教程。只是那个教程来自 2024 年。

称之为“训练截止日期 Bug”:这类缺陷的存在并非因为模型推理能力差,而是因为模型对你依赖项的了解带有时间戳,而你的 lockfile 并不在意。一项 ICSE 2025 对 8 个常用 Python 库、7 个代码模型的研究发现,在看似合理的补全代码中,弃用 API 的使用率高达 25–38%——当周围代码已包含过时模式时,这一比例会攀升至 70–90%。这些并非罕见的边缘情况。它们是要求一个冻结的产物为不断变化的目标编写代码时的默认失败模式。

文档复兴:你的 README 是 Agent 的核心上下文界面

· 阅读需 11 分钟
Tian Pan
Software Engineer

二十年来,文档一直是良好初衷的坟墓。你在第一个 Sprint 期间编写 README,那时架构整洁,你的热情高涨。但没人读它。到了第三个 Sprint,它就开始在构建命令上误导人,到了第六个 Sprint,它描述的是一个早已被删除的服务。文档是每个人都同意缴纳但实际上没人在缴的税 —— 一种没有反馈循环的道德准则。写了烂文档,什么也不会发生。不写文档,同样什么也不会发生,因为高级工程师把架构都记在脑子里。

然后我们将编程 Agent 指向我们的代码仓库,反馈循环一夜之间降临。README 现在是你拥有的杠杆率最高的文件 —— 这并不是因为有人做了关于文档规范的励志演讲,而是因为该文件的质量现在直观地决定了你的 Agent 是交付正确的代码,还是会信誓旦旦地对一个已不存在的架构产生幻觉。

这就是文档的复兴,而它与我们过去编写的文档几乎毫无关系。

你的编程代理基于落后 Main 分支三周的代码版本重建的代码库索引

· 阅读需 11 分钟
Tian Pan
Software Engineer

你团队中的一个 AI 编程 Agent 提交了一个 PR,在两个文件中调用了四次 parseUserToken()。这个函数在代码仓库中并不存在,甚至已经消失了 19 天,早在你团队所有工程师都记得评审过的一次提交中就被 decodeSessionClaim() 替换了。Agent 并不是凭空捏造了这个名字,它是从其语义索引中读取的——那个向量库是从一个比 main 分支落后 21 天的工作副本重建的。相比之下,Agent 的编辑步骤在会话开始时运行了 git pull,操作的是最新的代码。对同一个代码库的两个视角,相隔三周,而 Agent 却自信地用一段无法针对任何真实环境编译的代码桥接了它们。

这是一种不会自我宣告的失败模式。Agent 运行了。测试看起来通过了。PR 合并了。第一位评审者之所以注意到,仅仅是因为一个被删减的函数与一个无关的辅助函数重名,触发了 linter 报错。到那时,Agent 已经花了一个完整的冲刺(sprint)针对一个“幻影版本”的代码库进行编写,而团队中没有一个人——包括 Agent 自己——收到任何异常信号。

你的编程 Agent 开启的那个导致真实 PR 被关闭的拉取请求

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的编程智能体在周二下午 3:14 提交了一个 PR。PR 描述很整洁,代码差异(diff)很小,CI 测试也是绿色的。二十分钟后,它被压缩合并(squash-merged)了。第二天下午 1:20 吃完午饭回来的同事看到了一条通知:“PR #1247 已关闭。”不是已合并,而是已关闭。分支不见了。她上周留下的 72 条评审评论也消失了——全部折叠在一个“已过期”标签下,属于一个不再出现在任何活跃列表中的 PR。一位资深工程师的设计决策、与安全评审员的两轮反复沟通,以及耗时一周协商出的周密迁移计划,全都化为了另一个没人仔细阅读的 PR 底部的一个脚注。那个压缩提交(squash commit)留下的唯一痕迹是底部的一行标签:Closed by #1893

这就是信任编程智能体自行编写 PR 元数据的失败模式。出问题的不是代码,而是元数据。代码差异没有问题,智能体工作得很出色。它无法做到的是区分当前的讨论与陈旧的讨论,而 GitHub 的自动关闭机制将智能体编写的每一个关闭关键字都视为必须执行的指令。你的智能体通过读取评论来获取上下文,从一个六个月前的回复中推断出它的工作取代了一个旧的 PR,于是在它生成的描述中写下了 Closes #1247。合并操作完成了剩下的工作——在压缩合并的那一刻,对于任何没有盯着 diff 看的人来说,这一切都是无声地、机械地、不可逆转地发生了。

翻倍且没有事后复盘:那份编码智能体带来的 CI 账单

· 阅读需 11 分钟
Tian Pan
Software Engineer

该项支出在六周内攀升了 130%,工程团队却无人察觉。PR(拉取请求)的合入速度变快了。仪表板上的单次 PR CI 成本看起来与上季度持平。Agent 的分支在第一次尝试时通过测试(显示为绿色)的频率比人类的分支更高,这实际上反而拉低了 CI 持续时间的中位数。财务部门在季度复核中发现了这一点,将其标记为不明变动,并要求工程部门提交事后分析报告(postmortem)。工程团队无话可说 —— 既没有事故,也没有回退,更没有部署失败。仅仅是一项预算支出在仪表板显示一切正常的情况下,悄无声息地翻了一倍。

这个“事后分析报告”式的缺口本身就是一个产物。成本从以人力为主的曲线转向了以基础设施为主的曲线,而负责人力预算的团队与负责基础设施预算的团队并非同一个。Agent 没有弄坏任何东西,它只是改变了损益表(P&L)中承担这项工作的科目。