别再乱用AI辅助编程了,收下这份超实用指南

2025年6月11日

作者:Atharva Raykar。一位经验丰富的软件工程师和博主,专注于 AI 辅助开发与系统思考,致力于通过其深厚的技术洞察力,指导团队构建高质量的软件产品。

对于那些致力于打造精心设计、品质卓越产品的严谨工程团队而言,人工智能是不可或缺的。这要求我们熟练运用这些工具。十多年来,我们一直执着于构建高质量的软件,这促使我们深入探索如何利用这种新的构建方式来创造出更优秀的产品。

借助人工智能进行开发,速度得以显著提升。这种速度上的优势至关重要,因为它能帮助团队更快地与用户建立反馈循环,从而打造出更出色的产品。

然而,人工智能工具的使用颇具技巧。如果使用不当,不仅可能产出平庸的结果,更糟的是,还可能让项目充斥着粗制滥造和技术债务,反而拖慢开发进度。

这本活的行动手册,是我们基于在实际生产软件开发中与人工智能工具打交道的经验总结。在真实环境中,没有任何团队能承担得起"凭感觉"行事的后果。我希望其他团队能从我们的发现中学习并受益。

人工智能是一种倍增器

要充分发挥人工智能的效能,首先要提升自身能力。人工智能是一个倍增器。如果你自身能力不足,收获将微乎其微;如果自身能力是负值,那么结果将是负面的。

我注意到,最优秀、经验最丰富的工程师能够从人工智能工具中汲取更多价值。原因有以下几点:

  • 他们极其擅长沟通技术理念。
  • 他们对如何构建一个好的系统有着敏锐的洞察力和直觉,并能相应地引导大型语言模型(LLMs),我称之为"匠人精神"。
  • 他们拥有扎实的基础,因此能够迅速掌握新工具和新系统,因为在这种情况下,知识而非技能是瓶颈。
  • 人工智能仍然对语言和风格敏感,并且通常会反映提示者的品味和偏好。高技能工程师对于"什么有效、什么无效"有着非常敏锐的品味和直觉。

因此,请展现出匠人般的细致。归根结底,即使有AI的辅助,你也应该产出令自己引以为傲的作品。这种匠心精神也很好地体现在我从这些系统中看到的输出结果中。

举个例子。这个提示虽然不算不合理,但考虑得并不周全:

"编写一个Python限流器,将用户限制为每分钟10个请求。"

我预计这个提示会得到不错的结果,但也可能遗漏一些边界情况、最佳实践和质量标准。而在Nilenso,你可能会看到有人这样提示AI来完成相同的任务:

"使用令牌桶算法在Python中实现一个请求限流器,需满足以下要求:

  • 每分钟每个用户(通过user_id字符串标识)限制10个请求
  • 线程安全,支持并发访问
  • 自动清理过期条目
  • 返回元组 (允许:布尔值,重试间隔秒数:整数) 请考虑:
  • 令牌是逐步补充还是立即补充?
  • 当系统时钟改变时会发生什么?
  • 如何防止不活跃用户导致的内存泄漏? 优先选择简单、可读的实现,避免过早优化。仅使用标准库(不依赖Redis或其他外部库)。"

猜猜哪个提示能更好地实现程序设计者的意图?

对我们来说,一种行之有效的方法是元提示(metaprompting)。我向模型提供一个简单的任务,并要求它帮助发现权衡点和边界情况。然后我将它转化为一份技术规范,并交给另一个大型语言模型代理来执行。即使是我上面分享的"更好的提示",也是通过要求AI来构思一个好的提示而产生的。根据我的经验,模型已经善于自我提示。

这些工具的运作机制仍在不断变化,但一个可靠的原则是:努力提升自身,成为一名优秀的工程师。你的工作习惯会迅速影响你所使用的人工智能系统。这个方法之所以奏效,是因为对人类有益的,对人工智能也有益。

对人类有益的,对人工智能也有益

我想阐明一下软件工程的本质,鉴于人工智能的进步所带来的颠覆,我发现有必要重新审视它。

软件工程不仅仅是编写代码。或者至少,那不是其决定性特征,就像写作不仅仅是用墨水在纸上进行手腕练习一样。

对我而言,软件工程是维护大量定义明确的心智模型的艺术和科学,这些模型旨在满足商业或经济需求。大部分工作围绕着精心构建和管理这些庞大、复杂的社会技术系统,而代码只是这些系统的一种表现形式。

除非人工智能强大到足以吞噬整个社会技术系统,并淘汰所有培育它的人类,否则它必须参与并受益于这个系统本身。简单来说:人工智能在人类也能蓬勃发展的环境中,会发展得好得多。这意味着你的团队的软件基础必须扎实。

一个人工智能能蓬勃发展的系统,通常具备高质量团队和代码库的特征,例如:

  • 良好的测试覆盖率,包含有用的断言。
  • 代码合并前进行自动化的代码检查、格式化和测试。
  • 持续集成和持续部署。
  • 有良好提交信息的、文档清晰的变更记录、技术规范和架构决策记录(ADRs)。
  • 通过格式化工具强制执行的一致的代码风格和模式。
  • 简洁、精炼、组织良好的代码。
  • 定义明确的功能,并分解成多个小型故事卡。

如今的人工智能能够并且将会利用所有这些优点来让事情"顺利运作"。当我给一个编码代理一个任务时,它会通过运行测试用例和静态分析工具,在代理循环中不断地自我纠正。这极大地减少了完成工作所需的人工干预和指导。

一个丰富的环境和上下文有助于人工智能更好地工作。

举一个例子:我曾在一个项目中工作,该项目有两个服务,其中一个服务具备我上述描述的所有优点——良好的测试、文档完善的变更、代码中一致的模式、大量的检查和防护措施。而另一个服务则比较混乱,且不具备上述任何优点。我们的AI编码助手在后者的代码库上完成同样难度的任务时,比在前者的代码库上困难得多!这很可能是因为混乱的代码库对AI来说,就像对人类一样难以理解。它收到了关于"正确做法"的混杂信号。

编辑器中的工具和技巧

既然我已经概述了总体策略,下面是一些对我有所帮助的具体方法。

使用最顶尖的AI模型,不要吝啬。

使用市面上最好的编码模型。不要为了节省费用而使用次一级的模型。一个好的模型会带来复合效益。我接下来介绍的所有策略,只有当你一开始就使用强大的编码模型时,才能发挥更大的作用。

出色地提供上下文。

AI辅助编码的有效性,很大程度上取决于你如何巧妙地向大型语言模型(LLM)提供正确的上下文。

使用"代理式"编码工具。这些工具能够读取和分析文件、运行shell命令、获取文档、创建计划并执行这些计划,无需人工干预(或许只需批准)。我们目前推荐的此类工具有:Claude Code、Windsurf、Cursor、Cline。

如果提供不相关或杂乱的上下文,大型语言模型可能会分心并陷入"兔子洞"。通过仅@提及相关文件,并仅链接有助于任务的文档来集中其注意力。

将编码标准和实践编码到一个 RULES.md 文件中。将此文件软链接到代理特定的规则文件,例如 .cursorrules, .windsurfrules, claude.md, agents.md 等。该文件应包含有关技术栈、如何使用开发工具和运行代码检查器、编码标准和模式的信息,并涵盖大型语言模型在处理代码时常犯的错误。这里有一个例子

实施新功能或重构

分解问题。你越具体,AI的效果就越好。记住,你也可以利用AI来减少撰写更优质、更具体的提示的繁琐工作。推理模型在这方面表现出色!

如果你正在开发一个大型功能,请将其分解为小任务,并逐一完成这些任务,在每个任务结束时提交一次代码。如果你对你的用户故事(stories)也这样做,那么故事卡描述(包含任务列表)通常能为AI提供非常有帮助的描述。

提供技术规范以及有关产品和功能的 S相关文档。不要仅仅要求它在没有更广泛的产品上下文的情况下编写代码。同时,提供你所使用的库的使用文档。粘贴文档链接通常适用于大多数工具。一些库提供 llms.txt 文件供编码代理使用。

另一种对我们行之有效的方法是将功能分解为"规划"和"执行"阶段。有些编码代理已经能为你完成这种分解。

不要想当然地接受人工智能的建议。要求它解释其选择,提出替代方案,并思考优缺点。

调试

利用人工智能调试其生成内容中的错误。始终粘贴与大型语言模型最相关的错误上下文,以帮助其理解问题(我更喜欢将错误日志或输出放入单独的XML标签中)。

解释你已经尝试过的方法和额外的观察结果,以帮助模型生成正确的假设并排除错误的假设。提供大量的上下文。

编辑器外的工具和技巧

利用人工智能提升自身技能和知识

大型语言模型是极具耐心的老师,拥有海量的世界知识(最近,其有效研究能力也大幅提升)。积极利用它们来学习新事物,解密任何新的代码或技术栈。不懈地深入挖掘,找出最佳实践。通过让大型语言模型引用高质量来源,确保你正在正确学习。

创建详尽的文档

通过将代码库输入到大型语言模型中,轻松创建大量详细文档。例如: 解释功能、创建知识库。 总结目前正在收集的所有指标。 更智能地识别缺失的测试用例。

这样做有一个很好的理由——现在生成文档的成本很低,并且这反过来能让项目中的大型语言模型(和人类)工作效率大大提高。

微摩擦润滑剂

大型语言模型极大地降低了为团队日常遇到的所有微小摩擦点创建"润滑剂"的成本。

利用它们创建模拟服务器,以协调和解除前端和后端团队之间的工作阻塞。所需做的仅仅是就接口约定达成一致。

通过向大型语言模型提供shell历史会话,创建基础设施部署、常见故障排除类型等的运行手册和指南。

将现有的运行手册和指南提供给大型语言模型,使其转化为自动化常见任务的脚本。

代码审查

为拉取请求(Pull Request)设置模板,将每个功能的代码差异(git log -p <range>)提供给AI,让它解释变更以及如何部署。一些工具已经可以为你完成这项工作。

为了缩短首次PR审查的时间,可以先使用代码审查机器人进行初步审查。但切勿取代人工审查!

当你作为审查者未能完全理解某项变更时,可以使用大型语言模型来解释。向它寻求澄清,然后在收集到必要上下文后,再向实现者提问。

调试和监控实时应用程序

利用大型语言模型的查询能力,帮助查找不常见错误的解决方案。遵循编辑器内调试的建议,在编辑器外进行调试。尽可能多地提供上下文。

大型语言模型在编写查询和观察工具的告警规则方面表现相当不错。它们也擅长通过编写自定义Python代码来处理数据和执行分析。

性能优化

利用大型语言模型帮助优化数据库和调整配置。在此过程中,请提供基础设施和硬件的上下文。分享查询计划。

这是我最近一次类似互动的例子。

见:https://blog.nilenso.com/blog/2025/05/08/psa-ai-can-optimise-your-database/

人工智能如何改变工艺的含义

这是我们编写软件方式的一次巨大转变,我相信这需要对过去被视为常识的观念进行一些调整。

首先,花费过多时间寻找和构建复杂的抽象变得不那么有价值。DRY(不要重复你自己)原则对于确保代码中的模式保持同步是有用的,但实现和维护一个抽象来处理不断变化的需求会带来成本。大型语言模型使得一些重复变得可以接受,并允许你多等待一段时间,避免过早抽象。

现在,重复工作变得极其廉价。小范围的代码细节重要性下降,而大规模代码的结构模式和组织方式变得更加重要。你还可以构建大量的原型来测试一个想法。为此,"随性编码"(vibe-coding)非常棒,只要原型稍后会被废弃并重新编写得当。

与大型语言模型协作还能让你利用生成器-验证器之间的差距。通常,验证和修复比从头开始生成更容易。这降低了尝试新事物的启动能量。

测试是不可商议的,人工智能消除了所有不编写测试的借口,因为它能极快地生成测试。但务必审查断言!

本手册将进行未来增补

  • 部署像Devin/Jules/Claude Code这样的自主代理并善用它们
  • 用于编写查询、执行数据分析的AI工具
  • 关于专有代码泄露、托管LLM选项等问题
  • 建立分享提示、模式和模板的文化
  • 推动团队采纳AI的有效方式

参考文献

  • 《用大型语言模型编程》——David Crawshaw
  • 《我是如何使用大型语言模型帮助我编写代码的》——Simon Willison
  • 《我是如何使用"AI"的》——Nicholas Carlini