想象你是一家国际厨艺大赛的主评委。十位厨师要在三十分钟内,用同样的半成品食材完成一道招牌菜。你会怎么打分?如果只凭一句“我觉得好吃”,不同评委口味各异,结果既无法复现,选手也不服气。聪明的评委团会设计一套科学的评分体系:先对着参考摆盘照片比对成品的视觉还原度,再检查食材层次和摆盘结构是否合理,最后亲口品尝,验证火候和调味是否真的到位。 AI 代码补全的评测,和这场厨艺大赛如出一辙。你在编辑器里写下半个函数,AI 替你补全后半段——就像厨师料理那份半成品。要判断补全得好不好,同样需要一套“评委体系”:字符层面的比对(对照片)、语法结构的匹配(查摆盘)、功能正确性的验证(真实试吃),再加上一套标准化的比赛题库(评测基准)。这篇文章就带你完整走一遍这套评审系统的设计思路,让你从“凭感觉”升级为“看数据”。
掌握科学的代码补全评测方法,你就能用客观数据替代主观直觉,在模型选型、产品迭代和能力量化中做出可复现的决策——这是 AI 工程师与评测工程师的核心竞争力。
目录
可视化演示
展示编辑距离、AST匹配、功能正确性三种评测方法的原理对比,pass@k指标曲线,以及多模型基准雷达图。
本节配有交互动效(进入视口后自动加载,约 3KB)。
三种评测方法 编辑距离衡量字符级文本相似性 AST匹配评估语法结构正确性 功能正确性是金标准 ED + AST + Test = 全方位评测 三种方法互补,覆盖文本/结构/功能三个维度
评测缘起:为什么不能凭感觉打分
第一届厨艺大赛上,评委团靠直觉打分:有人偏爱清淡,有人偏爱浓油赤酱,同一道菜两个评委给出的分数差了四十分,冠军是谁吵了一个礼拜都没定论。第二年主办方换了一批评委,结果排名完全变了。选手们抱怨:“评分标准到底是什么?”缺乏统一尺度的评判,注定是一笔糊涂账。
代码补全产品也面临同样的困境。今天你让两位工程师分别试用 Copilot 和自研补全工具,一个说“补全挺准”,另一个说“老给我瞎编代码”,你该信谁?更麻烦的是,无论说好还是说坏,结论都复现不出来——换个场景、换个提问方式,体验就变了。评测的意义就在于把“我觉得好用”翻译成可重复测量的数字。
科学的评测通常围绕三个问题展开:测什么(数据)、怎么测(指标)、怎么解读(协议)。先定义一道“评测题目” $x_i$,再选择打分函数 $f$,最后把所有题目的得分平均,就得到了模型能力的整体估计。这套框架支撑起三大应用场景:横向对比不同模型、纵向监控同一模型的版本回归,以及把能力量化给管理层和客户看。
就像厨艺大赛第二年发布的《评分手册》把“好吃”拆成色、香、味、形四个可打分维度,AI 评测也要把“好用”拆成可量化的指标。接下来几节,我们依次认识这套手册里的几把尺子。
- 评测题目$x_i$ 表示评测集中的第 $i$ 道补全任务,比如“给一个函数签名,补全函数体”。
- 打分函数$f(M, x_i)$ 表示模型 $M$ 在第 $i$ 题上的得分,$f$ 可以是后面要讲的精确匹配、编辑相似度或 Pass@k。
- 平均聚合$\frac{1}{N}\sum_{i=1}^{N}$ 把 $N$ 道题的得分取平均,得到模型能力的整体估计。
基础指标:精确匹配与字符串相似度
评审手册里第一条最简单粗暴:把成品菜和参考照片逐像素对比。像素一模一样,满分;任何偏差,零分。这条规则省事,但厨师摆盘时多撒了一粒芝麻就判零分,显然不合理。这就像精确匹配(Exact Match,简称 EM):补全结果与标准答案字符串完全相同才算对。
精确匹配指标的定义非常干脆:给定 $N$ 道题,把“预测文本等于参考答案”的题数占总题数的比例作为得分。它计算快、容易理解,是最早被广泛使用的补全质量指标之一,至今仍是许多论文报告的基础指标。
但它的缺点同样明显:变量名不同、换行符不同、多了一个空格、把 return a + b 写成 return b + a,都会直接得零分。在真实开发中,这些写法完全等价,却被 EM 一票否决。于是评测者开始寻找“允许小差异”的宽松指标,编辑距离由此登场。
用严格的“照片比对”打分,虽然公平,却误伤了许多“其实做得不错”的菜。评委团意识到,需要一把允许微小偏差的尺子。
- 单题判定$\mathbb{1}[\cdot]$ 是指示函数,括号内的等式成立取 1,不成立取 0。
- 统计总数$\sum_{i=1}^{N}$ 把“与标准答案完全相同”的题数累加起来。
- 归一化比例$\frac{1}{N}$ 将累加结果转化为通过率,落在 0 到 1 之间。
编辑距离:允许微调的照片比对
评委团改进了规则:比对照片时,允许三种“微调”——把成品里的某种食材换掉(替换)、在成品里多放一种食材(插入)、去掉一种食材(删除),每做一次微调记一次“调整费”。最终,把两张照片调整到一模一样所需的最少调整费,就是两盘菜的“编辑距离”。距离越小,还原度越高。
计算机科学家莱文斯坦早在 1965 年就提出了这套算法,因此它也叫莱文斯坦距离(Levenshtein Distance)。对两段文本 $a$ 和 $b$,编辑距离就是通过插入、删除、替换三种操作,把 $a$ 变成 $b$ 所需的最少操作次数。它可以用动态规划高效求解——开头动效演示里那个 4×4 的数字表格,就是它在逐格填表:从左上角的 0 出发,每个格子取“删除、插入、替换”三者中的最小值。
为了让分数不受代码长度影响,评测时通常把距离归一化:相似度 = 1 − 编辑距离 ÷ 两段文本中较长的长度。两段代码越接近,相似度越接近 1。
逐格计算得出。
编辑距离让“多了一粒芝麻”不再被判零分,但新问题又来了:两盘菜都可能少放盐(同样的功能性错误),照片比对却都给高分。字符层面的对比,终究看不到“这盘菜靠不靠谱”。
- 编辑距离$\text{ED}(a,b)$ 表示把 $a$ 变成 $b$ 最少需要的插入、删除、替换次数,由动态规划按递推式
- 最长长度归一$\max(|a|,|b|)$ 取两段文本较长者的长度作为分母,把距离压缩到 0 到 1 的相对尺度。
- 补数转换$1 - \dfrac{\text{ED}}{\max}$ 把“距离”翻转为“相似度”,距离为 0 时相似度为 1。
AST匹配:检查摆盘结构
资深评委不会只看照片。他们会观察这道菜的结构:酱汁是淋在表面还是混进食材里?主菜和配菜的层次是否清晰?这些结构特征,照片上体现不出来,却决定了菜品的专业度。对代码而言,这个“结构”就是抽象语法树(Abstract Syntax Tree,AST)。
编译器在真正理解代码之前,会先把源码解析成一棵树:从根节点出发,函数定义、参数列表、返回语句都是一个个节点,嵌套关系对应树的父子结构。“返回 a 加 b”和“返回 b 加 a”虽然字符不同,AST 结构却一模一样;而“返回 a 减 b”虽然只差一个字符,AST 中却换了一个运算符节点。AST 匹配就是把参考代码与补全代码各自解析成语法树,统计两棵树中“类型与内容都相同”的公共节点数量,再用 Dice 系数归一化,得到 0 到 1 的结构相似度。更严格的做法是计算树编辑距离(Tree Edit Distance),把编辑距离算法搬到树上,允许对节点做插入、删除、替换操作。
检查摆盘结构能识别“形似而神异”的菜,但结构再完美,也代替不了最后一步——亲口尝一尝。如果菜是生的,摆盘再漂亮也是废品。功能正确性,就是这最后一道试吃。
- 两棵语法树$T_1, T_2$ 分别是补全代码与参考代码解析出的抽象语法树。
- 公共节点$\text{Common}(T_1, T_2)$ 是两棵树中类型与内容都一致的节点集合,其大小乘以 2。
- 节点总数分母$|\text{Nodes}(T_1)| + |\text{Nodes}(T_2)|$ 是两棵树的节点数之和,用于归一化。
- Dice 归一化比值落在 0 到 1,结构越像得分越高。
功能正确性:真正的试吃
厨艺大赛最有说服力的环节永远是试吃:夹起一筷子放进嘴里,咸淡、生熟、口感,一尝便知。代码评测里对应的动作是运行测试用例——像评委一样,给补全出来的代码输入真实数据,检查输出是否符合预期。这叫功能正确性验证。
具体做法是:每道补全题都附带一组单元测试,把补全结果放回原函数体中,编译、运行、断言。全部用例通过,这题才算通过;任何一个用例失败,这就是一道“夹生的菜”。比如要求实现加法,模型补全成 return a - b,代码能编译、能运行,但测试一跑就露馅。
由于大模型生成具有随机性,一次生成可能“手抖”,评测时普遍采用 Pass@k:对每道题生成 $k$ 个候选,只要其中至少一个通过全部测试,就算这题通过,最后统计通过比例。这相当于给厨师 $k$ 次重做机会,只要端出一盘合格的就计分。
试吃是终极标准,但成本不低:写测试用例、搭运行环境、处理超时,都很费功夫。而且一场比赛只能覆盖有限的菜式——于是评测界开始建设“标准化比赛”:把题目、测试和打分规则固化成大众认可的题库。这就是基准。
- 多次采样$S_{i,j}$ 表示对第 $i$ 题生成的第 $j$ 个候选补全,$k$ 是候选总数。
- 测试用例$\text{pass}(S_{i,j}, T_i)$ 表示候选补全 $S_{i,j}$ 是否通过了该题附带的测试用例 $T_i$。
- 或运算$\bigvee_{j=1}^{k}$ 表示“只要 $k$ 个候选中有一个通过,就记作通过”。
- 汇总平均$\frac{1}{N}\sum$ 统计 $N$ 道题中满足条件的比例。
主流基准:标准化的比赛规程
为了让不同厨师、不同年份的比赛结果可以横向比较,大赛组委会需要一份固定的菜单和评分规程。代码补全领域同样沉淀出了几个公众认可的“比赛”,其中最著名的是 OpenAI 提出的 HumanEval 和 Google 的 MBPP。
HumanEval 包含 164 道函数级编程题(对应思维导图中的“函数级基准”),每道题给出函数签名、文档字符串和几个单元测试,要求模型补全出函数体。MBPP(Mostly Basic Python Problems)则包含约 1000 道面向初学者的基础编程题,覆盖面更广、难度更低。两者的共同点是:题目固定、测试公开、评分协议明确,因此任何团队都可以复现和对比——这就是“数据设计”与“评测协议”的精髓。
HumanEval 在报告分数时,还引入了一个重要的统计技巧——Pass@k 的无偏估计。朴素的“采样 $k$ 次看是否通过”会高估模型能力,因此官方采用组合数公式修正偏差:设每题采样 $n$ 个样本、其中 $c$ 个通过,则随机抽取的 $k$ 个样本里至少有一个通过的概率是下面这个公式。这样只用一次采样就能无偏估计任意 $k$ 的通过率,节省大量算力。
基准比赛保障了“公平对比”,但它终究是标准化的模拟赛。真实厨房里的灶台、食材和顾客口味千差万别——这也解释了为什么 HumanEval 分数高的模型,在真实 IDE 里不一定最好用。聪明的团队会自己设计“内部评测赛”。
- 采样总数与通过数$n$ 表示每道题抽样的样本总数,$c$ 是其中通过测试的样本数。
- 全失败组合$\binom{n-c}{k}$ 表示从失败的 $n-c$ 个样本中任选 $k$ 个的组合数。
- 全体组合$\binom{n}{k}$ 表示从 $n$ 个样本中任选 $k$ 个的全部组合数。
- 期望修正$1 - \dfrac{\cdot}{\cdot}$ 得到“随机抽 $k$ 个至少含一个通过样本”的概率,再对 $(n,c)$ 的分布取期望;当 $n-c < k$ 时结果定义为 1。
实践要诀:设计你自己的评审体系
成熟的评委团从不指望一把尺子量遍所有菜品,而是把色、香、味、形按权重综合计分,并在每届比赛后复盘校准。实际评测代码补全,同样建议走“组合指标 + 持续跟踪”的路线,而不是迷信某一个分数。
一个实用的做法是设计复合评分:字符相似度 Sim 占权重 $w_1$,AST 结构相似度占 $w_2$,Pass@k 功能正确率占 $w_3$,三者加权求和。权重根据场景调节——偏重行尾补全的产品可以提高 Sim 权重;偏重函数生成的场景则把 Pass@k 放在首位,因为“能不能跑对”比“长得像不像”更重要。
执行流程上,先明确评测场景(补全粒度、语言、领域),再选择工具:通用场景用 HumanEval/MBPP 做横向对比,业务场景则从真实仓库的提交记录中抽取“补全前一刻的代码”构造内部题库。跑分后要结合人工抽检解读——某些指标异常可能是测试用例质量差,而不是模型退化。最后把评测集和脚本固化到 CI 流程,每次模型更新自动回归。
就像一流餐厅会持续追踪顾客评分、定期重测招牌菜,你的评测体系也应当随代码库演进而更新题库、随业务目标调整权重。真正的“评审大师”,不是会做一道菜,而是能设计一整套让所有人都信服的评分体系。
- 权重系数$w_1, w_2, w_3$ 是三个维度的权重,满足 $w_1 + w_2 + w_3 = 1$。
- 字符相似度$\text{Sim}$ 用编辑距离归一化得到,衡量字符层面的贴近程度。
- 结构相似度$\text{ASTSim}$ 用 Dice 系数得到,衡量语法结构的一致程度。
- 功能正确率$\text{Pass}@k$ 衡量真实运行的正确比例,三者加权求和即为综合分。
AI 应用场景
Copilot 类产品的选型评估
阶段:模型选型与产品评估
解决的问题:传统做法是让几位工程师试用一周再投票,主观且不可复现;不同试用者的代码习惯不同,结论常常互相矛盾。用评测框架后,团队抽取公司仓库的真实补全场景,离线计算编辑相似度、AST 相似度与 Pass@k,再结合小范围灰度确认体验,让选型决策建立在可复现的数据上。
具体案例:某研发团队要在 GitHub Copilot 与自研补全引擎间二选一。他们从 Git 提交历史中提取 800 个“真实补全片段”构造评测集,跑完三个维度指标后,发现自研引擎在新增代码场景的 Pass@1 高 8%,最终据此确定了方案,并把评测集沉淀为后续迭代的回归基线。
补全模型的迭代回归测试
阶段:模型迭代与质量监控
解决的问题:模型微调或更换底座后,“修好了 A 场景却悄悄破坏了 B 场景”是常态。把 HumanEval 加内部题库固化为评测集,在 CI 中自动跑分并对比历史基线,能在发布前拦截质量回退。
具体案例:某 AI 公司每个版本发布前自动运行 164 道 HumanEval 加 2000 道内部题,若 Pass@1 较上个版本下降超过 1 个百分点,流水线直接亮红灯,阻止上线并要求研发调参。
编辑器插件真实效果量化
阶段:产品效果度量与校准
解决的问题:离线指标只是“模拟赛”,用户真实使用中的接受率才是“实战成绩”。通过统计 IDE 插件里补全建议被接受还是被拒绝,得到用户反馈的“试吃”信号,再用它校准离线指标的权重,让评测体系与真实体验对齐。
具体案例:某团队统计一周内 10 万次补全建议的接受率,发现其与编辑相似度的相关性为 0.61,与精确匹配的相关性仅 0.15,因而在综合评分中上调了 Sim 的权重并下调了 EM,评测结果与用户反馈的一致性明显提升。
Python 演示
import astimport math def edit_distance(a, b): """计算莱文斯坦编辑距离:把 a 变成 b 所需的最少编辑次数""" rows = len(a) + 1 cols = len(b) + 1 dp = [[0] * cols for _ in range(rows)] for i in range(rows): dp[i][0] = i for j in range(cols): dp[0][j] = j for i in range(1, rows): for j in range(1, cols): if a[i - 1] == b[j - 1]: dp[i][j] = dp[i - 1][j - 1] else: dp[i][j] = min( dp[i - 1][j] + 1, # 删除 a 中的字符 dp[i][j - 1] + 1, # 插入 b 中的字符 dp[i - 1][j - 1] + 1, # 替换为 b 中的字符 ) return dp[rows - 1][cols - 1] def edit_similarity(a, b): """把编辑距离归一化成 0 到 1 的相似度""" if not a and not b: return 1.0 return 1.0 - edit_distance(a, b) / max(len(a), len(b)) def exact_match(a, b): """精确匹配:两段文本完全相同才得 1 分""" return 1.0 if a == b else 0.0 def ast_similarity(code_a, code_b): """AST 匹配:比较两段代码语法树的节点类型集合""" try: types_a = set(type(n).__name__ for n in ast.walk(ast.parse(code_a))) types_b = set(type(n).__name__ for n in ast.walk(ast.parse(code_b))) except SyntaxError: return 0.0 if not types_a and not types_b: return 1.0 common = len(types_a & types_b) return 2.0 * common / (len(types_a) + len(types_b)) def pass_at_k(total, passed, k): """Pass@k 无偏估计:k 次采样中至少一次通过的概率""" if total - passed < k: return 1.0 return 1.0 - math.comb(total - passed, k) / math.comb(total, k) def evaluate_completions(reference, candidates): """对一组候选补全结果做多维打分""" print("=== 代码补全评测示例 ===") for idx, cand in enumerate(candidates, 1): em = exact_match(reference, cand) es = edit_similarity(reference, cand) a_s = ast_similarity(reference, cand) print("候选%d: EM=%.1f 编辑相似度=%.3f AST相似度=%.3f" % (idx, em, es, a_s)) if __name__ == "__main__": reference = "def add(a, b):\n return a + b" candidates = [ "def add(a, b):\n return a + b", "def add(a, b):\n return b + a", "def add(x, y):\n return x - y", ] evaluate_completions(reference, candidates) print("Pass@1(5题过3题):", pass_at_k(5, 3, 1)) print("Pass@5(5题过3题):", pass_at_k(5, 3, 5))
dp = [[0] * cols for _ in range(rows)]初始化 DP 表格,行列分别是两段文本的长度加一,用来存子问题的编辑距离。if a[i - 1] == b[j - 1]: dp[i][j] = dp[i - 1][j - 1]当前字符相同则无需操作,直接沿用上一格的代价。dp[i][j] = min(...)从删除、插入、替换三种操作中取最小代价,这是莱文斯坦递推的核心。1.0 - edit_distance(a, b) / max(len(a), len(b))把绝对距离除以较长长度,归一化成 0 到 1 的相似度。ast.parse(code_a)把源码解析成抽象语法树,这是 AST 匹配的第一步。2.0 * common / (len(types_a) + len(types_b))用 Dice 系数衡量两棵树节点类型集合的重叠程度。if total - passed < k: return 1.0当失败样本数不足 k 时,任意抽 k 个必然包含通过样本,概率为 1。1.0 - math.comb(total - passed, k) / math.comb(total, k)用“全是失败样本”的组合占比取反,得到至少一个通过的无偏概率。
常见误区
误区我测试补全结果时,只要代码在 IDE 里能运行、没报错,就认为这次补全质量合格。
正解能运行不等于功能正确。比如要求实现加法,模型补全成 return a - b,代码完全能运行,结果却全错。正确的做法是用带断言的单元测试验证输入输出,并统计 Pass@k。这就像评委试吃时,菜能端上桌不代表熟了,必须尝一口才知道。
为何常见:本地运行报不报错是最容易观察到的信号,而且“运行通过”会产生安全错觉,让人忽略逻辑上的错误。
误区补全结果和标准答案的字符越接近,质量一定越高,所以字符串比较就够了。
正解字符相似度高只说明“长得像”。return a + b 和 return b + a 字符不同、相似度低,但功能完全相同;把变量名从 a、b 改成 x、y 也会拉低相似度,却完全等价。这时需要 AST 匹配和功能测试来兜底,才能分辨“形异神同”的合格答案。
为何常见:字符串比较最直观、实现成本最低,人们天然倾向于先用量化最方便的指标,并把它当成全部。
误区给模型打分只需要一个指标,比如 Pass@1 或编辑相似度,选一个就够了。
正解不同补全场景对指标的敏感度差异很大:行尾补全对字符相似度敏感,函数生成必须用 Pass@k 验证功能,重构类补全则要看 AST 结构。组合使用多个指标、按业务调权重,评测结论才稳健。单指标容易被特定分布的测试集“骗到高分”,就像只用“摆盘好看”来评菜,会漏掉味道这个关键维度。
为何常见:多指标意味着更多工程成本和分析负担,追求简单是人的天性,但评测对象的复杂性不允许偷懒。
误区HumanEval 分数越高的模型,接入我们的 IDE 插件后体验一定越好。
正解HumanEval 是通用函数题,和真实代码库的语境差异很大:真实补全包含大量行尾补全、长函数、框架 API 和业务命名,这些正是基准题不覆盖的。真实体验还需要结合内部评测集、用户接受率和人工评审,不能只看公开基准分数。就像拿国宴菜谱衡量家常菜厨师,维度全错。
为何常见:基准分数公开易得、宣传常见,且直觉上“分数高等于厉害”符合常理,容易让人忽略数据分布的巨大差异。
误区评测是一次性的,测完拿到分数,后面就不用再管了。
正解代码库在演进、模型在更新、业务场景在变化,评测集和权重都需要持续维护。成熟团队把评测固化到 CI 流水线,每次模型发布自动跑分,一旦 Pass@1 回退就阻止上线。评测体系是一套需要定期保养的工具,不是一次性的体检报告。
为何常见:搭建评测体系的成本不小,做完后容易产生“任务完成”的心态,忽略了评测本身需要持续投入的事实。
面试题
Q1. 评测代码补全时,以下哪项属于“字符串级”的相似度指标?
- A.编辑距离← 正确答案
- B.AST匹配
- C.单元测试
- D.覆盖率
答案:A。编辑距离直接在字符序列上计算插入、删除、替换次数,属于字符串级指标;AST 匹配针对语法树,单元测试和覆盖率属于功能正确性验证。就像比对菜品照片是“看长相”,编辑距离就是那张照片的差异计数。
Q2. 莱文斯坦编辑距离允许的三种基本操作是什么?
- A.插入、删除、替换← 正确答案
- B.复制、粘贴、剪切
- C.编译、运行、调试
- D.拆分、合并、排序
答案:A。莱文斯坦距离只允许插入、删除、替换三种字符级操作,其余选项都是对代码工程或文本处理的描述,不属于编辑距离的定义。三种操作对应评委对照片的“加料、减料、换料”。
Q3. 两段代码的编辑距离为 3,长度分别是 10 和 12,归一化后的编辑相似度约为多少?
- A.0.25
- B.0.75← 正确答案
- C.0.70
- D.0.85
答案:B。归一化相似度 = 1 − 编辑距离 ÷ 较长文本长度 = 1 − 3/12 = 0.75。分母取较长的 12,因为归一化的目标是让相似度落在 0 到 1 之间,用最长长度作为最大可能距离。
Q4. 与精确匹配(EM)相比,编辑距离的主要优势是什么?
- A.能容忍细微差异← 正确答案
- B.计算速度更快
- C.不需要参考答案
- D.能识别语法错误
答案:A。精确匹配要求字符串完全相同,而编辑距离允许插入、删除、替换造成的细微差异,因此对变量名、空格等变化更宽容。编辑距离并不比 EM 更快、仍需参考答案,且无法识别语法错误。
Q5. AST 匹配评估补全结果时,重点关注的是代码的哪个方面?
- A.代码的语法结构← 正确答案
- B.代码的注释风格
- C.代码的缩进格式
- D.代码的变量命名
答案:A。AST 匹配把代码解析成抽象语法树,比较节点的类型和嵌套关系,因此关注的是语法结构。注释、缩进和变量命名在语法树中都不会体现,属于“照片看长相”之外的“结构检查”。
Q6. 以下哪些方法可以用于评估代码补全的“功能正确性”?
- A.运行单元测试← 正确答案
- B.检查测试覆盖率← 正确答案
- C.对比字符串相似度
- D.检查是否通过编译
答案:AB。功能正确性必须通过运行测试用例验证输入输出,检查覆盖率能说明测试是否充分,两者都服务于“真试吃”;字符串相似度属于字符层面对比,编译通过只说明语法合法,不保证逻辑正确——能编译的 return a - b 仍是错的。
Q7. 关于 Pass@k 指标,下列说法正确的是?
- A.k 表示候选样本数← 正确答案
- B.有任一通过即算通过← 正确答案
- C.Pass@5 一定大于 Pass@1
- D.k 越大计算越简单
答案:AB。Pass@k 对每道题生成 k 个候选,只要有一个通过测试就算通过;Pass@k 随 k 单调不减,但可能相等,不能说“一定大于”;k 越大采样和测试成本越高而不是越简单。这相当于给厨师 k 次重做机会,次数越多成功率只会更高或持平。
Q8. HumanEval 基准的主要特点是什么?
- A.题目为函数级代码生成← 正确答案
- B.题目为无限长的程序
- C.只评测注释与补全
- D.不包含任何测试用例
答案:A。HumanEval 包含 164 道函数级编程题,每道题给出函数签名、文档字符串和单元测试,要求模型补全函数体。它题目有限、测试公开,是标准化的“模拟赛”,而不是无限长程序、注释补全或无测试的题库。
Q9. 使用 Pass@k 无偏估计公式时,关于参数与结果的描述正确的是?
- A.n-c 小于 k 时结果取 1.0← 正确答案
- B.结果表示至少一个通过概率← 正确答案
- C.结果等价于平均通过率
- D.k 必须严格等于 n
答案:AB。当失败样本数 n−c 小于 k 时,任意抽 k 个必然含通过样本,概率为 1;公式的物理意义是“随机抽 k 个至少有一个通过”的概率估计。它并不等于简单的 c/n(c/n 是单次采样通过率),也不要求 k 等于 n。这个修正避免了小样本下的乐观偏差。
Q10. 某模型每道题生成 10 个样本,其中 2 个通过测试,其 Pass@1 的无偏估计约为多少?
- A.0.20← 正确答案
- B.0.40
- C.0.80
- D.1.00
答案:A。Pass@1 = 1 − C(10−2, 1) / C(10, 1) = 1 − 8/10 = 0.20。从 10 个样本中随机抽 1 个,抽到通过样本的概率就是通过样本占比 2/10;当 k=1 时无偏估计恰好等于通过率 c/n。