提示词工程实战:从工作说明书到版本化评测的稳定交付

发布时间:2026/10/27 19:35:10
提示词工程实战:从工作说明书到版本化评测的稳定交付

提示词工程(Prompt Engineering)这件事我做了两年多,从最早把它当成“玄学咒语”,到后来把它当成一份需要反复打磨的“工作说明书”,中间踩的坑足够写一本小册子。这篇不打算讲什么高深理论,就是把我在实际项目里沉淀下来的一套方法摊开讲清楚:怎么把模糊的业务诉求翻译成模型能稳定执行的指令,怎么设计约束和输出格式,怎么在效果不达标时快速定位问题出在提示词还是任务本身就不该交给大模型,以及怎么把提示词当成代码一样做版本管理和回归测试。适合谁看?如果你已经开始用大语言模型做实际的事情——写文案、抽字段、做分类、跑批处理、搭内部工具——但效果时好时坏,每次改提示词都靠“感觉”,那这篇应该能帮你省下不少时间。如果你只是偶尔聊聊天,里面关于骨架设计和排查思路的部分依然值得扫一眼,只是部分细节会显得重一些。

1. 为什么提示词工程值得当成一门手艺来做

1.1 提示词不是咒语,是给模型的“工作说明书”

很多人对提示词的理解停留在“找一句神奇的话”,于是收藏夹里躺着一堆来路不明的“神级咒语”。我带过几个新人,几乎每个人第一周都会问:有没有那种一句话让模型变聪明的模板?我的回答一律是:没有,而且越相信这种东西,越容易在真实项目里翻车。

原因在于大模型的工作机制。它本质上是在给定上文的前提下逐词预测下一个最合理的词,这个“上文”包括你写的全部内容。你给的上文信息量越足、边界越清晰、目标越可判定,它预测出的下文就越接近你要的东西。反过来,一句含糊的“帮我写得专业一点”,模型能做的只是从训练数据里挑一种它认为“专业”的平均风格,结果自然千人一面。

所以我更愿意把提示词类比成给一个刚入职、能力很强但从没接触过你业务的同事写的工作说明书。这个同事知识面极广、理解力很好、执行力也强,但他不知道你的行业黑话、不知道你的客户是谁、不知道你们内部对“合格”的定义是什么。你把需求文档写得多清楚,他交付的东西就有多接近预期。你不会对同事说“随便弄一下”,那凭什么对模型说?

这个类比能解释很多现象。比如为什么同样的提示词在不同任务上效果差很多——因为说明书的详略程度需求本来就不同;为什么加了几个例子效果立刻提升——因为你给了参照物;为什么长对话后面模型开始跑偏——因为说明书被埋在了一堆闲聊后面,重点散了。

1.2 三个决定效果上限的变量

我把影响最终效果的因素归成三类,这三类基本决定了一个任务的天花板在哪里。写提示词之前先想清楚这三件事,比事后调十遍措辞有用得多。

变量含义不到位时的典型表现
信息密度提示词里有多少条真正影响决策的有效信息输出空泛、套话多、抓不到重点
约束清晰度边界条件、禁止项、判定标准是否可执行输出时好时坏,格式飘忽,偶尔越界
任务可验证性结果能不能被客观判定对错你无法判断改版是变好了还是变差了

先说信息密度。我见过一个做商品标题优化的提示词,全文四百多字,其中三百字在反复强调“要有吸引力”“要符合平台调性”“要能打动用户”。这些话说得都对,但对模型来说全是噪声,因为它没有任何可执行的落点。真正有用的信息是什么?标题字数上下限、必须包含的核心属性词、必须规避的违禁表述、参考的三个正例、目标人群的年龄段。这五条一给,输出质量立刻不一样。

再说约束清晰度。人写需求有个习惯,喜欢用形容词表达偏好,比如“语气友好一点”“不要太生硬”。形容词对模型来说是连续的、模糊的,它只能猜。换成可执行的约束就完全不同:“每段不超过三句”“不使用感叹号”“不使用‘亲爱的’这类称呼”“遇到无法确定的信息时明确写出‘未提及’而不是推测”。这类约束模型执行起来非常稳,因为它可以逐条核对。

最后是可验证性,这一点最容易被忽略,但它其实是整个迭代循环的前提。如果一个任务你自己都没法判断输出好坏,那你改提示词就是在盲改。所以我在动手写之前一定会先问自己:这个任务的合格标准能被写成三五条吗?如果写不出来,要么是任务定义还没想清楚,要么是这个任务应该拆成几个更小的子任务。

1.3 什么场景值得花时间打磨提示词

不是所有任务都值得投入。判断标准我一般看四条:调用频次高不高、输出能不能被客观判定、错误代价大不大、输入输出结构是否相对固定。四条里占三条以上,就值得认真做一版提示词,甚至值得建评测集。

反过来说,一次性用的小任务,比如临时让它帮我整理一段会议记录,随手写两句就够了,花半小时打磨纯属浪费。还有些任务本身就不适合交给模型,比如需要精确计算金额的、需要查实时数据库的、需要承担法律责任判定的,这类任务无论提示词写得多好都不该把最终决策权交出去,模型只能做辅助整理。

我自己的经验是,一个团队里真正需要精细打磨提示词的任务通常不超过十个,剩下大量的调用都属于“够用就行”。把精力集中在这十个上,收益远比平均用力高。

2. 提示词的骨架设计:六个必须交代清楚的模块

2.1 角色设定:给模型一个“专业视角”而不是“人设包装”

角色设定这块被玩坏了。很多人喜欢写“你是一位拥有二十年经验、学贯中西、获得过无数奖项的顶级专家”,写了半天,模型输出的东西并不会因此变好。原因很简单:角色设定的作用不是给模型打气,而是帮它缩小搜索空间,让它从训练数据里调用某个特定领域的表达习惯、术语体系和判断标准。

所以有效的角色设定应该指向“视角”和“判断依据”,而不是“资历”和“荣誉”。对比一下:

无效版本: 你是一位世界顶级的、经验丰富的、屡获殊荣的资深文案专家。 有效版本: 你是一名面向 25-35 岁城市用户的消费品文案编辑。你判断一段文案好不好的标准有三条: 一是前 12 个字能否让人产生继续读的欲望; 二是是否包含一个具体可感的场景而非抽象形容词; 三是是否避免了行业里被用滥的表达。

第二版好在哪?它把“专家”这个空壳换成了具体的判断标准,模型在生成时就有了可对照的尺子。我一般的做法是:角色一句话交代身份和面向对象,紧接着两三句交代这个角色的评判标准,剩下的全部留给任务本身。

还有一个细节:如果一个提示词里同时要求模型扮演多个角色(比如既当写手又当审稿人),务必分阶段写清楚,不要混在一段里。混着写会导致模型在生成时同时兼顾两种立场,结果通常两头不讨好。要审稿就单独开一轮,把上一轮的输出作为输入喂进去。

2.2 任务描述:把动词和交付物固定清楚

任务描述最常见的问题是动词太软。“帮我分析一下”“看看这段内容”“优化一下”,这些动词对模型来说都是开放式的,它只能猜你想要什么形态的结果。分析可以是列要点、可以是写报告、可以是画表格、可以是给建议,模型会挑一个它觉得最像的。

解决办法是把动词换成可交付的名词。不要说“分析用户评论”,而要说“从用户评论中抽取全部提到物流问题的不满点,每条整理成一句话,按出现频次从高到低排序,输出一个不超过 10 行的列表”。这一句话里包含了动作(抽取)、范围(全部提到物流问题的不满点)、形态(每条一句话)、排序规则(频次降序)、长度上限(10 行)。模型几乎没有猜的空间。

我在写任务描述时有个固定习惯,写完先自己念一遍,然后问:如果我是一个完全不了解背景的人,看到这段描述,能不能做出跟我脑子里想的一模一样的东西?如果不能,缺的那部分就是我要补的。

另外,一个提示词里最好只有一个主任务。有些提示词一口气要求“总结、翻译、改写、提取关键词、生成标题”,模型确实能全部做完,但每一项的质量都会下降,因为它要在有限的输出长度里分配注意力。真需要多个产出,拆成多轮调用,每轮一个主任务,成本和质量的平衡点通常更划算。

2.3 上下文与素材注入:怎么输入、输入多少、边界在哪

把素材放进提示词看起来是最简单的操作,实际上问题最多。我总结出三条实践准则。

第一条,素材和指令要物理隔开。用明确的分隔符把待处理内容和你的指令分开,比如三个反引号、三个等号,或者 XML 风格的标签。这样做有两个好处:模型能清楚知道哪部分是“要处理的东西”、哪部分是“怎么处理”,同时也能防止素材里恰好包含类似指令的句子时被误当成命令执行。这点在处理用户生成内容时特别重要,因为用户评论里完全可能出现“忽略以上所有要求”这种句子。

第二条,素材要标注来源和可信度。如果一次给多个文档,每个文档前面加一行说明,比如“以下为产品说明书节选,内容权威”“以下为用户反馈,存在主观性和错误”。模型对来源的敏感度比我们想的高,标了来源之后它引用时会更谨慎,也更容易在冲突信息里做出合理取舍。

第三条,控制素材的长度和位置。上下文不是越长越好。我的经验是,如果一个任务的素材超过上下文窗口的一半,就要开始考虑分块处理或者先做一轮摘要压缩。还有个现象值得注意:当素材很长时,放在中间部分的信息被利用的概率明显低于开头和结尾。所以真正关键的约束和问题,不要只写在开头就完事,最好在素材之后再复述一遍,形成“头尾夹击”。

2.4 约束条件:用“禁止清单”替代“形容词堆砌”

我认为约束条件是整个提示词里性价比最高的部分。它不需要你有多强的文字功底,只需要你把“什么算不合格”想清楚。

写约束有个技巧:优先写禁止项,其次写数量项,最后才写风格项。禁止项最好写,因为它是离散的、可核对的;数量项次之,比如字数、条数、段落数;风格项最难,因为它是连续的。所以我一般把风格要求尽量转化成可数的规则。

风格要求(模糊): 语气要专业、克制、有说服力。 转化后(可执行): - 不使用感叹号 - 不使用“非常”“极其”“震撼”这类程度副词 - 每个论点后面必须跟一个具体数据或案例 - 段落之间不使用“首先、其次、最后”这类连接词 - 全文不超过 800 字

第二版明显更容易被稳定执行。这里还有个反面经验:约束不是越多越好。我曾经在一个提示词里堆了二十多条约束,结果模型顾此失彼,反而把最重要的那几条丢了。后来我改成“分优先级”:三条硬约束(违反就算失败)、五条软约束(尽量遵守),并在提示词里明确标注哪些是硬约束。这样模型在冲突时知道该保什么。

2.5 输出格式:结构化输出是稳定性的第一道保险

只要输出结果要被程序消费,就必须把格式写死。这一步做不好,后面全是解析报错和人工返工。

格式约束我一般写三层。第一层是整体形态,说明输出是 JSON、是 Markdown 表格、还是纯文本段落。第二层是字段定义,每个字段叫什么、什么类型、是否必填、取值范围是什么。第三层是异常处理,也就是当信息缺失或者无法判断时,该填什么。

第三层最容易被忘,但它恰恰是稳定性的关键。如果不约定缺失值怎么处理,模型会自由发挥——有时候填 null,有时候填“无”,有时候干脆编一个看起来合理的值。约定之后就好办了:明确写“无法从原文确定时,该字段填unknown,不要推测”。

输出要求: 严格输出一个 JSON 对象,不要包含任何解释文字、不要使用代码块包裹。 字段定义: - title: 字符串,不超过 20 字,必填 - category: 枚举值,只能是 ["咨询", "投诉", "建议", "其他"] 之一 - urgency: 整数,1-5,5 表示最紧急 - keywords: 字符串数组,2-4 个元素 异常处理: - 若原文未提及分类依据,category 填 "其他" - 若无法判断紧急程度,urgency 填 3

对于纯文本输出,我同样会约定结构,比如“输出三段,第一段结论,第二段依据,第三段风险提示,每段之间空一行”。结构一旦固定,人工审阅的效率也会提高,因为看的人知道去哪儿找什么。

2.6 少样本示例:选例子的三条准则

示例的作用是给模型一个“参照系”,它比任何形容词都有效。但示例选错了,效果会反向恶化,这点很多人没意识到。

我的三条准则是:例子要覆盖边界情况、例子之间要有差异、例子要和当前任务同分布。

第一条,覆盖边界。如果你给的三个例子都是最典型的正常情况,模型遇到稍微特殊一点的输入就会懵。所以我通常会给一个典型正例、一个边界例(比如信息缺失、表述含糊的)、一个反例加说明(说明为什么这个不合格)。反例特别有用,它直接告诉模型“底线在哪”。

第二条,差异要够。三个风格雷同的例子,等于给模型一个很窄的模式,它会开始机械模仿,输出的东西雷同度极高。差异化的例子能让它理解“规则的适用范围”而不是“要模仿的样本”。

第三条,同分布。这条最容易被忽略。如果你要处理的是用户随手写的口语化短评,却给了三个从专业媒体上摘的规范长句作示例,模型就会朝着规范长句的方向偏,输出跟真实场景不搭。示例一定要来自真实数据,最好就是你实际要处理的那批数据里挑出来的。

还有个小细节:示例的排布顺序会影响结果。有实验和我的实际经验都指向同一个结论——靠后的示例影响力更大。所以如果你有一个特别希望模型照着的例子,放在最后。

3. 从能跑到好用:实操流程与模板拆解

3.1 需求转译:把模糊诉求拆成可判定的小任务

拿到一个需求,我第一步从来不是写提示词,而是把它拆开。举个例子,业务方说“帮我做个用户评论分析,看看大家在抱怨什么”。这句话如果直接扔给模型,你会得到一个四平八稳的总结,看起来很全面,但几乎没法用。

我的拆解流程是这样:先问这个结果拿去干什么。如果是要给产品排优先级,那需要的是问题分类加频次;如果是要发现新问题,那需要的是罕见但具体的描述;如果是要监控舆情,那需要的是情绪倾向加时间分布。三种目的,三种完全不同的提示词。

假设目的是排优先级,我会把它拆成三个可判定的子任务:

  1. 从每条评论中判断是否包含明确的不满点,有则抽取一句话描述,无则标记为无
  2. 把抽取出的不满点归入预设的问题类别,无法归类的单独标记
  3. 按类别统计数量并排序

拆到这个粒度,每个子任务的输出都能被逐条检查,提示词也就有了明确的靶子。这一步花的时间通常占整个工作量的三成,但它决定了后面七成的效率。我见过太多人跳过这步直接写提示词,写出来的东西看着挺长,跑起来之后发现根本没法判断对错。

3.2 第一版提示词的写法

第一版不要追求完美,追求的是“能被评估”。我常用的结构是固定的六段式,写完之后无论怎么迭代,骨架都不动,只改里面的肉。

# 角色 你是一名负责<业务场景>的分析人员,你的判断标准是<标准一>、<标准二>。 # 任务 从下面的<素材类型>中,完成<具体动作>,产出<交付物形态>。 # 素材 <<< <待处理内容> >>> # 约束 硬约束(必须满足,否则视为失败): 1. ... 2. ... 软约束(尽量满足): 1. ... # 输出格式 <字段定义 / 段落结构 / 异常处理> # 示例 输入:... 输出:...

这个骨架里,每一段都有明确职责,迭代时可以精确定位是哪一段出了问题。比如输出格式老是错,那就只动格式段;内容空泛,那就补素材和约束。最怕的是把六件事混成一大段散文,改一句就不知道影响在哪。

具体写的时候有几个措辞习惯值得养成。用“必须”“禁止”“只能”这类强指令词表达硬性要求;用“优先”“尽量”“如果可能”表达软性偏好;避免用“请”“希望”“最好”这类礼貌但含糊的词,模型对它们的执行力很弱。还有个细节,需要模型做判断时,把判断依据显式列出来,而不是让它自己找。前者稳定,后者随机。

3.3 迭代循环:单变量测试与版本记录

提示词迭代最大的坑是一次改三处,然后效果变好了也不知道是哪处起的作用,下次遇到类似问题依然没有可复用的经验。

我的做法是严格单变量。每一轮只改一处,跑同一批测试输入,记录结果。测试输入我一般准备十到二十条,覆盖典型情况、边界情况、容易出错的陷阱情况。这个量级手工比对还扛得住,再多就得上工具了。

版本记录我用最简单的形式,一个表格加一个文件夹。表格里记录版本号、改动内容、改的原因、测试结果、是否采纳。文件夹里存每一版的完整提示词文本。听起来很土,但真出问题时这套东西能救命——尤其是当你半个月后发现效果回退了,想找上一版好用的提示词时。

版本改动点改动原因测试通过率结论
v1.0初版六段式基线14/20保留
v1.1约束段增加“禁止推测”v1.0 出现 3 例编造18/20采纳
v1.2示例从 1 个增加到 3 个输出格式仍不稳定19/20采纳
v1.3增加 20 条软约束想进一步提升15/20回退

最后一行的回退很典型。约束堆多了反而掉分,因为模型在冲突的约束之间摇摆。这类教训只有记录下来才不会重复犯。

还有一点值得强调:不要在同一轮里既改提示词又换模型或改参数。模型版本更新带来的效果波动比提示词改动更大,混在一起测,结论全是错的。

3.4 参数与上下文预算的取舍

提示词之外,有几个参数直接影响输出表现,值得单独说。

温度(temperature)这个参数控制随机性。任务越需要确定性,温度应该越低。做字段抽取、格式转换、分类判定这类任务,我基本把温度压到接近 0,同样的输入每次给同样的结果,便于排查。做创意生成、头脑风暴、文案备选这类任务,才把温度调高,让它给出多样化的方案。中间地带的任务可以先低后高,先看它能不能稳定做对,再放开多样性。

上下文预算这块,我的经验是留出至少三成余量给输出。很多人把输入塞满窗口,结果模型没有足够空间生成完整回答,输出被截断,格式也就崩了。如果素材确实很长,优先考虑分块处理,或者先用一轮调用把长素材压缩成结构化摘要,再拿摘要去做正式任务。

还有个小技巧:把关键指令同时放在提示词的开头和结尾。长提示词里,中间位置的信息利用率是偏低的,头尾夹击能显著提升关键约束的执行率。这不是玄学,是位置效应,实测下来很稳。

3.5 一个完整案例:长文档摘要从 60 分到 85 分

拿一个我自己做过的任务举例:把一份二三十页的调研材料压缩成一页纸的决策摘要。第一版提示词只有两句话,“总结下面这份材料,输出一份摘要”。结果输出是这样的:大段大段的原文摘抄,没有主次,读完之后不知道重点在哪。

我把问题拆成三个:一是模型不知道摘要给谁看,二是不知道什么算重要,三是没有长度和结构约束。对应改了三处。

第一处,明确读者和使用场景:这份摘要给没有读过原文的决策者看,他要在三分钟内判断这份材料是否值得细读。第二处,给出重要性判定规则:优先保留带数据的结论、与既有认知相反的发现、以及明确的行动建议;删去背景介绍、方法论描述和铺垫性论述。第三处,固定结构:三到五条核心结论,每条不超过两句话;一段不超过三句的风险提示;一句总体判断。

改完之后通过率从六成上到八成多。后来又发现一个问题:材料里有多处数据互相矛盾,模型会随机选一个。于是加了一条约束——发现数据冲突时,明确指出冲突并说明各自出处,不要自行取舍。这条加上去之后,输出才能真的拿给决策者看。

这个案例说明一件事:质量提升几乎不来自“措辞变优美”,全部来自“把隐含的判断标准显式化”。每次改版我都问自己一句:这次改的是信息、约束还是结构?如果三者都没变,那这次改版大概率是白改。

4. 进阶技巧:让模型想清楚再回答

4.1 分步推理的用法与边界

让模型先写推理过程再给结论,在很多任务上确实能提升准确率,尤其是需要多步计算、条件判断、逻辑推演的任务。原因不难理解:逐词生成时,如果直接给结论,模型没有机会把中间步骤展开;而先展开步骤,后面的结论就是基于已经生成的内容推出来的,相当于给它一个草稿纸。

但这个技巧不是万能的,用错了反而添乱。我总结的适用范围是:任务有多步依赖关系、需要在不完整信息中做取舍、或者需要核对多个条件是否同时满足。反过来,如果任务是简单的信息抽取、格式转换、单点分类,加推理过程只会增加延迟和出错面。

还有一个实际问题:推理过程占输出长度。如果最终结果要被程序解析,冗长的推理会干扰解析。解决办法是分两轮——第一轮只让它输出推理过程,第二轮把推理结果作为输入,要求它只输出结构化结论。多一次调用,但稳定性提升明显。

另外要注意,模型写出来的推理过程不一定反映了它真实的计算路径,有时候是先有结论再补理由。所以对推理过程的正确性不要过度信任,它的价值主要在于提升最终结论的准确率,而不是用来做审计。

4.2 生成、复核、修订三段式

对于质量要求高的任务,我普遍采用三段式流水线,效果比单轮调用好一大截。

第一段生成,按正常提示词产出草稿。第二段复核,换一个提示词,角色从“作者”切换成“审稿人”,把草稿和原始要求一起喂进去,要求逐条核对约束是否满足、事实是否与素材一致、结构是否符合要求,输出一份问题清单而不是直接改。第三段修订,把问题清单和草稿一起喂进去,要求按清单逐条修改,不改动清单之外的内容。

第二段的关键是“输出问题清单而不是直接改”。如果让它直接改,它往往会把没问题的地方也重写一遍,引入新的错误。先出清单再定向修,改动范围可控。

这三段式听起来成本翻了三倍,但实际算下来常常更划算,因为单轮反复重试的次数往往超过三次,而且重试的结果不可控。不过它适合的是能明确列出检查项的任务,如果任务是创意类的,审稿人的标准本身就不明确,三段式的收益就没那么大。

4.3 结构化输出与解析容错

只要输出要进程序,就必须考虑解析失败的情况。我的经验是,纯靠提示词约束格式,成功率通常在九成上下,剩下那一成会是各种奇怪的变体:多一句话、少个逗号、字段名拼写错、用了代码块包裹。

处理办法有两层。提示词层面,把格式要求写得极其具体,并且明确禁止解释性文字和代码块包裹。工程层面,解析器必须写容错逻辑:先尝试直接解析,失败则尝试剥离可能存在的代码块标记,再失败则尝试提取第一个完整的括号结构,还失败就走降级流程——记录原始输出、重试一次、仍失败则转人工。

还有一个容易被忽略的点:字段值本身的容错。比如枚举字段,模型偶尔会输出一个不在枚举列表里的值,或者大小写不一致。这类问题在解析后做一次规范化处理就能兜住,比反复调提示词经济得多。

4.4 把提示词当代码管:模块化与复用

做到一定规模之后,你会发现很多提示词的段落是重复的。比如“禁止编造”这类约束、“无法确定时填 unknown”这类异常处理、JSON 输出的格式说明,几乎每个任务都要写一遍。手写重复内容的后果是改一处要改十处,总有一处忘了改。

我的做法是把提示词拆成几个可复用的片段:角色片段、通用约束片段、格式片段、异常处理片段、任务专属片段。拼装的时候按顺序组合。这样基础约束改一次全量生效,任务专属的部分单独维护。

更进一步,可以把每个片段和对应的说明写进一个配置文件,用脚本按任务配置拼装成完整提示词。这样提示词就有了“源码”和“构建产物”的概念,版本管理、review、回滚都能按工程流程走。我现在的项目里,提示词全部放在版本控制里,每次改动都要写清改动理由,跟改代码一个待遇。

5. 常见问题与排查实录

5.1 输出跑偏的六种典型症状

排查问题最怕没有方向。我把实际遇到的失败归纳成六类症状,每类症状基本对应固定的几个成因,按这个顺序排查能省不少时间。

症状最可能的成因优先尝试的修法
输出空泛、全是套话信息密度不够,缺具体约束补充硬约束和正例
格式时对时错格式描述层级不够细补齐字段定义和异常处理
内容编造未约束缺失值的处理方式增加“不确定时明确标注”的规则
长输入下漏掉关键信息关键信息埋在素材中间把关键约束在素材后复述一遍
输出千篇一律示例太相似或温度过低增加差异化示例,适度提高温度
前后矛盾提示词内部约束互相冲突给约束排优先级,删掉冲突项

空泛和编造这两类最常见,两者的病根都是“模型只能猜”。空泛是因为它不知道你要的具体粒度和判断标准,编造是因为它不知道“不知道”也是一种合法答案。解决办法都不是加形容词,而是加规则。

前后矛盾这一类最隐蔽。有一次我发现模型输出里一会儿说“总体满意”一会儿说“存在明显问题”,查了半天才发现提示词里既要求“简明扼要”又要求“覆盖全部要点”,模型在两者之间反复横跳。删掉一条之后立刻正常。

5.2 幻觉与过度自信的压制手法

让模型承认“不知道”是需要设计的。默认情况下,它倾向于给出一个完整的、看起来合理的答案,因为训练目标就是生成连贯文本。你不给它留“弃权”的出口,它就一定不会弃权。

我在提示词里通常设三道闸。第一道是来源约束:明确要求所有事实性陈述必须能在给定素材中找到依据,找不到依据的不能写。第二道是弃权机制:明确写出“如果素材中没有相关信息,直接输出‘素材未提及’,不要推测或补充常识”。第三道是自检:要求它在输出末尾列出“本次回答中哪些内容是基于素材推断的”,把推断和事实分开标注。

这三道闸配合起来用,编造率会明显下降。但要注意,弃权机制不能滥用。如果某个字段大部分情况下素材里确实没有,全填“未提及”就失去了意义,这时候需要回头看看是不是素材本身给得不够,或者这个字段根本不该要。

还有一个实用技巧:把不确定的部分拆出来单独问。一次调用里要填十个字段,模型倾向于把十个都填满;如果分成三轮调用,每轮只填三四个字段,它对每个字段的谨慎程度会提高。这个现象的成因我不完全确定,但实测有效。

5.3 长上下文下的信息丢失与重排

处理长文档时,中间部分被忽略是很普遍的现象。我的应对办法有三条。

第一条,结构化预处理。在把长文档喂进去之前,先用一轮调用把它的标题层级、章节划分、关键段落位置整理成一份目录,然后把目录和正文一起给出。模型有了目录,定位信息时就有了参照。

第二条,问题前置加后置。把核心问题写在最前面,在素材结束后再复述一遍。这属于利用位置效应的低成本操作,几乎不增加成本。

第三条,分段处理加汇总。如果文档确实太长,就按章节切分,每段独立处理输出小结,最后再用一轮把小结汇总成总结果。这套流程的成本会高一些,但准确率提升明显,尤其是需要精确引用的任务。

顺带说一个容易忽略的细节:切分的时候不要机械按字数切。切在段落或章节边界上,效果比切在句子中间好得多,因为模型对完整的语义单元理解更稳。

5.4 一份可以贴在显示器旁的排查清单

最后给一份我自己常用的排查清单,按顺序过一遍,大部分问题能定位到。

  • 任务本身是否可验证?如果自己都判断不了好坏,先回去拆任务
  • 提示词里有没有一句是“不可执行”的形容词?有就换成数量或禁止项
  • 硬约束超过五条了吗?超过就分优先级,删掉最不重要的
  • 示例和真实输入同分布吗?不同分布就换例子
  • 关键指令是不是只写在开头?补一条到素材后面
  • 输出格式的异常处理写了吗?没写就一定会有编造
  • 同一批测试输入跑三遍,结果稳定吗?不稳定先解决稳定性再谈优化
  • 上一版效果更好吗?立刻回退,别在坏版本上继续改

这份清单的价值不在于它多完整,而在于它把“凭感觉改”变成了“按项核对”。我带的几个新人用了一个月之后,改提示词的效率普遍提升了一倍以上,因为大部分人卡住的地方都在这几条里。

6. 评估与长期维护:让提示词不随时间退化

6.1 建一个小而狠的评测集

没有评测集,提示词就只能靠感觉迭代,这是个死循环。好消息是,你不需要一个很大的评测集。我的经验是二十条左右就足够起步,关键是这二十条的质量。

构建方法很朴素:从真实数据里挑。挑五条最典型的、五条最边缘的(信息缺失、表述含糊、格式不规整)、五条历史上出错过的、五条看起来简单但实际上有坑的。每条都手工写一份期望输出,或者至少写清楚判定标准。这份东西一旦建起来,后面所有改版都能快速验证。

评测集的维护同样重要。每次线上出现新类型的错误,就把那条样本加进去。跑一段时间之后,评测集会自然覆盖你实际会遇到的各种情况,价值远超任何公开的通用测试集。我现在的习惯是,只要某个错误出现了两次以上,就把它固化进评测集,避免同一个坑踩第三遍。

6.2 版本管理、回归与模型更新应对

模型会更新,这是无法回避的事实。同一个提示词,接口背后换了版本之后表现可能变化,有时候变好,有时候变差。所以回归测试是必须的。

我的流程是:评测集跑一遍出个基线分,任何提示词改动、任何模型版本变更,都跑一遍对比。分数下降就查原因,是提示词和模型不匹配,还是评测集里的某些样本本来就标注有问题。这个过程听起来繁琐,但比线上出问题之后再回滚省事得多。

版本管理上,我把提示词文本、版本号、改动说明、对应的评测分数放在一起维护。生产环境用的版本单独标记,实验版本不许直接上线。这套流程跟发布代码几乎一模一样,唯一区别是提示词改动的风险更隐蔽——它不会报错,只会悄悄变差。

最后分享一个我在实际项目里最深的体会:提示词工程真正难的地方从来不是写,而是定义什么叫“好”。那些效果稳定的提示词,背后都是把业务判断标准一条条掰开揉碎写进约束里,没有例外。所以每次有人问我有没有快速提升的窍门,我的回答都是一样的——先去把判定标准写清楚,那一步做扎实了,提示词基本就成型了。