模型写代码的速度两年里从快一半变成快十倍,代码本身不再是瓶颈了,可大家还是把它硬塞进原有的团队和流程里。于是问题变成一个更根本的问题:软件交付里,人的注意力到底该放在哪儿?
Jonathan Ellis 讲了一个他自己的判断:把人按三年前那样一行行读 diff 的代码审查砍掉,因为那纯粹是浪费时间。这是他在那篇关于停止表演式代码审查的博客里做的一部分研究——人工代码审查通常只能发现约三成缺陷,安全问题域大约两成;那些「我抓到过 bug」的记忆之所以让人不肯放手,是因为人脑天生不擅长做这种性价比统计。
Jonathan 上一家公司 DataStax,在那里参与 Apache Cassandra 的开发,现在做 Brokk AI,围绕智能体做工具:静态分析工具 Bifrost、元 harness Mjolnir,以及更贴近现实的编程评测 BrokkBench。这场对话从代码审查该不该保留,延伸到 oracle 和静态分析、harness 与开源维护、初级工程师怎么长大,以及为什么编程评测已经落后于现实。他的主要观点包括:
该砍掉的第一件事,是让人一行行读 diff 的代码审查。 Jonathan 说他做过量化:人工代码审查通常只能发现约三成缺陷,安全问题域大约两成。他并不认为代码审查没价值,而是强调为找这些缺陷投入的时间已经不划算,同样的时间该花到别处去。
代码快十倍,是因为能并行的任务更大了。 每秒生成的 Token 数大多没变,变的是能派给模型的任务规模。他现在用 Fable 同时开十二个任务,每个跑几个小时甚至几天,靠并行和更少的监督把速度拉起来,这也让面向人的流程彻底失效。
应该给 agent 造 oracle,而且用 agent 来造。 oracle 指对某一类问题知道正确答案的判定器。他想把 Coverity 那种水准的确定性分析带进智能体 harness:agent 发起一次工具调用说跑一下释放后使用检查,几毫秒就能拿到答案,而不是推上去让 CI 跑几个小时。
静态分析工具生成一大堆误报,这就是这个领域的本性。 Jonathan 说以前 SonarQube、FindBugs、Coverity 的报告误报太多,大多数团队根本懒得管,他举例说 DataStax 做 Cassandra 时也只有极少的应用。现在可以让模型把报告过一遍、扔掉误报、该修的建工单,过去二十年攒下的研究终于用得上。
模型不是实习生,是每天都在入职第一天的优秀新员工。 Jonathan 引用这个说法,指的是 agent 现在更聪明、代码写得更好,但仍然没有大局观。所以知识库、操作手册、执行计划文档这些人类团队招新人时的最佳实践,现在要写给 agent 看,也顺手回答了两周后、两个月后当初为什么这么干。
这是 Jonathan 给十八岁儿子的原则:例行事交给 agent,别的别交。 他的儿子在学计算机、想当工程师。他说任何你懂怎么做的例行的事都可以让 agent 干,但别把一个你自己都不懂的问题丢给 Claude。他拿心算、笔算和计算尺类比,说手工做过一遍本身有价值,只是这一回这条线被推得远太多,对教育体系是一次思维方式转变。
他引用一句被反复说过的说法:开源维护者最重要的工作就是说不行。 能提 PR 的人从专业开发者变成字面意义上的所有人,很多 PR 提之前没有任何把关,维护者很容易被埋。Bifrost 旗舰仓库干脆关掉 PR、只开 issue,其他仓库没这么做,由维护者用自己的 agent 和 QA 系统把改动推到位。
他记得最新一代编程评测里 DeepSWE 已经饱和。 分数都在 80% 左右见顶,而且它给出的结论是 Opus 5 比 Fable 5.1 强,他认为这不是真的。至于原因是智能体或实验室拿评测集做训练还是评测本身失效,他自己也不确定。最早的 SWE-bench 全是 Python,其中他记得 49% 左右是 Django。
停止表演式代码审查:人的注意力该放到哪
Tobias:你还记得自己最早是怎么进到机器学习和 AI 这个领域的吗?
Jonathan:这个得往前倒很远。我一直很认同一个想法:作为工程师,我们应该能轻松地给自己造工具、把活儿自动化、让自己更高效。这个理念可以一路追到 Richard Stallman、Emacs,还有更早的那些人。所以对我来说最爽的一件事,就是 AI 把这件事给解锁了。
五年前我会说,天哪,我天天泡在 IntelliJ 里,那玩意儿五百万行代码,大得离谱,想给它做点贡献特别吓人。而现在我可以直接说:我真希望 IntelliJ 有这个功能,你去代码里挖一挖,搞清楚怎么做,回来告诉我。不过通常,我觉得正确的做法不是一上来就说你直接给我做出来,而是先回来给我三个方案,咱们一起聊聊利弊,再往下走。反正现在任何我日常在用的工具,我都能用 AI 去增强和扩展,这在生成式 AI 出现之前,从时间投入上根本不划算。Brokk 基本就是这个思路的延伸:我觉得有一堆工具本该存在,但没人在做,那我自己来做。
Tobias:是啊,这个解锁确实很惊人,因为从想法到交付,哪怕只是到原型,速度快了太多。而放到公司的环境里,在一个专业工程团队里,这会产生很多连锁反应,影响大家每天在做什么、时间花在哪,尤其是那些已经存在两年以上的团队。这些人已经养成了固定的工作流和预期,很大一部分是围绕代码审查的,这也正是我们今天要聊的。因为写代码本身不再是瓶颈了,瓶颈就转移到了别的地方。我想听听你怎么看这件事对工程团队的影响,他们会怎么重新理解自己的工作。
Jonathan:对,我觉得在这个问题上,整个行业都是问题比答案多。我当然有我的看法,而且我觉得我们正在慢慢摸索出一些答案。但说实话,事情是怎么变成今天这样的呢?一开始,每出一个新模型,AI 写代码就快一点,再快一点,可大家还是把它硬塞进原有的团队和流程里。就变成:太好了,Jonathan 写代码比以前快了,真好,其他什么都不用改,最多就是他清 backlog 快一点。但现在不一样了,我们从快百分之五十,到快一倍,到快两倍,现在是实打实的快十倍,而且还会更快。
因为现在的新模型,每秒生成的 token 数大多并没有变快,也有例外。真正变的是我能派给它的任务有多大。所以我现在用 Fable 同时开十二个任务,每个都要跑好几个小时,有时候好几天。这就是现在代码生成速度提升的原因:能并行,而且监督更少,不是完全不管,但监督更少了。这就把老范式彻底打碎了,我们再也没法继续用那套面向人的工具、面向人的流程。那接下来怎么办?代码快了十倍之后,软件开发生命周期剩下的部分怎么重新排布?
Jonathan:我先说结论。我认为最先该砍掉的,就是让人花时间一行行读 diff、像三年前甚至一年前那样做代码审查这件事,因为那纯粹是浪费时间。我可以把论点展开讲讲。
Tobias:先给听众一个背景:你写过一篇博客,说现在该停止表演式的代码审查了,链接我会放在节目笔记里。另外我觉得这个时间点上还有一个很有意思的地方:尤其是入行两三年以上的人,他们的一部分身份认同和自尊是跟自己的代码绑在一起的,包括自己写代码的路子,以及各种相互竞争的阵营,什么才算最佳实践、什么才算某个语言或框架的地道写法。我自己见过的一个争议点就是有人说,AI 写的代码不是我会写的样子,所以它就是烂的;或者说它忽略了我花很多时间才练出来的那个习惯,比如本来可以不用一堆 if then,改成一个字典直接查,或者我更喜欢函数式而不是命令式。这些细节说到底其实根本不重要,除非它会影响性能。所以我觉得这也是工程中人的那部分正在被 AI 冲击的原因,因为你得放下那个执念:行吧,也许我根本没读过这段代码,只要它能做到我要的事,这才是我最在乎的。有句话说得挺到位,没人是在为软件买单,大家买的是软件能干的事。那我们工程师为什么还要花那么多时间在自行车棚效应、在那些没完没了的杂活上纠结你的 for 循环怎么写,而不是关心它到底有没有做出客户真正想要的东西?
Jonathan:这点说得很棒,也点出了我在身边这些有才华的工程师身上看到的差别:面对 AI,那些带过、管过人类工程师团队的人,更容易接受你说这些事。因为虽然程度上有差别,我绝对不是说不管理 AI 智能体和管人类团队是一回事,那肯定不是,但有一点是像的:如果你带的是人类工程师团队,而你的代码审查方式是“我不同意你这个 switch 写法,应该用字典去匹配”,那这根本不是有效的代码审查时间。真的不是。所以我觉得,当过团队负责人的人,都经历过这个调整,说服自己去接受:代码在功能上对不对,比它符不符合我偏爱的写法更重要。
Tobias:社区里很多博客和讨论还有另一种说法:大家不再只是单个贡献者了,每个人都要变成管理者,只不过管的不是人,而是智能体。所以你得把自己的抽象层次抬到产品和功能的层面,而不是代码行或者模块的层面。我看到的一个表现是,那些本来就有很强的 RFC 和架构决策记录文化的团队,也就是在真正做出功能之前先写文档的团队,在新格局下更有优势。因为一旦你有了那份 RFC、ADR 或者规格说明,讲清楚了我们到底要建什么,实现就变得自动化了,因为智能体有了大家共同认可的上下文。所以我觉得审查这个动作必须往流程前段挪,你得让更多人参与到设计讨论里来,讨论我们到底要做什么、为什么做,而不是怎么做。只要最终落地的代码能对回最初的设计文档、能拿它来验证,那人类就不必再逐行审代码了,你只要有办法验证它符合当初定下的目标就行。
Jonathan:关于这一点我有两个想法。先说大方向,我们现在都是产品经理了,对吧?我们都在被推向这样一个方向:作为人,我们能提供的价值越来越不在于这个决定怎么落地,而在于我们该做哪些决定,下一步该做什么才是重要的。所以我觉得,如果你待过的组织里这两拨人界限特别分明,工程师就只负责实现另一个团队交代下来的决定,那这种模式恐怕要走到头了。人的时间花在这上面还算有用的时代正在结束,不是说完全没了,但空间越来越小。而且已经能看到终点,就是这些事你都交给智能体,本来就该这样。所以我觉得,那些工程师和产品经理之间边界本来就比较模糊的团队,产品经理现在拿自己的智能体做概念验证,工程师也参与设计讨论,这种状态健康得多,转型起来也会顺利很多。
Tobias:那我们再花点时间聊聊软件生命周期里审查、验证和交付这个阶段。大家一直特别看重人在这一环的作用,说代码上线前必须有人看过,因为只有人知道它到底能不能跑,或者掌握更全面的上下文。可这个说法在 AI 把代码量放大之前就不总成立,因为你要是让一个从没在这个代码库里干过的人做代码审查,帮助很小,除非目的纯粹是让他了解这段代码在干什么、怎么干的。可就算你找的是熟悉这个代码库的专家,他也很容易漏东西;或者正因为他是这个代码库的专家,他自己手头的实现已经忙不过来了,根本不想再为代码审查多花那些精力。但还是得有一些验证和防护机制,这样代码写出来、上线之前我们才有信心,毕竟谁也不想天天因为代码有 bug、跑不起来而到处救火。所以我很好奇,你看到的团队是怎么处理这一块的,需要设置哪些检查和防护,我们才能放心地把人从生命周期的这个阶段拿掉。
Jonathan:这就是你提到的那篇文章引起争议的地方。因为有些原因我自己也不是完全明白,当我像刚才那样说,一年或者两年之后,人就不再手写代码了,大多数人看着我们过去两年画出来的那条曲线会说,是啊,把这根线再往外延一点,大概就是这样。可当我说,那你也不该再去审查它了,他们就直接炸了。就像你说的,人们非常非常强烈地认为,没有经过人阅读的代码就不该上生产。
我写那篇文章时做的一部分研究,就是去看如果你真去研究、真去量化,人工代码审查能发现多少缺陷?答案通常是大约三成的缺陷。如果问题领域更复杂,比如安全,那大概就是两成。所以就发现缺陷这件事而言,人其实并不擅长做代码审查。那为什么大家会有那种反应,说什么没有人工审查我根本不敢上线?是因为我们都记得自己找到过缺陷的那些时刻。这就像我们人类这颗猿猴大脑,天生就不擅长统计思维,它特别擅长记住发生过一两次的刺激事,却特别不擅长评估:考虑到我审查过那么多次都没发现问题,花时间去找出这些缺陷到底值不值。
Jonathan:我的立场不是说代码审查没有价值。我不是这个意思,因为就像我说的,我也和别人一样记得自己抓到过 bug 的时候。我的立场是,为了找那些缺陷投入的时间已经不划算了,那些时间应该花到别处去。现在有更高价值的方式去用这段时间。哪怕我说我需要拿出三成、五成甚至八成的时间做质量保证,就是字面意义上保证代码的质量、保证它做了该做的事,不管你觉得这类问题该花多少时间,都比手工读代码有更好的选择。
Tobias:我举个自己的例子。我至少有一个生产系统,它不面向客户,但面向团队,完全由 AI 写的,我可能一行代码都没读过,结果非常有用,帮了大忙。这个项目是给编码智能体管理团队记忆、任务图和项目图的,做成一张大家都读写得了的共享扁平图,能把上下文切成块,这样你就不用开一个跑三天的会话,生怕把开头放进去的东西都丢了;而且记忆在不同智能体 harness 之间还能通用,而不是躺在你磁盘某个角落的一个 markdown 文件里,指望它哪天不会消失。我也基本绕过了里面的人工审查环节,因为它能跑。我在用,我改,我确认改动达到了我想要的效果,然后就发布。
Jonathan:完全正确。而且我觉得这算是简单的情况,我这么说不是贬低,意思是如果我做的是一个给少数人用的内部工具,出了 bug 天也不会塌,那就直接上线、直接用,发现问题再修。更有意思的问题是,当出了 bug 天就要塌了,或者上线有缺陷代码可能带来非常糟糕的后果时,你该怎么办?现在该怎么做?我觉得开始这个讨论的一个健康起点就是我刚才说的,其实以前靠读代码你也没抓住所有 bug。那么这又意味着,我们不再花在读代码上的那些时间,该拿去干什么?
造 oracle 而不是读 diff:Bifrost 与静态分析
Tobias:我觉得其中一个用法,就是让智能体帮着搭建这些质量门和验证回路,尽早、尽频繁地抓到错误,最好是在提交 PR 之前就抓到。这大概就和你做的工作接上了。我知道 Bifrost 是一个 linter,也是一个 MCP server,它能给出更全面的代码结构视图,让智能体直接拥有这种洞察力,而不用靠一千次 grep 调用去找某个符号。所以我很想听听你在这个方向上投入了什么,以及你还看到哪些团队借着交付节奏的加速,把这些本该早就建好、却因为太占做产品的工夫而被搁置的工作,更多地放进 CI 系统、防护机制和验证循环里。
Jonathan:就像你说的,我在做一个叫 Bifrost 的工具。我对它的理解基本就是 Coverity——一个从 2008 年就有了的静态分析工具,其实我是想说 1996 年。它很老,但非常强大,也非常慢,非常难扩展。它能做的是通过分析数据在程序里的流动,找出像释放后使用这类问题,或者某些类型的并发死锁。
我想把这种水准的确定性分析带进智能体 harness 里:不是那种先推上去、让 CI 跑几个小时再看结果是什么,而是智能体发起一次工具调用说“跑一下释放后使用的检查”,几毫秒就能拿到答案,而不是几分钟甚至几小时。
Jonathan:为了做出 Bifrost 本身,我们一次啃十三种语言。市面上我知道还有别的工具,但我们大概是第一个想一口气覆盖这么多语言的。AI 让这件事变得可行,靠的就是我刚才说的那种并行化。但保证正确性其实还是特别难,语言一多,边角情况就多得吓人。
我最核心的一个思路来自我不久前做的一场演讲:你应该给 agent 造一个 oracle,也就是判定器,而且你该用 agent 来造这个判定器。oracle 是 AI 工程里的说法,指的是对某一类问题知道正确答案的东西,之所以知道,通常是因为我们把这个问题的构造方式设计成答案事先就定好,或者比在完全通用的通用问题空间里更容易推导出来。QA 工程领域熟悉的工具类别里就有模糊测试,也有属性检查器,这些东西 Bifrost 都做了,然后用它们让 agent 去分拣找出来的 bug。
顺便说,这也是 agent 解锁的另一件事:这些技术里很多并不新鲜,模糊测试不新鲜,变异测试也不新鲜,我也没有多有创造力。真正新的是接下来的变化。
Jonathan:在 AI 之前,你手上有个 SonarQube、FindBugs、Coverity,或者任何这类静态分析工具出的报告,它们会生成一大堆误报,这就是这个问题空间的本性。所以大多数团队根本懒得管,除非你在一个极其敏感的领域,一个 bug 流出去就是灾难性的,那种情况下花时间去用这些工具才划算。
但即便在我上一家公司 DataStax,我们在那儿做 Apache Cassandra,苹果、Netflix 这些公司都在用它存他们极其在意的数据,我们对这类静态分析也只有极少的应用,因为误报实在太多了。
Jonathan:但现在你可以直接告诉 Opus 或者 Sonnet,或者你选中的任何模型:把这份报告过一遍,把误报扔掉,该修的建工单。这一下就解锁了软件工程研究者过去二十年想出来的那么多东西——以前没人用得起,要么没时间去实现,要么投入根本不划算。
而现在,免费的已经不只是代码了,或者说几乎免费了;看这些工具的输出,现在也免费了。
把时间花在造工具上:harness、元 harness 与开源维护
Tobias:既然现在这么多活都能自动化,总有个老问题,就是拿着锤子到处跑,看什么都像钉子。所以我很好奇,你看到的人类时间投入回报最高的地方是哪些?有没有什么好用的启发式,能判断哪些地方 AI 最有用、最有效,哪些地方我得用自己的判断和推理?这或许也能引出另一个话题:如果有人职业生涯还早,没经历过 AI 之前那一代人走过的那些痛苦的学习路径,我们怎么帮他们建立这种知识和推理能力?
Jonathan:这是两个很不一样的话题,但都挺有意思。先说第一个,你怎么决定时间花在哪儿?对我来说,时间最好的用法就是刚才说的,造更多的 oracle,以及造驱动它们的 harness。
就像我说的,我不是个特别有创造力的人,所以我直接去问 ChatGPT 或者 Claude。我开新项目的方式就是先问:过去二十年软件开发或者软件工程研究里,有哪些最有意思的研究思路可以用到这个项目上?按你估计的性价比排个序。然后就从那儿开始琢磨怎么把它们做出来。
Jonathan:另一件值得花时间的事是把工具做得更好。我刚说的那些东西,我们都有 Bifrost 专用的 harness 去驱动。不是简单地在 Codex 里敲一句「帮我做个差分分析」,而是造一个系统,把它当成每晚跑的任务,然后给我一份报告,再让 Bifrost 那个 agent 过一遍,挑出真正的缺陷。
这也可以细到微观层面。Bifrost 是给 agent 用的工具,所以我们很多工作是去看模型尝试使用 Bifrost 工具的轨迹,找出哪些地方工具没帮上预期的忙。我们做的一个很底层的东西,就是解析 Codex 里跟 Bifrost 工具调用有关的轨迹,把相关上下文抽出来,这样 Astra 每次做这类活的时候不用重新造轮子。往高了说,还可以是 Mjolnir 这样的东西。我做了一个类似元 harness 的东西,或者说是 harness 的 harness,这样我可以把 Codex、Anthropic、Kimi、GLM 这些订阅都放在一个界面里,随时掌握不同 agent 在干什么。
Jonathan:你还提到了另一个问题,初级工程师怎么提升自己。如果你想往这个方向聊,我们也可以聊聊。
Tobias:对,我觉得这也是个有意思的角度,因为大家都在问这个问题。不少人试过给答案,但我还没看到有什么标准成型,说到底我们究竟该怎么做到。不是说 AI 之前我们做得有多好,但现在可能机会更少了,也可能换个角度看机会更多,因为初级工程师能做成更多事,但他们手里也握着一把更大的枪。对问题理解不到位,潜在的爆炸半径可能更大。
我觉得人类可以花时间的一个方向,就是接上你刚才说的挖掘 agent 轨迹、看它怎么发出对 Bifrost 或者其他工具的调用,这是为了避免把大量算力和 token 浪费在五十个不同的 agent 会话里重复走同一条路,同时也给初级工程师留个地方去看,什么是最佳实践,这类问题我们怎么处理。办法就是引入各种技能文档:它既帮 agent 干活,同时也是一份产物,人能去看,理解做这件事的方法是什么,以及我们为什么这么做。只要你真的花时间去看,这就是一个共享的知识库。
这其实也是我和我团队一直在投入的另一个方向:每次我又得按某种特定方式做某件事,我就说,行,那我们把做过这个工作流的所有会话翻一遍,把它沉淀成一个技能,下次我想做这件事直接触发就行。一个例子就是代码审查,因为我会开一个来自我的 agent 的 pull request,然后让另一个 agent 去评审,最近用的是 Copilot,不过哪个 agent 都行。然后我有一个技能叫「处理 PR 反馈」,它会自己跑一遍,找出所有评论拉进来,评估并做必要的修改,然后回复关闭这些评论。这样我就能在写代码、拿到反馈、处理问题之间来回迭代,而不必在这一切做完之前就牵扯到人——除非我说,这个改动足够大,我想让另一个人看看我整体的方案和设计对不对,再真正合并上线。
Jonathan:对,有人这么说。有那么两三年吧,我觉得我们大体上已经过了这个阶段,但确实有那么几年,大家说 AI 就像一个实习生,还算聪明,但犯很多错,而且不知道自己不知道什么,所以你得盯紧点,那是他们对 AI agent 的心智模型。现在 agent 更聪明了,代码写得也更好了,但还是没有大局观。所以有人说——我忘了是谁——现在更好的模型不是实习生,而是一个很棒的新员工,只不过每次你跟他说话,都是他在公司上班的第一天。
这就把我们推向了你说的那些东西,那些在人类团队里本来就算最佳实践的东西,至少是经常招新人的团队:你得有这个知识库,还得有一套操作手册,让这些新人能搞清楚现在是什么状况,我们已经做了哪些决定、不用每天再翻来覆去地重新争,我们那个又大又难的目标是什么,我们到底想建什么、为什么,我们在解决什么问题。
Jonathan:当然,区别在于:以前维护这套东西,那真是难上加难,所以大多数团队做得都不够好。现在我可以直接说,行,Fable,把咱们干了什么、踩了哪些死胡同都记下来,放进我们那套计划文档里,下次就不用重新推一遍。
至于怎么存,后面可以聊。我不太认可纯文本文件,我是数据库出身的,所以我觉得有比一个满是 markdown 文件的目录更好的方案。但我们现在大概就在这个水平上,就是 markdown 文件。它还挺好用的,早晚你会超出它的能力,但它确实挺好用,甚至可以说,就它这么个东西,好用得有点出人意料。
Jonathan:说个特别实操的点,有件事对我们特别管用。OpenAI 差不多一年前写过一篇文章,我记得是 25 年 11 月,反正是 25 年年底。他们写了一篇讲 exec plan 的文章,说用执行计划文档来驱动智能体做更长的任务。文章的框架是给你一套结构,告诉你计划文档怎么写,以及怎么让你的智能体自己写出它能照着执行的计划文档,从而在耗时几小时甚至几天的任务里不跑偏。
要记得那是多久以前:当时 GPT-5.1 应该是最强的,因为 5.2 是十二月才出的,这肯定在它之前,Opus 大概还是 4.5。这两个模型算是我们现在这个新智能体时代的开端,但它们都特别容易走神,也都挺懒,你给个大任务,它们做完第一部分就停了,你要是只说一句斜杠 goal、去做这个大任务,那它们就彻底天马行空了,压缩上下文的效果也差。所以 OpenAI 说,用这套计划文档的思路,让它们在长任务里跨过一次次上下文压缩还不跑偏。
现在我们基本上不太需要计划文档来干这件事了,或者说在 harness 里敲一下斜杠 plan 就够了。但我们还在写执行计划文档,因为还有另一类问题,就是两周后、两个月后,我们当初为什么这么干。执行计划文档能把这件事记下来,而且这种方式比把说明塞进代码注释里更贴合智能体干活的方式。因为种种原因,它们走查代码用的是 grep 和 sed 那一套,知识里是有洞的,很容易漏掉那种注释。但如果你有一个文档说,我们所有的计划都放在这儿,想弄清某件事为什么这么做就去看,那效果就好太多了。
Tobias:对,架构决策记录也是同理。它记的是设计,以及我们为什么选择这么做,人类也能看。这个东西其实在 AI 工作流之前就有了,给新加入公司的人用——他们正好在代码里那团没人敢碰的角落干活,心里想,这我知道怎么修。然后就会有那种段子,我肯定见过,有人说,行,每次你觉得能解决这个问题,就给它加一,看看在你之前到底有多少人试过,最后还是绕回原来的方案。
Tobias:说到这个,说到数据库是这类数据更好的结构,这也是我为什么自己做了一个工具,用来做我的共享智能体任务和记忆的上下文。它其实用了一个叫 OmniGraph 的存储层,底层用 Lance 作为存储格式,但在上面建了一个图。这样项目、任务、记忆之间就真的有连接关系,可以从一个跳到另一个;而且记忆还能被新版本取代,你了解得越多,就能拿到最新的,同时还能回溯,看看当时我们是怎么想的。这也是个挺有意思的角度。
Jonathan:那你得去看看这个。我有几个朋友做了家公司叫 Vectorize,他们的主打产品叫 Hindsight,基本上就是给智能体做的基于图和嵌入的记忆,在 GitHub 上有。我觉得你可以去看看,至少里面有些想法可能挺有意思,能互相借鉴。说不定你看完会说,哦,我不用自己维护了,直接用别人的,人家是全职做这个的。
Tobias:对,我一定去看看。这也是我们现在这个时代另一个有意思的地方:有大量的人在解决相邻的问题,或者用稍微不同的路子解决同一个问题。软件工程智能体,或者特定工作流的智能体,到底需要哪些概念和基础构件,现在正处在一次大爆发里,就是那种百花齐放的心态。所以挺有意思的是,两年之后会是什么样,等市场开始收敛到大家都认可有用的一些基础构件上,收敛到那么两三种正确的做法,那些现在正在发布的一大堆工具和产品会被怎么收掉。
Jonathan:对,我觉得是这样。而且我觉得这件事我们得集体稍微有点自觉,因为对我来说,我想对很多工程师来说也是,每当我看到有人在卖一个东西,我心里想,哦,这个我会做。从我会做到那我也应该做一个,这个跨度特别特别小,尤其是当我自己能做的东西就不用花钱买的时候。但 AI 写代码的好处是,自己做一个比以往容易太多了。
我觉得这也意味着有个陷阱,就是看不到水面下冰山的其余部分。做出原型一个周末就够了,但维护它,还有处理团队提的功能需求,那接下来半年会是个大坑,哪怕真正写代码的大部分活是 AI 干的。所以我觉得,我自己肯定也这样,希望我在 Mjolnir 上没掉进这个陷阱——自己造东西是很有诱惑力的,但不总是对的选择。
Tobias:这就是内容管理系统或者静态站点生成器的时代,每个人都说,哦,这问题简单,我自己写一个。然后做到百分之八十,说,哦,我快做完了。接下来所有时间都花在剩下那百分之二十上。
Jonathan:这个类比太贴切了。我自己也写过静态站点生成器。
Tobias:所以这就是另一个有意思的方面:我们现在处在什么位置,你怎么决定哪些事、哪些地方值得花你有限的人类注意力。因为就像你说的,说一句「哦这个我会做,我给自己做一个吧」太有诱惑力了,但结果是我越来越多的时间沉在这个衍生出来的玩具项目上,它可能有点用,但它让你偏离了你真正拿钱要达成的更大的目标。如果是当爱好、业余时间做着玩,那没问题。但还是那句话,爱好这东西你能有几个,多了就会占掉你越来越多的生活。
Tobias:我觉得这个问题还有一个层面,超出智能体软件工程的范畴,是整个更大的智能体生态。当智能体越来越多地接手日常事务,处理我的邮件、管数据摄入流程、在数据出问题的时候去修,或者根据用户提的需求去构建和迭代产品,那人类的角色是什么?这就回到开源维护者已经面对了好些年的那个问题:人类的判断。有人能提一个功能需求,不等于这个功能我愿意负责。
Jonathan:不,这话百分之百对。还是那句话,我不记得是谁先说的,可能很多人说过:开源维护者最重要的工作就是说不行。这话五年前就对,而现在更是如此。
顺带说一句,我在 GitHub 上用的那些库,凡是开着 PR 的,我都特别感激。就在昨天,我还给 Brokk 在用的两个库提了 PR,两组都被采纳了,能这样出点力我挺高兴的。但我不觉得这事能规模化,不能一有问题就是,行,我扔个 PR 上去。因为很多人提 PR 之前,根本没做我们说的那种审查。所以开源维护者很容易就被埋了,他们得去给那些几乎没人把关、由 agent 写出来的 PR 挨个反馈,有时候提 PR 的人还不是职业开发者。
所以一方面,我不是来设门槛的。AI 让非专业开发者也能量产出工具,把数字世界里的生活变好,我觉得这特别好。但另一方面,能给一个产品提 PR 的人,不再是专业开发者,而是字面意义上的全世界所有人,那确实需要再有一道门槛,来缓解维护者的过劳。
Jonathan:所以我们在 Bifrost 上的做法是,我们其他仓库都没这么干,只有旗舰的 Bifrost 仓库,我们把 PR 关掉了,issue 是开着的。你遇到问题或者想要个功能,就开个 issue,但让我用自己的 agent、自己的 harness、自己的 QA 系统把它往正确方向推,比我跟你来回跳这个舞要快得多,不然就是「喂,你能不能改一下」,跟贡献者这么来回,可能要好几天。
我觉得这挺可惜的,因为开源生态、社区建设、培养下一代,这些从我们过去那套做法里长出来的东西都是好事。但历史上也有先例:八十年代 Richard Stallman 创办自由软件基金会的时候,并不是 GitHub 那种大家都来贡献、我们一起把它建起来。他非常坚定地相信,到现在也依然相信,源码必须可得,这样你才能改动,才有这个自由。但八十年代的 FSF 不接受外部贡献者的补丁,那更像我们今天说的共享源码,而不是开源。我觉得我们正在往那个方向走。
Tobias:对,我确实听过好几个别的开源项目也走这个模式,就是你可以开 issue,然后我把这个 issue 丢给我的 agent 去改代码,因为就像你说的,PR 本身要花的时间和沟通成本高多了。
所以我觉得,作为行业,我们该想的一件事是:当 AI 成为主要的执行者,我们的工作流要怎么围绕它来调整。其中一点就是把对人的判断力的要求更多地写进流程里,并且强制执行。不要只是给 agent 一个目标说,去把这个建出来,而是逼它来问你为什么,问我们真正想达成的到底是什么。这其实也是个老问题:我可以直接跟员工说,去把这个建出来,他就会开开心心地照做,因为大家觉得我是专家,但也许我在这一块根本不懂。所以要让这种反问更多一些,让人更多地参与到端到端的交付里来——我们到底在建什么?为什么要建?
初级工程师怎么长大:辅助轮、蒙眼推演与象棋类比
Tobias:所以,有些事是需要在把它推向世界之前想清楚的。而且可能就像你说的,问题 X 已经有五十个不同版本了——agent 记忆、编码 harness,这个时代翻来覆去就是那么几个。那就先去看看,有没有哪一个已经解决了我以为我在解决的那百分之九十的问题?也许直接用现成的就好,别再自己造一个了。
Jonathan:我还想回到你前面说的培养下一代。我们聊过 onboarding agent,是类比成 onboarding 新人的,但那跟另一个问题不太一样:怎么让一个刚毕业的大学生成长到能像你一样有效地监督 agent。这个我确实没有好答案,我还指望你有呢,或者至少我们能一起想出办法来。
目前我能想到的最好的办法是,我那个十八岁的儿子现在在学计算机,他想当工程师。我跟他的原则是:任何你懂怎么做的、例行的事,你都可以让 agent 干,但别用它干别的。别把一个你自己都不懂的问题丢给 Claude,说帮我解决一下,因为那你就是在亏待将来的自己,让他少了这份理解。这方面其实有点历史先例——我们教孩子心算、笔算,尽管计算器已经存在很多年了,在更早之前还有计算尺。
Jonathan:所以这里面是有价值的。我们已经形成了一些模式,说明这件事手工该怎么做,以及为什么手工做有价值,哪怕我们早就已经会自动化了。但这一回,那条线被推得远太多了:哪怕读到研究生,你还在手工做那些我们本来已经可以用 agent 自动化的事。这对我们的教育体系来说,至少是一次思维方式的转变。
Tobias:放到软件工程团队里,可能有个想问题的角度,尤其对职业早期的人,或者在一个陌生领域补课的人,就是辅助轮这个思路。harness 和 agent 会干活,但也许要等你能把问题空间和你想过的东西说清楚之后,它才动手。等你在某个领域越来越熟练,它也会调整,说,行,你在这个领域已经证明过自己了,那我就照你说的做。就像我们在工作里靠能力证明自己、然后升职一样。让 harness 多顶回来一点,别把它收到的每条指令都照单全收。
Jonathan:另一个让我稍微乐观点儿的类比是国际象棋。人类最后一次是世界最强棋手,已经是三十年前的事了。1997 年深蓝赢了 Garry Kasparov,那是复赛——我记得第一台深蓝在 96 年是被他赢下来的,后来他们回去改算法、扩硬件,复赛才赢回来。今天当然不用 RS/6000 那种超级计算机撑着了,我手表上的算力都够赢下除最强人类之外的所有人。
但就算这样,下棋主播现在还是 Twitch 上最受欢迎的一类内容,而且越来越火。所以空间是有的:哪怕机器比人强,人还是愿意去比、去在这个领域里进步,这件事依然有用、依然有意思。当然,在更偏体力的领域,机器比人强已经两百年了,我们还是跑去健身房把自己练得更能打。我不属于那种觉得 AI 什么都比人强、那我们干脆放弃算了的阵营。我觉得哪怕机器比我强,人自己做这件事仍然有价值。但没错,世界不会是原来那样了,也回不到原来那样。所以,会很刺激。
Tobias:而且人类永远有角色可演,因为不管我们用多少术语、这个生态里长了多少泡沫,这些大语言模型、这些各种各样的深度学习模型,本身是没有自主意志的。它们是我们指向某个方向的工具。所以你仍然需要人的判断,决定我想让它往哪个方向走,而且你要理解:一是它有什么能力、我为什么要往这个方向走,二是要有足够的知识判断自己有没有达成那个目标。
Jonathan:这个我就不确定了。今天是这样,明年也肯定是。十年后还是吗?我们会不会有一天能跟 Claude 14 说:写个循环,自己去找下一个该建的东西。这是我的目标,这是我想做出来的东西,你就循环着把下一个更接近目标的东西建出来。我们会走到那一步吗?这个我比较不确定。
Tobias:但就算在那个例子里,目标也还是你定的。AI 不会跑来告诉你你的目标是什么。我是说,也许有时候它会,但作为人,你仍然拥有模型本身没有的那种能动性。
Mjolnir 与 Bifrost:元 harness 和建在 Git 之上的数据库
Tobias:好,这个话题聊完了。我想绕回你正在做的东西。你现在重点投入的这条工具链,你见过最有趣、最有创意或者最出人意料的用法是什么?就是 Bifrost、MuleRun,还有我记得你也在做一个叫 Anvil 的东西。
Jonathan:对。Anvil 我们现在已经降级处理了。Mjolnir 就像我说的,是个元 harness。在这个语境下它的意思是,我们直接驱动 Codex、Claude Code、Kimi Code、GrokBuild 和 Muse Code,从 Mjolnir 展示给用户的那个文本界面直接驱动它们,走的是一个叫 ACP 的协议。ACP 当初被造出来,是为了让你能把 Claude Code 塞进 IntelliJ 或者 VS Code 里,但底层还是 Claude Code,不是另一套 harness。
所以 Anvil 当初的想法是,我们对 harness 本身有些有意思的设计思路,那就自己做一个 ACP 服务器,这本来就是 harness 的角色。但随着模型越来越成熟,它们开始根据你会话里正在发生的情况来做事。我就想,这种程度的集成,我不觉得自己能跟那些大实验室竞争,所以 Anvil 就被降级了。我确实认为,在 Codex、Claude Code 这一层之上,Mjolnir 是有附加价值的。
Jonathan:举个你问的那种例子,什么让我觉得意外或者骄傲:我们刚给 Mjolnir 加了个功能。Mjolnir 里有工作区的概念,会话属于某个工作区,你可以在会话之间切换,看看进展。我们加了一个给子智能体用的虚拟工作区,所以你可以有 Codex 的子智能体,点一下那个写着六个子智能体的标签,就会打开一个虚拟工作区,你能看到里面在干什么。这些子智能体不必来自同一套 harness。
所以你可以让你的 Fable 去驱动一个 Luna 子智能体,这是用 Fable 非常省钱的办法,因为 Luna 真的非常非常便宜;或者驱动 DeepSeek Flash。昨天我就让 Fable 驱动六个 DeepSeek Flash 子智能体一起解一个问题。这属于订阅优化那一套玩法,我的 Fable 额度比订阅的另一半值钱多了,另一半在 Anthropic 那边只能让我用 Opus 和 Sonnet。所以在元 harness 这一侧,让我兴奋的是把我手上不同的订阅拼起来用,把它们的价值释放出来。
Jonathan:然后在 Bifrost 这一侧,这就要深入到技术细节里了:我们基本上是把 Bifrost 的数据库建在 Git 之上。Bifrost 数据库的主键就是 Git 的 blob ID,也就是 Git 索引里那些内容的哈希值。这解锁的是什么呢?如果有十二个智能体在十二个工作树里同时改东西,我只需要重新索引那些新的、从没在任何工作树里出现过的内容,任何在别处已经存在过的东西都不用重新索引。所以新建一个工作树、在 Bifrost 里索引它,是瞬间完成的,因为那些 blob 早就存在了。
接下来它解锁的是速度差异:我可以在编码会话中途就问 Bifrost,我有没有犯下并发方面的罪,让 Bifrost 的策略引擎直接抓出来,而不是跑几个小时的 CI。因为我只需要重新索引那些自上次索引以来真的被改动过的部分。
Tobias:你在这个领域做了这么久,一直在琢磨人类参与这个由智能体主导的软件交付生命周期,最有效的方式到底是什么。这过程中你学到的最有意思、最意外或者最难的教训是什么?
Jonathan:我大概要稍微推翻一下自己的标准说辞了。因为最让人抓狂、最难的部分在于,我们前面说的「智能体现在写代码太强了、不需要审查它们的产出」,这话平均来说是对的,但总有边角情况。我们 Slack 上的玩笑是,我大概还没被淘汰,因为你总能不断找到那种地方。
比如 Fable 认定我真正需要的是克隆。Mjolnir 是用 Rust 写的,它认定我真正需要做的,是我每往那个会话里追加一条新消息,就把整个会话克隆一遍。所以我就想,我的 Mjolnir 进程为什么老把时间花在内存重映射上?哦,因为你的内存分配高到天上去了。我就想,都 2026 年了,我还得去告诉 Fable 这种内存分配方式不行吗?
我真心觉得我不该说这话,但这事上我确实说了。所以是的,边缘还是毛毛糙糙的。但我确实认为,长期看它是持续向上的。到某个时候——不是今天——到某个时候我们就不用再操心这些了。
Tobias:是啊,模型真的特别擅长自信地犯错。
Jonathan:对,这点还是成立的,没错。
评测落后于现实:真实工单上的烘焙对决与缺口
Tobias:在大家重新安排整体工作流、重新思考人类在软件生产中扮演什么角色的时候,你为未来的工具、文章或者实验都规划了些什么,来帮我们这个行业往某个定义下的好方向走?
Jonathan:先说一个很具体的层面:让我很郁闷的一件事,还是模型评测的现状。我说“还是”,是因为2025年评测编程模型的最先进水平就是SWE-bench。最早那版SWE-bench百分之百是Python,其中很大一部分——具体数字我记不清了,49%左右——是Django。他们的题目全都取自十年跨度里的GitHub工单。所以SWE-bench分数高,基本上就是看你的模型把Django背得多熟,外加一点scikit-learn,再加几个别的Python包。
所以我写了BrokkBench,做更贴近真实的编程挑战。今年年初,我们算是有了下一代编程评测,尤其是DeepSWE、CursorBench,还有Frontier Suite,我记得是另一个。有两三个现在做得还不错,我就说,行,那我不用自己搞了。但最近这几个月发的几版模型之后,DeepSWE已经饱和了,所有分数都在80%左右见顶。而且它告诉我的结论是Opus 5比Fable 5.1强,我知道这不是真的。它测的那个东西,已经不如半年前有用了。我不知道是因为这些智能体或者实验室在拿这个评测集做训练,还是它本身就没那么有用了。
Jonathan:所以我最近这两周在做的事情是,我拿Bifrost上真实的工单,一次让两三个模型做烘焙对决,然后让Fable和Astra来评判结果。这样我基本上会得到一系列两两排名,覆盖几百个任务,针对DeepSeek Flash、GLM 5.3和5.3 Flash、MuseSpark、GrokBuild,基本上就是你可能想用的所有模型。那种时候你会说,哎呀救命,我的Claude订阅额度用光了,我现在能用什么,既不会把钱包掏空、又能帮我把事做完?这基本上就是我想回答的问题。第一批结果这周末之前应该能出来,最晚下周。
Tobias:你在Brokk AI做的这些工作,还有你投入的这几条工具链,或者就说这个更大的问题:在AI生成一切的世界里,我们人类的注意力到底该放在哪、怎么放最好?还有什么我们没聊到、你想在节目结束前补充的?
Jonathan:我在Brokk AI的目标就是到达你前面说的那个理想状态:我们人类把时间花在决定要做什么上,少花在检查模型到底有没有按我说的做上。这就是我们想用Brokk做出来的东西。
Tobias:好。那想联系你、想跟进你和团队工作的人,我会请把你的联系方式放到节目说明里。最后一个问题,我想听听你的看法:今天要构建AI系统,你觉得工具、技术或者人的培养上最大的缺口是什么?
Jonathan:我觉得最大的缺口是面向智能体的协作工具。我们有GitHub,那是面向人的;我们有Linear,也是面向人的,它在适应智能体这件事上大概比GitHub快一点。但我想要的是这样一个世界:我提一个工单的时候,系统里能有人说,这段代码跟agent 345上周写的有关,把那个session在合适的harness上恢复起来,跟它说,你把这里搞出回归了。这样上下文它全都有,不用再重新摸一遍。把生命周期上这些环节都串起来。谁要是做出来这个,我明天就当他的客户。
Tobias:好,非常感谢你今天抽时间跟我聊,分享你在这个飞速变化的领域的看法、观点和专业判断,聊的就是人类现在该做什么。谢谢你为此投入的时间和精力,祝你这一天剩下的时间过得愉快。
原节目:Data Engineering Podcast《What Do Humans Do Now? Rethinking Software Engineering in the Age of AI Agents》
https://www.aiengineeringpodcast.com/agentic-software-engineering-human-judgement-episode-81
中文播客:在小宇宙App搜《硅谷对谈》,或直接访问下面的链接
https://www.xiaoyuzhoufm.com/episode/6ad29130641ef406308cd3b0
编译:磊哥Thomas

