Hualin Luan Cloud Native · Quant Trading · AI Engineering
返回文章

Article

如何设计高质量的编程题目:从题面到评估契约

高质量编程题不是更长的 prompt,而是能稳定暴露能力边界的评估契约。本文从 Bloom 层级、难度校准、任务契约、测试设计和题库治理出发,说明如何为 AI Coding Mentor 构建可复现的题目体系。

Meta

Published

2026/3/30

Category

interpretation

Reading Time

约 23 分钟阅读

版权声明与免责声明 本文基于 Bloom 认知分类法、APPS 基准测试设计方法、LiveCodeBench 评估框架等多项研究进行综合解读。原文版权归各自作者与研究机构所有。

观点归属声明 本文提出的分层设计框架、难度分级标准、测试用例设计原则和防套路策略,为作者基于理论研究和工程实践的原创综合。

原文参考

  • Bloom Taxonomy — Benjamin Bloom et al.
  • APPS Benchmark — Hendrycks et al., Stanford
  • LiveCodeBench Methodology — Jain et al., UC Berkeley

原创性质 本文不是逐段翻译,而是将教育学理论与 AI 评估实践结合,重建适合实际应用的题目设计方法论。


开头:好题不是描述更长,而是约束更清楚

很多团队第一次评估 AI 编程能力时,会自然地从一道“看起来像编程题”的需求开始:写一个排序函数,实现一个缓存,做一个表单校验,或者修复一段已有代码。这样的题目能快速启动实验,却很难支撑长期评估。原因不在题目太简单,而在题面没有把任务边界、输入输出、约束条件、验收标准和失败判定说清楚。

对人类工程师来说,模糊需求还有二次澄清的机会。候选人可以反问排序字段、稳定性、异常输入、性能要求和业务优先级。AI 编程助手通常不会稳定地追问,它会直接补全缺失信息:默认语言、默认数据结构、默认边界处理、默认异常策略。看起来它完成了任务,实际只是把题目没有写出来的部分替团队做了假设。

这正是 Coding Mentor 视角下题目设计的核心问题:一道人类觉得“差不多能懂”的题,对 AI 未必是一个可评估任务。可评估任务必须减少隐式假设,让模型的输出主要反映能力,而不是反映它碰巧猜中了出题人的意图。

一条有效的判断标准是:题面能否被不同的人、不同模型、不同时间点重复执行,并得到可比较的评分结果。如果不能,题目就不是评估资产,只是一次性的交互材料。

可评估编程题目的任务契约

评估边界:从传统出题到能力层级

为什么传统出题方法不能直接迁移到 AI 评估

传统编程题常常服务于教学、面试或训练。它们默认人类读题者具备上下文理解能力,也默认评价者可以在过程中追加解释、追问思路、观察调试过程。AI 评估的环境不同:模型输入是题面,输出是代码、解释或修复补丁,评分通常依赖测试、静态检查、人工 rubric 或多轮反馈记录。

这会带来三个差异。

第一,题目需要封闭。人类题可以留一些解释空间,AI 评估题不能把关键条件藏在语气里。比如“合理处理异常”不是可评分要求;“当输入为空时返回空列表,当页码越界时返回空结果并保留总数”才是可评分要求。

第二,题目需要抗模式匹配。模型见过大量公开算法题和常见业务片段。题面只要落入熟悉模板,它可能不真正分析需求,而是调用记忆里的标准解法。高质量题目不追求故意刁难,而是通过业务约束、组合边界和验证机制,让模板解法的漏洞暴露出来。

第三,题目需要可校准。AI 能力更新很快。同一道题在不同模型、不同工具权限、不同上下文预算下,通过率可能变化明显。题目难度不能只靠“出题人感觉”,而要绑定评估设置、通过率分布、失败类型和版本记录。

因此,给 AI 设计编程题,不只是写题面,而是在设计一份评估契约。契约的作用是把“我希望模型会什么”转换成“我能观察到什么证据”,再转换成“我如何判断它是否达标”。

从知识点到能力层级:Bloom 分类法的工程化用法

Bloom 认知分类法把学习目标拆成六个层级:记忆、理解、应用、分析、评价和创造。它本来是教育学框架,但在 AI 编程评估里有很强的工程价值,因为它提醒出题者不要把所有题目都写成“实现某个函数”。

不同层级对应不同能力证据。

Bloom 层级编程能力证据适合观察的问题AI 评估风险
记忆回忆语法、API、概念名词是否知道某个语言特性或库函数容易被训练语料覆盖,区分度低
理解解释概念差异和适用场景是否能说明浅拷贝、事务隔离、幂等等概念答案可能流畅但缺少工程约束
应用按明确要求实现算法或业务逻辑是否能把已知方法落到代码最适合自动化测试,但容易被模板命中
分析拆解复杂需求、定位瓶颈和边界是否能识别依赖、状态、失败路径需要更细的 rubric 和证据记录
评价在多个方案之间取舍并说明理由是否能做技术判断和风险权衡不能只用单元测试评分
创造设计新结构、协议或系统方案是否能组织开放问题并形成架构必须引入人工复核和长期评估

多数 AI 编程评估失败,并不是因为题目不够难,而是能力层级混乱。题面说要考“架构能力”,测试却只验证了一个函数是否返回正确列表;题面说要考“问题分解”,评分却只看代码是否运行;题面说要考“工程判断”,rubric 却没有区分安全性、可维护性、性能和可观测性。

Coding Mentor 在出题前应先回答一个问题:这道题到底要观察哪一种能力证据?如果目标是应用层级,就应该给出清晰接口、输入输出和自动化测试;如果目标是评价层级,就必须给出多个候选方案、约束冲突和决策依据;如果目标是创造层级,就要明确架构边界、非功能需求、复核标准和不可接受风险。

Bloom 层级与 AI 评估难度映射

难度与任务契约

难度分级体系:从Easy到Hard的设计标准

难度不是题面长度,也不是参考答案行数。一个 20 行函数可能因为边界状态复杂而很难,一个 200 行脚手架也可能只是机械填空。对 AI 评估更有意义的难度定义,是模型在固定评估预算下需要完成多少判断、组合多少约束、暴露多少失败模式。

这里可以把难度拆成两层口径。

第一层是人类参考口径,用来估算题目规模。比如一个熟练工程师完成参考实现大约需要 15 分钟、45 分钟还是更久。这能帮助团队判断题目是否过重,但不能直接套用到 AI。AI 不会按人类时间工作,它的实际能力受上下文长度、工具调用、测试反馈、重试次数和模型类型影响。

第二层是 AI 评估口径,用来固定实验条件。比如是否允许模型读取多文件上下文,是否允许运行测试,是否提供失败日志,是否允许一次修复,是否允许访问外部文档。没有这些条件,所谓 Easy、Medium、Hard 就无法比较。

维度EasyMediumHard
目标能力单一概念的正确应用多概念组合和边界处理复杂状态、跨模块约束或方案取舍
人类参考规模通常 15 分钟以内通常 15 到 45 分钟通常超过 45 分钟
AI 评估预算单轮生成,不提供测试反馈单轮生成加一次测试反馈允许多文件上下文、工具调用和有限修复
概念数量1 个核心概念2 到 3 个核心概念4 个以上概念或多个子系统
参考实现形态一个短函数或局部逻辑一个函数组或小模块多函数、多状态或跨模块改动
边界条件空输入、单元素、重复值多条件组合、分页越界、排序稳定性极值数据、退化路径、并发或一致性问题
自动化评分单元测试基本可覆盖单元测试加边界与性能测试测试、rubric、人工复核或轨迹审查组合
预期通过率在目标模型上稳定较高能拉开模型差距主要用于暴露能力边界

Easy 题的价值不是证明模型“会写代码”,而是建立基线。它适合检查语法、接口遵循、简单边界和基本测试通过率。高质量 Easy 题也要写清楚输入范围和异常策略,否则通过率高没有意义。

Medium 题是最适合长期评估的主体。它不要求模型做开放式架构设计,但需要在多个规则之间保持一致。例如筛选、排序和分页组合;缓存淘汰和容量控制组合;解析、校验和错误报告组合。Medium 题能比较稳定地暴露模型在边界、复杂度和状态更新上的差异。

Hard 题不应该只是把需求写得更长。真正的 Hard 来自状态空间、约束冲突和评估方式的升级。事务型 KV 存储、批处理任务调度、跨模块重构、并发安全修复、性能瓶颈定位,都属于 Hard 的典型形态。此时只靠“所有测试通过”往往不够,还需要记录模型的计划质量、风险识别、修改范围控制和验证策略。

一个常见错误是用人类难度标签替代 AI 难度标签。某道题对人类是 Medium,但如果模型训练语料里存在大量近似模板,它对 AI 可能只是 Easy。反过来,一道业务规则很简单的题,如果题面存在隐式优先级、异常输入和状态回滚,对 AI 可能已经进入 Hard。难度必须从实际通过率和失败类型中校准,而不是由题目名称决定。

高质量题目的六层任务契约

高质量题目可以被看成六层契约。每一层都回答一个评分问题:模型该做什么、在什么边界内做、怎样证明做对、怎样识别做错。

第一层是任务目标。目标不应停留在“实现一个功能”,而要说明该功能服务的工程场景。场景不是为了增加故事感,而是为了明确优先级。例如同样是排序,运营后台关注稳定性和可解释性,实时推荐关注延迟和吞吐,数据导出关注全量一致性。场景不同,正确解法也不同。

第二层是接口契约。接口契约包括函数签名、参数含义、返回值、错误处理、空值策略和可变性约束。AI 很容易在接口不明确时自行设计数据结构,导致答案看似正确却无法进入统一测试。接口越稳定,评分越可复现。

第三层是数据约束。输入规模、字段范围、唯一性、排序规则、时间格式、编码规则、并发假设,都应显式写入题面。数据约束决定算法选择,也决定测试是否能排除暴力解、隐式类型转换和偶然正确。

第四层是行为约束。行为约束说明遇到边界、冲突和异常时应该怎样处理。例如排序是否稳定,分页页码越界是否报错,重复请求是否幂等,事务失败是否回滚,缓存容量为 0 时如何处理。这一层最容易被忽略,却最能区分“能跑”和“符合工程要求”。

第五层是示例契约。公开示例不是答案提示,而是题意校准。好的示例应该覆盖正常路径、至少一个边界路径和一个容易误解的规则。示例解释应说明为什么输出是这样,而不是只给输入输出。这样可以降低模型靠猜测题意通过的概率。

第六层是验收契约。验收契约说明评分由哪些部分组成:公开测试、隐藏测试、性能测试、静态检查、人工 rubric、日志审查或修改范围审查。只要评分维度没有提前定义,后续评价就容易变成主观印象。

这六层契约不是模板字段,而是出题时必须完成的工程判断。题面可以很短,但这六层不能缺位。缺少任务目标,模型不知道优先级;缺少接口契约,测试无法统一;缺少数据约束,算法选择无法判定;缺少行为约束,边界处理无法评分;缺少示例契约,题意容易被误读;缺少验收契约,结果无法复盘。

从能力目标到测试证据

面向 AI 的题目设计:不要测试模板,要测试判断

AI 编程助手在常见算法题上的表现,往往高于它在真实工程任务中的表现。原因并不神秘:公开题库、博客讲解、题解仓库和训练数据里充满了标准模板。题面越像经典题,模型越容易调用记忆里的套路。

题目设计的目标不是故意设置陷阱,而是让关键判断无法被模板绕过。

第一种方法是加入业务约束。不要只问“实现 LRU 缓存”,而要说明容量为 0、重复写入、读取后是否更新热度、异常 key 如何处理、统计信息是否参与状态。业务约束能迫使模型处理题面中的具体规则。

第二种方法是组合多个普通概念。筛选、排序、分页单独看都不难,组合后就会暴露顺序错误:先分页再排序、先排序再筛选、总数统计位置错误、稳定性被破坏。组合题比孤立题更接近工程任务。

第三种方法是设计对抗性边界。对抗不等于冷门,而是针对常见错误。比如最大输入规模验证复杂度,重复元素验证稳定性,空结果验证返回契约,退化输入验证算法假设,并发调用验证共享状态。

第四种方法是区分题面事实和模型建议。对开放题而言,模型可以提出建议,但不能把建议当成事实。题目应明确哪些约束不可改变,哪些方案可以取舍,哪些风险必须说明。这样才能评价模型是否尊重任务边界。

第五种方法是保留失败证据。一次测试失败本身不是坏事,坏的是失败后没有结构化记录。失败类型、触发输入、违反的契约层、模型修复方式和最终结果,都应进入题目校准过程。长期看,这些失败证据比单次得分更有价值。

一个 Medium 题应该如何从能力目标长出来

题目设计不应该从“我想让模型写什么代码”开始,而应该从“我想观察什么能力证据”开始。

假设目标能力是多条件业务逻辑组合。一个合适的 Medium 题可以围绕商品列表的筛选、排序和分页展开。这个场景足够常见,模型不需要额外理解行业知识;同时它又包含多个容易出错的规则,能观察模型是否真正维护了任务契约。

能力目标可以拆成四项。

能力目标可观察证据常见错误
多条件筛选能同时处理价格、评分、分类等条件条件之间误用或关系,空条件处理错误
稳定排序相同排序键时保留原始相对顺序使用不稳定排序或二次排序破坏结果
分页语义返回当前页数据和筛选后的总数先分页后筛选,或把当前页数量当总数
边界处理空列表、空结果、越界页码行为一致抛出未声明异常或返回结构不一致

有了能力目标,题面就可以围绕任务契约展开:给出商品字段,说明筛选条件可以为空,说明排序字段只允许白名单,说明分页从 1 开始,说明总数是筛选后的总数,说明当页码越界时返回空列表但总数不变。这里每一句规则都不是装饰,它们都会对应测试或 rubric。

公开示例不需要堆很多。一个正常示例展示多条件筛选和排序,一个边界示例展示空结果或越界页码,一个解释说明总数为什么不是当前页数量。对读者来说,这比展示大段参考代码更有价值,因为它说明了题目真正要评价的判断点。

隐藏测试则围绕常见错误设计。比如把分类条件设为空,验证模型是否把空列表理解成不过滤还是过滤为空;构造同价格同评分的商品,验证稳定排序;构造最后一页之后的页码,验证分页契约;构造十万条商品,验证复杂度。每个隐藏用例都应能回答一个问题:它在防哪一种错误?

如果这道题只要求模型实现一个函数,它仍然是 Medium。如果把它放进已有代码库,要求模型理解现有数据结构、修改测试、保持 API 兼容,并解释为什么没有改动公共类型,它就可能升级为 Hard。难度变化的根本原因不是业务场景变了,而是任务边界、上下文依赖和验证责任变了。

测试用例设计:公开示例不是评估集

公开示例用于解释题意,隐藏测试用于验证能力,性能测试用于排除错误算法,对抗测试用于暴露常见误解。把这几类测试混在一起,会让题目失去校准价值。

一套健康的测试集通常包含五类用例。

测试类型主要作用设计重点
基础用例验证主路径是否正确覆盖最常见输入,不追求刁钻
边界用例验证契约是否完整空输入、单元素、重复值、越界和空结果
组合用例验证多规则顺序筛选、排序、分页、状态更新等规则组合
压力用例验证复杂度和资源使用最大规模、退化分布、长字符串或大图
对抗用例验证是否套错模板针对已知错误模式构造输入

测试比例不必固定。初始题库可以让基础和边界用例占较高比例,后续根据失败分布调整。如果模型主要错在边界处理,就提高边界用例权重;如果模型经常超时,就增加压力用例;如果模型反复套用错误模板,就加入更明确的对抗用例。

测试还需要和评分解释绑定。只给一个失败日志,很难沉淀 Mentor 信号。更好的做法是把失败映射到契约层:接口不匹配、数据约束违反、行为规则错误、复杂度不达标、异常策略不一致、修改范围越界。这样一来,题目不仅能给出分数,还能告诉团队模型到底不会什么。

题目测试与治理闭环

Rubric:把主观评价变成可学习信号

自动化测试适合评价确定性行为,但不能覆盖所有编程能力。代码审查、架构设计、调试过程、风险判断、迁移策略和性能分析,都需要 rubric。

高质量 rubric 不是“代码质量好”“结构清晰”这类泛化评价,而是把评价拆成可观察条件。比如可维护性可以拆成命名是否表达领域概念、是否避免重复规则、是否把边界条件集中处理、是否保持公共接口稳定。安全性可以拆成输入校验、权限边界、敏感日志、并发状态和失败回滚。性能可以拆成复杂度、热点路径、内存占用和退化输入表现。

Rubric 还需要区分合格线和优秀线。合格线回答“是否可以接受”,优秀线回答“是否体现了更强工程判断”。如果只给满分标准,评分者会在中间情况上摇摆;如果只给缺陷清单,优秀方案又无法被稳定识别。

在 Coding Mentor 场景里,rubric 的另一个作用是沉淀训练信号。一次人工评价如果只留下“这次回答不好”,没有长期价值;如果记录为“违反排序稳定性契约,触发用例为同价格同评分商品,根因是二次排序覆盖原始顺序”,它就可以进入错误类型库、评估集、反馈协议,甚至成为后续 SFT 数据的候选来源。

题目库治理与常见反模式

题目库治理:让题目随模型迭代继续有效

题目一旦进入长期使用,就不再只是 Markdown 文件,而是评估资产。评估资产需要治理,否则很快失效。

最基本的治理单位是题目元数据。每道题至少应该记录题目 ID、能力层级、难度标签、领域标签、语言或框架、评估预算、公开测试数量、隐藏测试数量、预期通过率区间、污染风险、版本号和最近校准时间。这些信息不一定全部写在题面里,但必须能被题库系统查询。

难度校准应该周期性进行。团队可以选择几类代表模型:主力闭源模型、成本友好模型、本地开源模型、带工具调用的 agent、无工具的基础模型。每次复跑后记录通过率和失败类型。如果某道 Medium 题在主力模型上长期稳定高于目标通过率,它可能应该降级,或增加更能暴露能力边界的约束。如果某道题长期几乎无人通过,它可能不是 Hard,而是题面不清、测试过窄或验收不合理。

污染风险也必须治理。公开发布的题面、测试、参考实现和题解,都会进入未来模型的训练语料或检索结果。用于公开文章的题目可以服务教学,但不应直接作为私有评估集。真正用于模型选择、内部验收和训练闭环的题目,需要控制暴露范围,并记录哪些部分已经公开。

版本记录同样重要。题面改一个边界条件,测试新增一个隐藏用例,评分脚本修改一个异常判定,都会影响历史分数。如果没有版本号,团队很容易把不同版本的结果放在一起比较,最后得出错误结论。

常见反模式

第一种反模式是把题目写成需求故事,却没有验收契约。场景写得很像真实业务,但输入输出、异常策略和测试标准都不明确。这样的题能激发模型生成大量解释,却很难评分。

第二种反模式是把题目写成代码模板填空。模板能降低实现波动,但过度模板化会把评估变成格式遵循,模型只要补齐局部逻辑就能通过。它适合训练入门能力,不适合评估真实工程判断。

第三种反模式是只看公开示例。公开示例越多,模型越容易从示例反推规则,却不一定理解完整契约。公开示例应该帮助读者理解题意,不能替代隐藏测试和边界覆盖。

第四种反模式是难度标签不校准。题库里标着 Hard 的题,也许只是题面很长;标着 Easy 的题,也许包含隐式状态和异常路径。难度标签如果不绑定评估预算和实际通过率,就会误导模型选择和能力判断。

第五种反模式是把人工评价留在评论区。人工反馈如果没有结构化,就无法复用。好的反馈应能进入错误分类、rubric 修订、测试补充和训练候选样本,而不是停留在“这个答案感觉不行”。

结语:出题能力就是评估能力

给 AI 设计高质量编程题,本质上是在为能力评估搭建可复现环境。题目不是越长越好,也不是越难越好,而是越能稳定暴露目标能力边界越好。

从 Coding Mentor 的角度看,一道好题至少要完成四件事:明确要观察的能力层级,写清任务契约,设计能暴露错误模式的测试,保留可进入治理闭环的失败证据。只要这四件事成立,题目就不再是一次性交互,而是可以沉淀、复跑、比较和改进的组织资产。

下一篇会进入更直接的评估实践:当题目、测试和 rubric 已经准备好,团队如何系统性地评估 AI 的编程能力,并把评估结果转化为可执行的 Mentor 反馈。


参考与致谢

  • Bloom’s Taxonomy — Benjamin Bloom et al.
  • APPS Benchmark Design — Hendrycks et al., Stanford
  • LiveCodeBench Methodology — Jain et al., UC Berkeley

Series context

你正在阅读:AI Coding Mentor 系列

当前为第 3 / 9 篇。阅读进度只写入此浏览器的 localStorage,用于回到系列页时定位继续阅读入口。

查看完整系列 →

Series Path

当前系列章节

点击章节会在此浏览器记录本地阅读进度;刷新后可继续阅读。

9 chapters
  1. Part 1 已在路径前序 为什么你需要给AI当Coding Mentor? 当AI编程助手成为标配,真正的竞争力不再是会不会使用AI,而是能不能判断、校准和约束AI的工程输出。本文从信任缺口、反馈协议、评估标准和能力闭环出发,建立“人类作为Coding Mentor”的核心框架。
  2. Part 2 已在路径前序 AI编程能力评估全景:从HumanEval到SWE-bench,基准测试的演进与选择 公开基准不是模型排行榜的装饰,而是理解AI编程能力边界的测量工具。本文从HumanEval、APPS、CodeContests、SWE-bench、LiveCodeBench和Aider等基准出发,说明如何读榜、如何选择基准,以及如何把公开评估转化为团队自己的Coding Mentor评估体系。
  3. Part 3 当前阅读 如何设计高质量的编程题目:从题面到评估契约 高质量编程题不是更长的 prompt,而是能稳定暴露能力边界的评估契约。本文从 Bloom 层级、难度校准、任务契约、测试设计和题库治理出发,说明如何为 AI Coding Mentor 构建可复现的题目体系。
  4. Part 4 AI能力评估四步法:从一次测试到持续评估系统 给AI当Coding Mentor不是做一次模型测评,而是建立一套能持续暴露能力边界、记录失败证据、驱动专项改进和支撑协作决策的评估运营系统。
  5. Part 5 与AI协作的最佳实践:任务协议、对话控制与反馈闭环 给AI当Coding Mentor的核心技能不是写更长的提示词,而是设计任务协议、控制对话节奏、识别错误模式,并把协作过程沉淀为可验证、可复用的反馈信号。
  6. Part 6 实战案例:反馈协议、评估闭环、代码审查与编程教育数据 案例研究不应该停留在“如何更会用AI工具”。本文用模型选型评估、反馈协议设计、代码审查信号沉淀和编程教育数据闭环四个工程场景,说明人类如何把AI协作过程转化为可评估、可训练、可复用的导师信号。
  7. Part 7 从交付到训练:如何把AI编程协作变成Coding Mentor数据闭环 AI编程助手真正的组织价值,不只是提高交付速度,而是在每一次需求拆解、代码生成、评审修正、测试验证和上线复盘中沉淀可训练、可评估、可复用的导师信号。本文重构AI训练、AI辅助产品工程化交付、高质量SFT数据沉淀与模型评估的闭环框架。
  8. Part 8 从工程实战到训练数据:AI工程化自动产出SFT数据的系统化方法 承接第7篇的数据闭环,本文聚焦如何将已筛选的工程资产加工为高质量SFT样本,并接入可治理、可评估、可迭代的训练流水线。
  9. Part 9 未来展望:AI编程评估的演进趋势与长期思考 作为系列收官篇,本文以工程决策视角重构 AI Coding Mentor 的未来路线:评估对象如何演进、组织能力如何分层、治理边界如何前置。

Reading path

继续沿这条专题路径阅读

按推荐顺序继续阅读 AI 编程评估 相关内容,而不是只看同专题的随机文章。

查看完整专题路径 →

Next step

继续深入这个专题

如果这篇内容对你有帮助,下一步可以回到专题页继续系统阅读,或者订阅后续更新。

返回专题页 订阅 RSS 更新

RSS Subscribe

订阅更新

通过 RSS 阅读器订阅获取最新文章推送,无需频繁访问网站。

推荐使用 FollowFeedlyInoreader 等 RSS 阅读器

评论与讨论

使用 GitHub 账号登录参与讨论,评论将同步至 GitHub Discussions

正在加载评论...