CodexQA

行业与实践工具与框架

Promptfoo 事实性:子集、超集、一致、冲突、措辞不同

CodexQA 团队阅读约 8 分钟

Promptfoo 用 OpenAI evals 的五类标签给模型打分。默认 A、B、C、E 记 1.0 通过,D 记 0.0 失败。参考写成「巴黎是法国的首都」,多写埃菲尔铁塔仍算超集;写成里昂则是冲突。

本文目录

评测事实性

什么是事实性,为什么重要?

事实性衡量的是大语言模型的回答与既定事实或参考信息有多一致。简单说,它回答的是:人工智能说的到底是不是真的?

一个具体例子:

问题:「法国的首都是哪里?」 人工智能的回答:「法国的首都是巴黎,自公元 987 年起它就是这个国家的首都。」 参考事实:「巴黎是法国的首都。」

在这个例子里,人工智能的回答在事实上是准确的(它包含了正确的首都),但额外加上了巴黎何时成为首都的信息。

随着大语言模型越来越多地进入关键应用,确保它们提供事实上准确的信息,对下面这些事是必要的:

  • 建立信任:用户需要有信心,相信人工智能的回答可靠、真实。_例如,一个理财顾问聊天机器人如果给出错误的税法信息,可能让用户做出代价很高的决定,并失去对你服务的信任。_
  • 减少错误信息:事实上不正确的人工智能输出,可以大规模传播错误信息。_例如,一个医疗机器人错误地说某种常用疫苗危险,可能影响成千上万的患者不去接受重要的预防。_
  • 支持关键用途:医疗、金融、教育和法律领域的应用需要很高的事实准确度。_一个法律助手如果歪曲判例,可能导致有严重后果的错误法律策略。_
  • 改进模型选择:比较不同模型的事实性,有助于为你的应用选对模型。_一家公司可能发现,一个模型更有创造性,另一个在技术文档上的事实准确度高出 30%。_
  • 识别幻觉:事实性评测帮助发现模型何时在「编造」信息。幻觉是模型说出参考里没有、也不符合事实的内容。_例如,发现你的产品支持聊天机器人有 15% 的时间编造并不存在的排障步骤,会是一个关键发现。_

promptfoo 的事实性评测让你系统地测量模型输出与参考事实有多对齐,从而在问题到达用户之前发现并处理它们。promptfoo 是一个用配置文件驱动的大语言模型评测命令行工具。

快速开始:今天就试

开始事实性评测最快的办法,是用我们预先做好的 TruthfulQA 示例。TruthfulQA 是一套用来测试模型是否说真话的问答集。

# Initialize the example - this command creates a new directory with all necessary files
npx promptfoo@latest init --example huggingface/dataset-factuality

# Change into the newly created directory
cd huggingface/dataset-factuality

# Run the evaluation - this executes the factuality tests using the models specified in the config
npx promptfoo eval

# View the results in an interactive web interface
npx promptfoo view

这些命令做什么:

  1. 第一条命令用 huggingface/dataset-factuality 示例模板初始化一个新项目。
  2. 第二条命令进入项目目录。
  3. 第三条命令对照 TruthfulQA 数据集运行事实性评测。
  4. 最后一条命令在浏览器里打开结果供分析。

这个示例:

  • 获取 TruthfulQA 数据集(用来测试模型是否说真话)
  • 创建带有内置事实性断言的测试用例。断言是判定一条测试通过或失败的检查。
  • 把模型输出和参考答案比较
  • 给出详细的事实性分数和分析

你可以这样改它:

  • 在 promptfooconfig.yaml 里取消注释更多 provider,以测试更多模型。provider 是 promptfoo 用来调用某一个模型的适配器。
  • 调整提示词模板,改变提问方式
  • 修改事实性评分权重,以符合你的要求

事实性评测如何工作

promptfoo 实现了一套结构化的事实性评测方法,依据是 OpenAI 的 evals,使用 factuality 这种断言类型。

由模型打分的事实性检查接收下面三项输入:

  • 提示词:发给大语言模型的提示词
  • 输出:大语言模型产出的文本
  • 参考:理想的大语言模型输出,由评测的编写者提供

关键术语

评测把大语言模型输出和参考之间的关系分成五类之一:

  • A:输出是参考的子集,并且与参考完全一致
  • _例子:若参考是「巴黎是法国的首都,人口 210 万」,一个子集是「巴黎是法国的首都」——信息更少,但完全一致_
  • B:输出是参考的超集,并且与参考完全一致
  • _例子:若参考是「巴黎是法国的首都」,一个超集是「巴黎是法国的首都,也是埃菲尔铁塔所在地」——它加上准确信息,同时保持一致_
  • C:输出包含与参考相同的全部细节
  • _例子:若参考是「地球绕着太阳转」,输出是「太阳被地球绕着转」——信息相同,措辞不同_
  • D:输出与参考不一致
  • _例子:若参考是「巴黎是法国的首都」,但输出声称「里昂是法国的首都」——这是事实上的分歧_
  • E:输出与参考不同,但差异不影响事实性
  • _例子:若参考是「地球到月球的距离是 384,400 公里」,输出说「月球离地球大约 384,000 公里」——这个小差异并不实质影响事实性_

默认情况下,A、B、C、E 视为通过(分数可以自定义),D(不一致)视为失败。

创建一次基本的事实性评测

为你的大语言模型输出建立一次简单的事实性评测:

  1. 创建配置文件,带一条事实性断言:

``yaml title="promptfooconfig.yaml" providers

  • openai:gpt-5-mini

prompts:

  • |

Please answer the following question accurately: Question: What is the capital of {{location}}? tests:

  • vars:

location: California assert:

  • type: factuality

value: The capital of California is Sacramento


2. **运行评测**:

```bash
npx promptfoo eval
npx promptfoo view

这会产出一份报告,显示你的模型回答相对参考答案在事实上有多准确。

比较多个模型

事实性评测尤其适合比较不同模型在同一批事实上的表现:

``yaml title="promptfooconfig.yaml" providers

  • openai:gpt-5-mini
  • openai:gpt-5
  • anthropic:claude-sonnet-5
  • google:gemini-2.5-flash

prompts:

  • |

Question: What is the capital of {{location}}? Please answer accurately. tests:

  • vars:

location: California assert:

  • type: factuality

value: The capital of California is Sacramento

  • vars:

location: New York assert:

  • type: factuality

value: Albany is the capital of New York


## 在外部数据集上评测

若要做更完整的评测,可以对照 TruthfulQA 这类外部数据集跑事实性测试。快速开始一节已经讲过。

### 接入你自己的数据集

你可以这样接入任何数据集:

1. **创建数据集加载器**:用 JavaScript 或 TypeScript 获取并整理你的数据集
2. **加上事实性断言**:在每个测试用例里放一条事实性断言
3. **在配置里引用**:

```yaml
tests: file://your_dataset_loader.ts:generate_tests

写出有效的参考答案

参考答案的质量对准确的事实性评测至关重要。下面是具体指南。

什么是好的参考答案?

  1. 清楚:直接、无歧义地陈述事实
  • _好:「法国的首都是巴黎。」_
  • _避免:「人人都知道,美丽的巴黎是壮丽的法国的首都。」_
  1. 精确:包含必要细节,不夹带多余信息
  • _好:「在标准大气压下,水在 0 摄氏度结冰。」_
  • _避免:「水,H2O,在 0 摄氏度结冰,也就是 32 华氏度,形成会漂起来的冰。」_
  1. 可核验:确保参考有权威来源支撑
  • _好:「按照世界卫生组织,COVID-19 大流行于 2020 年 3 月 11 日宣布。」_
  • _避免:「新冠大流行是在 2020 年初某个时候开始的。」_
  1. 完整:包含答案的全部必要部分
  • _好:「美国联邦政府的三个分支是行政、立法和司法。」_
  • _避免:「美国政府有三个分支。」_

要避开的常见坑

  1. 主观陈述:参考答案里避免意见或判断
  2. 随时间变化的事实:对时效信息要小心
  3. 含糊措辞:确保这句话只有一种解释
  4. 不必要的复杂:参考要简单到足以清楚评测

自定义评测

选择打分用的 provider

默认情况下,promptfoo 用 gpt-5 打分。要指定另一个打分模型:

defaultTest:
  options:
    # Set the provider for grading factuality
    provider: openai:gpt-5

也可以按断言覆盖:

assert:
  - type: factuality
    value: The capital of California is Sacramento
    provider: anthropic:claude-sonnet-5

或者用命令行:

promptfoo eval --grader openai:gpt-5

自定义评分权重

按你的具体要求调整事实性评分:

defaultTest:
  options:
    factuality:
      subset: 1.0 # Category A: Output is a subset of reference
      superset: 0.8 # Category B: Output is a superset of reference
      agree: 1.0 # Category C: Output contains all the same details
      disagree: 0.0 # Category D: Output and reference disagree
      differButFactual: 0.7 # Category E: Differences don't affect factuality

#### 理解默认评分权重

默认情况下,promptfoo 使用简单的二元评分:

  • A、B、C、E 的分数是 1.0(通过)
  • D(不一致)的分数是 0.0(失败)

何时使用自定义权重:

  • 如果你担心模型加上可能不正确的信息,就降低 superset
  • 如果措辞的精确对你的应用重要,就降低 differButFactual
  • 如果要求回答全面,就把 subset 调低

分数 0 表示失败,任何正分数都视为通过。分数值可以用来排序和比较模型输出。

自定义评测提示词

若要完全控制事实性如何被评测,可以自定义提示词:

defaultTest:
  options:
    rubricPrompt: |
      You are an expert factuality evaluator. Compare these two answers:

      Question: {{input}}
      Reference answer: {{ideal}}
      Submitted answer: {{completion}}

      Determine if the submitted answer is factually consistent with the reference answer.
      Choose one option:
      A: Submitted answer is a subset of reference (fully consistent)
      B: Submitted answer is a superset of reference (fully consistent)
      C: Submitted answer contains same details as reference
      D: Submitted answer disagrees with reference
      E: Answers differ but differences don't affect factuality

      Respond with JSON: {"category": "LETTER", "reason": "explanation"}

你必须实现下面这些模板变量:

  • {{input}}:原始提示词或问题
  • {{ideal}}:参考答案(来自 value 字段)
  • {{completion}}:大语言模型的实际回答(由 promptfoo 自动提供)

响应格式

事实性检查器支持两种响应格式:

  1. JSON 格式(主要格式,也是推荐格式):
   {
     "category": "A",
     "reason": "The submitted answer is a subset of the expert answer and is fully consistent with it."
   }
  1. 单个字母(旧格式):
   (A) The submitted answer is a subset of the expert answer and is fully consistent with it.

实践建议

建立事实性评测时:

  1. 仔细选择参考答案:它们应当准确、清楚、完整
  2. 考虑多个 provider:不同模型可能擅长不同类型的事实知识
  3. 自定义评分权重:按你的应用对不同事实问题的容忍度来调
  4. 用更强的打分模型:能力更强的模型通常给出更可靠的事实性评估
  5. 用已知例子测试:用你知道正确答案的问题来核验这套设置

另见

Promptfoo,Evaluating factuality,2026-09-29,https://www.promptfoo.dev/docs/guides/factuality-eval/,MIT

觉得有用,转给同事

微信扫码

用微信扫一扫,在手机上打开后即可转发。

用 RSS 订阅

提交勘误