只要产品里嵌了 AI,就一定要做 evals。这是过去两个月在 sgai.md(新加坡 AI 战略观察站)上踩坑总结出来的判断。

eval 是什么#

eval = 评估测试。给 AI 输出和数据完整性写的回归测试,但和单元测试不是一回事。

单元测试测的是「函数给定输入,输出是不是这个值」——确定性的。

eval 测的是「AI 这次生成的东西,和金标 / 规则相比,质量有没有掉」——非确定性的。

简单说:单元测试盯代码,eval 盯模型 + 数据

eval 解决什么问题#

任何依赖大模型的系统,都有三个天然漏洞。代码里写的单元测试管不到,人肉 review 一定漏。

模型会幻觉。 LLM 会编一个看起来合理但根本不存在的 URL、人名、事实。我自己在 sgai.md 上踩过——5 月初让 agent 给一批 voice 人物档案补「主导项目 / 公开引言」,agent 给两条记录写了根本不存在的 sourceUrl(一个伪造的 Fintech Festival 演讲者 ID,一个伪造的航空业报道)。URL 模式正确得肉眼分辨不出,靠用户事后报错才发现。

模型会退化。 升级模型(Claude 4.6 → 4.7)或改 prompt,输出可能变差。但你不会主动知道——除非有人发现产出明显烂了。等用户先发现就太晚了。

数据会漂移。 AI 生成的内容入库后,没人持续盯着完整性,漏字段、缺翻译、链接腐烂会慢慢累积。sgai.md 是中英日三语站,数据文件里每条 record 要求 title / titleEn / titleJa 三套字段必须同时给。我有一次只 commit 了中文,下一个 PR 想补英日——结果 EN/JA 页面立刻断裂。

eval 是把人肉的「我应该再检查一遍」变成 cron 自动跑。

evals 的最佳实践#

第一,从事故反推。

不要「我觉得应该测 XYZ」。要「我们漏了什么 → 怎么自动化抓住下次」。sgai.md 的 CLAUDE.md 里有几条「🔴 顶层硬规则」,每条都对应一次具体 commit 事故。比如「sourceUrl 真实性约定」直接来自伪造 URL 那次;「addedAt 字段约定」来自手动加视频但忘同步首页「最近更新」那次。

每个 eval 必须对应一个真实漏洞真实事故。否则就是装样子。

第二,分层。

sgai.md 的 i18n 检查就是分层叠加:

  • 数据层:每条 record 中英日字段必须配对
  • 构建层:sitemap 里每个中文 URL 必须有英日 sibling,hreflang 四条必齐
  • 内容层:英文页面禁止 CJK,日文页面必须含 hiragana/katakana
  • 源码层:扫源码里 lang === 'zh' ? 这种二元三元(会让日文静默落到英文分支)

每一层抓不同盲区。一层挡不住的事情,下一层挡。

第三,存量不强清,但只许变好不许变烂。

sgai.md 源码里曾有 518 处旧的硬编码反模式,不可能一口气改完。做法是把当前数字记下来当基线,往后只看「比基线多了几条」——多一条 fail。改好的可以更新基线,永远只许变小。

这个原则在所有领域都通用——代码债、桌面、戒糖、健身。要的是趋势变好,不是一夜清零。后者大概率半途而废,反而把规则废了。

sgai.md 现在的 evals#

Eval出问题会怎样频率
网址巡检AI 编一个看似合理但根本不存在的网址,访客点进去 404
字段配对新加内容只写了中文,英日字段空着,对应页面立刻断裂每 PR
URL 三语对齐中文站点地图里有的页面,英日版本却没生成,搜索引擎以为日文版根本不存在每构建
多语言声明页面没告诉谷歌「我有中英日三种版本」,被识别成单语站,三语 SEO 全废每构建
语种纯度英文页面里残留中文字符;日文页面看上去全是汉字、没有平假名片假名(其实根本没翻译)每构建
模板硬编码源码里有种写法会让日文版静默退化成英文,访客以为日文版坏了每 PR
首页「最近更新」加了新内容但忘记打日期标,首页看不到,等于白做每 PR
结构化数据JSON-LD 漏字段,谷歌搜索结果不出 rich card,掉点击率每构建
摘要金标升级模型或改 prompt 后,AI 写的摘要质量悄悄下降,没人察觉
翻译金标升级模型后术语翻错(人名、机构名、政策名),全站翻译统一性破坏

每条都对应一次真实踩过的坑,或一次可预见的退化场景。这是健康的 eval 设计——从事故反推回防御,不从理论正推。