何时使用 AI Agent:从核心架构到扩展功能的实践指南
何时(不该)使用代理
在某些情况下,积极主动地使用人工智能代理(如Codex)是十分明智的选择。而在另一些场合,则应坚决避免使用,如同避瘟疫一般。至于某一特定任务究竟该归入哪一类,其实很难给出一个明确的答案。 任何声称你“永远”或“从不”使用大语言模型的人,都只是对问题进行了过于简单的概括。
当然,对于网络上与大语言模型相关的任何规定性观点,我们都应当抱持相当谨慎的态度。 这包括我本人所要表达的见解。
存在差异
人工智能代理可以带来巨大的帮助。 关键在于“可以”。 并非总是能保证一定有效。
事实上,大多数开发者在接受调查时都表示,他们预计自己的工作效率至少会超过1倍。
换句话说,当他们使用Claude Code或Codex时,往往觉得自己的工作效率至少能提升一倍。 然而,在现实中,代理往往会拖慢你的进度,即便你感觉它们似乎在帮你做事。 事实上,一项由METR进行的研究发现,与那些自认为效率更高的开发者相比,这些代理反而更常起到反作用,而非真正带来效率提升。
在过去几个月里,我通过亲身经历,不断追踪着那些被证明更适合使用代理完成的任务类型,以及那些更适宜仅靠自己头脑中的智慧来完成的任务类型。
我将这些经验总结为一套原则,我相信这套原则能够帮助每一位软件工程师节省大量时间。
本文将介绍其中的几项原则。
你的实际效果可能各不相同
不过,在深入探讨这些原则之前,我想先向各位读者澄清一点:我从事的是高度技术密集型的集成系统开发工作,这些系统往往需要深厚的知识储备。 如果对这些系统进行虚假的修改,而缺乏对系统运行机制的清晰认知,那么最终的结果往往难以预测。
这意味着,许多错误只需短短几行代码就能解决;而许多功能的实现,也只需通过巧妙地将看似毫不相关两个系统连接起来,便能轻松达成。
我的经验未必适用于你,尤其是当你所负责的系统架构相对松散、整合程度较低时。
宁可选择无代理开发
“在我那个年代,我们干脆就叫它‘开发’。”——我在写下上述标题之后说道。
如果你无法清晰地说明为何使用代理能更好地完成某项任务,或是为何代理能更快地完成任务,那很可能是因为你本该亲自动手完成这项工作。
在我最初探索ChatGPT,后来又尝试使用Codex时,我总是在有空的时候,迫不及待地拿起那款崭新的工具。渐渐地,这成了一种习惯。 我常常坐在笔记本电脑前,确定自己想要处理的工作内容,然后不知不觉间,就已经在向某个大语言模型输入提示词了。
“我明白为什么人们很容易爱上这些工具——因为那种充满正向强化的变量式‘牛仔黑客’游戏, 说实话,比第一次就完美无缺地完成任务还要有趣。 ”——Matt Mullenweg
老实说,这些习惯的养成和强化方式并不重要。 真正关键的是,一旦你把使用Codex或Claude Code当作一种习惯,却因此浪费了大量时间。
当然,有时候代理确实能一次就“做对”。 但问题在于:如果代理未能成功完成任务,你往往不得不从头开始,才能最终得到一个切实可用的产品。
我曾花费数小时反复打磨提示词,与代理反复交流,却最终将所有努力付诸东流,转而花不到十五分钟,就自己重新编写出更优的解决方案。
关键在于:如果你无法准确地阐述为何相信代理能以比自己亲自完成任务更短的时间完成工作,那么在解决问题时,最好还是选择不依赖代理。
至少在最初的阶段是这样。
用于大型重构时使用代理
总会有一些时候,你所选用的编程语言本身所配备的专用工具,显然不足以应对各种需求。
我曾遇到过这样的情况:有时需要将一个接口转化为类,有时则需要将一个静态调度的系统改造成动态调度的系统。
这类问题非常适合由代理来处理,因为其逻辑简单易懂,而且大部分改动都只是语法层面的调整。
当时,我手头的Rust和C++专用工具,根本无法胜任这类任务。
当我把代理投入这些问题的解决中时,它不仅完全有能力完成这些改动,还能确保这些改动完全符合我的预期。
事实上,我甚至怀疑,它所做的修改,正是我原本打算去做的那些调整。
至少,我因此省去了不少打字的工作。
换句话说,如果问题的核心部分都是“琐碎的重复性工作”(即“忙活”的事),那就让代理来处理这些事务,这样你就可以把更多精力集中在那些更为复杂的任务上。
核心系统不应由代理来编写
软件核心系统有两个关键要求,而截至撰写本文时,市面上现有的任何代理都无法满足这些要求。
它们需要:
1. 具备灵活性。
2. 充分契合领域需求并加以建模。
灵活性意味着,系统可以在无需过多费力的情况下进行扩展或修改。 你可以独自构想整个系统,未来任何贡献者也能轻松参与其中; 而对小部分组件进行语义上的变更,通常也不会意外地影响到其他小部分组件。
目前,市面上还没有任何代理能够做到这一点。相信我——我曾经亲自测试过它们。
同样地,核心系统架构也需要与所要解决的领域或问题相契合。否则,即使只实现最微小的功能模块,也会耗费过多的精力。
正如灵活性这种难以言喻的特质一样,这一特性同样无法通过市面上代理生成的代码来体现。 这些代理的解决方案要么过于笼统,要么过于直接。 无论哪种情况,最终生成的代码都远谈不上易于扩展。
扩展功能非常适合由代理来完成
虽然核心系统应该以人类的智慧为核心进行架构设计,但对这些系统进行扩展时,却完全可以借助代理来完成。
扩展功能的范围通常较小,受环境限制,且不太可能对其他系统造成影响。
这意味着,扩展功能通常更容易审核,更不容易引入安全漏洞,而且创建扩展功能也不需要深入的思维模型。
这也正是为什么像Telex这样的软件,能够发挥如此卓越的效果。
也正是因此,那些长期与垂直整合系统打交道的人,往往在使用代理时,比在水平整合系统中更容易遇到各种问题。
你的经验如何?
我仍在学习如何以及何时将代理融入我的工作中,就像其他人一样。
我很想知道:你是否遇到过一些特定的问题或错误,而这些问题或错误最适合用代理来解决?在哪些时刻,你觉得自己在没有代理的情况下反而能更加高效地完成工作?
我确信,这里还存在着许多我尚未注意到的细微差别。那么,这些差别究竟是什么呢?