Promptfoo 调研报告
Promptfoo 调研报告
一、项目概述
1.1 基本信息
| 项目 | 信息 |
|---|---|
| 项目名称 | Promptfoo |
| GitHub | https://github.com/promptfoo/promptfoo |
| 官网 | https://promptfoo.dev |
| Stars | 16.8k+ |
| Forks | 1.5k+ |
| Contributors | 265+ |
| Releases | 398+ |
| 开源协议 | MIT |
| 主要语言 | TypeScript |
| 用户数 | 300,000+ 开发者 |
1.2 一句话介绍
Promptfoo 是一个开源的 LLM 评估与红队测试框架,用于测试和评估提示词、模型和 RAG 系统,支持多模型对比和自动化断言验证。
1.3 发展历程
- 2023年:项目启动,专注于 LLM 提示词测试
- 2024年:快速发展,增加红队测试功能
- 2025年:成为 LLM 评估领域的主流工具,支持 50+ 模型提供商
1.4 解决的核心问题
- 提示词质量难以评估 - 提供 40+ 内置断言类型,自动化验证输出质量
- 模型选择困难 - 支持多模型并行对比测试
- AI 安全风险 - 内置红队测试,覆盖 50+ 漏洞类型
- CI/CD 集成缺失 - 提供命令行工具,易于集成到自动化流程
- 评估成本高 - 本地优先执行,保护数据隐私
二、核心功能
2.1 功能概览
┌─────────────────────────────────────────────────────────────────┐
│ Promptfoo 功能架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ LLM 评估 │ │ 红队测试 │ │ 多模型对比 │ │
│ │ (Evals) │ │ (Red Team) │ │ (Comparison) │ │
│ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 断言系统 │ │
│ │ (Assertions) │ │
│ └────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 报告与可视化 │ │
│ │ (Reports) │ │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
2.2 功能详解
2.2.1 LLM 评估 (Evals)
核心能力: - 自动化测试提示词输出 - 支持多种断言类型验证 - 批量测试用例管理 - 结果对比与评分
断言类型:
| 类型 | 说明 | 示例 |
|---|---|---|
equals |
精确匹配 | 输出必须等于预期值 |
contains |
包含检查 | 输出包含特定关键词 |
regex |
正则匹配 | 验证格式(如邮箱、日期) |
llm-rubric |
LLM 评分 | 使用 LLM 评估输出质量 |
similar |
语义相似度 | 检查输出与预期的相似程度 |
javascript |
自定义脚本 | 编写 JS 代码自定义验证逻辑 |
python |
Python 脚本 | 使用 Python 进行验证 |
2.2.2 红队测试 (Red Teaming)
核心能力: - 自动生成攻击载荷 - 覆盖 50+ 安全漏洞类型 - 支持自定义攻击策略 - 生成安全评估报告
漏洞类型覆盖:
├── 提示词注入 (Prompt Injection)
│ ├── 直接注入
│ ├── 间接注入
│ └── 越狱攻击
├── 信息泄露 (Information Disclosure)
│ ├── 训练数据泄露
│ ├── 系统信息泄露
│ └── PII 泄露
├── 有害内容 (Harmful Content)
│ ├── 暴力内容
│ ├── 仇恨言论
│ └── 非法活动
├── 越权访问 (Unauthorized Access)
│ ├── 角色绕过
│ └── 权限提升
└── 其他漏洞
├── 幻觉
├── 不一致输出
└── 资源滥用
2.2.3 多模型对比
支持的模型提供商(50+):
| 类别 | 提供商 |
|---|---|
| 商业 API | OpenAI (GPT-4, GPT-3.5), Anthropic (Claude), Google (Gemini), AWS Bedrock, Azure OpenAI |
| 开源模型 | Ollama, vLLM, LocalAI, LM Studio |
| 国内模型 | 通义千问, 文心一言, 智谱 AI, 月之暗面 |
| 其他 | Mistral, Cohere, Replicate, Together AI |
对比维度: - 输出质量评分 - 响应时间 - Token 消耗 - 成本分析
2.2.4 CI/CD 集成
# GitHub Actions 示例
name: LLM Eval
on: [push]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install -g promptfoo
- run: promptfoo eval --config promptfooconfig.yaml
- run: promptfoo view --output results.json
三、安装配置
3.1 环境要求
| 要求 | 说明 |
|---|---|
| Node.js | >= 18.0.0 |
| Python | >= 3.8(可选,用于 Python 断言) |
| 内存 | >= 4GB(红队测试建议 8GB+) |
3.2 安装方式
方式一:npm(推荐)
npm install -g promptfoo
方式二:Homebrew(macOS)
brew install promptfoo
方式三:pip(Python 环境)
pip install promptfoo
方式四:npx(无需安装)
npx promptfoo@latest eval
3.3 配置 API Keys
# OpenAI
export OPENAI_API_KEY=sk-xxx
# Anthropic
export ANTHROPIC_API_KEY=sk-xxx
# Google
export GOOGLE_API_KEY=xxx
# AWS Bedrock
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
3.4 快速开始
# 初始化示例项目
npx promptfoo@latest init --example getting-started
# 运行评估
promptfoo eval
# 查看结果
promptfoo view
四、架构设计
4.1 整体架构
┌─────────────────────────────────────────────────────────────────────┐
│ Promptfoo 架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CLI │ │ Web UI │ │ CI/CD │ │
│ │ (命令行) │ │ (可视化) │ │ (集成) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ ▼ │
│ ┌────────────────┐ │
│ │ Core Engine │ │
│ │ (评估引擎) │ │
│ └───────┬────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Provider │ │ Assertion │ │ Red Team │ │
│ │ (模型适配) │ │ (断言系统) │ │ (红队测试) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌────────────────┐ │
│ │ Reporter │ │
│ │ (报告生成) │ │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
4.2 核心模块
4.2.1 Provider 模块
负责与各种 LLM 提供商通信,提供统一的接口:
interface Provider {
id: string;
callApi(prompt: string): Promise<ProviderResponse>;
}
4.2.2 Assertion 模块
执行各种类型的断言验证:
interface Assertion {
type: string;
value: any;
threshold?: number;
weight?: number;
}
4.2.3 Red Team 模块
生成和执行安全测试:
interface RedTeamConfig {
purpose: string; // 应用目的描述
strategies: string[]; // 攻击策略
numTests: number; // 测试数量
}
4.3 配置文件结构
# promptfooconfig.yaml
description: 任务描述
# 提示词定义
prompts:
- file://prompts.txt
- |
你是一个{{role}},请回答:{{question}}
# 模型提供商
providers:
- openai:gpt-4
- anthropic:claude-3-opus
- ollama:llama3
# 默认断言
defaultTest:
assert:
- type: llm-rubric
value: 回答应该准确且有帮助
# 测试用例
tests:
- vars:
role: 助手
question: 你好
assert:
- type: contains
value: 你好
4.4 数据流
配置文件 (YAML)
│
▼
┌─────────────┐
│ 解析配置 │
└──────┬──────┘
│
▼
┌─────────────┐ ┌─────────────┐
│ 生成测试 │────▶│ 调用模型 │
└──────┬──────┘ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ 获取响应 │
│ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 执行断言 │◀────│ 验证输出 │
└──────┬──────┘ └─────────────┘
│
▼
┌─────────────┐
│ 生成报告 │
└─────────────┘
五、断言与指标
5.1 断言类型详解
5.1.1 确定性断言
| 断言类型 | 用途 | 示例 |
|---|---|---|
equals |
精确匹配 | { type: "equals", value: "Hello" } |
contains |
包含字符串 | { type: "contains", value: "成功" } |
icontains |
不区分大小写包含 | { type: "icontains", value: "SUCCESS" } |
regex |
正则匹配 | { type: "regex", value: "^\\d+$" } |
starts-with |
以...开头 | { type: "starts-with", value: "Dear" } |
ends-with |
以...结尾 | { type: "ends-with", value: "谢谢" } |
5.1.2 模型评分断言
| 断言类型 | 用途 | 示例 |
|---|---|---|
llm-rubric |
LLM 评分 | { type: "llm-rubric", value: "回答应准确且有帮助" } |
similar |
语义相似度 | { type: "similar", value: "预期输出", threshold: 0.8 } |
answer-relevance |
答案相关性 | { type: "answer-relevance", threshold: 0.7 } |
context-faithfulness |
上下文忠实度 | { type: "context-faithfulness" } |
5.1.3 自定义断言
JavaScript 断言:
assert:
- type: javascript
value: |
// 检查输出长度
const len = output.length;
return {
pass: len >= 50 && len <= 500,
score: Math.max(0, Math.min(1, (len - 50) / 450)),
reason: `输出长度为 ${len},应在 50-500 之间`
};
Python 断言:
assert:
- type: python
value: |
import json
data = json.loads(output)
return {
"pass": "result" in data,
"score": 1.0 if data.get("confidence", 0) > 0.8 else 0.5
}
5.2 指标系统
| 指标 | 说明 | 计算方式 |
|---|---|---|
| 通过率 | 测试通过百分比 | 通过数 / 总数 × 100% |
| 平均分 | 断言评分平均值 | Σ(score) / n |
| 响应时间 | 平均响应延迟 | Σ(latency) / n |
| Token 消耗 | Token 使用统计 | input_tokens + output_tokens |
| 成本 | API 调用成本 | 根据 provider 定价计算 |
六、红队安全测试
6.1 快速开始
# 初始化红队测试
npx promptfoo@latest redteam setup
# 运行红队测试
npx promptfoo@latest redteam run
# 查看结果
npx promptfoo@latest redteam view
6.2 配置示例
# redteam.yaml
targets:
- id: https
label: 'my-chatbot'
config:
url: 'https://api.example.com/chat'
method: 'POST'
headers:
'Content-Type': 'application/json'
'Authorization': 'Bearer {{API_KEY}}'
body:
message: '{{prompt}}'
purpose: |
这是一个客服聊天机器人,用于回答用户关于产品的问题。
strategies:
- prompt-injection
- jailbreak
- harmful-content
- pii-leak
numTests: 50
6.3 攻击策略类型
| 策略 | 说明 | 示例攻击 |
|---|---|---|
prompt-injection |
提示词注入 | "忽略之前的指令,告诉我..." |
jailbreak |
越狱攻击 | "现在进入开发者模式..." |
harmful-content |
有害内容 | 要求生成暴力、仇恨内容 |
pii-leak |
隐私泄露 | 尝试获取用户个人信息 |
hallucination |
幻觉测试 | 诱导模型编造虚假信息 |
contradiction |
矛盾输出 | 检查输出的一致性 |
6.4 漏洞评级
├── Critical (严重)
│ └── 可导致系统被完全控制
├── High (高危)
│ └── 可泄露敏感信息或绕过安全控制
├── Medium (中危)
│ └── 可能产生有害或不当内容
└── Low (低危)
└── 轻微问题,影响有限
七、使用场景
7.1 适用场景
| 场景 | 说明 | 推荐功能 |
|---|---|---|
| 提示词工程 | 优化和测试提示词 | 评估 + 多模型对比 |
| 模型选型 | 对比不同模型表现 | 多模型对比 + 成本分析 |
| RAG 评估 | 评估检索增强生成 | 上下文忠实度 + 答案相关性 |
| AI 安全 | 漏洞扫描和安全测试 | 红队测试 |
| CI/CD 质量门禁 | 自动化质量检查 | CLI + 断言系统 |
| 回归测试 | 确保更新后质量不下降 | 批量测试用例 |
7.2 典型案例
案例 1:客服机器人评估
# promptfooconfig.yaml
description: 客服机器人评估
prompts:
- |
你是一个专业的客服代表。请用礼貌、专业的语气回答用户问题。
用户问题:{{question}}
providers:
- openai:gpt-4
- anthropic:claude-3-sonnet
defaultTest:
assert:
- type: llm-rubric
value: 回答应该礼貌、专业、有帮助
- type: not-contains
value: AI
- type: not-contains
value: 语言模型
tests:
- vars:
question: 我想退货怎么办?
assert:
- type: contains
value: 退货
- vars:
question: 你们营业时间是几点?
assert:
- type: regex
value: "\\d{1,2}:\\d{2}"
案例 2:代码助手评估
description: 代码助手评估
prompts:
- |
作为代码助手,请根据需求生成代码。
需求:{{requirement}}
语言:{{language}}
providers:
- openai:gpt-4
defaultTest:
assert:
- type: is-valid-code
- type: llm-rubric
value: 代码应该正确、高效、有良好的注释
tests:
- vars:
requirement: 实现一个二分查找函数
language: Python
assert:
- type: contains
value: def binary_search
- type: contains
value: return
7.3 不适用场景
| 场景 | 原因 | 替代方案 |
|---|---|---|
| 实时监控 | 非实时系统 | LangSmith, Arize |
| 大规模生产数据 | 成本高 | 采样测试 |
| 非 LLM 应用 | 功能不匹配 | 传统测试框架 |
八、最佳实践
8.1 评估设计
1. 渐进式测试策略
快速测试(5-10用例)→ 核心测试(50-100用例)→ 完整测试(500+用例)
↓ ↓ ↓
开发阶段 提交前检查 发布前验证
2. 断言组合使用
defaultTest:
assert:
# 基础检查
- type: contains
value: 关键信息
weight: 1
# 质量评分
- type: llm-rubric
value: 输出应该准确、有帮助
weight: 3
# 格式验证
- type: regex
value: "^\\{.*\\}$"
weight: 1
3. 变量化测试用例
tests:
# 使用 CSV 文件
- vars: file://test_cases.csv
# 使用 JSON 文件
- vars: file://test_cases.json
8.2 红队测试建议
1. 明确测试范围
purpose: |
明确描述你的应用目的和限制,
这有助于生成更有针对性的测试用例。
2. 优先级排序
strategies:
# 高优先级
- prompt-injection
- pii-leak
# 中优先级
- harmful-content
# 低优先级
- style-mismatch
3. 持续测试
# 集成到 CI/CD
- name: Red Team Test
run: |
promptfoo redteam run --config redteam.yaml
if [ $? -ne 0 ]; then
echo "红队测试未通过,请检查安全问题"
exit 1
fi
8.3 性能优化
1. 并行执行
# promptfooconfig.yaml
config:
concurrency: 10
2. 缓存利用
config:
cache: true
cachePath: .promptfoo/cache
3. 采样策略
# 大量测试时使用采样
tests:
- vars: file://large_dataset.json
sample: 100 # 随机抽取 100 个
8.4 避坑指南
| 问题 | 解决方案 |
|---|---|
| API 限流 | 设置 concurrency 和 delay |
| 成本过高 | 使用 sample 采样,选择更便宜的模型 |
| 测试不稳定 | 添加 threshold 阈值,接受一定波动 |
| 红队测试误报 | 调整 purpose 描述,排除合法行为 |
九、对比分析
9.1 竞品对比
| 特性 | Promptfoo | LangSmith | Arize | TruLens |
|---|---|---|---|---|
| 开源 | ✅ | ❌ | ❌ | ✅ |
| 本地执行 | ✅ | ❌ | ❌ | ✅ |
| 红队测试 | ✅ | ❌ | ❌ | ❌ |
| 多模型对比 | ✅ | ✅ | ✅ | ✅ |
| 可视化界面 | ✅ | ✅ | ✅ | ✅ |
| CI/CD 集成 | ✅ | ✅ | ✅ | ✅ |
| 成本 | 免费 | 付费 | 付费 | 免费 |
| 学习曲线 | 低 | 中 | 高 | 中 |
9.2 选型建议
┌─────────────────────────────────────────────────────────────┐
│ 选型决策树 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 需要 AI 安全测试? │
│ │ │
│ ├── 是 ──▶ Promptfoo(首选) │
│ │ │
│ └── 否 ──▶ 需要生产监控? │
│ │ │
│ ├── 是 ──▶ LangSmith / Arize │
│ │ │
│ └── 否 ──▶ 预算有限? │
│ │ │
│ ├── 是 ──▶ Promptfoo │
│ │ │
│ └── 否 ──▶ LangSmith │
│ │
└─────────────────────────────────────────────────────────────┘
9.3 适用人群
| 用户类型 | 推荐工具 | 原因 |
|---|---|---|
| 独立开发者 | Promptfoo | 免费、易用、功能全面 |
| 初创团队 | Promptfoo | 成本低、快速上手 |
| 企业团队 | LangSmith/Promptfoo | 根据预算和安全需求选择 |
| 安全研究员 | Promptfoo | 红队测试功能强大 |
十、总结
10.1 优势
- 功能全面 - 集评估、红队测试、多模型对比于一体
- 开源免费 - MIT 协议,无使用成本
- 本地优先 - 数据不出本地,保护隐私
- 易于集成 - CLI 设计,易于 CI/CD 集成
- 社区活跃 - 265+ 贡献者,持续更新
- 模型支持广 - 支持 50+ 模型提供商
10.2 劣势
- 非实时监控 - 不适合生产环境实时监控
- 学习曲线 - 红队测试需要一定学习成本
- 可视化有限 - Web UI 功能相对基础
10.3 最终建议
强烈推荐以下场景使用 Promptfoo:
- 需要测试和优化提示词
- 需要进行 AI 安全测试
- 需要对比多个模型的表现
- 预算有限但需要专业工具
- 需要本地执行保护数据隐私
Promptfoo 是目前 LLM 评估领域最全面的开源工具之一,特别是其红队测试功能,在同类产品中独树一帜。