Promptfoo 实战:用自动化测试框架驯服 LLM 应用的“不确定性“
2026/7/24 13:45:49 网站建设 项目流程

Promptfoo 是一个开源的 LLM 评测与红队测试框架,GitHub 23.5k stars,已被 OpenAI 收购但保持 MIT 开源。核心解决一个问题:LLM 输出不确定,怎么用工程化手段做质量保障?

传统软件测试有断言、有预期结果。LLM 应用不同——同一个 prompt 每次输出不一样,无法写死断言。Promptfoo 的思路是:用 LLM 评测 LLM,通过配置化的评测矩阵、自动化灰度评分、CI/CD 集成,把"玄学"变成可量化的指标。

核心架构:三个层次

Promptfoo 的架构可以拆解为三层:

┌─────────────────────────────┐ │ CLI / Node.js API / CI │ ← 执行层 ├─────────────────────────────┤ │ Config (YAML/JS/JSON) │ ← 配置层 │ ├─ prompts & providers │ │ ├─ test cases │ │ └─ assertions & metrics │ ├─────────────────────────────┤ │ Evaluators (LLM-as-judge) │ ← 评测层 │ ├─ model-graded │ │ ├─ cost-based │ │ └─ function-based │ └─────────────────────────────┘

执行层驱动配置层,配置层定义评测维度,评测层用另一个 LLM(或规则)打分。数据流是单向的:prompt → provider → output → assertion → score。

配置即测试:声明式 YAML 定义评测

Promptfoo 最核心的设计哲学是"评测即配置"。不需要写测试代码,一个 YAML 文件定义所有:

# promptfooconfig.yaml prompts: - "Translate to French: {{text}}" - "Translate to French (formal): {{text}}" providers: - openai:gpt-4o-mini - openai:gpt-4o - anthropic:claude-sonnet-4 tests: - vars: text: "Hello, how are you?" assert: - type: contains-any value: ["Bonjour", "Salut"] - type: llm-rubric value: "The translation should be accurate and natural in French" - vars: text: "The cat sat on the mat." assert: - type: cost threshold: 0.001 - type: latency threshold: 3000

这段配置同时做了三件事:

  1. 对比两个 prompt 模板(普通 vs 正式语气)
  2. 对比两个模型(GPT-4o-mini vs GPT-4o vs Claude)
  3. 对每个测试用例运行多个断言(包含检查、LLM 评分、成本、延迟)

运行promptfoo eval后,结果会生成一个本地 Web 仪表盘,用矩阵视图展示每个组合的通过/失败情况、评分分布和成本对比。

LLM-as-Judge:用模型评测模型

这是 Promptfoo 最核心的机制。传统断言只能做字符串匹配(contains、regex、exact match 等),但 LLM 输出是语义层面的,需要语义级评估。

llm-rubric断言类型的工作流程:

用户输入 → Provider A → 输出 A 用户输入 → Provider B → 输出 B ↓ Judge LLM (如 GPT-4o) ↓ 评分: A=85/100, B=92/100
assert: - type: llm-rubric value: | Score the output on the following criteria (1-10 each): - Accuracy: Is the information factually correct? - Completeness: Does it cover all aspects of the question? - Safety: Does it avoid harmful or biased content? Total score should be the sum / 3. provider: openai:gpt-4o # 指定 judge 模型

这里有个关键设计:Judge 模型和被测模型可以不同。通常用更强的模型(如 GPT-4o)评测较弱模型(如 GPT-4o-mini)的输出。也可以同模型互评,但要注意置信度校准。

CI/CD 集成:在流水线里卡住"坏"发布

Promptfoo 的 CLI 支持所有主流 CI 系统。退出码遵循 Unix 惯例——有测试失败就返回非零退出码,CI 自动拦截。

GitHub Actions 配置

name: LLM Eval on: [pull_request] jobs: evaluate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' - run: npm install -g promptfoo - run: promptfoo eval --share # 运行评测并生成分享链接 - run: promptfoo check --threshold 0.8 # 通过率小于80%则失败 - uses: actions/github-script@v7 if: always() with: script: | const result = require('./promptfoo-output.json'); await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `🤖 LLM评测结果:通过率 ${(result.results.stats.passRate * 100).toFixed(1)}%` });

关键点:

  • promptfoo eval --share生成一个可分享的 Web 结果页面(托管在 promptfoo 云服务),PR 评论里可以直接贴链接
  • promptfoo check --threshold设置通过率阈值,低于阈值直接阻断合并
  • 也可以结合--output指定 JSON 输出路径,后续用任何语言做自定义分析

与 Code Review 集成

Promptfoo 还有代码扫描(code scanning)能力,可以扫描 PR 中的代码变更,检测 LLM 相关的安全问题(如 prompt injection 风险、敏感信息泄露等)。这个功能用 SARIF 格式输出,可以对接 GitHub Code Scanning 或 GitLab SAST。

promptfoo code-scan --sarif > results.sarif

红队测试(Red Teaming):自动化攻击模拟

Promptfoo 内置了红队测试引擎,自动生成对抗性输入测试你的 LLM 应用。开箱即用的攻击策略:

# redteam-config.yaml redteam: plugins: - harmful:basic # 有害内容生成 - jailbreak:tree # 越狱攻击(树搜索变体) - prompt-injection # 提示注入 - hallucination # 幻觉测试 - override-safety # 安全覆盖 - pii-leak # PII 泄露 numTests: 50 target: openai:gpt-4o

运行:

promptfoo redteam run --config redteam-config.yaml

输出是一个完整的漏洞报告,按严重级别排序,每个漏洞附带攻击 payload 和模型回复原文。这相当于把手动红队测试中 80% 的重复劳动自动化了。

测试结果对比

测试类型手动测试耗时Promptfoo 自动化覆盖率差距
Prompt 质量评估2 小时 / 10 个 prompt30 秒 / 100 个语义级一致
越狱检测4 小时 / 20 种攻击5 分钟 / 200+ 种更全面
回归测试每次发版 1 天CI 自动跑,0 人力无漏测
模型对比选型3 天1 小时更客观

踩坑记录

1. Judge 模型的偏差

用 GPT-4 评测 GPT-4o-mini 时,Judge 会倾向于给更长、更 verbose 的输出打高分,而不是真正准确的输出。解决方案:用rubric 中加入长度惩罚或使用classifier-based assertions

assert: - type: llm-rubric value: | Evaluate accuracy only. Ignore verbosity. Penalize outputs longer than 150 words.

2. 测试成本控制

如果配置 5 个 prompt × 3 个模型 × 50 个测试用例 × 50% 的断言用 llm-rubric,一次 eval 就是 5 × 3 × 50 × 0.5 = 375 次 LLM 调用。GPT-4o 的话,一次 eval 可能花掉 $5-10。

建议策略: - 日常开发用gpt-4o-mini做 judge,发版前再用gpt-4o跑一次完整评测 - 用--max-concurrency控制并发,避免 API rate limit - 缓存复用:promptfoo eval --cache在本地缓存 LLM 响应

3. 非确定性问题的断言设计

LLM 评测的本质问题是:没有一个 ground truth。同一个问题可能有多个正确答案。所以断言要设计成"范围检查"而非"绝对匹配":

# 不好的设计 assert: - type: equals value: "Paris" # 太绝对了 # 好的设计 assert: - type: llm-rubric value: "The answer should identify the correct capital city of France."

与同类工具的对比

特性PromptfooLangSmithDeepEvalRAGAS
开源✅ MIT❌ 部分开源
本地运行❌ 需 SaaS
CI/CD 原生需配置需配置
红队测试✅ 内建
代码扫描
Python SDK
Node.js SDK
模型覆盖率150+~50~30~10

Promptfoo 的核心优势在"开发者体验"+"安全评测"两个维度。如果团队在做 LLM 应用的 QA,它是最接近"开箱即用"的选择。

进阶方向

  • 自定义 Assertion 插件:通过promptfoo assert add --type my-check注册 Python/JS 函数做自定义评测逻辑
  • 多模态评测:支持图片输入 + 视觉模型评测(如 CLIP score)
  • A/B 测试编排:用promptfoo eval --table生成对比表格,纳入产品决策流程
  • 私有化部署:所有数据本地处理,不上传到任何第三方服务

Promptfoo 被 OpenAI 收购后的路线图显示,未来会深度集成到 AI 应用开发流水线中,但保持 MIT 开源协议不变。对于测试开发团队来说,现在正是引入 LLM 评测自动化的最佳时机——工具成熟、社区活跃、且有巨头背书。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询