提示词迭代
凭感觉调提示词不会收敛:改完试一条觉得好了,上线发现另一类输入坏了。要有尺子、一次动一处、和上一次跑比。
第一章解决的是「怎么说」:把活派清楚,它一次就能做对。但一次做对和次次做对是两回事——实际工作里,提示词很少一遍就写到位,它是一点点调出来的。而调有个前提:你得有能力判断这次调整到底有没有让结果变好——不然改动只是换了个说法。
读完你能回答:
- 为什么「改完试一条,感觉好多了」这句话几乎不提供信息?
- 那组测试样例该有几条、怎么挑,为什么边界情况最不能少?
- 分数变好之后,还要看什么才知道这次改动是安全的?
改动能归因,其余纪律都从这一条长出来
要让一次调整说得清,得同时管住两件事:一次只放一个变量进去,以及有一个固定的东西用来量结果。前一件让你知道是谁起的作用,后一件让你知道作用有多大。缺任何一个,改完之后的结论都只是印象。
一次只动一个地方。三处一起改,就算效果变好了,你也说不清功劳属于哪一处——更麻烦的是,可能其中两处改对了、一处改坏了,净效果只体现为一点点提升,于是那处坏的被你一并保留下来。它以后会成为一句没人敢删的话。
每次改动留一行记录。写清改了什么、针对什么问题、分数从多少走到多少。这行字日后很值钱——半年之后如果有人来问某条限制能不能删,你手上有依据。
没有变好就退回去。不要因为「花时间写了」就把它留下。提示词里每多一句,都在增加成本、稀释重点、给日后的维护添负担。
动手的顺序也有优先级:缺的部件先补齐,例子跟上,然后才是技巧,参数排在最后。越靠前的动作,能换回来的分数越多。
那把尺子要挑成什么样
前面说的「固定的东西」,就是这个栏目里反复出现的测试样例。
准备二三十条来自真实场景的输入,每条都配上你认可的标准答案——退一步,至少也要有判断对错的标准。往后所有关于提示词的决定,都拿它当尺子。
挑的时候,常见情况占大头,另外专门留几条边界情况:超长的输入、信息残缺的、格式古怪的,以及那些你希望它回答「不知道」的。这里有个规律值得先记住——边界情况永远是最先被牺牲的那一批,而线上真正出事的偏偏就是它们。
这件事得占掉半天到一天。在提示词相关的投入里,它的一次性回报是最高的,因为之后无论改提示词、换模型还是加技巧,判断依据都是它。换模型和降级用的也是同一组样例。
这组数据还有第二个用途:它和你要放进提示词的示例取自同一批数据。挑出来的好样本进提示词充当例子,剩下的留作测试集——要留神的是同一条不能两边都用,那样量出来的分数就不算数了。
官方指南都把「先建立评估、再改提示词」放在迭代流程的第一步。anthropic-prompt-eng 这不是流程洁癖,是因为没有尺子的时候,你其实在同时改两个变量:提示词,和你自己的印象。
只试一条为什么不算数
有了尺子,最常被省掉的动作是跑完整组。
改完挑一条试了试、觉得「好像好点了」,是这份工作里最常见的自欺,原因很简单:你挑中的那条,往往恰好就是这次改动针对的场景。改动正是为了让这类输入过得更好,它当然会过关。所以必须整组跑完,总数要看,逐条也要看。
和上一次的整组结果并排看
整组结果拿到手,最容易犯的错是只盯着这次的绝对值。
脱离对比的数字说明不了什么。一组 24 条样例这次过了 20 条——算好算坏,要看上一次是多少,也要看这 20 条里究竟是哪些。因此每次改动都要把同一组样例的本次结果和上次结果摆在一起比,而且要比到条目一级。
上一次过 19 条、这一次过 20 条,看上去是在往好的方向走。可是逐条摊开,如果发现「四条变好、三条变差」,那这次改动的风险其实不小——很可能只是把错误从一类换成了另一类。这种「总数小涨、局部大挪」的改动最容易被放过,也最容易在线上炸出新的问题类型。
所以读结果至少看三层:
- 总数,判断方向对不对。
- 逐条差异,判断有没有把错误搬家。
- 变差的那几条,判断它们是不是你真正在乎的场景。有些条目的重要性远高于其他,它们变差了,总数再涨也不能上线。
还有一条时机上的纪律:改动和评测之间不要夹别的变化。同一天里换了模型版本、改了检索参数、又动了提示词,分数变了你也归不了因。一次只放一个变量进去,这个变量包括模型本身。
分不清是没写清还是不稳定,就跑三遍
这两种问题的解法完全不同,但表现很像,所以要先分清。
同一条输入连着跑三遍:三次都错、而且错法一致,说明提示词本身没写清楚,该回去补部件;三次结果忽上忽下,说明问题出在随机性上,该调随机性。
拿不准的时候,把同一条跑三遍——这个小动作能省掉大量瞎调的时间。它把「它答得不对」这个模糊的感觉,拆成了两个可操作的判断。
官方指南里那条最常见的建议——「一次改一个变量,记录结果」——本质上就是这两条纪律。openai-prompt-eng
停手之前,先确认样例集本身还没过期
调得越久,越容易冒出另一种毛病:某两条特殊样例怎么都过不了,于是你加了一条很别扭的专门说明。这两条如愿过了,线上遇到的其他情况反而更差。
信号很明确:你已经开始围着单条样例写规则了。这时候该停下来问一句:这条样例真有代表性吗?如果它只是个孤例,那不如接受它偶尔出错。
还有一层判断更根本:你的样例集本身也会过期。上线一段时间后,真实输入的样子会变——用户的说法变了、业务加了口径、上游数据格式动了。测试样例要跟着真实流量更新,否则你一直在优化一个已经不存在的分布。这部分评估集怎么养有专门展开。
过了这一关,才轮到问什么时候停手。提示词追求的不是完美,而是「足够好且稳定」。把出错的比例从一半压到一成,和把那一成再磨到几乎不见,后者通常更费时间。剩下那部分,用校验兜底或者人工复核来解决,通常更划算。
判断「可以停了」有三条依据:
- 常见的输入都稳了,剩下的失败集中在少数不常见的场景。
- 失败可被发现。错了你能立刻知道,而不是等用户来告诉你。
- 有兜底。出问题时的分支写好了——重试、降级、转人工,而不是把乱的结果直接给用户。
这三条都满足,就该把精力挪到别处了。继续磨提示词,边际收益已经低于把校验做厚。
这也正是先定义完成、再动手那套纪律在提示词上的样子:先想清楚什么算做完了、怎么判断做完了,再开始改。改动有归因、有记录、能回滚之后,剩下的事就是让它别散掉——提示词一旦散在代码里,很快就会变成没人敢动的一坨。
