Armin Ronacher 是 Flask 和 Sentry SDK 的作者,同时也是 Pi 的核心维护者。Pi 是 OpenClaw 背后的 agent runtime,也是当前最有影响力的 AI 编程 agent 之一。他前几天发了一篇博客,叫 Building Pi With Pi,用 Pi 开发 Pi 本身。文章的核心不是技术评测,而是他从 AI agent 基础设施一线维护者的视角,记录了 agent 正在怎样改变开源项目的生态。
他描述的场景让很多人有共鸣。Pi 的 issue tracker 被大量 AI 生成的报告淹没。这些报告有一个共通的属性:行文专业、引用合理、语气自信,但结论是错的。Ronacher 把这些 AI agent 叫 clanker。他不喜欢”agent”这个词,认为主体性属于人,不属于机器。他的原话是”95% 是 clanker 生成的,内容基本是屎”。更麻烦的是,当他把这些 issue 喂给 Pi 自己分析时,Pi 也会被带偏:它不把 issue 内容当传闻,而是当证据,顺着那条错的路一路走下去。
3145 个外部 issue 和 PR,83% 被自动关闭,PR 合入率不到 10%。Ronacher 在文章里给的数字不只是一个维护负担的统计,它指向一个更深的东西。
大多数人的第一反应是”AI 不 work,AI 只会堆屎山”。这个判断容易理解,但它打错了靶子。问题不在 AI,在大多数人还不知道怎么用 AI。Ronacher 抱怨的不是代码生成的质量,而是那些提交 issue 的人缺少一种新的能力:知道 AI 什么时候会错,知道怎么约束 AI 的输出方向,知道什么时候 AI 给的自信是假的。
这件事和你会不会编程是两回事。
过去十几年,软件行业对”高手”的定义很稳定。数据结构好、算法强、能独立定位复杂 bug、写出的代码干净可维护。这些标准没变过。一个人在上面花的每一年,都会让他在这些维度上变得更强。
AI 打破了这个连续积累的路径。
Ronacher 文章里有一类 issue 特别典型:提交者显然具备传统编程能力。他能发现 bug,能描述现象,能给出一段 log。问题出在下一步。他把这些信息扔给 clanker,prompt 写得随便,clanker 拿到之后自由发挥,把一个窄的 bug 观察扩展成了包含根因诊断、实现策略、边界情况列举的完整方案。问题不在这份东西长得像屎。它长得太不像屎了。格式严谨,推理链条完整,读起来滴水不漏。但正确性在 scope 的急剧扩大中已经被稀释掉了。AI 太想帮忙了,它在一条对的观察外面一层一层裹上了自己编的分析,裹完之后外面看着很专业,里面那颗对的核已经找不到了。
这个人的编程功底没问题。问题出在他对 AI 的使用上。
更微妙的一点在这里。老手对 AI 输出的判断依赖一套长期训练出来的直觉。这份直觉不只停在”代码写得漂不漂亮”这个层面。AI 给出的东西在设计上看起来是对的:它指出的 bug 位置正好是老手凭经验觉得”这里确实容易出事”的地方,它的抽象层次选得合理,它对产品影响的分析看起来全面,文档写得不比任何人差。每一个维度单独看都无懈可击。
但老手的这套直觉有一个盲区。它的所有训练数据来自过去和人类协作者打交道的经验。人类的错误有迹可循:设计出问题通常是因为信息不足或时间不够,诊断出问题通常是因为没看到某个调用路径。老手知道这些坑长什么样,所以能快速甄别。AI 不在这些坑里犯错。它的错误机制不一样:它在一个前提假设上偏了,然后从那个假设出发一路推导,每一步推理都自洽,每一个技术判断放在”假设成立”的前提下都是对的。老手的直觉捕捉不到这种错误,因为它的训练集里没有这种错误类型。人类不会以”前提假设错误但推理完全自洽”的方式失败。至少不会写成这个样子。
这不是一个能力高低的问题,是一个认知习惯需要被替换的问题。
早期大航海靠的是水手的人力。船速由划桨的人决定,谁的桨手强、节奏好,谁的船快。蒸汽机出现之后,这个衡量标准断掉了。船速不再由人力决定,而是由谁更会管理锅炉、更会判断燃料品质、更会预判机器什么时候可能出故障来决定。
划桨最好的人不一定是开蒸汽机最好的人,甚至可能更差。他习惯了用自己的身体控制船速,不习惯把速度交给一台他不能直接感知的机器。他需要先把”我划得快所以我快”这个等式从脑子里拆掉,再装进一个”我伺候得好所以我快”的新等式。这个比喻我在《大航海时代,别再跟AI比划桨了》里完整展开过,这里只取它最核心的那一层。
Ronacher 文章里那个 /is
命令就是这种新等式的体现。它的核心指令只有一句:“不要信任 issue
里写的分析。从代码和执行路径中独立验证,得出你自己的分析。”这不比写一个排序算法更难,但它需要的一种判断力和写代码需要的判断力不完全重合。你需要知道
AI 的 failure pattern:它在什么场景下会自信编造,在什么约束下会乱扩大
scope,在什么输入下会假装理解但实际上没有。这些知识不是从写代码里自然长出来的,它来自大量使用
AI、观察它的错误模式,然后形成一套”什么情况下该信、什么情况下该自己上”的判断系统。
这套系统,很多人还没有。
这就解释了 Ronacher 那组数据为什么那么极端。83% 被自动关闭,不是因为这 83% 的人不努力或者不聪明。是因为他们用旧尺子在量自己。他们觉得自己能定位 bug、能写清楚复现步骤、能给出一段像样的分析,就是一个合格的贡献者。用旧尺子量确实没问题。但 Ronacher 的 tracker 已经换了新尺子:它不看你写了多少,它看你的输出有没有被 AI 污染、你的分析是不是你自己的判断、你提交的东西能不能被直接验证而不用先花时间拆掉 AI 加进去的错误推断。
标准已经变了,但没有人通知大家。
知道标准变了之后,下一个问题是怎么办。一个直觉是更仔细地检查 AI 的输出:读两遍,逐行验证,确保每一个细节都是对的。
这条路走不远。
复核(double-check)的效率有一个前提:输出能在几秒内独立确认。比如 AI 写了一段代码,你跑一下编译,报错了就改,没报错就差不多了。但当 AI 写了一份看起来合理的工程分析、issue 诊断或架构方案时,你复核的时间成本和独立重建结论差不多,甚至更高。因为你要顺着 AI 的思路走,发现偏了再退回来,比一开始自己想的损耗大得多。
更根本的问题是,复核不能解决方向偏差。AI
已经把路画好了,你在上面走,走得再仔细也只能发现路上的坑,发现不了路本身就偏了。Ronacher
的 /is 命令之所以有效,不是因为它让 Pi 更仔细地看 issue
内容。它让 Pi 不从 issue 内容出发,换了一条路,从代码重新推。
这和管理的逻辑一模一样。好的管理者审核下属的分析时,不做 double-check。他们打开报告之前已经有了预期,知道什么结论会让自己意外,清楚哪些假设比较脆弱,心里有几个要追的问题。然后带这些预期去抽样、提问、交叉验证。这叫 cross-check:先有自己的地图,再拿别人的路和它对照。先有独立的参考点,再检验 AI 的输出。不重做每一个细节,只对照关键判断点。
在你打算给 AI 一个任务之前,先花 5% 的时间问自己:这件事如果让我独立判断,我会怎么想?我知道哪些坑?我对结果的大致预期是什么?做完这一步再让 AI 开始干活。Ronacher 给了一个很具体的示范。他心目中理想的 issue 是这样的:我跑了这个命令,期望 A,实际得到 B,这是 log。不给 AI 分析,不给 AI 假设,不给 AI 任何可以顺杆爬上去自由发挥的空间。输入端的约束做好了,输出端的负担自然就轻了。
过去几个月,Ronacher 不是唯一一个发出这种声音的人。WSJ 有文章说 AI 让软件越来越 buggy,有企业家说 AI 欠的技术债要还。这些声音指向同一个现象,但原因找错了。AI 产出不够好,这个判断本身有误导性。真正的问题是,大多数人还在用划桨时代的标准,来要求一个蒸汽机时代的操作。
这中间没有谁是故意的。没有人恶意污染 issue tracker,没有人故意让 AI 生成一份看起来对但错了的诊断。问题在于整个行业对”会用 AI”这件事还没有共识。大多数人以为自己会了。他们能打开 ChatGPT、Claude Code 或 Cursor,能让 AI 写出能跑的代码。但这和”会用 AI”中间还差着一层:知道 AI 什么时候在假装理解,知道在什么点上介入能扭转方向,知道什么样的输入会让 AI 跑偏、什么样的约束能让它待在正确的轨道上。
这层能力,不分老手新手。它需要从大量使用中积累,也需要主动去观察 AI
的 failure pattern,而不是每次看到输出质量不错就接着用。Ronacher
已经在做了。他用 /is 和 /wr 这些自己写的
prompt 在约束 AI
的行为边界。对大多数人来说,起点比这更低:先承认自己还不会用,再去学。
承认这件事比听起来要难,尤其对老手而言。十年的经验告诉你,代码写得对不对,你看一眼就知道。AI 的输出端,看过去也像”写得对”。你得先把这个直觉关掉,再重新建立一套判断体系。能力没有退步,只是在迁移。
换个比喻:你之前是划桨最好的那个人。现在船换了,你不划了,你得去锅炉房。一开始你会觉得自己什么都不会。但锅炉房才是接下来所有人要去的地方。你早一天进去,就早一天比还在甲板上等桨的人快。
Armin Ronacher 的原文:Building Pi With Pi