AI Agent 落地必看:如何用 Promptfoo 搭建第一套自动化测试工作流(一)

前言:别让 Agent 测试成为“玄学”

在开发基于 LangGraph 或 Spring AI 的企业级 Agent 时,最痛苦的莫过于:

你改了一个提示词(Prompt),却不知道它是否修好了 A 漏洞的同时又搞挂了 B 功能。

传统的网页端手动测试效率极低,我们需要一种像 单元测试 一样的工具来量化 Agent 的表现。

这就是 Promptfoo——一个专为 LLM 评测而生的开源神器。


1. 环境准备:解决“版本不匹配”的初级坑

Promptfoo 是基于 Node.js 的。安装命令很简单:

npm install -g promptfoo

🚩 避坑指南 1:Node 版本与 EBADENGINE 警告

如果你使用的是 Node 18,安装时可能会看到一堆 EBADENGINE 警告(提示需要 Node 20+)。虽然这不影响核心功能,但为了环境整洁,建议使用 nvm 切换到 Node 20 或 22。

nvm install 22
nvm use 22
nvm alias default 22

#随后重新安装 promptfoo即可
npm install -g promptfoo

2. 核心:如何接入公司内部 Agent?

公司内部的 AI 接口通常有复杂的鉴权(如 MD5 签名、时间戳、Header 校验)。直接配置 URL 很难跑通。

最优雅的方案:复用现有的 Python 调用类。

2.1 准备 Python 桥接脚本

假设你已经封装好了一个 agent_client.py,里面处理了所有签名逻辑。我们只需要写一个简单的 provider.py

# provider.py
import sys
import json
from agent_client import CompanyAgentClient # 导入你现有的类

def main():
    # Promptfoo 默认会将提问作为命令行参数传进来
    # 我们需要过滤掉空字符和上下文 JSON
    args = [a for a in sys.argv[1:] if a and not a.startswith('{')]
    user_query = args[0] if args else "你好"

    try:
        # 初始化你封装好的类
        client = CompanyAgentClient() 
        # 发送请求并获取响应
        response = client.send_request({"message": user_query})
        
        # 提取真正的 AI 回复文本并打印到 stdout
        # 只有 stdout 里的内容会被 promptfoo 捕获为回复结果
        result = response.json()
        print(result['data']['content'])
        
    except Exception as e:
        # 报错信息一定要输出到 stderr,方便调试
        sys.stderr.write(f"Error: {str(e)}\n")
        sys.exit(1)

if __name__ == "__main__":
    main()

3. 配置文件:Promptfoo 的“大脑”

创建 promptfooconfig.yaml,告诉它去哪里找你的脚本:

description: "公司 Agent 自动化评估计划"

prompts:
  - "{{query}}"

providers:
  # 使用 exec 模式调用你的 Python 脚本
  - id: "exec:python3 provider.py"
    label: "My-Agent-V1"

tests:
  - vars:
      query: "如何申请远程办公权限?"
    assert:
      - type: icontains
        value: "申请流程"

这个文件定义了测试的逻辑:谁来问、问什么、怎么样才算是一个正确的回答。

参数详解:

  • prompts:测试模板。{{query}} 是占位符,会自动替换为下面 tests 里的具体问题。
  • providers:执行者。exec: 模式极其强大,它直接驱动你的本地脚本,不需要把代码暴露给第三方。
  • tests:测试用例集。vars 定义输入,assert 定义预期的正确答案。

4. 开启评估之旅:从 OpenAI 到 Gemini 的“白嫖”之路

配置完成后,执行 promptfoo eval 即可开始。但很快你会发现,当我们想用更高级的 llm-rubric(让 AI 像人一样理解语义并打分)时,Promptfoo 会伸手跟你要 OPENAI_API_KEY

众所周知,OpenAI 是要钱的。 我们可以直接切换到 Google AI Studio,使用 Gemini 2.5 Flash,每天有非常慷慨的免费额度。

操作步骤:

1. 获取 Key:在 Google AI Studio 创建一个 API Key。

2. 设置环境变量:在你的 .env 文件(或终端)中添加:

GOOGLE_API_KEY=你的密钥

3. 修改 .yaml 配置:告诉 Promptfoo 用 Gemini 做裁判

  - vars:
      query: "你是谁?"
    assert:
      - type: llm-rubric
        value: "确保 AI 的身份声明符合公司规定,没有提及 OpenAI 或其他竞品"
        provider: "google:gemini-2.5-flash"

🚩 避坑指南 2:代理明明开了,却依然连不上 Gemini(Connect Timeout 报错)?

如果你使用 Gemini 等国外模型作为“裁判(Grader)”,即便你电脑挂了代理,Promptfoo 依然可能报连不上,报超时报错

原因Node.js 不会自动读取系统的代理设置。

解法:在终端运行前显式注入环境变量:

export HTTP_PROXY=http://127.0.0.1:你的端口
export HTTPS_PROXY=http://127.0.0.1:你的端口
promptfoo eval

5. 调通第一步

执行 promptfoo eval 后,你会看到一个清晰的对比矩阵。最后运行:

promptfoo view

你也可以在浏览器中查看漂亮的测试报告,从此告别盲目调试。

http://localhost:15500/eval