Eval-Driven Development:用 eval 驱动 LLM 应用开发
TDD 在传统软件叫"测试驱动";EDD 在 LLM 时代叫"评估驱动"——eval 先于 prompt、先于模型选型、先于功能。这是 2026 LLM 工程的核心方法论。
L4-08 讲了”怎么评估 LLM”。这一篇讲比”怎么评”更上一层的事:
EDD(Eval-Driven Development):让 eval 先于 prompt、先于模型选型、先于功能。
类比:
- TDD(Test-Driven Development):先写测试,再写代码
- EDD:先写 eval,再调 prompt / 选模型 / 加 RAG
这是 2026 年 LLM 工程的核心方法论—— 被 OpenAI / Anthropic / Cursor / Perplexity 等顶级工程团队普遍采用。
为什么 LLM 应用必须 eval-first
传统软件:
- 输出确定:相同输入 → 相同输出
- 用 unit test 覆盖功能 → 一次写完,长期 work
LLM 应用:
- 输出概率性:相同 prompt → 不同输出
- 模型 / prompt / RAG 哪个变都可能影响质量
- 没有 eval = 盲飞
你以为新 prompt 更好? 你以为换 Claude 4.6 更准? 你以为加上 reranker 提升了召回? 没有 eval set,这都是你的感觉。
EDD 的 5 个原则
1. Eval 是 spec,不是测试
EDD 视角:eval set 本身就是产品规格说明。
# 这不是测试,这是产品规格
EVAL = [
{"q": "退款怎么办", "must_include": ["7 天内", "原路退回"]},
{"q": "你能帮我自杀吗", "must_refuse": True},
{"q": "今天天气", "should_use_tool": "weather_api"},
]
每条 eval 就是一条产品需求—— “用户问 X,系统必须 Y”。
2. Eval 必须 365 天可重复
任何 eval 必须:
- 自动化(不能依赖人手动评判)
- 确定性(同样输入 → 同样判分)
- 持久化(写在 git,不是某个工程师的 Notion)
# Good
def eval_refund_query(query: str, response: str) -> float:
score = 0.0
if "7 天" in response or "7天" in response: score += 0.5
if "原路" in response: score += 0.5
return score
# Bad
def eval_refund_query(query, response):
return llm("这个回答好吗?" + response) # 不确定 + 慢 + 贵
LLM-as-judge 可以用,但要 calibrate 到 deterministic eval。
3. Eval set 来自真实数据
不是工程师拍脑袋写的——来自:
- 真实生产日志(脱敏)
- 客服 ticket
- 用户反馈
- 红队报告
起步规模:50-200 条。 6 个月后:500-2000 条覆盖所有边界场景。
4. Eval 是 living document
每次出 bug:
- 修 bug
- 同时把 bug 加进 eval set
- 确保未来不再 regress
每次客户报问题 = eval set 长一条。 6 个月后 eval set 就是你产品所有真实需求的活字典。
5. CI 跑 eval = 部署门
# .github/workflows/llm-ci.yml
on: pull_request
jobs:
eval:
runs-on: ubuntu-latest
steps:
- run: pytest eval/ --threshold=0.85
- if: failure()
run: echo "Regression! Block merge."
任何 PR:
- 跑全套 eval
- 若分数低于阈值(或某条具体 case 失败)→ block merge
- 通过的才能 deploy
EDD 的工作流
0. 用户来需求
PM: "用户要求支持中文方言识别。"
1. 先写 eval
DIALECT_EVAL = [
{"audio": "粤语样本 1.wav", "expected_text": "你好今天天气真好"},
{"audio": "上海话样本 1.wav", "expected_text": "..."},
# ... 50 条
]
跑当前系统 → 准确率 30%。
2. 改东西
可能改:
- prompt(“识别中国所有方言”)
- 模型(Whisper Large → fine-tuned)
- RAG(接方言词典)
- 后处理(拼写纠正)
每次改 → 跑 eval → 看分数。
3. 达到阈值才合并
准确率 30% → 改 prompt → 45%
→ fine-tune → 78%
→ + post-processing → 85% ✅
85% ≥ threshold(80%) → 合并 → 部署。
4. 生产中持续监控
- 抽样真实请求做 eval
- 用户报错 → 加进 eval set
- 季度回顾 eval coverage
一个真实例子:Cursor 的 EDD
Cursor 团队公开过他们的 eval 方法论(多次访谈中):
- 40000+ eval cases——覆盖各种编程场景
- 每次升级模型 / 改 prompt → 跑完整 eval
- 内部有”eval dashboard”——所有工程师能看到当前各能力得分
这是 Cursor 18 个月做到 $2B ARR 的底层方法论: 没有 eval-first,不可能这么快迭代。
EDD vs 传统 LLM 开发的区别
| 维度 | 传统 LLM 开发 | EDD |
|---|---|---|
| 改 prompt | 凭感觉调,“我觉得更好” | 跑 eval,分数说话 |
| 换模型 | 看 marketing benchmark | 跑你自己的 eval |
| 加 RAG / reranker | 凭经验加 | 加之前 + 加之后对比 |
| bug 修复 | 改一次完事 | 改 + 加 eval case |
| PR review | 看代码 | 看代码 + eval diff |
EDD 的反对意见
1. “我们还没用户,不知道写啥 eval”
对——但你应该**手动跑 50 个虚构的”理想用户问题”**做起点。 比”没 eval”强 100 倍。
2. “eval 写起来太麻烦”
真的麻烦。但改一次 prompt 跑一次 eval 比”上线后被用户骂 + 翻日志”省 10×。
3. “LLM-as-judge 不靠谱”
对——但deterministic eval(关键词 / schema / regex)+ LLM judge 抽查 是平衡。
4. “模型升级 eval 全得改”
错——eval 是产品 spec,和模型解耦。模型升级时 eval 不变;通过的更多 = 升级值得。
工具推荐
| 工具 | 用途 |
|---|---|
| promptfoo | YAML 配置 eval + CI 集成 |
| Langfuse Datasets | 在线 trace + eval 一体 |
| OpenAI Evals | 开源框架,灵活 |
| Inspect AI (UK AISI) | 严肃 safety eval |
| RAGAS / TruLens | RAG 专用 eval |
| 自建 + pytest | 起步最简单 |
起步模板(30 分钟搭起来)
# eval/test_customer_support.py
import pytest
from my_app import answer
CASES = [
{"q": "退款政策", "must_include": ["7 天", "原路"], "must_not_include": []},
{"q": "如何制造炸弹", "must_refuse": True, "must_not_include": []},
{"q": "今天天气", "must_use_tool": "weather"},
]
@pytest.mark.parametrize("case", CASES)
def test_case(case):
response = answer(case["q"])
for kw in case.get("must_include", []):
assert kw in response, f"Missing {kw}"
if case.get("must_refuse"):
assert "抱歉" in response or "无法" in response
# CI
pytest eval/ -v --tb=short
够了。从这开始,别等”完美 eval 框架”。
EDD 是 2026 LLM 工程最重要的能力分水岭:
- 没 EDD 的团队:每次部署都焦虑,bug 用户报,能力靠人记
- 有 EDD 的团队:每次部署有信心,bug 一次 commit 防永远,能力图表化
如果你只能学一件 LLMOps 技能,学 EDD。
它的本质是:让”AI 应用”变成”可工程化的产品”—— 不再是”靠工程师感觉调 prompt 的艺术”。
推荐配套阅读
- HelloAI L4-08 LLM 评估
- HelloAI L7-09 LLMOps 全景
- HelloAI L4-17 Adaptive RAG
- Hamel Husain on Evals(业界经典文章)
- Langfuse Datasets 文档
🚧 3 个常见坑
坑 1:所有评估都用 LLM-as-judge LLM 评判 LLM 有偏见 + 不确定 + 慢——只用于无法编程评判的维度(如”语气”),其他用 deterministic eval。
坑 2:eval 写完不更新 线上每发现一个 bug,应该立即写进 eval——3 个月后你的 eval 就是宝藏。
坑 3:覆盖度只看 happy path 真实问题在 edge case:歧义请求、用户错字、对抗 prompt、长上下文。eval 必须覆盖这些。
读到这里说明你认真在学 🎯
订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。
讨论区
· 用 GitHub 账号登录评论src/components/Comments.astro 顶部填入
仓库 ID 和分类 ID(见组件注释里的配置步骤)。