本篇复用上一篇生成的runs/demo-001/contract.json读取其中的protected与checks把workspace/tests复制成runs/demo-001/grader/tests并输出grader_snapshot.json。上一篇契约中的摘要是本篇快照的父标识后续检查只运行快照测试不信任 Agent 可写工作区里的同名文件。一、确定性测试也会被“正确地欺骗”单元测试每次给出相同结果不代表它安全。如果 Agent 能修改断言测试仍然确定性地执行只是确定性地证明了被篡改的新标准。防御重点不是把检查写得更聪明而是隔离写权限被评估的生产代码可以变负责给分的测试、契约和执行脚本不能与它共享写域。快照创建时逐文件计算摘要拒绝符号链接并把清单写到运行目录。复制完成后再次从目标读取并校验避免只相信复制调用返回成功。下面代码没有依赖特定容器在支持权限隔离的环境中还应把快照以只读挂载交给裁判进程。from__future__importannotationsimporthashlibimportjsonimportshutilfrompathlibimportPathdefsha256(path:Path)-str:digesthashlib.sha256()withpath.open(rb)ashandle:forchunkiniter(lambda:handle.read(65536),b):digest.update(chunk)returndigest.hexdigest()defsnapshot_tree(source:Path,target:Path)-dict[str,str]:iftarget.exists():raiseFileExistsError(fsnapshot already exists:{target})manifest{}forpathinsorted(source.rglob(*)):ifpath.is_symlink():raiseValueError(fsymlink forbidden:{path})ifnotpath.is_file():continuerelativepath.relative_to(source)destinationtarget/relative destination.parent.mkdir(parentsTrue,exist_okTrue)shutil.copyfile(path,destination)source_hashsha256(path)ifsha256(destination)!source_hash:raiseOSError(fcopy verification failed:{relative})manifest[relative.as_posix()]source_hashreturnmanifestdefmain()-int:contract_pathPath(runs/demo-001/contract.json)contractjson.loads(contract_path.read_text(encodingutf-8))targetPath(runs/demo-001/grader/tests)filessnapshot_tree(Path(workspace/tests),target)snapshot{contract_sha256:contract[sha256],files:files}outputPath(runs/demo-001/grader_snapshot.json)output.write_text(json.dumps(snapshot,indent2),encodingutf-8)print(fsnapshot_files{len(files)}contract{contract[sha256][:12]})return0if__name____main__:raiseSystemExit(main())运行输出snapshot_files4 contract7a1a4a54d861二、为什么复制一份还不够如果 Agent 与裁判使用同一系统账号它仍可能找到运行目录并改写快照。文件chmod 444只能防误写文件所有者可以改回权限。更强的边界是不同账号、容器只读挂载、独立工作树或者由 CI 控制面持有隐藏测试。隔离强度应匹配风险个人本地辅助工具可用权限与摘要检测自动合并生产代码则需要独立执行环境。另一个坑是只保护测试文件却让 Agent 修改测试发现规则、环境变量或依赖解析路径。比如把同名模块放到更靠前的PYTHONPATH快照测试仍可能导入伪造实现。裁判命令应固定解释器、工作目录与模块路径并记录环境白名单。记忆点是保护裁判不只保护题目还要保护考场入口。importjsonfrompathlibimportPathdefverify_snapshot(snapshot_path:Path,root:Path)-list[str]:snapshotjson.loads(snapshot_path.read_text(encodingutf-8))changed[]forrelative,expectedinsnapshot[files].items():pathroot/relativeifnotpath.is_file()orsha256(path)!expected:changed.append(relative)returnchanged snapshotPath(runs/demo-001/grader_snapshot.json)changedverify_snapshot(snapshot,Path(runs/demo-001/grader/tests))print(fsnapshot_ok{notchanged}changed{changed})运行输出snapshot_okTrue changed[]三、公开测试与隐藏测试各解决什么公开测试给 Agent 精确反馈便于定位隐藏测试降低针对样例硬编码的收益。全部隐藏会让修复变成猜谜全部公开又容易过拟合。更稳妥的组合是公开契约级示例、隐藏边界集合、再加不依赖具体样例的性质检查。例如折扣函数可以公开10000 → 9000隐藏零值和舍入边界同时检查结果永不为负。隐藏测试不是安全机密的万能替代。模型可能从公开仓库历史或网络检索到答案执行环境也可能泄漏文件。真正重要的是多种独立证据保护快照确认标准没变性质测试确认行为族差异审查确认没有无关改动。四、如何运行隔离裁判检查前先验证契约和快照摘要再把工作区生产代码复制到临时评估目录最后从只读测试入口执行。测试输出、退出码和快照摘要一起写事件。只记exit_code0不够因为无法证明运行的是哪一版测试。失败输出要限制长度并保留完整工件摘要防止超长日志淹没下一轮上下文。本篇产物是grader_snapshot.json与只读测试树。下一篇会以契约目标、裁判失败输出和快照摘要为输入生成steer.json。它不会把“测试变绿”改写成新目标而是始终保留原目标只追加本轮最小失败证据。快照还应记录创建工具版本与文件模式避免文本相同但执行属性不同。跨平台交付时路径大小写与换行转换可能改变摘要应在创建前规定规范环境不要在验证失败后临时放宽比较规则。参考来源Dev.toLoop Engineering: How to Stop Your Agent Reward-Hacking Its Own ChecksPython 文档shutil — High-level file operations 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《Agent可靠性工程实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。