随着AI代理承担越来越多的实现工作,从产品决策到生产交付,这八个软件工程领域变得愈发关键。
AI translation, not an official translation. Refer to the original for technical details.
Adapted from @bibryam# 8本因AI而更具价值的软件书籍 ## AI如今已能编写大量源代码。那么,哪些软件工程书籍依然重要? AI可以生成一个服务、其测试代码以及部署文件。在这一过程中,它会对业务规则、数据、依赖关系和错误处理做出各种决策。其中一些决策可能适合你的系统,另一些则是没有人认可的假设。 这正是我认为在使用编码代理时理解以下八个领域至关重要的原因。你委托给代理的实现越多,就越需要辨别哪些决策是合理的,哪些需要重新审视。当你能生成大量代码时,懂得什么是好软件就变得更加宝贵。 下方的路线图按照从产品决策到生产交付的顺序梳理了这些领域。这些书籍阐释了背后的理念,尽管其理论基础早于当今的编码代理。 ## 决定什么值得构建 《Escaping the Build Trap》挑战了将已交付功能视为进展的习惯。Melissa Perri对输出与结果的区分,让工程师有理由在讨论如何构建一个功能之前,先质疑是否应该构建它。工作的起点是客户或业务需要发生什么改变,其次才是改变已经发生的证据。(https://www.amazon.com/dp/149197379X) AI让这一区分更难被忽视。代理可以在任何人弄清楚用户是否真正需要之前,就把一个需求变成一个令人信服的原型。原型一旦存在,就很容易继续优化它。风险在于:你可能会在构建一个无人需要的东西上变得极为高效,同时将每一个生成的功能都视为进展的标志。 ## 就"正确"的含义达成共识 《Specification by Example》解决了一个常见问题:人们可以在字面上认同一个需求,却在脑海中想象着不同的行为。它将产品经理、领域专家和工程师聚集在一起,共同梳理具体案例。"客户可以取消订单"会演变成一场关于已发货订单、部分发货以及已收款项的讨论。(https://www.amazon.com/dp/1617290084) 使用编码代理时,一个未解决的解释歧义可能同时成为实现代码和用于验证它的测试代码。一切测试都能通过,因为两者共享同一个假设。独立于生成代码之外达成一致的示例,为代理提供了一个可以检验其工作的参照。这使得本书所倡导的协作方式尤为重要,即便实现和测试示例的工具已经发生了变化。 ## 让业务含义显式化 《Learning Domain-Driven Design》帮助团队将业务知识转化为软件模型。统一语言为人们提供共享术语,而限界上下文则界定了某个特定含义的适用范围。计费和履单可以对"订单"有不同的规则,而无需将两者强行合并到同一个模型中。(https://www.amazon.com/dp/1098100131) 大型语言模型可能了解你所在行业的通用语言,却不了解你组织内部的例外情况。当代理在具有相似数据结构的服务之间复制代码时,可能会将错误的业务规则一并带入。领域术语、清晰的边界、类型定义和测试,有助于让这些差异变得可见。它们为代理提供了比一堆业务含义需要猜测的文件更有用的上下文。 ## 选择适合系统的架构权衡 《软件架构:艰难的部分》审视了将系统拆分和重新整合所带来的后果。服务边界、耦合、数据所有权以及分布式事务相互影响。一个让部署更容易的选择,可能使一致性或恢复变得更加困难,因此答案取决于系统的约束条件。(https://www.amazon.com/dp/1492086894) 编码智能体降低了创建新服务的成本,但网络调用、协调机制以及故障模式依然随之而来。这可能让分布式设计看起来比实际更廉价。同样的问题也会在后续变更中出现——当智能体删除一个在局部看起来多余的边界时。理解其中的权衡,有助于解释该边界存在的原因,以及某项拟议变更是否真正是一种改进。 ## 理解你的数据保证 《设计数据密集型应用(第二版)》阐释了隐藏在数据库与消息传递 API 背后的决策。复制、事务、一致性、排序以及模式演进,决定了应用程序能够向用户承诺什么。无论何时复制、处理或读取数据,只要系统正在发生变化,这些保证就至关重要。(https://www.amazon.com/dp/1098119061) 智能体可能会修改一个模式,并更新其所能看到的每一个消费者,而旧版客户端、已存储的事件以及派生索引仍依赖于原有结构。代码仓库看起来可能是一致的,而更广泛的系统实际上已经不兼容了。正是在这里,理解数据系统变得更加重要:生成集成代码并不能确定哪个状态是权威的、数据需要多新鲜,或者当一条更新到达两次时会发生什么。 ## 识别威胁与信任边界 《威胁建模:面向安全的设计》提供了一种结构化的方法,用于理解系统中可能出错的地方。梳理数据流和信任边界、识别威胁并检验所提议的控制措施,使安全成为设计讨论的一部分。它同时也揭示了关于谁可以访问什么、以及他们可以执行哪些操作的各种假设。(https://www.amazon.com/dp/1118809998) 编码智能体可能在拥有 shell 访问权限和凭据的同时,读取不可信的 README 或工具响应。提示注入可以影响它如何使用这些权限。该书早于这些攻击出现,因此需要与更新的安全指南配合使用,但其底层问题依然适用。提示可以引导模型的行为,而强制执行的权限则在行为出错时限制了可用的操作。 ## 为生产故障做好设计 《发布!(第二版)》解释了局部问题如何在运行中的系统中蔓延。线程阻塞、依赖项响应缓慢以及容量不匹配,可能将一次故障演变为全面中断。超时、熔断器、舱壁以及背压等模式有助于遏制损害,前提是其行为与系统相匹配。(https://www.amazon.com/dp/1680502395) 当智能体被要求修复一个失败的 API 调用时,它可能会添加一个重试循环,却没有注意到客户端库本身已经在重试。代码看起来更具弹性,实际上却将请求成倍地压向一个已经举步维艰的依赖项。这正是为什么熟悉某个模式的实现方式只是工作的一部分。在接受生成的修复之前,我们还需要理解该模式对负载、时序和恢复的假设。 ## 改善整体交付流程 《Accelerate》审视有效软件交付背后的实践与条件。小批量交付、持续集成、部署自动化、松耦合架构以及学习型文化,有助于变更安全地推送至生产环境。吞吐量与稳定性本就应放在同一个维度下讨论。(https://www.amazon.com/dp/1942788339) 多个编码智能体可以并行工作,而团队仍只有一个审查队列。更多生成的代码可能意味着更多积压在审查中的工作、更大的变更规模,以及更困难的集成过程。我会以变更能否更快到达用户手中、部署后运行是否更可靠来评判 AI 的采用成效。生成的代码行数和被接受的建议数量或许能描述工具的使用情况,却无法告诉我们交付是否真正得到了改善。 ## 从哪里开始 从你的团队最缺乏清晰认知的领域开始。这些书之所以有价值,是因为它们能帮助你对那些生成代码可能掩盖的决策进行系统性思考。 你会向这份书单中补充哪本软件工程书籍?为什么 AI 的出现让它变得更加重要? 在此阅读完整文章 https://generativeprogrammer.com/p/8-software-books-ai-has-made-more