说明:本文基于 Simon Willison 的一篇英文文章整理,结合原文案例,重写其中更值得复用的协作方法,不追求逐字翻译。
原文标题:Adding a new content type to my blog-to-newsletter tool
原文作者:Simon Willison’s Weblog
原文链接:https://simonwillison.net/guides/agentic-engineering-patterns/adding-a-new-content-type/#atom-everything

很多人第一次用 Coding Agent,都会有一种类似的挫败感:模型看起来很强,真放进项目里,却还是会理解错需求、改错地方,或者忙了半天,最后没把问题真正解决。

这种落差不一定说明模型不行,很多时候,是任务交代得不够适合让它工作。

Simon Willison 最近写了一篇文章,里面有个很典型的例子。他想给自己的 blog-to-newsletter 工具新增一种内容类型,于是把这件事交给 Claude Code 去做。值得注意的是他给任务的方式,而不是功能本身:prompt 不长,但把参考代码、目标文件和验证方式都交代清楚了,于是 agent 一次性把整件事做完了。

这件事很像我们平时带新人。你只丢一句「你去改一下」,剩下全靠猜——最怕的往往是这个,而不是对方能力差。对 Coding Agent 也一样:很多任务做砸,是因为上下文没给够,或者给错了。

Prompt 能落地,比写得长更重要

很多人给 agent 提需求,习惯是先在脑子里想一遍背景,再把这些背景压缩成一段自然语言,希望模型「理解我的意思」。问题在于,软件系统里的很多真实约束,几句话很难说清楚。

一个新功能怎么接,往往同时牵涉到这些东西:

  • 现有数据库结构
  • 老代码形成的约定
  • 系统里已经存在的类似行为
  • 那些没写在文档里、但已经写进代码里的边界条件

这些东西如果全靠人重新口述一遍,不但费劲,而且很容易失真。Simon 这篇文章里最值得学的一点,就是他没有试图把所有规则都解释给 agent 听,而是把 prompt 设计成一种能让 agent 自己补全上下文的任务说明。

说白了,一个好 prompt 不一定要把所有信息都写进去,但它至少要把这三件事讲清楚:

  • 去哪里找背景
  • 该参考什么
  • 最后怎么验证

这三件事清楚了,prompt 本身反而不用太长。

直接给参考实现,比反复解释省事

文章里最关键的做法之一,是作者直接让 agent 去 clone 一个相关代码仓库,把它当参考资料。这个动作看起来普通,实际非常有效。

因为很多时候,需求真正的定义并不在嘴上,而在现有代码里。

比如你想让 agent 给一个旧系统新增功能,如果你只是说「按我们现有逻辑做,和某个模块保持一致」,这句话对人可能已经够用了,但对 agent 来说还是太虚。它不知道「现有逻辑」在哪,也不知道「一致」到底是页面结构一致、数据格式一致,还是边界判断一致。

而如果你直接给它一个参考仓库,或者指向项目里已经存在的实现,它就能自己去看:

  • 数据结构是什么样
  • 相关逻辑已经怎么写了
  • 现有行为是怎么表现出来的

这比你再补一大段解释,通常更准确,也省事得多。

更直白一点:

别费劲把系统规则翻译成自然语言,让 agent 直接去读规则真正存在的地方——代码本身。

把参考仓库放进 /tmp,是个很实用的小习惯

Simon 在 prompt 里特意提了一句,让 agent 把参考仓库 clone 到 /tmp。这不是可有可无的小细节,反而很实用。

因为实际协作里,agent 常常同时要碰两个代码库:

  1. 当前真正要修改的项目
  2. 用来参考的另一个项目

如果这两个仓库混在一起,或者都放在当前工作目录里,后面很容易出问题:

  • 把参考代码也带进当前仓库变更里
  • 提交时夹带无关文件
  • 自己都分不清哪些是正式修改,哪些只是参考资料

把参考仓库放进 /tmp 的好处很直接:

  • 它可以随便看
  • 可以拿来理解逻辑
  • 但不容易误提交到当前项目

这其实是一种很朴素的隔离策略。很多时候,任务做得干不干净,不只取决于你怎么描述需求,也取决于你有没有顺手把执行环境安排清楚。

不要只说“把功能做出来”,还要告诉它怎么验收

很多人给 agent 提需求时,最容易漏掉的一件事,就是验收方式。

也就是说,任务描述里有「要改什么」,却没有「怎么判断改对了」。

这会导致一种很常见的失败:agent 确实改了代码,甚至改得还不少,但因为没有验证路径,它根本不知道这些修改有没有真正满足需求。于是你看到的结果就是,它看起来很忙,实际上没有把事情做完。

Simon 这篇文章里,prompt 不只是告诉 agent 要更新哪个文件,还明确告诉它:

  • python -m http.server 启动本地服务
  • 用浏览器自动化工具检查页面表现
  • 再把结果和线上页面做对照

这一步很关键,因为它把「任务完成」从一种主观判断,变成了一套可以执行的流程。

对 agent 来说,任务没有闭环比任务难更麻烦。只要你告诉它:

  • 改哪里
  • 参考什么
  • 最后去哪里验证

它就更有机会把问题真正做完,而不是停留在「我觉得应该差不多了」的状态。

所以这篇文章里一个特别实用的结论就是:

好的 prompt,不只描述目标,还要描述验收路径。

系统里已经有正确样例时,别重新发明需求说明

文章里还有一个很值得抄作业的点:作者没有重新详细解释新内容类型该怎么展示,而是告诉 agent,新逻辑要和博客里现有的 Atom feed 类似。

这其实是个很强的做法。

在真实项目里,「做到什么程度才算对」往往比「做什么」更难讲清楚。如果系统里已经有一个现成的正确样例,通常直接告诉 agent 就够了:

  • 去看那个已经正确的行为
  • 新功能按那个行为对齐

原因也很简单:现有系统行为是具体的、可观察的,而且往往已经把很多隐藏约束一起带上了。比起重新解释一遍规则,让 agent 去模仿一个已经跑通的样例,通常更稳。

有用的 Prompt,在帮 Agent 找上下文

这篇文章让我印象最深的一点:高质量 prompt 的重点,是帮模型更快找到它缺的那些信息,而不是把所有信息都塞给模型。

低质量 prompt 往往是这样:

  • 背景写了一大段
  • 需求也写了一大段
  • 充满抽象概括
  • 但没有明确参考对象和验证方式

高质量 prompt 更像一张路线图。它不一定长,但会很明确地告诉 agent:

  • 背景知识去哪找
  • 参考实现在哪里
  • 要改哪个文件
  • 最后怎么自测

一旦这些路径给出来,agent 自己就能把剩下的上下文补齐。这样做的好处是,prompt 不需要无限膨胀,任务也更不容易跑偏。

我的看法

我觉得这篇文章的价值,不在于证明某个工具有多强,而在于它提醒了我们:不要把 agent 当成一个只会「听命令」的黑箱。更合适的看法是——它能自己探索上下文,但需要你给出正确的探索路径。

如果你只给它一个模糊目标,它就只能在模糊里猜;如果你给它参考实现、现有样例和验证路径,它就更像是在一个边界清楚的任务里工作。

这也是我越来越认同的一点:以后和 coding agent 协作,真正重要的能力,未必只是会不会写 prompt。更关键的是你能不能把一个模糊任务拆成三部分:

  • 可参考的上下文
  • 可执行的修改目标
  • 可验证的完成标准

这三件事一旦清楚,agent 的表现通常就会稳定很多。

结语

如果要把这篇文章的经验浓缩成一句话,我会这么说:

想让 Coding Agent 一次把事做对,就不要只给目标,还要给参考、给样例、给验证方式。

这听起来很朴素,但在真实项目里,它往往比「换个更强的模型」更能直接提高协作成功率。