模型换了、系统提示词改了、用户输入稍带点方言,兜底回复就开始胡言乱语。这大概是所有提示工程从业者都经历过的尴尬时刻。很多人把“测 prompt”理解为在对话框里多聊几句,看起来没问题就上线,结果线上真实流量一进来,各种边界 case 全崩。其实提示系统想要稳定,需要的不是手感,而是一套可复现、可量化的测试方法和工具链。
这篇文章我打算从自己搭建评测体系的实际经验出发,讲清楚三件事:提示系统为什么要单独做测试、到底该测哪些维度、用什么方法和工具把这些测试落地到日常开发里。内容会比较实在,适合正在做 Agent、聊天机器人、内容抽取这类功能的工程师和架构师参考。
1. 先搞清楚为什么提示系统不能靠“感觉”来测
1.1 提示词不是代码,但更需要在线上前被验证
普通代码写错了直接报错或返回错误结果,快速可感知,但提示词出问题往往是“看起来都对、实际全错”——模型返回了流畅的文本,却把关键实体漏了,或者把用户指令理解偏了。更麻烦的是,同一个 prompt 加上同一个输入,换一个模型版本、调一下 temperature,得到的结果就不一样。这种不确定性决定了提示系统必须用工程化的手段来对抗飘忽不定的输出。
我团队里有个项目是做客服工单的自动分类,刚开始负责人说“多测几个话题都挺准”,上线第二天就翻车:用户一个长句子带了好几个诉求,分类结果直接乱掉。后来我们复盘发现,当时根本没有标准测试集,也没有判定“准不准”的统一口径,所谓的“挺准”全凭个人感觉。从那以后,我在所有涉及 prompt 的项目里都会强制推行一套测试流程。
1.2 提示系统测试和传统软件测试的本质差异
传统软件测试验证“程序是否按需求实现”,而提示系统测试验证的是“模型输出是否满足用户意图与业务约束”。前者偏向确定性断言,比如输入 1+1 期望返回 2;后者天然带有语义开放性,比如“请总结这段对话”,合理的总结结果有很多种,不能只靠一个字符串去比对。
这就带来两个转变:第一,断言方式从精确匹配变成语义相似度、规则校验、人工评估的混合策略;第二,测试用例的设计需要覆盖语言表达多样性、极端输入、对抗性输入,而不是只测常规路径。换句话说,提示系统测试更像在做质量评测体系,不是简单地跑自动化用例。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 测试对象与指标体系:先知道自己要测什么
2.1 把评测拆成三个层面,缺一不可
我在实际项目里习惯把提示系统的测试拆成三个层面:底层的提示词模板、中间的应用逻辑与参数配置、上层的整体用户体验。大多数人只盯着“改改 prompt 看回复”,其实真正影响线上稳定性的往往来自中间层,比如超时、重试策略、上下文截断、模型路由。
具体来说,底层要测的是单条 prompt 在各种输入下的输出质量;中间层要测的是整个请求链路是否稳定,包括动态变量填充后 prompt 是否合法、长度是否超限、解析模型输出的代码是否会抛异常;上层要测的是整个产品在真实用户手里的体验,比如用户是否理解系统回复、业务指标是否达成。三层测试承接不同风险,只有三层都有覆盖,线上才相对安心。
2.2 我常用的八项核心指标
评测指标不用一开始就堆很多,但关键几项必须有。
- 任务完成率:模型输出是否完成了用户的核心请求,这是功能性指标,优先于一切。
- 正确率与准确率:比如分类场景里结果是否分对、抽取场景里实体值是否精确。
- 鲁棒性:同一语义换十种表达,输出是否稳定。这条最能暴露 prompt 的脆弱性。
- 幻觉率:输出里是否存在事实性错误或编造内容。RAG、问答类应用特别关注这点。
- 格式合规率:输出是否符合约定的 JSON/XML 结构,以及字段约束是否满足。
- 延迟与成本:模型响应时间、Token 消耗是否符合预算,这决定了方案能不能规模化。
- 安全性:是否容易被注入、诱导输出有害内容,或者泄露系统提示词。
- 人工满意度:直觉体验打分,用于补足自动指标的盲区。
一轮测试跑下来,指标建议控制在三到五个,否则团队会被报告淹没。通常我先盯任务完成率、格式合规率和鲁棒性,上线后再逐步加延迟与成本、人工满意度。
3. 提示系统的测试方法拆解:从用例到流水线
3.1 测试集必须来自真实场景,不能靠拍脑袋
我在项目里吃过最狠的亏是测试集完全由开发自己编,用例和线上真实输入差异巨大。现在我的做法是提前花时间从日志里捞真实用户输入,最少几百条,按类型分层,比如正常输入、长文本、多轮对话、中英混杂、空输入、超长上下文、恶意指令。同一份测试集在不同 prompt 版本上反复跑,才有对比价值。
对于冷启动项目没有历史日志的情况,可以让团队分别扮演不同类型用户,模拟说话习惯生成种子用例,把范围铺开。测试集不是一次性工作,每月至少更新一次,把线上新出现的问题输入沉淀进去。
3.2 改写样本与属性测试:用可控方式对抗不确定性
因为模型输出的随机性,我建议对同一输入跑多次采样,比如固定 seed 或 temperature=0 验证稳定性,再在 temperature=0.7 时跑 N 次验证抖动范围。除了原始输入,还可以用同义改写扩展测试集。早期我手动写了几十条改写,后来直接用另一个大模型辅助生成,但会人工复核,防止改写反而引入错误标签。
属性测试的思路也值得借鉴:不给具体内容,而是给约束条件自动生成或挑选测试输入。比如“输入包含三个以上诉求”“输入语气很冲”“输入是纯符号”。这比按自然语言写死用例更容易暴露边界问题。
3.3 断言从精确匹配走向多层校验
提示系统的输出断言要分层设计。最粗暴的是关键字匹配,只用来做快速检查。真正可靠的是语义相似度评估,用模型或向量化方式判断输出与参考答案是否意思一致。格式与字段校验必须用代码做硬校验,比如 JSON 是否可解析、字段类型是否对、是否在枚举值内。规则化校验也很有用,比如“输出必须包含至少一个工单编号”“不能出现电话号”。
我通常的组合是一个硬校验先卡格式,再用语义评分卡内容,最后加三到五条业务规则做最终把关。三层都过才算这条用例通过。
3.4 黄金样本是回归测试的锚点
每个业务场景都应该维护一个 golden set,也就是参考答案集合。它不需要特别大,几十条高质量、有代表性的输入输出对就够,关键是答案要经人工仔细确认。
每次调整 prompt、换模型版本、改参数,都用这份黄金样本跑一遍回归,分数不低于阈值才允许上线。这是防止“改好 A 场景毁了 B 场景”的最有效手段。我在实际工作中见过太多次因为优化某类问题导致其他场景效果劣化,回归测试拦住了一大半问题。
4. 工具选型与实操:从最轻量到企业级
4.1 轻量起步:一张表、一个脚本也能跑评测
如果团队还小,没必要一上来就上复杂平台。我当时就用一个 CSV 表格记录测试用例、参考答案和预期约束,再写一个 Python 脚本调用大模型 API,批量跑完后输出一份 Markdown 报表。这套手工流程支撑了前两个项目的全部评测需求。
脚本核心逻辑不复杂:读取用例、调用接口、断言校验、汇总得分。真要用起来,会发现自己对 prompt 的理解深入很多,因为你必须把“什么是好的输出”想清楚,变成可执行规则。我建议不管以后用什么工具,早期都要亲手做一遍这样的小系统,否则你很难理解后来那些自动化平台到底替你解决了哪些问题。
4.2 用 pytest 把评测固化进日常开发
当我需要保证每改一次 prompt 都自动跑回归时,就把测试结合进 pytest 流程。做法是把测试集和 prompt 模板放成固定目录,pytest 参数化遍历所有用例,每次跑对应接口,断言里支持语义评分阈值和规则匹配。
代码思路大概是下面这样:
python复制import pytest
import prompt_lib
TEST_CASES = [
{"input": "我的订单没收到,电话是13800138000", "expected_entity": "13800138000"},
]
@pytest.mark.parametrize("case", TEST_CASES)
def test_entity_extraction(case):
result = prompt_lib.run_prompt(case["input"])
assert case["expected_entity"] in result["text"]
这主要是把“手动验证流程”变成“可持续回归的资产”。可以配合 git hook 或 CI 配置,在 prompt 模板变更时自动触发执行。哪怕团队没有专业评测平台,先用 pytest 把测试跑起来,已经比纯靠聊天窗口靠谱得多。
4.3 专业评测与可观测工具:promptfoo、LangSmith、Langfuse、Ragas
当系统复杂到需要可视化对比、线上链路追踪时,就该引入专项工具。
promptfoo 是开源评测框架,用 YAML 配置测试用例,支持断言、多模型对比和回归测试,非常适合我这种不喜欢重复造轮子的人。你可以在一个文件里定义所有 prompt 变体和测试用例,跑完自动出报告,还能把 History 保存下来做持续追踪。
LangSmith 更重在线评测和追踪,可以记录每次 LLM 调用的输入输出、Token 消耗和延迟,支持把真实线上流量拉回测试集,这是它最实用的场景。Langfuse 的开源可观测性和数据集管理也做得不错,适合自托管团队。
如果做的是 RAG 方向,Ragas 是专门评估检索与生成质量的框架,可以计算忠实度、答案相关性、上下文精确率等指标,比完全手写评估逻辑省力很多。
选型标准我总结为三个问题:是否需要开源自托管?是否需要追踪线上真实流量?团队能不能接受写 YAML 或代码配置用例?想清楚这些,再选工具就不容易踩坑。
| 工具 | 定位 | 核心优势 | 注意点 |
|---|---|---|---|
| promptfoo | 回归评测 | 轻量、配置简单 | 偏离线评测 |
| LangSmith | 追踪评测 | 线上链路完整 | 有使用成本 |
| Langfuse | 可观测 | 数据管理灵活 | 需要自建或部署 |
| Ragas | RAG 专项 | 指标计算专业 | 依赖评估模型 |
4.4 评测流程纳入 CI/CD:要不要自动阻断
评测纳入 CI/CD 是个值得斟酌的问题。我的建议是分阶段:项目早期,评测结果只作为展示,不阻塞合并;等指标稳定、测试集可靠之后,再逐步加上阈值阻断,比如核心用例准确率低于 90% 就不允许上线。
主要原因是提示词评测天然带有波动,加上模型版本变化会导致同一 prompt 分数浮动,过于严格会导致大量无效阻塞,团队成员会产生警惕心理,甚至绕过流程。最好是先跑一周记录基线,观察分数分布,再定合理阈值。此外,线上数据回放应该做自动化的定时任务,每周拉取近期真实请求做一轮评测,防止模型悄悄退化而无人察觉。这一条很关键,却经常被团队忽略。
5. 提示系统测试过程中的那些坑与排查技巧
5.1 稳定不等于对:只测“不报错”是最大的陷阱
最常见的错误是只检查“系统有没有返回结果”。系统稳定返回了不代表答案是用户要的。比如一个问答机器人,面对用户追问,每次都回复“根据以上信息,我无法回答该问题”,测试接口上可能全部通过,但用户体验完全不可接受。所以任何“是否通过”都必须在指标定义上关联业务目标,而不是只看流程有没有走完。
5.2 参考答案本身有误怎么办
维护 golden set 时,我发现有时参考答案自身就是错的,或者覆盖不全。这类问题处理建议是:遇到争议用例,先由至少两个人独立标注,再对照差异讨论;实在无法达成一致就先剔除出主测试集,单独放到讨论集。不要因为分歧就让测试流程卡死。参考答案的版本管理也很重要,我在实际项目中用 Git 管理测试集,每次修改都能追溯。
5.3 评测指标之间互相矛盾怎么办
我遇到过准确率上去了,但用户满意度反而下降的情况,原因是对抗性测试加了太多规则,让模型变得过度保守,遇到没见过的表达一律拒答。这就是指标之间打架。处理这类矛盾,我的经验是给指标排优先级。对于客服场景,用户满意度最高,其次才是分类准确率。所有指标分开打分、合并看趋势,不要追求单一数字。
5.4 线上评测还没根治就着急自动化
很多团队一上来就想做全自动的线上评测。我建议保守一点做“半自动”:线上流量先记录日志,定时任务每天抽取一批,自动跑评测,但结果只发到告警群,由人来确认是否真的存在问题。等人力确认的环节稳定了,再考虑对明确规则的问题直接自动阻断。这个节奏可以防止评测体系带来新的运维负担。
6. 我在实际项目中的两点补充经验
6.1 用“两套 prompt 并行评测”替代拍脑袋决策
当我要在一个场景里决定用哪个 prompt 版本时,不会只凭几个例子“感觉 A 比 B 好”。我会做一轮 A/B 式评测:同一批测试集分别跑 A 和 B,输出结果混在一起,让我和同事在不提前告知哪个是哪个的情况下打分。这种盲测能有效减少偏向性。我做过一次,发现大家第一印象选中的方案,盲测结果反而分数更低。
6.2 建立“变更日志+原因说明”的提示词管理习惯
每次修改 prompt 都会同步更新一段说明,写清楚“为什么改、预期解决什么问题、影响哪些场景”。这不是形式主义,而是当三个月后某个用例突然失败时,你能快速定位是当初哪次改动带来的连带影响。我见过太多团队,改了 prompt 不记录,最后谁也说不清线上版本为什么不稳定。
提示系统测试本质上是在为一个概率性的东西建立确定性保障。用测试集搭好基线、用自动评测守好回归、用真实链路反馈形成闭环,这个思路无论用什么工具、无论系统多复杂都适用。希望这篇文章能让你在建设评测体系的路上少踩一些坑。
