Skip to content

提示词评估工具

Promptfoo 是一个专为提示词工程而设计的开源测试与评估工具,它允许你:

Promptfoo 的核心功能:

  1. 多提示词对比:比较多个提示词在相同输入下的输出质量
  2. 多模型对比:比较 GPT-4、Claude、Gemini、LLaMA 等模型对同一提示词的输出差异
  3. 批量输入测试:用多个输入样例评估提示词的稳定性
  4. 手动或自动评分:支持人工打分、关键词匹配、甚至调用 LLM 对输出进行自评
  5. 报告输出与分析:自动生成 Markdown、HTML、JSON 格式的测试报告
  6. 命令行 & Web UI:提供 CLI 工具,也支持运行 promptfoo web 启动可视化评测界面
  7. CI 集成:可集成至 GitHub Actions、CI/CD 流程,做提示词的“自动回归测试”

模板示例一#

Terminal window
npx promptfoo init

会默认生成一个 promptfooconfig.yaml 模板,内容如下:

# 对本次 prompt 评估做一个简单的描述,比如你要测试什么内容、比较哪些提示词或模型。
description: 'My eval'
# 定义两个提示词模板,它们都包含变量 {{topic}}
# promptfoo 会自动将每个变量替换为 tests 中定义的具体值
prompts:
- 'Write a tweet about {{topic}}'
- 'Write a concise, funny tweet about {{topic}}'
# 指定调用的模型提供者,支持多个。
providers:
- 'openai:gpt-4o-mini'
- 'openai:gpt-4o'
# 定义每一组测试输入(变量)
tests:
- vars:
topic: bananas
- vars:
topic: avocado toast
assert:
- type: icontains
value: avocado
- type: javascript
value: 1 / (output.length + 1)
- vars:
topic: new york city
assert:
- type: llm-rubric
value: ensure that the output is funny

assertions 类型速览

类型描述
equals严格等于某个期望值
icontains忽略大小写包含
regex匹配正则表达式
javascript使用 JS 表达式动态打分
llm-rubric通过 LLM 自动判分(更智能)
1 / (output.length + 1)

output.length 表示模型输出内容的字符数。加 1 是为了避免除以 0。整个式子是:输出越长,分数越低;输出越短,分数越高。

输出内容output.length分数 (1 / (len + 1))
“Hello”51 / 6 ≈ 0.166
”Hello, how are you today?“241 / 25 ≈ 0.04

这个规则鼓励模型输出简洁的结果。

进行评分

Terminal window
promptfoo eval

在线模型配置Key

  1. OpenAI(GPT-3.5 / GPT-4 / GPT-4o)
providers:
- id: openai:gpt-4o
config:
apiKey: $OPENAI_API_KEY
  1. Anthropic(Claude 系列)
providers:
- id: anthropic:claude-3-opus
config:
apiKey: $ANTHROPIC_API_KEY
  1. Cohere
providers:
- id: cohere:command-r
config:
apiKey: $COHERE_API_KEY

promptfoo 会自动从 .env 文件中读取变量,例如:

OPENAI_API_KEY=sk-xxx...
ANTHROPIC_API_KEY=sk-ant-xxx...

确保你运行 promptfoo 命令时,处于 .env 文件所在目录下(或将它放在项目根目录)。

模板示例二#

下面是另外一份提示词模板示例:

prompts:
- id: basic-summary
label: '基础总结'
raw: '请用一句话总结下面这段话:{{input}}'
- id: formal-summary
label: '正式语气总结'
raw: '请用正式、简洁的语气总结以下内容:{{input}}'
providers:
- id: ollama:llama3
- id: ollama:gemma3
tests:
- vars:
input: '小明今天早上迟到了,因为他错过了地铁。'
- vars:
input: '天气预报说今天有雨,所以我们取消了郊游计划。'
- vars:
input: '这家咖啡馆的氛围很好,适合工作和学习。'
eval:
automatic:
- type: keyword-match
criteria:
- '总结'
- '简洁'

这份配置文件大致分为四大部分:

prompts: # 提示词设计
providers: # 模型提供方设置
tests: # 输入样本
eval: # 自动评分方式

提示词设计

prompts:
- id: basic-summary
label: '基础总结'
raw: '请用一句话总结下面这段话:{{input}}'
- id: formal-summary
label: '正式语气总结'
raw: '请用正式、简洁的语气总结以下内容:{{input}}'

说明如下:

字段说明
id每个提示词的唯一标识符(用于结果记录/引用)
label提示词在结果中显示的中文/人类可读名
raw实际传递给模型的提示词模板,支持变量(如 {{input}}

在上面的提示词中,我们设置了两个不同风格的提示词(一个通用、一个正式),Promptfoo 会分别用这两个提示词+输入变量进行测试,形成组合。{{input}} 是变量占位符,会从 tests 中填入。

模型提供方设置

providers:
- id: ollama:llama3
- id: ollama:gemma3

说明如下:

字段说明
id指定要调用的模型(格式为 平台:模型名

我们测试的本地模型有 llama3 和 gemma3,通过 Ollama 调用。Promptfoo 会用所有的 prompt × 所有的 model 做笛卡尔积组合进行测试。

输入样本

tests:
- vars:
input: '小明今天早上迟到了,因为他错过了地铁。'
- vars:
input: '天气预报说今天有雨,所以我们取消了郊游计划。'
- vars:
input: '这家咖啡馆的氛围很好,适合工作和学习。'

说明如下:

字段说明
vars输入变量定义(对应 prompt 中的 {{input}}
input实际输入内容,会被插入到 prompt 中的位置

每条样本会作为一次完整测试输入,和每一个 prompt 和模型组合配对,例如有 3 个 input × 2 个 prompt × 2 个模型 = 12 次测试运行

自动评分方式

eval:
automatic:
- type: keyword-match
criteria:
- '总结'
- '简洁'

说明如下:

字段说明
type自动评分的方式,这里使用的是 keyword-match
criteria模型输出中必须包含的关键词,如果包含则判定“命中”

Promptfoo 会在每一组结果中查找是否出现了这些关键词。若命中多项,得分越高,可用于粗略判断“是否按照我们要求的格式说话”。也可以使用:

这里说一下 llm-rubric,你可以把它理解为模型自己给自己打分(就像一个助教评分学生作业)。提前设计一个评分规则,然后让 GPT 或 Claude 这样的模型代替人类来打分。Rubric 原意就是“评分标准”,在 Promptfoo 中,它就是你写的一段评分说明或标准句子,告诉评分模型:

例如:

eval:
automatic:
- type: llm-rubric
rubric: |
评分标准:
如果输出内容准确、表达清晰且逻辑合理,得5分;
如果有小问题但大体合理,得3分;
如果严重偏题或错误,得1分;
请只输出一个整数分数,不加解释。

Promptfoo 会把你的提示输出 + 输入内容 + rubric 一起打包发给 GPT 模型,然后它会输出类似:

4

你可以指定评分的模型使用哪一个:

eval:
automatic:
- type: llm-rubric
rubric: '...'
provider: openai:gpt-4

如果你没指定,Promptfoo 默认使用你在 providers 中定义的第一个模型。

总结:llm-rubric 是用一个 LLM 来给另一个 LLM 的输出打分的机制。你只需要写一段评分标准,它就能自动判分,不需要你一个一个手动看结果。

模板示例三#

prompts:
- id: good-job-title
label: '好提示词:具体要求 + 输出格式'
raw: |
请根据以下岗位信息,撰写一句吸引人的招聘广告标题:
- 以年轻人喜欢的口吻
- 控制在15个字以内
- 用一句话概括岗位亮点
岗位信息:
{{input}}
- id: bad-job-title
label: '坏提示词:无要求,模糊指令'
raw: |
写一句话。
providers:
- id: ollama:llama3
tests:
- vars:
input: '我们是一家AI初创公司,正在招聘前端开发,技术栈为Vue和TypeScript,提供远程办公和股票期权。'
- vars:
input: '本公司招聘客服专员,工作环境轻松,带薪培训,有下午茶。'
- vars:
input: '招聘Python数据工程师,参与大模型推理平台建设,年薪40万起。'
eval:
automatic:
- type: llm-rubric
rubric: |
请从以下维度为这个输出打分(1~5分):
- 是否突出岗位亮点(2分)
- 是否语言吸引人(2分)
- 是否符合短标题要求(1分)
请仅返回一个整数分数(1~5分)。

可视化输出:

Terminal window
promptfoo view