评审 AI 生成代码,重点看验证器漏掉了什么
样例通过只说明覆盖了少量输入。生成的题解还可能在空输入、极值、重复元素、递归深度或输出量上失败。验证器应把格式、编译、运行、资源超限和测试失败分开记录,避免把所有错误都交给模型“反思”。
AST 检查能发现部分禁用 API 或语法问题,但不是安全证明。代码仍应在独立的受限环境运行:非特权用户、无网络、只读文件系统、CPU/内存/PID/输出限制及超时后对子进程树的回收。容器镜像、运行时和挂载点也属于攻击面。
ctx, cancel := context.WithTimeout(parent, limit)
defer cancel()
cmd := exec.CommandContext(ctx, binary, args...)
cmd.Dir = workdir
CommandContext 只负责取消主进程;复杂运行器还要确认子进程组、日志上限和临时目录都能清理。不要把完整源码、测试输入或环境信息写入模型反馈。
修复尝试应有次数和 token 预算,每次候选代码重新经过同一套验证。结果页明确写“通过哪些测试”,而不是宣称代码已被完全证明正确或安全。
验证器的失败分类决定修复方向
编译失败、测试断言失败、运行超时和启动失败的处理方式不同。若验证器只返回一段混合日志,模型或人工评审都很难判断下一步该修改代码、减少输入规模,还是检查运行环境。结构化记录阶段、退出状态、资源限制是否触发,以及经过截断的诊断信息,会比一整段原始输出更可用。
也要承认验证器的边界:固定测试集无法覆盖所有路径,AST 规则只能识别已知的危险写法。反例是仅凭一次样例通过就放开网络、文件写入或长时间执行;这会把正确性不足变成环境风险。运行隔离和测试覆盖是两道独立防线,不能互相替代。
用拒绝用例检查隔离是否真的生效
可以准备不应被允许的候选程序,例如尝试访问网络、向工作目录外写文件、派生过多子进程或持续输出。验证重点不是收集它们的完整内容,而是确认运行器在限制触发后及时终止进程组,临时目录被清理,下一次任务不会继承前一次的文件或环境。
对正常代码,则至少覆盖空输入、边界输入和资源接近限制的输入。结果页把用例范围和未覆盖部分写清楚,读者才能判断“可运行”在这里具体意味着什么。修复循环达到预算后应返回当前失败类型,而不是继续无上限地调用模型。
3. 审查结论要保留不确定项
生成代码通过一组测试,并不等于所有行为已经被证明正确。评审结果可以明确列出已验证的路径、未覆盖的分支和需要人工确认的业务规则。这样开发者知道下一步该补什么,调用方也不会把“通过自动检查”误读成发布许可。
对改动范围较大的补丁,先做小粒度提交更容易审。每次只处理一个错误类别,运行相应测试,再进入下一轮;若模型建议重写整段逻辑,则先要求它说明影响的接口和不变量。把验证器发现的问题、修复后的差异和仍未解决的风险一起留下,后续排查才不会重新从生成结果开始猜。
4. 依赖变化也属于代码审查范围
生成的补丁有时会顺手加入一个包或改动锁文件。即使业务代码很小,依赖也可能改变许可证、体积、构建脚本或安全边界。评审时先确认新增依赖是否真的不可替代,再看它的版本范围和安装后的实际差异。
测试通过不代表依赖路径可信。对需要联网、读取环境变量或执行安装脚本的包,应结合项目既有策略处理。把这部分列在审查结论里,能避免大家只盯着生成出来的函数,却漏掉运行环境的变化。

371

被折叠的 条评论
为什么被折叠?



