为 AI 编码代理编写正确提示词的方法

为 AI 编码代理编写正确提示词的方法

大多数开发者使用 AI 编码代理的方式是这样:打开聊天窗口,输入"帮设置页面加一个深色模式切换钮"之类的句子。代理会产生一些东西。大致能用。但边边角角还很粗糙。接下来二十分钟,开发者就在来回往返中把东西补起来。

然后他们就认定这个模型不怎么样。

模型没问题。问题出在提示词。

模糊提示词的现实,令人不太舒服

提示词里的每一个模糊之处,都是模型在没有你的情况下所做的决定。深色模式的偏好要不要跨会话保留?要不要尊重操作系统层面的设置?偏好要存在哪里,localStorage、数据库里的用户个人档案,还是 cookie?用的是哪个组件库,主题在里面是怎么运作的?

你没说。所以模型用猜的。有时猜对。更多时候不是。于是你得到一段在一个环境正常、换个环境就坏掉的代码,或是一个忽略用户既有偏好的组件。

这是信息的问题。

技巧:让代理自己组出它的提示词

认真打造 AI 辅助开发流程的团队,摸索出来的结论是这样:对于把一件事做好需要什么,模型比大多数开发者更清楚该怎么问。

模型处理过数量庞大、规格清楚明确的工程任务。所以它知道一份完整的功能请求长什么样,也知道一份模糊的错误回报通常缺了什么。诀窍是,在你要求它做任何事之前,先让它告诉你缺了什么。

流程是这样:

  1. 大致描述你的目标 够让代理理解问题范围就行
  2. 问它需要什么才能做好 "要把这件事做好,你需要哪些信息?我该厘清哪些模糊的地方?我还没指定什么?"
  3. 补上缺口 回答它的提问,提供它要的上下文
  4. 然后才把任务交给它 把它的提问并入提示词,或请它把你的原始请求改写成完整规格,再核准并执行

最后一步可有可无,但值得做。你可以对代理说:"根据我的回答,把我的原始请求改写成一份完整的任务规格。"你拿回来的,是模型自己都认为够完整、足以执行好的提示词。再把这句提示词当成真正的任务交出去。

有些人开始把这叫做任务执行的反向提示词工程。你不是从零写出一份完美提示词,而是让模型浮现出一份完美提示词该包含什么,再从这里往下走。

示例 1:做一个功能

假设你想在设置页面加一个深色模式切换钮。两种做法是怎么展开的。

天真的做法:

"帮设置页面加一个深色模式切换钮。"

代理产出一个写死的切换钮组件,把偏好存在组件状态里(刷新就消失),不接任何已有的主题系统,而且用的是内联样式,而不是你原本在用的 CSS 变量或主题 token。

接下来一小时你都在修。

反向提示词的做法:

你从同一句话开始,然后问:"开始之前,要把这个做对,你需要知道什么?我该厘清什么?"

代理会回你大概像这样的东西:

你回答这些问题。你告诉它,这个 app 用的是 next-themes,偏好会通过既有的 PATCH /users/me 端点存进用户的个人档案,而且设置页面已经有一个"外观"区块,里面的其他切换钮都遵循特定的组件模式。

现在代理有了它需要的东西。它产出的实现会接上正确的主题提供者、用既有的 API、配合既有的 UI 模式,也会处理操作系统偏好的回退。你什么都不用修。

示例 2:修一个错误

错误回报是模糊提示词杀伤力最大的地方。因为一个上下文不足的模型,不只产出平庸的代码,还会产出自信满满、但其实写错的代码。

想象有人回报:"登录按钮有时没反应。"

天真的做法: 你把这句话贴进代理。它开始扫描认证代码,看到一个可疑的 async/await 模式,觉得大概就是这里,改写那个函数,然后开一个 PR。错误还在。它改的那个函数根本无关。

反向提示词的做法:

你把错误回报交给代理,然后问:"要把这个诊断好,你需要知道什么?资深工程师在碰任何代码之前,会先问哪些问题?"

它会这样回应:

你回头找那位回报错误的人,拿到答案:这是断断续续的,只有用户待在页面超过十分钟之后才会发生,没有控制台错误,但网络请求完全没发出去。这下是完全不同的错误了。原因很可能是 token 过期,或是事件处理器里一个过时的闭包。

你把这些信息交给代理,它这次就会去对的地方。它找到一个 useCallback,依赖项过时,从初次渲染就抓着一个认证 token。修复就是一个锁定目标的小改动,没有其他伤及无辜。

为什么这有效

多数 AI 辅助写代码会像一场谈判,让你在好几轮里来回打磨输出,原因就是最初的提示词把太多决定留给了模型。每一轮的修改,都是你在更正模型因为你没指定而做出的猜测。

反向提示词把这些轮次的大部分,收拢成开头的一场对话。模型的提问会精确告诉你,它本来会自己做出哪些决定。你来替它做这些决定。因为信息完整,输出第一次就对了。

还有一个附带的好处。模型问的那些问题,本身就是一份检查清单。如果你对类似的任务——像是加新的设置、修认证的错误、集成新的 API——持续使用同一套技巧,那些问题会慢慢变得眼熟。久了之后,不用人问,你自然会把这些细节写进提示词里,你基本的提示词质量就提高了。

一些实操上的提醒

这套技巧对有工具和文件访问能力的代理效果最好,像是 Cursor 或代理模式下的 GitHub Copilot。一个能读你代码库的代理,问的问题会比两眼一抹黑、凭空工作的代理具体得多。

两轮式的流程(你需要什么 -> 给你 -> 现在做任务)确实多了一步。对又小又明确的任务来说,这有点小题大做。但只要是会碰多个文件、要跟已有系统集成、或涉及不明显的设计决策的工作,它稳定比直接动手做实现出更好的结果。

第三步产出的那份规格值得留着。它是一份可以重复使用的模板。下次有人要加一个会存进用户个人档案的设置,你手上已经有一份规格清楚的提示词了。

更大的重点

大多数开发者对编码代理下提示词的方式,是以牺牲质量为代价来追求速度。一句话快速丢进去、一个平庸的输出丢回来,然后花十分钟清理,一天重复几十次。

反向提示词的做法把这个取舍倒过来。你在一开始多花一点时间,确保模型有它需要的东西。回报是,输出更接近你真正想要的,你花在修正上的时间也更少。

对一项任务来说最好的提示词,是模型告诉你它需要的那一份。

© Melvin Laplanche - All rights reserved.