Flask作者发出警告:AI Loop写的代码,正在变成没人能看懂的“生物”

Claude Code 之父 Boris Cherny 说过一句话,读完之后很难忘掉:

"我已经不再直接Prompt Claude 了。我写的是 Loop(循环),让循环去提示 Claude,让循环去决定下一步做什么。我的工作,是写循环。"

Armin Ronacher 是 Flask、Jinja2 的作者,Sentry 联合创始人,也是 AI 工程平台 Pi 背后的核心人物。

他最近写了一篇文章,标题叫《即将到来的循环》。

从文章中能感受到他的不安,原文地址:

https://lucumr.pocoo.org/2026/6/23/the-coming-loop/

循环套循环

每个编程 Agent 内部本来就有一个循环:模型调用工具,读取结果,再调用下一个工具,读文件,改文件,跑测试,最终给出答案。

这个循环,大家已经很熟悉了。

而 Ronacher 说的是套在外面的那一层循环。

具体是这样一种模式:任务进入队列,机器领取,尝试执行,停下来,然后由一个外壳程序(harness)来判断,这次执行算不算完成。如果不算,外壳程序可以继续当前会话,注入新消息,用修改过的上下文重启一个新会话,或者把任务转发给另一台机器。

这样,任务生命周期,不是模型自己说"我完成了",而是靠外部Harness判断。

这个外层循环不稀奇,Claude Code 早期就有人在玩了。

但现在变得越来越主流,最近几周技术圈都在聊。

他自己用得并不顺手

Ronacher 承认:对于他真正在乎的代码,这套方式目前没什么用。

原因有两个:品味和控制感。

他对代码质量有很高的要求,而且他需要理解自己发布的代码。

在压力下,或者和别人讨论时,他希望能解释清楚系统是怎么工作的,而不是先去问机器帮他解释。

问题在于,当前的模型写出来的代码,倾向于过度防御、过度复杂、局部推理。

它们回避强不变量,用兜底逻辑代替"让错误状态根本不可能发生",重复代码,发明糟糕的抽象,用更多机制掩盖设计上的模糊。

Karpathy 曾经提到,模型对异常"极度恐惧"。

在有重要的系统里,如持久化数据格式或核心基建,正确修法不是"处理每一种畸形情况",而是让畸形状态根本无法被写出来。

但即便手动引导,LLM 也很难自然地写出这类代码。

更荒谬的是,就算错误已经不可能发生,它们还是会去处理那个不存在的错误。

把这种行为放进循环里,结果是放大。

每次迭代都加一点小防御,系统慢慢变得难以理解,表面上却越来越"健壮"。

越是放手,越是如此。

Ronacher 认为这个问题没有在改善,甚至在倒退。

Claude Code 加上 ultracode 这类全自动外壳,产出的代码质量比去年秋天还差。

原因:以前是人机协作,现在是机器独自跑三十分钟以上,没有人在中途介入。

还有一个附带伤害:这类工具交给初级工程师,没有明确指导的话,他们会学到非常糟糕的习惯。而且他们能为自己的每一行代码振振有词地辩护。

循环真正好用的地方

但 Ronacher 也不是说循环没用,它在某些领域好用得惊人。

代码迁移是一个。

他自己用循环把 MiniJinja 移植到了 Go,效果不错。

Bun 把部分代码从 Zig 迁移到 Rust,据报道也是类似的自动化方式完成的。

性能探索是另一个。

机器可以跑实验、做基准测试、丢掉失败方案、继续搜索。

安全扫描复杂问题空间的探索也很适合,让系统去探索、汇报,不一定要提交持久的代码。

这些场景有一个共同点:要么不生成新代码,只是变换已有的代码;要么生成的代码本来就不打算长期存活。

是概念验证,是想法,是发现,或者是机械变换。

循环需要的只是一个信号,让它知道该不该继续。

这个信号不必是客观的、二元的,只要足够有用,能驱动下一次迭代就行。

用另一个 LLM 来做判断,在很多场景下已经够了。

软件正在从机器变成生物

Ronacher 用了一个比喻:软件正在从确定性的机器变成有机体

他是在一个鼓励理解机器的环境里成长为工程师的。

每一层都可以剥开,加深理解。

架构上,他认为应该推向更多确定性,而不是更少。

在设计良好的系统里,总有工程师知道不变量在哪里,哪些部分是承重墙,哪些改动是安全的。

这个理想当然一直有压力。

大型软件系统本来就太大、太动态、太依赖外部服务,没有人能把它完整地装进脑子里。

即便没有 LLM,诊断分布式系统也已经像医生看病:观察症状,提出假设,"再做几个检查",尝试治疗,再观察。

但 LLM 把这个趋势扩大。

现在已经有不少工程师,生产问题出现后的第一步,是让机器读日志、提出根因、主动生成补丁。

补丁再由另一台机器审查,有时候甚至直接合并进主分支,没有任何人工监督。

我们修复它,监控它,让它保持稳定,但不一定真正理解它。

Ronacher 承认,对某些软件来说,这没问题。

不是每一行代码都值得人工撰写。

但他不想让所有软件都变成这样。

你没办法完全退出

让他真正感到不舒服的,可能是没退路。

安全是最直接的例子。

就算你不用循环(Loop)来构建软件,别人会用循环来攻击你的软件。

攻击者会让机器持续运转,安全研究员也会。

信号和噪音会同时涌来,量大到你不得不也用机器来处理。

Daniel Stenberg 写过一篇关于 curl 的文章,描述了维护者已经承受的压力。

curl 的核心开发目前 AI 参与并不多,但维护者已经被大量报告淹没,其中大多数是 AI 生成的。

攻击者在循环,报告者在循环,防御者迟早也得循环,才能跟上节奏。

竞争层面同样如此。

有些团队会靠纯粹的速度甩开其他人。五个人做五十个人的事,这已经在发生。

有人甚至会把 AI 瞄准你的产品,让它循环运行,指令就是"做成那个样子"。

如果他们的用户满意,这重要吗?

不是所有软件都会受到同等冲击。

有些领域会惩罚粗糙,要求信任和责任。

但大量软件活在一个速度、实验和覆盖面比精确性更重要的世界里。

我们正在变得过于依赖

Ronacher 认为最可怕的部分,是我们正在以新的方式依赖这些。

软件一直依赖工具。他还记得需要为编译器付费的年代。

现在的工具让他想起那个时代,创作软件再次有了真实的成本。

但这次不是一次性购买,而是持续依赖。

不只是钱包的依赖,还有认知上的依赖。

如果一个代码库是循环写的、循环审查的、循环打补丁的、循环维护的,当你失去访问同类系统的能力时,会发生什么?如果切断了最强大模型的访问权限怎么办?成本变得无法承受怎么办?

你和你的团队失去了不借助机器就理解代码的最后能力怎么办?

我们可能会创造出一种代码库,它不只是人类难以维护,而是把AI参与本身当作维护模型的一部分。

这已经在发生,越来越多的人合并自己无法完全解释的代码。

越来越多的人在提 issue 或聊天时,需要先让机器帮他们补充上下文、重新措辞。

越来越多的人通过 LLM 的 Agent 和别人对话。

循环的边界,需要人来划

Ronacher 对 Pi 的定位也在重新思考。

Pi 一直比较谨慎,他认为这种谨慎是对的。

他不想要一个每次交互都变成失控机器群的未来,不想让 Pi 为了赢得"软件自己写自己"的竞赛而变成一团无法维护的混乱。

但 Pi 本身就是一个Harness外壳程序,而外壳程序正处于这些新实验、探索的中心。

任务队列、Agent 编排、子 Agent、持久会话,这些会越来越重要。

即便是对循环有保留的人,也必须开始做这些实验,因为必须理解如何让这个未来有边界、可以存活。

在 Agent 内层循环里,模型说"完成",他来审查,中途也会介入引导,他是参与者,也在学习。

在外层循环里,他不确定自己的角色是什么。

连"完成"这个信号都失去了意义,只是被传递给另一台机器去判断。

他的角色被压缩成了一个信使。

他不喜欢这种感觉,也不喜欢这种方式建出来的大多数代码。

但他毫不怀疑,这个循环的未来,就是我们的未来。

他已经看到规模小得不可思议的团队以不可能的速度在构建,也看到越来越多的代码库变成只有机器才能诊断的晦涩生物。

这些代码库同时有用,又一团糟。

所以他正在接受的,不是"我们会不会循环"这个问题,因为答案显然是会。

真正的问题是:在一个循环的未来里,我们如何不放弃判断力,如何保留良好工程的准则,如何确保负责任的人类仍然能够监督,如何重新思考架构方式,让我们在这条路上不至于失去理智。

这个问题,目前没有人有答案。

但它值得每一个认真做工程的人,现在就开始想。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论