☰
提示词评估与优化全流程:从基线搭建到A/B测试的工程实践
2026/10/20 3:28:22 网站建设 项目流程

做提示词评估与优化这件事,最早是从一次很尴尬的线上事故开始的。当时某项目上线的客服助手,提示词里只写了一句“请友好地回答用户问题”,结果生产环境里用户问一句“你们的退款政策是什么”,助手直接发挥了想象力,编了一个不存在的退款时限。事后排查了一圈,代码逻辑没问题,数据检索也没问题,问题就出在那句看起来人畜无害的提示词上。

从那以后我就形成了一个习惯:任何提示词,上线之前必须先过一遍评估,上线之后还要持续做回归优化。这篇文章就是我最近一个“提示词评估与优化”专项项目的完整笔记,从评估思路、指标体系、实操流程到常见坑点,尽量把能直接照搬的部分都写出来。

这个项目本质上解决的是三件事:如何判断一个提示词好不好、如何定位提示词哪里不好、以及如何通过系统化的手段让它变得更好。适合正在做 LLM 应用落地、Agent 开发、RAG 问答系统,或者只是单纯觉得“提示词改了又改但效果依然飘忽不定”的读者。

1. 提示词评估的起点:从“凭感觉”到“可量化”

1.1 为什么提示词总像开盲盒

大语言模型本身就带随机性,同样的提示词、同样的输入,两次调用结果可能完全不同。更麻烦的是,这种随机性和提示词的结构、表述、示例密度纠缠在一起,很难单独归因。以前项目里调提示词,基本就是“改一句、跑一次、肉眼看结果”,觉得输出顺眼了就上线。这种做法短期可以,长期完全不可控。

我这次项目的第一个目标就是把“评估”这件事工具化。一份提示词好不好,不能只看一两轮对话的主观感受,而是要放到一组有代表性的输入上,批量跑、批量打分,最后算出一个可比较的指标。只有把评估做成了数据,优化才有方向。

做法其实不复杂:准备一批覆盖典型场景的问法,让提示词逐条处理,然后从多个维度给每个输出打分,汇总成平均分、达标率、方差等统计量。同一份提示词在不同输入上的平均表现,就是它的“基线”。后续改一版,再用同样的测试集跑一遍,分数涨了就是真涨,而不是某条样本上碰巧运气好。

1.2 评估对象比评估方法更重要

评估之前必须先明确一个边界:我们评估的到底是“提示词本身”,还是“整个系统”?在实际项目里,提示词几乎不会单独工作。RAG 系统里要拼接检索到的文档片段,Agent 场景里要穿插工具调用,代码生成还要经过编译检查。如果把这些外部环节的输出一起算到提示词头上,评估结果会非常失真。

我这次的做法是做一个“最小化闭环”:把提示词固定在一个可以复现的输入输出环境里,外部依赖尽量模拟或者打桩。比如测一个 JSON 抽取类的提示词,就把输入文本固定住,调用参数固定住,只改变提示词文本本身;检索结果直接使用预设好的固定片段,不允许跑真实检索。这样每次分数的差异,基本都能归因到提示词的变化上。

这个设计看起来多花了一点时间,实际上省了大量排查问题的精力。否则优化提示词时发现分数波动,根本分不清是提示词变了还是检索结果变了。

1.3 先定场景,再定标准

提示词评估有个特别容易踩的坑:试图用一套通用的标准去衡量所有提示词。提取结构化信息的提示词和生成营销文案的提示词,评估维度应该完全不同。前者看重字段完整性和格式正确性,后者看重相关性和可读性。评估体系必须根据目标场景定制。

在这个项目里,我把场景分成了几类:信息抽取、内容生成、代码生成、对话问答、以及需要多轮规划的 Agent 任务。每一类建立了不同的评估侧重,信息抽取类重点看字段覆盖率和格式错误率,对话问答类重点看有用性和引用准确性,Agent 任务则额外关注步骤执行的成功率。

这看起来像常识,但真到了执行层面,很多项目还是用同一个 prompt 模板、同一套评估脚本在跑所有场景。最后结果就是分数很好看,实际体验很差。所以我把“场景划分”作为整个评估设计的第一步,先列清楚当前要优化哪些任务,再按任务定制打分表。

2. 指标体系设计:一套能落地打分的评估维度

2.1 六个核心评估维度的定义与权重

我整理了六个通用维度,每个场景根据侧重点不同分配权重:

维度含义典型案例判断标准建议权重范围
任务完成度输出是否达成用户/系统设定的目标是否给出了正确格式的结果、是否包含必要操作步骤25% - 35%
格式遵循度输出结构是否符合提示词中的格式要求是否严格输出 JSON、是否遵守 Markdown 层级、是否包含指定字段15% - 25%
语义相关性输出内容是否紧扣输入指令回答是否答非所问、是否偏离主题15% - 20%
事实一致性输出是否有据可依,不编造信息是否引用了检索片段中的原文,是否出现幻觉15% - 25%
鲁棒性面对不同表述的输入,输出质量能否保持稳定换一种问法结果是否依然可用10% - 15%
成本效率达成目标所需 token 消耗是否合理是否能用更短输出完成同样任务5% - 10%

权重不是固定的。在信息抽取类任务里,格式遵循度和任务完成度加起来我会给到 50% 以上;而开放式问答里,语义相关性和事实一致性更重要。这个权重表在项目开始时就要和需求方对齐,避免后期因为“你打分标准不客观”产生扯皮。

2.2 打分方式:人工打分与模型打分结合

打分方式直接影响评估体系的成本与可信度。我在这项目里用的是“模型初步打分 + 人工抽检校准”的组合。

模型打分阶段,我直接选一个参数稳定的通用模型作为评审模型,给它一套详细打分规则,让它对每条输出按维度打分,并强制要求给出理由。这样一个测试集几百条样本,几分钟就能出结果,成本很低。但它本身也是模型,会存在偏好和偏差,比如可能偏爱更长、更华丽的输出,或者对特定格式要求过严,甚至会有“自己在夸自己”的倾向。

人工校准阶段,我会抽取 10% 到 15% 的样本,让项目成员对照真实需求人工打分,再和模型得分做一个对比。如果发现系统性的偏移,比如模型普遍给分偏高,就调整打分提示词里的校准锚点(给出几个“边界样本”的分数作为参照),然后重新跑一遍。这一步非常必要,直接裸用模型打分做决策,很容易被分数误导。

2.3 指标不要只看平均数,要看分布

平均数是最基础、也是最容易骗人的指标。在提示词评估里,平均分搭配合格率和方差才有意义。举个例子:两个提示词的平均分都是 8.2,但一个是在所有样本上都稳定在 9 分左右,另一个是在 80% 样本上拿满分、20% 样本上彻底跑偏得 2 分,这两者完全不是同一种质量水平。

我在每次评估报告里都会附上三张图:分数分布直方图、按输入类型分组的柱状对比、以及失败样本(低于 6 分)的具体输出列表。真正指导优化的,往往不是平均分,而是那批“某一类输入上总是失败”的样本。后续优化方向,也是从这里拆出来的。

3. 从评估到优化:一套可落地的闭环流程

3.1 建立测试集:评估体系的“地基”

测试集的质量直接决定了评估结果有没有参考价值。我这次项目的测试集选了几个不同的来源:线上日志里沉淀的真实用户问法、业务方手动补充的典型用例、以及针对容易出现幻觉的边界问法。总量控制在 500 条以内,信息抽取类用了 300 条左右,内容生成类用了 200 条左右。数据量不是越大越好,关键在于覆盖度和标签清晰度。

每条测试样本都要有对应的“期望结果说明”,标注清楚输出里必须包含什么、可选包含什么、绝对不能出现什么。比如“产品价格问答”这条,期望结果必须包含“价格字段”,绝对不能出现“根据某具体日期计算”这种不存在的逻辑。有了这些标签,打分阶段就不需要纯靠评审模型脑补,约束条件和判断标准都写在评估项里。

测试集也需要做版本管理,避免后期无意间污染了基线。这里有必要提一下“回归测试”的概念:基准测试集的数据一经确认,就只允许追加、不允许随意删改。每次优化提示词,都用这套数据跑回归,看分数涨跌;如果发现某条样本题意已经变了,移入“废弃样本”区,而不是直接改判分标准。

3.2 优化手段:从结构化指令到示例引导

提示词优化的几个常用手段,在这类评估驱动项目里基本都能发回作用。

第一是结构化指令。把“请回答用户问题”改成“先判断问题类型,再根据已知信息回答问题,回答控制在 200 字以内”,输出质量通常会有显著提升。原因是模型在开放指令下默认的推理路径不明确,约束越多,行为越稳定。

第二是 few-shot 示例。在系统提示词里加入 3 到 5 个“输入输出对”,相当于给模型工作范本。这个方法对格式遵循度的提升尤其明显,比如要求模型输出 JSON 时,给一个标准 JSON 示例,格式错误率往往能直接下降三分之一甚至更多。

第三是步骤分解。把复杂任务拆成两步或三步,比如“先抽取实体,再判断关系,最后输出 JSON”,每步输出作为下一步的输入。这种方式会牺牲一点响应速度,但能明显提升复杂任务的任务完成率。

第四是措辞和权重的调整。我发现两个技巧特别有用:一是直接在提示词里标明“优先级”,比如“格式正确性优先于回答完整度”,模型的行为会发生明显变化;二是避免否定式表达,比如“不要输出无关内容”的效果远不如“只输出与问题相关的内容”稳定。

3.3 A/B 测试与单一变量原则

在优化过程中,我踩过的最大的坑就是同时改多个变量,导致最终无法判断是哪一处改动起了作用。因此,这个项目的所有版本更新都强制走 A/B 流程:一次只改一个变量,比如只调整示例数量、只调整指令措辞、只调整输出格式约束,运行同一个测试集,对比新旧两版的分数差异。

这样的对比跑得多了会积累出大量经验:比如某类任务,把输出从自然语言改成 JSON 格式后,任务完成度不升反降,因为模型把很多精力放在生成格式上,忽略了内容本身;再比如某些场景,加示例的效果比加描述性指令更好,因为描述容易被模型忽略。这些经验最终沉淀成了一份场景规则表,进入项目标准流程,后面再遇到类似需求,直接查表选择初始方案,省掉大量试错时间。

4. 实操复盘:一个知识问答提示词的完整评估与优化过程

4.1 基线搭建与第一轮评估结果

下面用一个简化案例来完整展示流程。假设某项目需要优化一个企业内部知识问答助手的提示词,原始提示词大概是这样的:

请基于以下文档片段回答用户问题:{context} 用户问题:{question}

这是最典型的“裸提示词”。我用基准测试集(150 条问题,覆盖制度查询、流程说明、数据定义等类型)跑了第一轮评估,结果如下:

维度基线得分(满分 10 分)问题表现
任务完成度7.6部分回答遗漏关键操作步骤
事实一致性6.8频繁出现文档中不存在的细节,编译进提示词里的固定上下文被忽略
格式遵循度9.0自然语言输出,格式问题不明显
语义相关性7.4部分回答跑偏,把“报销政策”答成了“请假流程”

这个结果不算惨,但事实一致性 6.8 分意味着存在明显的幻觉风险。翻看失败样本后发现几个典型问题:模型经常“自由发挥”文档里没有提到的金额和时限;面对文档片段里没有直接答案的问题,倾向于编造而不是说“不知道”。于是第一轮优化重点就落在“降低幻觉”上。

4.2 第一轮优化:明确指令与限制条件

第一轮优化,我只改了提示词的指令部分,不调整示例,也不调整输出格式:

请严格依据以下文档片段回答用户问题。如果文档片段中没有足够信息,请直接回答“无法从当前资料中获得该信息”。 文档片段:{context} 用户问题:{question}

改动看起来不大,就是加了“严格依据”和拒绝回答策略。跑同一测试集,事实一致性从 6.8 升到了 8.4,任务完成度从 7.6 升到 8.1。这个涨幅比我预想的还大。原因也好理解:原提示词虽然提到了“基于文档片段”,但没有明确处理“信息不足”的情况,模型在模糊状态下,自动补全的倾向就会显现。加了清晰规则后,模型更容易选择保守路径。

同时注意到一个新的副作用:部分样本上,模型开始有点“过于保守”,明明文档里能推断出来的信息也不敢说,只说“无法获取”。这本质上是因为我在提示词里用了“严格依据”这种强约束词,模型过度执行了拒绝策略。针对这个现象,我在优化记录里标记了一条注意点:约束指令不能太“硬”,要给模型留出推断空间,并在第二轮尝试通过示例来平衡。

4.3 第二轮优化:示例引导与“软约束”调整

第二轮优化加了两组 few-shot 示例,一组是文档信息充分、应该给详细回答的样例;另一组是文档信息不足、应该拒绝回答的样例,同时在“严格依据”措辞上做了柔和化调整:

请依据以下文档片段回答用户问题。可根据片段中的信息进行合理推断;如果片段中完全没有相关信息,请明确回答“无法从当前资料中获得该信息”。 示例1: 文档片段:加班补贴标准为每小时20元,需提前提交申请。 用户问题:加班补贴是多少钱一小时? 回答:根据文档,加班补贴标准为每小时20元。 示例2: 文档片段:报销需要提供发票和付款凭证。 用户问题:报销最晚多久内提交? 回答:无法从当前资料中获得该信息。 现在处理以下内容。 文档片段:{context} 用户问题:{question}

这轮的评估结果:事实一致性 8.4、任务完成度 8.2、语义相关性 8.0。没有大幅跃升,但显著减少了过度保守的问题。同时我观察到格式遵循度从 9.0 降到了 8.6,原因是有部分输出开始自动带上了“回答:”前缀,格式风格和前两版出现了偏移。

这个现象在优化里很常见:新增的示例会把格式风格“传染”给后续所有输出。如果不希望出现某种格式趋势,示例本身就要严格设计。这个版本上线前,我在提示词末尾加了一句“直接输出回答内容,不要输出‘回答:’前缀”,格式问题才压下去。

4.4 回归测试与上线标准

最终版本跑完整回归测试,和基线对比结果如下:

维度基线得分最终版本得分提升幅度
任务完成度7.68.2+0.6
事实一致性6.88.4+1.6
格式遵循度9.08.8-0.2(可接受)
语义相关性7.48.0+0.6

事实一致性提升最明显,这也对应了最初的风险点。我把“可接受标准”设成全部维度不低于 7.5、关键维度不低于 8.0,这个版本达到了要求,可以进入灰度上线。同时我把这三版提示词全部存档,记录改动点、评估结果和失败样本,保证后续任何时候都能回溯到某个状态。

5. 工具选型与自动化评估管线搭建

5.1 轻量级脚本方案的完整实现

评估流程如果全靠手动逐步操作,很快就会被淘汰。这个项目里,我用 Python 写了一个轻量级评估脚本,核心流程大概分四步:读取测试集、调用模型API生成答案、调用评审模型打分、汇总输出报告。

# 伪代码示例,展示评估脚本的核心流程结构 import json import time from collections import defaultdict TEST_FILE = "eval_set.jsonl" API_BASE = "本地模型服务的OpenAI兼容接口地址" def call_model(prompt): # 此处为实际的模型调用逻辑 pass def judge_output(question, context, answer): # 调用评审模型,按打分规则输出分数与理由 pass def main(): results = [] with open(TEST_FILE, "r", encoding="utf-8") as f: samples = [json.loads(line) for line in f if line.strip()] for idx, sample in enumerate(samples): # 1. 构造输入 user_input = sample["question"] context = sample["context"] # 2. 调用生成模型 answer = call_model(user_input) # 3. 调用评审模型 score = judge_output(user_input, context, answer) # 4. 记录原始输出,用于人工抽检 results.append({**sample, "answer": answer, **score}) time.sleep(1) # 控制调用频率,避免触发限流 # 5. 汇总统计 dims = ["task_completion", "factual_consistency", "semantic_relevance"] summary = defaultdict(list) for r in results: for d in dims: summary[d].append(r[d]) for d in dims: print(d, sum(summary[d]) / len(summary[d])) if __name__ == "__main__": main()

这个脚本的价值不在于代码本身有多复杂,而在于它让评估流程变得可复现。每次跑完,生成一个带时间戳的评估结果目录,里面包括每题得分明细、失败样本列表、平均分报告。这样当你改完一版提示词再跑一次,对比报告里的分数,就会有非常确定的反馈。

如果项目预算允许,把测试集和结果存到数据库,加一个简单前端展示仪表盘会更好用。但对大多数项目来说,脚本方案已经完全足够。

5.2 模型服务参数固定:一个容易忽视的关键点

提示词优化过程中,有一个特别容易导致误判的细节:模型服务的温度参数(temperature)、随机种子(seed)等生成参数如果不固定,两次评估差异会混入随机性,根本看不出来优化是否有效。

我在跑评估前,把 temperature 固定在 0.1 甚至 0,同时固定 seed(如果服务支持),确保每一次调用都是确定性的。这样做的代价是结果会少一些多样性,但对于评估“提示词本身的效果”来说,确定性是绝对必要的。

不过这里也要提一个局限:即使固定了参数,模型在部分企业私有化部署上仍可能无法做到完全确定性输出,因为底层浮点计算和批处理调度都可能带来微小的差异。因此我在评估报告里会标注出测试运行的时间、模型版本、采样参数,便于后续复现。这类环境问题的排查经验我在“常见问题”部分还会详细展开。

5.3 评审模型选择与校准

评审模型是整个评估体系中不太起眼、但影响极大的环节。如果用一个非常弱的模型来当评审,打分水平可能不稳定;如果用一个非常强的模型又嫌贵。实际项目中,我会优先选择一个能力中上、响应稳定且便宜的模型,把它配置成固定角色来做评审。

评审指令也需要仔细设计。下面是我实际使用过的评审指令模板:

你是一个公平的评审员,请根据以下规则给模型回答打分。 打分规则: - 任务完成度(0-10):回答是否完整体现了目标结果,是否遗漏关键信息 - 事实一致性(0-10):回答内容是否严格基于给定的文档片段,是否出现编造内容 - 语义相关性(0-10):回答是否紧密围绕用户问题,是否答非所问 评分说明: - 9-10分:优秀,几乎完全满足标准 - 7-8分:良好,有轻微瑕疵但不影响使用 - 5-6分:一般,有可以明显感知的缺陷 - 1-4分:较差,无法直接使用 请先给出每个维度的具体分数,再给出简单的打分理由。输出格式为 JSON。 文档片段:{context} 用户问题:{question} 模型回答:{answer}

这里的一个关键细节是:给评审模型的打分规则里要带上“9 到 10 分必须同时满足哪些条件”这种校准锚点。如果没有这些锚点,评审模型很容易把所有输出都打高分,导致区分度极差。校准之后,还要抽样人工核对,确保分数分布和人工判断一致。

6. 常见问题与排查技巧实录

6.1 评估结果不稳定,多跑几次差异很大

这个问题我遇到不止一次。可能的原因有三个:模型采样参数没有固定;并发调用触发了服务端的负载均衡策略,不同请求落到了不同模型实例上;或者测试样本中存在超长输入,触发了模型的截断行为,导致结果漂移。

排查步骤也很明确:先把 temperature 和 seed 固定,重新跑一轮;如果还想稳定,就把并发数降下来,改成顺序调用;如果问题依旧,检查超长样本和上下文截断策略,看是不是某些样本在输入阶段就被截断了,导致模型看到的上下文始终不一致。经过这几步排查,绝大多数不稳定的情况都能定位到根因。

6.2 评审模型打分与人工判断差距很大

当评审模型打分和人工判断出现系统性偏差时,不要急着换评审模型,先看是差在哪里。常见的一种情况是评审模型偏好长答案,输出越长分数越高,但业务侧恰恰希望回答精炼。另一种情况是评审模型无法识别领域知识错误,明明写错了制度条款,但因为表述流畅给了高分。

针对长答案偏好,可以在评审指令里显式加入一条:“输出长度不影响评分,仅根据内容质量评分”,并配一个短答案高分的示例。针对领域知识错误,最好的办法是把标准答案或核心关键字段放进评审指令,让评审模型按“是否命中关键信息”来判断。如果领域性实在太强,那就干脆把该场景的评估改为全人工打分,模型打分只作为参考。

6.3 优化后分数反而下降,怎么定位

加了示例、改了措辞之后分数反而下降,先不用慌。我通常直接看一下失败样本,找出成绩下降最厉害的那几条。八成的问题出在“新增的约束与旧约束产生了冲突”或“示例的风格和现有需求不一致”上。

比如一个典型情况:原来输出是自然语言,改成 JSON 格式后,格式遵循度上去了,但任务完成度下降了,因为模型把生成精力都放在处理结构上,忽略了内容的准确性。这种情况并不代表优化方向错了,而是提示词需要配合调整,比如在 JSON 输出指令之外同时保留对内容完整性的要求,甚至可以明确写出“确保所有字段内容均完整且准确,再输出 JSON”。

另一个常见原因是“过度拟合测试集”。提示词逐渐变得只针对现有测试集里的问法风格有效,一旦遇到新的问法就抓瞎。这个可以通过定期补充新样本到测试集里缓解,同时在设计提示词时保持一定的通用性,不要把测试集里的特殊措辞硬编码到模板里。

6.4 失败样本分析怎么做才有效率

失败样本分析是评估项目里最能产出干货的环节。我建议按照“先聚类、再归因”的顺序去做。先把失败样本按问题类型分组,比如“带数字的查询”、“带条件判断的查询”、“信息不足的查询”、“含多个子问题的复合查询”等,每一类下再看模型的错误输出属于哪种模式:是编造信息、遗漏信息,还是格式错误。

这样一轮分析下来,你会得到一张非常清晰的“薄弱点清单”。比如这个项目里发现:含多个子问题的复合查询最容易出现遗漏;带数字的查询最容易出现编造;信息不足的查询在加了拒绝回答策略后明显改善。每一条都可以对应到具体的优化动作,让优化不再靠感觉。

6.5 基线版本管理混乱,回不到历史状态

提示词迭代做多了,版本管理特别容易出问题。我现在的习惯是:每一版提示词存成一个独立文件,文件名带日期和版本号;同时每次评估运行生成的测试结果目录,也与提示词版本号一一对应。这样任何时候翻回去,都能看到那一版提示词长什么样、当时的评估数据是多少。

版本管理的收益在跨团队合作时体现得最明显。某次项目里需要对比两个同事分别提出的优化方案,如果没有版本记录,就只能靠记忆判断哪个改动影响最大。有了版本记录,直接跑两份历史版本的提示词到同一测试集,数据说话,争论自然结束。

6.6 别忘了“负面样本”的评估价值

大部分人在设计测试集时都会聚焦于“正常问题”,却忘了配上“负面样本”。比如:明显超出知识范围的提问、恶意输入、空输入、超长输入、模糊问题等。这些样本的加入,对于评估提示词的鲁棒性和安全性至关重要。

我在这个项目里专门加了一组“边界样本”,包含若干个不应让模型继续回答的问题类型。结果表明,基线提示词在这组样本上的得分只有 4.8,远低于正常样本的 7.6。这组数据直接促使我们加上了一层输入拦截逻辑,而不仅仅是调整提示词。这是整个评估流程中最有价值的部分——它说明提示词评估不只是“改文案”,更是发现系统性问题的探照灯。

7. 最后分享一点个人体会

这类评估项目做下来,我最大的感触是:提示词优化,本质是一个“预期管理”和“信息结构设计”的问题。你得先知道模型在默认状态下会怎么处理你的指令,再通过结构化的方式一步步收紧它的行为,同时用足够的评估数据确保你没有在“拆东墙补西墙”。

我个人建议,任何一个要上生产的提示词,哪怕再简单,也至少维护一个 30 条样本的迷你测试集,每次改动跑一遍,成本很低,但能拦住大量上线后才暴露的问题。如果你能把评估脚本也沉淀下来,后面所有相关的优化工作都会轻松很多。

另外还有一个小技巧:优化提示词时,把每版改动的原因和结果写进注释或变更记录里,不要只存最终版。一个月后回头翻,你会发现每一行修改背后都有当时的思考和代价,这些经验比最终那版提示词本身值钱得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询