AI Automation

promptfoo: viết test cho prompt và chạy eval LLM trong CI

Tóm tắt

promptfoo là CLI mã nguồn mở để test prompt, agent và RAG. Viết test case bằng YAML với assertion xác định hoặc chấm bằng model, chạy trên nhiều model và chặn PR khi chất lượng tụt.

Team sửa một dòng trong system prompt để chữa một lỗi khách báo, deploy, và tuần sau phát hiện ba tính năng khác bị "lệch giọng" hoặc trả sai format. Với phần mềm thường, ta có unit test để bắt hồi quy; với ứng dụng LLM, nhiều team vẫn kiểm thử bằng cách… thử vài câu bằng tay. promptfoo (repo promptfoo/promptfoo, MIT) là công cụ CLI để viết test cho prompt, agent và RAG, so sánh nhiều model, và chạy trong CI như unit test. README cho biết dự án đã được OpenAI mua lại nhưng vẫn là mã nguồn mở MIT.

Bắt đầu trong 5 phút

npx promptfoo@latest init --example getting-started
cd getting-started
export ANTHROPIC_API_KEY=...
npx promptfoo@latest eval      # chạy bộ test
npx promptfoo@latest view      # mở giao diện web xem kết quả dạng bảng

Cũng cài được bằng npm install -g promptfoo, brew hoặc pip. Eval chạy cục bộ, có cache để chạy lại nhanh.

Cấu trúc file cấu hình

Mọi thứ nằm trong promptfooconfig.yaml: prompt nào, chạy trên model nào, với bộ test nào:

prompts:
  - file://prompts/triage.txt

providers:
  - anthropic:messages:claude-haiku-5-5
  - anthropic:messages:claude-sonnet-5-5

tests:
  - vars:
      ticket: "Tôi bị trừ tiền 2 lần cho cùng một đơn"
    assert:
      - type: is-json
      - type: javascript
        value: JSON.parse(output).priority === 'P1'
      - type: latency
        threshold: 5000

  - vars:
      ticket: "Làm sao xuất báo cáo ra Excel?"
    assert:
      - type: icontains
        value: how_to
      - type: llm-rubric
        value: Không hứa hẹn tính năng không tồn tại
        weight: 2

Kết quả là một ma trận: hàng là test case, cột là model. Bạn thấy ngay model rẻ có đạt yêu cầu không, prompt mới có làm hỏng case cũ không.

Các loại assertion

NhómVí dụDùng khi
Chuỗiequals, contains, icontains, regex, contains-anyKiểm tra từ khoá, nhãn phân loại
Định dạngis-json, contains-json, is-sql, is-refusalOutput phải parse được
Code tuỳ chỉnhjavascript, python, webhookLogic nghiệp vụ cụ thể
Hiệu nănglatency, costĐặt trần thời gian/chi phí
Agent/toolis-valid-function-call, trajectory:tool-usedKiểm tra agent gọi đúng tool
Chấm bằng modelllm-rubric, factuality, context-faithfulness, similarTiêu chí mềm: giọng văn, đúng ngữ cảnh RAG

Thêm tiền tố not- để phủ định (not-contains). weight đặt trọng số (mặc định 1, đặt 0 để chỉ ghi metric); threshold ở cấp test cho phép pass khi điểm trung bình có trọng số đủ ngưỡng.

Đưa vào CI

  1. Commit promptfooconfig.yaml và thư mục prompt vào repo, cạnh code.
  2. Thêm job CI chạy promptfoo eval khi PR đụng tới thư mục prompt.
  3. Fail PR nếu tỉ lệ pass dưới ngưỡng; đính kèm link báo cáo để reviewer xem diff từng case.
  4. Mỗi bug từ production → thêm một test case. Bộ test lớn dần như regression suite.

Ngoài eval, promptfoo có chế độ red teaming để quét lỗ hổng (prompt injection, rò rỉ dữ liệu…) và sinh báo cáo, rất hữu ích trước khi mở chatbot ra ngoài.

Rủi ro và lưu ý

  • LLM chấm LLM không tuyệt đối: llm-rubric có thể chấm sai. Ưu tiên assertion xác định (JSON, regex, code) khi có thể; dùng rubric cho phần còn lại và thỉnh thoảng kiểm tra tay.
  • Chi phí eval: 200 case × 3 model × chấm bằng model = nhiều lượt gọi. Dùng model nhỏ để chấm, bật cache, chỉ chạy khi prompt đổi.
  • Kết quả dao động: output LLM không cố định. Có thể chạy lặp và dùng ngưỡng tỉ lệ thay vì đòi 100%.
  • Dữ liệu test: case lấy từ ticket thật phải ẩn danh trước khi commit.

Áp dụng thế nào?

  • Dev: Bắt đầu với 20 case thật cho prompt quan trọng nhất, chủ yếu assertion xác định. Chạy trước mỗi lần sửa prompt.
  • Tech Lead: Đưa eval vào CI như unit test; dùng ma trận đa model để chứng minh khi nào hạ được xuống model rẻ hơn.
  • PM: Viết tiêu chí chất lượng thành rubric cụ thể ("không hứa hẹn tính năng", "trả lời bằng tiếng Việt"). Đó chính là acceptance criteria cho tính năng AI.

Nguồn & tham khảo

  1. promptfoo — GitHub repository — promptfoo
  2. Assertions & metrics — promptfoo docs