https://addyosmani.com/blog/ai-evals/
An Engineer's Guide to AI Code Model Evals
工程师的 AI 代码模型评估指南
作者:Addy Osmani | 2025年7月25日
改进一个具备编程能力的 AI 模型,例如 Google 的 Gemini 或 OpenAI 的代码模型,并非单纯依靠增加数据量或调整参数就能实现。其中一个关键环节是评估,业内通常缩写为 "Evals"。在 AI 模型的语境下,Evals 指的是用于衡量模型在特定任务上表现的结构化测试或基准。对于非 AI 领域的软件工程师和 Web 开发者而言,可以将 Evals 类比为软件工程中的单元测试或集成测试,它们定义了模型输出“正确”或“高质量”的标准,使我们能够系统性地验证改进效果或及时发现性能退化。
本文将深入探讨 Evals 的具体内涵、构建方法,包括 “黄金样本” 的概念,模型开发中 “爬山” 的含义,以及这些环节如何串联成一个持续训练与改进代码模型的闭环。我们将以提升模型在全栈 Web 开发中的能力,例如生成 React 或 Next.js 代码,为例来阐释这些概念。相关经验源自我们在 Google 开发 Gemini 编程能力过程中的实践积累。
代码模型为何需要 Evals?
开发传统软件时,通常会编写测试来确保代码按预期运行。同理,AI 模型,尤其是生成代码的大语言模型,同样需要测试来衡量其执行编程任务的能力。与确定性的传统程序不同,AI 模型的输出往往具有不确定性,因此需要一套稳健的方法来定义和检测“好的”解决方案。AI 评估 正是提供了这样一套标准与测试用例,使得我们能够量化模型的能力。
对于代码模型,评估通常聚焦于功能正确性,即模型生成的代码是否能够真正解决问题。在实际操作中,这意味着需要执行模型生成的代码,观察其是否产生预期结果,能否通过针对特定提示词设置的全部单元测试。例如,OpenAI 的 HumanEval 基准会提供编程题目及一组隐藏测试,若模型生成的代码通过了所有测试,该题目即被视为“通过”。
随着时间的推移,代码评估也在不断演进。早期基准,如 HumanEval 和 MBPP,主要采用简单的单函数任务,并引入了 Pass@k 指标,即在 k 次生成尝试中,只要有一次能够通过测试即算成功。这类似于给模型多次尝试机会,以观察其能否找到正确答案。
缺乏 Evals,便无法客观判断新版本模型是否真正优于旧版本。 Evals 使团队能够追踪进展,例如“本次更新后,通过率从 70% 跃升至 85%”,这才能构成有说服力的改进证据。同时,Evals 也有助于捕获性能退化的情况,即某次更新在不经意间导致模型在特定任务上的表现下滑。总而言之,Evals 是指引模型开发的反馈回路,其作用正如测试指引软件开发一样。
代码生成的 Evals 具体形式
一套优秀的代码模型 Eval 本质上是一批具有明确成功标准的编程任务集合。这些任务的复杂度跨度很大,从极简的,例如编写一个计算斐波那契数列的函数,到高度真实的,例如修复一个多文件 React 应用中的缺陷。每个任务通常包含以下要素:
• 输入或提示词:问题描述或起始代码片段,例如:“实现一个 React 组件,通过 API 接口获取并展示用户列表。” • 期望输出或行为:可以是明确的预期输出,即参考解决方案,也就是黄金样本,或者更常见的是代码必须满足的一组测试用例与标准。 • 评估指标:用于衡量模型输出与期望结果之间差距的方法。在代码评估中,核心指标通常是通过率,即模型生成的代码能否通过所有单元测试。

Evals 完全可以实现自动化。对于代码任务,自动化实施相对直接,只需在沙箱环境,例如 Docker 容器,中运行模型生成的代码,并验证其是否满足预设要求即可。
当前的综合基准已超越了单纯的“能否运行”层面,它们还会评估代码能否与现有代码库集成、能否处理多文件项目、API 调用是否正确、是否遵循良好的工程实践。例如,SWE-bench 基准采用真实的编程挑战,如向生产环境代码库添加新功能,来评估模型表现,这比孤立的算法题更为复杂,也更贴近真实的软件工程工作。
自动评分器 已成为将代码评估规模化的关键工具。自动评分器通常本身就是一个大语言模型,经过特定的提示词调整或微调,专门用于评估另一个模型的输出,充当人类评估者的自动化替代。这些评分模型能够评估代码的功能正确性、风格规范、安全漏洞及可维护性,同时提供详细的评判理由与置信度分数,将评估周期从数周缩短至数小时。
模型改进的“爬山”方法
掌握一套 Eval 任务之后,另一半工作在于如何有效利用这些信息。这就引出了“爬山”的概念。在 AI 开发领域,它指的是一种由 Eval 结果驱动的、渐进式的迭代改进过程。可将每个模型版本视为地形图上的一个点,其“海拔高度”代表在评估指标上的表现得分。目标是向更高处攀登,通过调整模型或优化训练流程来提升分数。

基于 Evals 的“爬山” 实践流程通常如下:
1. 基线评估:全面评估当前模型在所有任务上的表现,获得基线分数,并识别具体弱点。例如,模型在 Next.js API 路由或 CSS-in-JS 样式任务上的失败率较高。 2. 分析失败原因:将模型的失败案例视为故障报告进行分析,探寻其根本原因。是对特定库函数不熟悉,产生了语法错误,还是未能准确理解需求。 3. 提出改进方案:在识别失败模式后,有针对性地实施改进措施。这可能包括增加相应类型的训练样本、微调模型架构或优化提示词设计。 4. 重新评估:完成修改后,再次运行相同的 Evals。若分数提升,则表明攀登取得进展;若分数未变或下降,则说明此次改动无效或引入了性能退化。 5. 持续迭代:总结本轮经验教训,进入下一轮优化循环。
这是一个实验循环,与敏捷开发周期或科学方法高度相似:实施改动,测量结果,学习分析,再次迭代。
具体示例:假设 Evals 结果显示模型在配置 Next.js 的 getServerSideProps 数据获取时频繁出错。分析发现,模型通常忘记导出该函数或用法不正确。对应的改进措施是,使用几个正确的 Next.js 示例对模型进行针对性微调,并在提示词中加入相关提醒。重新运行评估后,与 Next.js 相关任务的通过率从 40% 提升至 80%,这便是“爬山”取得的实际成效。
“爬山”过程中需留意的陷阱:
• 避免 Eval 过拟合:若针对特定 Eval 任务过度优化,例如直接用评估题目进行训练,即便分数看似很高,模型的实际能力未必得到真实提升。这如同学生背诵考题答案,虽能通过考试,但并未真正掌握知识。应确保 Evals 保持“新鲜”,即不在训练数据范围内,并考虑采用多样化或定期轮换的任务集。 • 局部最优与全局最优:爬山算法有时会陷入局部最高点,即某项改动在特定指标上表现更佳,却在不经意间损害了模型的其他重要能力。因此,需要同时监控覆盖面广泛的 Evals,涵盖算法、Web、API 等多种任务类型,以防出现顾此失彼的情况。
何为“黄金样本”?
黄金样本 是 Eval 任务的真实参考答案,即模型在给定输入下理想情况下应生成的输出。如同教师持有的答案手册,黄金样本界定了模型应当输出的内容或行为模式。
对于代码任务,黄金样本可以是一个正确实现的函数,也可以是一套供参考解决方案通过的单元测试集。没有黄金样本,便无法量化模型输出与期望之间的差距。它们是确保评估可靠性的基础。

黄金样本的两种主要应用方式:
• 自动评分:通过程序将模型输出与黄金样本进行对比。对于代码任务,常用方法是使用模型生成的代码与黄金样本代码分别运行相同的测试用例,对比其结果是否一致。 • 辅助人工评估:对于涉及定性判断的方面,如代码可读性或风格,可将模型输出与黄金样本输出并列呈现给人工评估者,使黄金样本成为参考基准。
构建高质量的黄金样本本身就是一项精细工作。 必须确保黄金样本输出具备真正的高质量和正确性,否则评估标准便会失准。在全栈 Web 开发示例中,一个 Next.js 功能任务的黄金样本应由资深 Web 开发者编写,满足所有要求,包括正确使用 Next.js API、完善的错误处理等,随后以此为基础编写测试用例或作为对比参考。
黄金样本与训练改进过程直接相关:当模型在某个任务上失败时,审查黄金样本解决方案可以揭示其应有的正确做法。可以将黄金样本解答加入训练数据中,这是一种有针对性的微调,从而教会模型正确的实现路径。部分团队遵循“错误驱动训练”的方法,将模型答错的题目连同黄金样本答案一并加入下一轮训练,以此逐步弥补模型的知识盲区。
案例:提升模型的全栈 Web 开发能力
将上述概念串联起来,以下展示一个完整案例。假设我们拥有一个代码生成模型,目标是使其擅长全栈 Web 开发,尤其是 React 和 Next.js 相关任务。

第一步:定义 Evals
创建一套具有代表性的全栈评估任务,例如:
• 任务 A:实现一个接收表单提交,包含姓名和邮箱,并存入数据库的 Next.js API 路由,需包含错误处理与 JSON 响应。 • 任务 B:创建一个用户资料卡 React 组件,在挂载时从 API 获取数据,并在加载过程中显示加载指示器。 • 任务 C:在一个多文件 Next.js 项目中,修复登录表单状态更新不正确的缺陷。
创建约 20 至 50 个此类任务,覆盖前后端多种场景,构成评估套件。
第二步:基线测量
运行当前模型,每道题尝试 N=5 次,计算 Pass@5 指标,观察整体通过率。假设模型平均仅能正确完成 30% 的 Web 任务,尤其在 Next.js 相关任务上表现不佳。具体发现包括:
• React 组件经常忘记初始化 state 或清理 effect。 • Next.js API 路由解决方案有时未能正确处理 async/await,或未返回正确的 HTTP 状态码。 • 模型对 getServerSideProps等 Next.js 特有约定不够熟悉。
第三步:分析并改进,进入“爬山”模式
• 针对 React state 问题:收集展示正确用法的开源 React 代码片段,对模型进行微调,并在提示词中加入 React 最佳实践的提醒。 • 针对 Next.js 约定:通过微调或检索增强生成技术,向模型提供 Next.js 文档或示例项目。 • 针对 async 处理问题:增加正确处理 async/await 模式的训练样本。
改进后重新运行 Evals,通过率提升至 50%。继续迭代,逐步解决剩余的失败模式。经过几轮迭代后,通过率从 30% 提升至 50%,再提升至 70%,这表明我们正朝着正确方向稳步前进。
与此同时,需关注更广泛的 Evals,如通用编程任务,以确保在强化 Web 开发能力的同时,未损害模型的通用编码能力。
第四步:结果反哺
将本轮获得的所有经验成果,包括高质量的全栈示例数据以及最初失败任务的黄金样本答案,整合进模型的下一个版本。版本发布后,开发者会发现模型在构建 Next.js 应用或提供 React 修复建议方面更加可靠。
这一过程并不会就此终止。随着真实用户的使用,新的失败案例将被收集并转化为新的 Eval 任务或黄金样本,继续推动“爬山”循环,形成持续改进的闭环。
最佳实践与常见陷阱
• Evals 应与真实任务对齐:最有价值的 Evals 应当代表你真正希望模型擅长的任务。当 Evals 与真实应用场景对齐时,分数的提升才能真正转化为用户价值的提升,这意味着你正攀登在正确的山峰上。 • 保持一致性,同时不断演进:需要一个固定的测试集来公平对比不同模型版本,但也需随着模型的进步和需求的变化定期引入新的测试。同时,维护一个保留集,该集合中的任务永不用于训练,专门用于衡量模型的真实泛化能力。 • 警惕数据泄漏与代理指标:若模型在训练阶段已见过评估题目的答案,Eval 便失去了衡量意义。同时需确保所选指标能真正反映成功,单纯依赖“是否通过单元测试”有时可能导致模型寻找捷径而非真正解决问题。 • 利用 Evals 驱动模型设计决策:Eval 反馈可能指向训练数据之外需要调整的方面,例如对更大上下文窗口的需求、采用不同的解码策略,或使模型能够在收到错误反馈后进行自我修正。 • AI 与工程师协作:在创建与维护 Evals 时,应邀请软件工程师,即领域专家,深度参与。他们清楚何为高质量的代码,哪些任务更具重要性。可将 Eval 套件视为 AI“功能迭代”的活的测试平台。
结语
Evals 看似是额外的任务负担,但对于系统性地改进代码模型而言,却是不可或缺的一环。通过精心设计评估任务,配以清晰的黄金样本,利用它们引导“爬山”式的迭代优化,并始终与真实开发者的需求保持对齐,我们才能确保每个新版本的模型都在真正有意义的维度上优于前一版本。
这套方法论与改进软件的方式高度相似:编写测试,即 Evals,实施改动,即训练或微调,运行测试,然后再次迭代。
对于从事 Gemini 或下一代编程助手开发的从业者而言,掌握 Evals 是核心能力之一。仅依靠海量代码数据训练大型模型远远不够,必须持续地测试它、理解它、引导它。当前,顶级 AI 实验室均大量使用 Eval 基准来驱动模型开发,Evals 是将训练数据与算力转化为真实、可量化进步的关键所在。
从“它能写代码吗?”到“它能胜任工程任务吗?”,Evals 正是我们提出并回答这一问题的根本方式。
原文作者 Addy Osmani 是 Google 软件工程师,负责 Google Cloud 和 Gemini 相关工作。原文链接:addyosmani.com/blog/ai-evals
夜雨聆风