当你有三版 Prompt、两种模型和五十条案例时,需要执行的已经不是一次问答,而是一组有结构的实验。Promptfoo 值得阅读的地方,是它怎样把这些配置变成独立运行、断言和可比较的记录。
本文固定源码提交 fc57736863f0a73860ebae67eab5dcc587cfb341;该快照的 package.json 标记为 0.123.0,源码提交与 npm 发布包仍应分别核对。我们先使用不调用模型的本地 Provider 看清流程,再说明替换真实系统的位置。
配置描述的是实验矩阵
Prompt 定义待比较的任务指令,Provider 定义怎样取得被测输出,tests 提供变量和期望断言。若全部组合都适用,两版 Prompt、两个 Provider、三条案例会形成十二个运行单元。重复试验还会进一步扩大数量。
这个组合不是永远应当全展开。有的模型不支持某种输入,有的任务需要特定环境,应该显式筛选并报告适用范围,不能把未运行组合算成失败或从比较中无声消失。
配套配置使用一个本地 CommonJS Provider。它从 context.vars 读取订单号,返回固定查询结果;输出字面包含 paid 并不等于真实 Agent 已查询数据库。这个示例只验证 Provider—断言—报告的连接。
# 下载到同一目录后运行;这份配置没有模型网络调用。
prompts:
- "查询订单 {{order_id}}"
providers:
- file://provider.cjs
tests:
- vars:
order_id: A1042
assert:
# 固定标签适合精确匹配;开放式回复不应普遍用 equals。
- type: equals
value: paid
- vars:
order_id: A9999
assert:
- type: equals
value: not_found
完整文件见 promptfooconfig.yaml下载 和 provider.cjs。本轮没有安装或运行 Promptfoo CLI,预期通过仅描述固定示例设计,不是实际执行报告。
沿着一次执行阅读源码
在该快照中,src/evaluator.ts 包含实验编排和 runEval。一次运行会取得渲染后的 Prompt,调用 Provider 的 callApi,再把输出交给断言流程。围绕这些步骤还有限流、取消、回调、输出处理和记录保存。执行器源码
阅读时不要试图一口气读完整个大文件。先沿着“渲染结果 → Provider 输入 → ProviderResponse → 断言结果”追踪你自己的案例,记录每一步的数据形状,再回头看并发与缓存。这样可以知道一个失败来自模型回答、适配器异常,还是评分逻辑。
src/assertions/index.ts 的 runAssertion 处理单项检查,runAssertions 组织一组断言,其他处理器负责具体类型。断言入口
如果返回 paid,但断言期待 shipped,属于被测结果不符合期望;如果 Provider 抛异常或输出格式不符合适配契约,则应保留为执行问题。最终报告不能只剩一个 false,让开发者猜是哪一层坏了。
断言怎样分工
等值和 JSON 检查适合结构化结果,JavaScript/Python 自定义断言适合业务规则,模型评分适合语义判断。断言可以返回分数、通过状态与理由,配置中的权重或阈值会影响汇总,具体行为需要随版本核对。
对于退款任务,业务约束应进入独立门禁。不能因为几个语义断言分数很高,就允许错误金额被加权稀释。把评分平台的默认汇总直接当作发布策略,是常见的责任错位。
自定义断言是可执行代码,应该只从受信任仓库加载;候选回答里的代码片段不能直接作为断言执行。给断言进程的网络和密钥权限也应最小化,因为评测工程同样具有执行能力。
接入真实 Agent 的边界在哪里
用实际 API Provider 或自定义适配器替换本地类,让它接收公开任务输入并调用待测服务。服务返回最终输出,以及可关联的 trace_id 和受信任业务快照。隐藏期望留在评分侧,不能为了方便把整个 test 对象送给 Agent。
带副作用的任务每次运行都需要独立初始状态。如果十二个组合共用同一笔订单,第一轮退款以后,第二轮看到的是已退款订单,版本比较就变成环境污染。Provider 适配器应创建隔离案例环境,并在日志里记录环境版本。
只返回助手最后一句话,只能评这句话;要评授权、工具结果和业务状态,就要提供相应观测或关联查询接口。框架不会自动从文本中恢复真实发生的全部动作。
缓存、并发与红队怎样解释
缓存适合减少重复成本,但研究模型随机性时,要明确是否绕过缓存以及缓存键的构成。否则重复十次可能只是同一份结果被取出十次。并发则可能触发限流,要区分排队、请求失败和任务失败。
红队扩展会生成攻击输入,并按攻击目标判断是否突破边界。它不是一份通用安全证书。要检查攻击者能力、预算、目标系统和成功定义,同时保留相似的正常请求,评估误拒。
CI 中可以先运行便宜的结构与规则案例,再运行有预算的模型评测。保存配置、案例摘要、模型标识和逐条结果,才能解释一次提交为什么被拒绝。不要把一个绿色总分当作所有风险都已覆盖。
官方断言类型和选项见Assertions and Metrics。源码解读关注执行链,运行时仍应以固定版本的配置说明为准。
继续阅读与配套材料
上一篇:读懂 Ragas:一个评测指标怎样变成可执行的评分过程。
下一篇:读懂 τ-bench:怎样评测一个真正完成业务任务的 Agent。
完整示例、运行方式和验证边界见评测实验指南下载。本系列的订单、政策、金额和实验数据均为教学示例。