如何设计一个最小可用的 AI 评估系统
很多团队知道 AI 应用需要 Eval,但一开始容易把事情想得过重:标注平台、复杂指标、多人评审、线上实验、模型榜单、数据仓库,全都想一次搭好。
结果是系统迟迟做不出来,Prompt 仍然靠感觉改。
最小可用的 AI 评估系统不需要很复杂。它应该先解决一个问题:每次改动前后,团队能不能用一组稳定样例判断质量有没有明显退化。
这篇文章从前端工程师熟悉的工程流程出发,设计一套可以逐步演进的 Eval 系统。
最小可用系统的边界
一个 MVP Eval 系统应该覆盖六件事:
- 有一组可版本管理的评估样例。
- 能用同一套输入运行当前 AI 链路。
- 能保存输出、trace、成本和延迟。
- 能用规则和 LLM-as-judge 给出评分。
- 能生成可读报告,突出失败样例。
- 能作为发布门禁,阻止明显退化。
暂时可以不做的事:
- 不必一开始建设复杂标注后台。
- 不必追求全自动判断所有开放式答案。
- 不必覆盖全部线上场景。
- 不必把每个指标都做成实时看板。
- 不必把人工评审流程做得很重。
先把“能稳定回归”做出来,再逐步扩展。
第一步:选一个具体功能
不要从“评估整个 AI 平台”开始。
先选一个用户价值明确、线上风险可控、样例容易收集的功能。例如:
- 知识库问答。
- 工单摘要。
- 商品标题改写。
- 订单助手。
- 文档问答。
- SQL 生成。
- 客服回复草稿。
如果你负责前端,可以优先选那些有明确 UI 状态和用户反馈的功能。因为这些功能更容易收集真实失败样例,也更容易定义期望行为。
一个好起点通常满足三个条件:
- 用户每天都在用。
- 团队经常改 Prompt 或知识库。
- 出错后能明确判断哪里不好。
第二步:建立评估集
评估集是 Eval 系统的地基。
最小版本可以从 30 到 50 条样例开始,不需要一上来几千条。关键是覆盖类型要均衡。
建议至少包含:
评估样例应该进入 Git 或数据库版本管理。早期放在仓库里就很好,便于 code review。
一个简单结构可以这样设计:
这里的重点不是字段名固定,而是每条 case 都要说明“什么算好”。
第三步:让 Runner 调真实链路
Eval Runner 不应该只调用模型 API。它应该尽量调用和产品一致的 AI 链路。
如果真实产品链路是:
- 读取用户信息。
- 拼装系统 Prompt。
- 裁剪历史消息。
- 生成检索 query。
- 调知识库检索。
- 调模型生成。
- 解析结构化输出。
- 返回 UI message。
那么评估也应该经过这些步骤。否则你测出来的是“裸模型能力”,不是产品质量。
Runner 至少要记录:
- case id。
- prompt version。
- model。
- temperature。
- retrieval query。
- retrieved document ids。
- tool calls。
- final output。
- parsed result。
- latency。
- token usage。
- estimated cost。
- error。
这些字段决定失败后能不能定位。
对前端团队来说,Runner 的输出最好保留 UI 需要的数据结构,而不只是最终文本。这样才能评估引用、组件渲染、工具状态和错误状态。
第四步:先做规则评分
规则评分便宜、稳定、可解释,应该优先做。
适合规则评分的检查包括:
- JSON 是否能 parse。
- 是否符合 schema。
- 必填字段是否存在。
- 枚举值是否合法。
- 引用 ID 是否来自本次检索。
- 是否包含必须字段。
- 是否没有出现禁止内容。
- 工具调用参数是否符合权限。
- 失败时是否返回正确错误状态。
例如:
这段代码很简单,但它能抓住很多回归。比如 Prompt 修改后,答案不再提“180 天”,规则评分会立刻失败。
规则评分不适合判断所有质量问题,但它是 Eval 系统最可靠的一层。
第五步:为开放式回答加 LLM-as-judge
开放式回答很难只靠规则判断。比如“回答是否清晰”“是否完整解释”“是否基于资料”,通常需要 judge。
LLM-as-judge 的关键不是随便问另一个模型“这个回答好吗”,而是提供明确 rubric。
一个 judge prompt 可以包含:
- 用户问题。
- 参考上下文。
- 候选回答。
- 评分维度。
- 每个分数的含义。
- 输出 JSON schema。
例如评分维度可以设计为:
Judge 输出也要结构化:
需要注意,LLM-as-judge 不是绝对真理。它适合做规模化初筛,关键样例仍然要抽样人工复核。
第六步:生成报告,而不是只看分数
Eval 报告应该帮助团队决策。
最小报告可以包含:
- 总通过率。
- 各维度平均分。
- 和 baseline 的差异。
- 失败 case 列表。
- 严重失败列表。
- 成本和延迟变化。
- 每条失败的输入、输出、评分理由和 trace。
一个有用的报告不是“本次得分 86”,而是:
- 格式通过率从 99% 降到 93%。
- groundedness 失败集中在
policy标签。 - 新 Prompt 让回答更完整,但平均输出 token 增加 38%。
- 3 条权限边界样例从拒答变成了直接回答。
这些信息才能指导修复。
第七步:设置发布门禁
最小可用 Eval 必须进入发布流程。否则它只是一个偶尔运行的脚本。
门禁规则可以先简单一些:
- 严重安全样例必须 100% 通过。
- 结构化输出通过率不能低于 baseline。
- 核心任务正确率不能下降超过 2%。
- 平均延迟不能上升超过 20%。
- 单次成本不能超过预算阈值。
不同指标不一定都要卡死。你可以把门禁分成阻断和警告:
这样既能保护核心质量,又不会让团队被低价值波动卡住。
第八步:接入线上反馈
最小 Eval 系统上线后,很快会遇到一个问题:评估集里的样例越来越不够。
真实用户会不断发现新问题。所以线上反馈要能进入评估集。
前端反馈入口不要只收一个“有用/没用”。更好的方式是让反馈绑定 run id,并允许用户选择问题类型:
- 答非所问。
- 事实错误。
- 引用错误。
- 没有使用上传文件。
- 操作没有完成。
- 太长或太短。
- 不安全或不合规。
后端根据 run id 找到当时的 prompt、上下文、检索结果、工具调用和输出。团队复盘后,把代表性失败样例加入 golden dataset。
这就是从线上反馈到 Eval 的闭环。
最小架构建议
早期可以用很朴素的架构:
eval/cases/*.json保存样例。eval/run.ts运行评估。eval/scorers/*.ts保存规则评分器。eval/judge.ts调用评审模型。eval/reports/*.json保存每次结果。- CI 中加入
pnpm eval或预发布任务。
随着规模变大,再考虑:
- 数据库存储 case 和 run。
- Web 报告页面。
- 人工评审队列。
- A/B 模型对比。
- 按租户或功能分层统计。
- 与日志、反馈、监控系统打通。
不要一开始就把系统做成平台。先让团队每次改 AI 功能时真的愿意跑、看得懂、用得上。
常见坑
第一个坑:评估集太小且太干净。
只放 10 条理想问题,几乎一定会高估质量。评估集要包含真实失败和边界样例,哪怕数量不大。
第二个坑:只保存分数,不保存输出和 trace。
分数下降时,你需要看到当时模型答了什么、检索到了什么、工具有没有失败。没有 trace,就只能猜。
第三个坑:Judge prompt 不版本化。
如果评审标准自己变了,分数就失去可比性。Judge prompt、模型和评分 rubric 都应该记录版本。
第四个坑:把所有问题都交给 LLM-as-judge。
格式、引用、权限、工具参数这类确定性问题应该用规则检查。Judge 更适合开放式质量判断。
第五个坑:没有 baseline。
单次得分没有意义。你需要和当前线上版本、上一次发布版本或候选模型做对比,才能知道改动是进步还是退化。
第六个坑:Eval 和产品日志脱节。
线上用户反馈如果不能追溯到 run id,就很难复现问题,也很难把失败样例沉淀到评估集。
小结
最小可用的 AI 评估系统不需要一开始就很庞大。它的核心是:用一组稳定样例,持续评估真实 AI 链路,并把失败、分数、trace 和发布门禁连接起来。
对前端工程师来说,Eval 会反过来推动产品结构变清晰:消息要有状态,引用要有来源,工具调用要可追踪,用户反馈要绑定 run id,结构化输出要能校验。
当团队能在每次改 Prompt、换模型、调检索之前先跑 Eval,AI 应用才真正进入可维护阶段。