提示词里放什么 — 静态澄清与动态上下文
这一章讲三件事: 提示词的内容怎么分成「澄清任务」和「提供情境」两类; 放例子(few-shot)这件利器为什么会反噬;以及动态上下文该按什么规矩收集。 原书第 5 章很长,我们把它拆成两章——本章管「从哪来、怎么选」, 第 07 章专管「检索与摘要」这条最大的来料渠道。
1. 这一章讲什么
第 05 章立了四准则,这一章开始填第一准则和第二准则的料: 提示词里到底该放什么、从哪来。
主走查围绕同一个应用——图书推荐——分两段: 先看同一句「下一本读什么」怎么被拆成静态、动态两块; 再看一个「猜书评评分」的提示词,例子的三种摆法怎样引出三种不同的模型行为。
2. 顶层全景:模型最擅长处理的,恰恰是你没给它的
先看书的引子。做一个图书推荐应用,传统做法(协同过滤那类)只看 「谁读过什么」。拿 LLM 做,你可以喂给它乱糟糟的文字: 人口统计、书之外的爱好、最近的经历—— 它能像一个「读遍了全网书评的人」那样,用常识做推荐1。
只给「最近读过《白鲸》和《哈克贝利·费恩》」,它推荐《杀死一只知更鸟》,合理。 加上「中年、爱旅行、刚发帖吐槽过背包客」之类的杂料, 推荐立刻变得贴身。模型的长处是消化乱七八糟的文字信息—— 但把信息找来给它,是你的工作2。
这些料分两类,这是全章的总纲3:
静态内容 = 写死在代码里的文字
作用:定义任务、澄清问题、给精确指令
动态内容 = 请求到来时才取来的文字
作用:提供「这一个用户、这一次请求」的具体情境
图说:分在哪一类,不看文字本身,看它从哪来——
写死的就是静态,从可变来源取的就是动态。
3. 核心原理
3.1 一条会移动的分界
主走查第一段。 同一句问话,三个版本4:
| 版本 | 文字 | 第二句是什么 |
|---|---|---|
| A | 「下一本读什么?我是说消遣读物,不是教科书。」 | 静态:澄清「书」在这任务里指什么 |
| B | 「下一本读什么?我上一本读的是《白鲸》。」 | 动态:这一次的具体情境 |
| C | 「下一本读什么?我要正经书,不要自助书。」 | 不一定 |
C 分在哪边,取决于你怎么实现: 如果「不要自助书」是你写死的应用规则——它是静态澄清; 如果是你从这位用户的聊天记录里发现的偏好——它是动态上下文。 同一句话,出身决定类别5。
这个分界不是学究:静态料要在上线前打磨到完美, 动态料要解决「从哪来、多快能取来」的工程问题——两拨不同的工作。
3.2 澄清任务:显式指令的三条写法规矩
为什么「澄清」值得专门一节?因为程序化的调用里, 一次误解就是一次彻底的失败——没有人替你追问「你刚才是不是这个意思?」。 而且澄清带来一致性:每次都以同样方式理解任务,才谈得上优化和信任6。
显式指令就是直说:用 Markdown(一种拿 #、* 做排版标记的轻量写 法,
网上文档里遍地都是)、别带链接、别提某日期之后的事。
业界真实应用的系统消息里,这种「该做/不该做」能列一长串——
书里引了一张从 Bing Chat 套出来的指令表(代号 Sydney),
并特别注明:是否真是 Bing 生产用的提示词,未获证实7。
写指令的三条经验法则,书是用「十诫」句式对比给的8:
- 说正,不说反。 「Thou shalt not kill」→「Thou shalt preserve life」;
- 给命令配个理由。 「…since the act of killing disrespects the other person's right to life」;
- 忌绝对化。 「…kill only rarely…and make sure it's really appropriate!」
对聊天模型,显式指令放系统消息——它被训练成最服从那里; 但没有任何模型百分百听话,指令只是强倾向,不是保险锁9。
3.3 主走查第二段:例子教会的,比你说出来的多
另一种澄清是给例子——第 01 章说的少样本(few-shot)。 主走 查开始: 造一个「读一句书评,猜打几分」的提示词, 里面放几个例子(书评 + 评分),最后留一句新书评等它打分10。
模型从这几个例子里学到的东西,数一数:
评分是数字 ← 你说过吗?没有
格式是「评语:分数」换行分隔 ← 你说过吗?没有
分数是 1–5 的整数,越高越好 ← 你说过吗?没有
分布上 4 分 5 分居多,低分稀少 ← 你说过吗?你根本没想到这条
图说:一条隐式规则都没写,它全学走了。
写成显式规则试试:又长、又怕漏、有的你说不清(「我知道什么样是好,但说不出来」)。
这就是「隐式常常胜过显式」:模型有延续模式的强迫症, 模式里带的规矩,它执行起来比你明文规定的还稳。 例子还顺带定人设— —例子里的评语刻薄,它就一路刻薄下去,而且每次都同样刻薄, 一致性白捡11。
3.4 坑一:例子随上下文膨胀
例子的类型得跟主问题一致。可如果主问题本身拖着一大坨上下文呢?
书里的反例:推荐系统给每个用户都采集了冗长资料(人口统计、历史书评……),
你照着造了四个假用户当例子(For ${PersonA.name}, we know the following: ${JSON.stringify(PersonA)}…),再跟上真用户。
四段又长又相似的 JSON,加上一段更长的——窗口先爆,模型后晕12。
为什么会晕?回到第 03 章的注意力游戏: 负责写答案的小脑们回头喊「谁有相关经验?」, 四段结构雷同的段落同时举手,答案看起来全都像—— 它分不清哪段是例子、哪段是正题13。
把例子缩短?短例子会把它往「浅薄的匹配」上引,而且信息量比主问题少太多, 学不到东西。例外:只澄清「输出长什么样」时,小例子就够使—— 这是少样本最划算的用法14。
3.5 坑二:锚定——例子会替你预设立场
锚定——先看到的信息会不成比例地影响后续判断,人如此,模型也如此。
书里两组对照实验(都是 text-davinci-003 的真实输出)15:
- 问「某个名字听起来像哪个年代的人?」—— 例子里全是二十世纪初的名字,它答二十世纪初; 例子全换成二十一世纪初的,同一个名字,它改答二十一世纪初;
- 「猜评分」的例子改成 1、2、3、4、5 分各来一个——看起来很公平, 但真实分布里 5 分占绝对多数。没有线索时,它按「均匀」猜 3, 而无所知的正确猜法是 5。
要点:例子不只教格式,还偷偷运输了一个「什么算正常」的概率分布。 对策有三:例子尽量贴近真实分布(有真实样本就抽样,别手编); 主要类别都要覆盖;边界案例一定要给——不给,它遇到边界时只能乱猜16。