记忆点:先回归,后影子,再灰度;效果和代价必须一起看。
💡 答案要点
Prompt 不是写完就好的——它像代码一样需要版本管理、回归测试和生产灰度
三层 Prompt 评估体系
┌─────────────────────────────────────────────────┐
│ Layer 1: 离线回归测试 (Offline Regression Test) │
│ → 每次改 prompt 跑一遍黄金数据集 │
│ → 确保没引入 regression │
├─────────────────────────────────────────────────┤
│ Layer 2: 线上影子测试 (Shadow Testing) │
│ → 新旧两个 prompt 同时运行 │
│ → 旧结果给用户,新结果记录但不展示 │
│ → 收集真实用户反馈 vs 新输出比较 │
├─────────────────────────────────────────────────┤
│ Layer 3: 在线 A/B 测试 (Online A/B Test) │
│ → 按流量百分比分流不同版本 │
│ → 监控业务指标(CTR/满意度/转化率) │
│ → 统计显著后全量切换 │
└─────────────────────────────────────────────────┘具体实践:离线回归测试
yaml
# eval_set.yaml — 黄金评测集(20-50条真实样本)
test_cases:
- id: TC001
input: "帮我写一封拒绝客户投诉的邮件"
expected_keywords: ["抱歉", "理解", "补偿", "解决方案"]
forbid_keywords: ["不能", "不行", "没办法"]
min_flexibility_score: 0.7
- id: TC002
input: "Python中如何实现线程安全?"
expected_patterns: ["锁", "同步", "互斥"]
max_hallucination_score: 0.1python
import yaml
from collections import defaultdict
def run_regression_eval(eval_set_path="eval_set.yaml", prompt_version="v2"):
"""每次改prompt必跑的回归测试"""
cases = load_yaml(eval_set_path)
results = []
for case in cases:
response = call_llm(case["input"], prompt=prompt_version)
score = evaluate(
response=response,
expected_keywords=case.get("expected_keywords", []),
forbid_keywords=case.get("forbid_keywords", []),
expected_patterns=case.get("expected_patterns", []),
max_hallucination_score=case.get("max_hallucination_score", 0.5)
)
results.append({
"id": case["id"],
"passed": is_pass(score, case),
"score": score
})
pass_rate = sum(1 for r in results if r["passed"]) / len(results)
print(f"Prompt {prompt_version}: {pass_rate:.1%} pass rate ({len(cases)} tests)")
return resultsLLM-as-a-Judge 评分方案
python
def evaluate(response: str, **criteria) -> dict:
"""用另一个更强的 LLM 当裁判打分"""
judge_prompt = f"""
你是一个专业的质量评审员。请根据以下标准给 AI 的输出评分(1-5分):
【任务】{criteria['task']}
【AI回复】{response}
【应该包含的关键词】{', '.join(criteria.get('expected_keywords', []))}
【不应该出现的关键词】{', '.join(criteria.get('forbid_keywords', []))}
请按以下格式评分:
relevance: X (相关度)
accuracy: X (事实准确性)
completeness: X (完整性)
tone: X (语气恰当性)
total: X (总分 1-5)
"""
judge_response = llm_call(judge_prompt, temperature=0)
scores = parse_scores(judge_response)
return scoresA/B 测试的正确做法(避免陷阱)
python
# 固定评判模型和 rubric,控制变量;显著性检验方法取决于指标分布
# Control prompt 和 Variant prompt 在同一批用例上被同一个 Judge 评分
control_scores = [evaluate_case(case, "prompt_v1") for case in test_set]
variant_scores = [evaluate_case(case, "prompt_v2") for case in test_set]
pairwise_comparison(control_scores, variant_scores) # 可用 bootstrap / permutation test
# ❌ 错误:不同 Judge 评不同版本
# Judge-A 评 V1,Judge-B 评 V2 → judge variance 污染结果Prompt 工程在 CI/CD 中的最佳实践
yaml
# .github/workflows/prompt-evals.yml
name: Prompt Eval Gate
on:
pull_request:
paths:
- 'prompts/**'
- 'eval_sets/**'
jobs:
eval-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run prompt regression
run: python scripts/run_evals.py --set production_golden --threshold 0.85
- name: Check regression
run: |
if [[ $(cat eval_results.json | jq '.failures') != '0' ]]; then
echo "❌ New prompt introduced regressions!"
exit 1
fi常见框架对比
| 框架 | 特点 | 适用场景 |
|---|---|---|
| Promptfoo | YAML 配置,CI集成,red-teaming | OSS首选,A/B + 回归 |
| LangSmith | LangChain 团队提供,支持 trace 与在线/离线评测 | LangChain 或跨模型应用 |
| DeepEval | 开源,多种metric | 灵活自定义评估 |
| Ragas | RAG专用,faithfulness/relevance | RAG管道评测 |
| Braintrust | 云端协作,版本管理 | 团队协作+实验追踪 |
30 秒回答
“我会分三层评估 Prompt:先在按错误类型分层的离线集上做回归,再用影子流量检查真实输入,最后才做用户级稳定分桶的在线 A/B。指标同时看任务成功、业务结果、安全、延迟和成本。LLM Judge 要用人工样本校准、交换候选顺序并报告一致性;样本量和显著性方法由最小可检测效果决定,不预设固定的 20~50 条。”
