Agentic Coding(智能体编程)正在向来自各种背景的人开放软件构建的大门。因此,今天我们将探讨作为开发者的你如何通过确保为智能体提供极佳的上下文来掌握主导权。例如,假设你要求你的智能体添加一个登录端点。
那么,这个智能体会遵循你的错误格式和文件夹布局吗?它会使用你指定的认证库吗?这一切都取决于该智能体所掌握的上下文。因此,如果我们的提示词仅是一句要求添加登录端点的简短指令,而代码库包含成千上万个文件甚至积累了多年的决策,那么仅凭提示词是无法解释所有这些内容的。
因此,我们的编码决策需要依赖于现有的代码基础:使用哪个框架?数据库层是如何设计的?是否存在大家共同遵循的验证模式?正因如此,完全相同的请求在不同的代码库中可能会产生不同的代码。在仓库 A 中,我们可能有一个带有 Pydantic 模型的 FastAPI 路由;而在仓库 B 中,我们可能使用具有完全不同结构的 Go Handler。
那么,智能体实际用来理解这些仓库的理想上下文是什么?让我们谈谈智能体的输入要素。首先,我们需要考虑文件和现有代码。最优秀的智能体能够自行搜索、复制和打开文件,从而理解你无法在提示词中完全涵盖的内容。而你的工作则是引导智能体走向正确的方向,例如在提示词中加入“遵循 README 中的模式”,以便智能体知道从哪里开始。
这就引出了我们的下一个要点:仓库结构。测试代码在哪里?模块布局是怎样的?确保你拥有某种工具,为智能体构建一个紧凑的仓库映射图。这可以是一个文件和符号列表,使模型能够在不必逐行阅读的情况下看清项目的整体结构。
第三点是依赖项。这一点比较隐蔽,因为仅仅知道使用了某个库是不够的。智能体还需要版本号。你的锁定文件(lock file)是一种机器生成的文件,记录了项目中每个依赖项包括传递性依赖的确切解析版本。它指明了哪些 API 实际存在,因为许多幻觉产生的函数错误可能实际上是版本不匹配造成的。
第四种能真正帮助智能体的输入是测试用例,且该智能体知道如何通过这些测试。这样它就能形成一个反馈循环:编写代码、运行测试,然后尝试修复并解决失败的测试。当智能体知道什么是“良好”的标准时,Agentic Coding 的优势就能真正发挥出来。
第五点,让我们考虑文档。对智能体有价值的文档包括开发规范、构建命令以及诸如“不要触碰此目录”之类的指令。你可以将这些内容放入一个已提交的说明文件中,称为 agents.md。这是一种新兴的开放约定,许多工具都有自己版本的实现。
第六点,开发者意图至关重要。对你而言,“完成”是什么样子的?有哪些约束条件?它不应该做什么?这是智能体无法通过阅读你的仓库发现的一条上下文信息,只有你拥有这些信息。
现在,也许你会想,如果你已经知道什么是认证库或锁定文件,这些建议都很有用,但许多新手开发者还不知道该问什么问题。因此,我们可以让智能体为我们浮现出它所需的上下文。为此有三个步骤。
第一步是个妙招:在编写任何代码或要求智能体为你写代码之前,告诉它“采访我”,并向你提问直到它理解所需的内容。
第二步,你可以指示智能体探索该仓库并用通俗语言解释其组成结构。现在,你们双方都对这份仓库地图有了理解。
第三步,制定计划并列出你所做的假设。在进入这个过程之前了解智能体的假设是非常有益的,这样你就能提出那些原本可能不知道要问的问题。完成后,让它将学到的内容写回这个 agents.md 文件中,以便下次进行此过程时这些信息已经存在。
理想情况下,你的智能体会负责挖掘信息,但你仍需确保自己掌握决策权。人们自然的直觉是上下文越多越好,因此把整个仓库都倾倒给智能体。但不要这样做,因为模型不会同等关注长输入中的所有内容。
研究表明,它们在开头和结尾的信息上表现最好,而在中间被埋没的内容上表现较差。每一个无关的文件都会与重要文件争夺注意力。因此,你的上下文必须与任务相关,这应该是你思考时的过滤标准。
如果我们回到之前更改登录流程的例子,智能体需要认证模块、其测试用例以及我们的规范,但不需要账单服务或三周前的构建日志。因此,实际操作意味着为每个新任务启动一个新的会话,以便你可以指向这些特定文件并在会话变得冗长时清除噪音。
总结一下:仅靠提示词是不够的,因为好的代码依赖于其周围的代码库。因此,给你的智能体提供正确的输入:代码、结构、测试、文档、依赖项以及你的所有意图。如果你不知道该问什么,就让智能体来问你并进行筛选。目标不是更多的上下文,而是正确的上下文,并让你保持掌控权。非常感谢观看,请在评论区留下你最喜欢的上下文技巧。