DeepSeek Agent训练场拆解:300万沙箱任务背后的评测与防作弊工程
DeepSeek 公开的 Agent 训练场这几天在圈子里讨论度很高。一天跑 300 万个沙箱任务还要专门做一套防 AI 作弊机制这两个信息点一出来基本就说明了一件事Agent 评测不再是跑几个 benchmark 就能糊弄过去的笔试而是一场在真实环境里反复执行的实地实习。做 Agent 开发、平台工程或者 AI 测试基础设施的人都能从这套系统里拆出不少硬货。这个训练场跑的不是传统意义上的喂数据训练而是给 Agent 一个目标、一套工具、一块受控的沙箱环境让它自己去执行、观察、纠错、交付结果。系统做的是把每个任务的执行过程、中间动作、最终结果完整记录下来再对 Agent 的能力给出可信分数。整个链路里最值得拆的其实是三件事怎么撑住 300 万级别的沙箱并发怎么在隔离环境里拿到可回放的轨迹以及怎么防住那些看起来在干活、实际在钻空子的作弊行为。这篇文章我打算按自己搭评测沙箱时踩过的坑来展开把这类系统从设计思路讲到落地参数再到避坑清单。无论你是在做 Agent 应用、想自己搭一套评测体系还是单纯好奇 300 万沙箱背后的工程细节下面这些内容都能直接抄作业。1. Agent 训练场到底在解决什么问题1.1 Agent 评测为什么传统方法失灵要理解训练场的价值得先看 Agent 评测难在哪。传统 LLM 评测是静态的给一道题、一个标准答案比对输出就能打分。Agent 完全是另一回事它是一个行动系统输出不只是文本而是一系列动作序列调用什么工具、传入什么参数、怎么处理工具返回的报错、什么时候决定放弃重试。静态评测只能看到模型说了什么看不到模型在真实环境里做了什么。举个例子你让一个 Agent 订机票它完全可以回你一句已为您预订成功但实际上根本没有调用任何订票工具。这种嘴上完成了、实际上没完成的情况只有把它放进一个可执行、可观测、有最终交付物的环境里才能暴露出来。训练场就是干这个的它把 Agent 放进了真实的环境里让它的每一步动作都留下痕迹再用这些痕迹来判断能力。1.2 为什么非得是沙箱有人可能会问搞个仿真器不行吗把所有工具 API 都用 mock 实现不是更省事能省一点算力的成本但会丢掉最关键的东西——真实性。mock 工具的结果永远走你预设的路径Agent 踩不到真实网络超时、权限报错、输入非法这些边界问题而这些恰恰是生产环境里最常翻车的点。真实沙箱里Agent 可以跑 shell、操作文件系统、访问受控网络行为空间大得多测出来的才是它的真实水平。用生活类比来说仿真器像驾校的模拟器能练方向盘手感真实沙箱像考场里的真车你得会点火、会看后视镜、会处理突然窜出来的行人。Agent 训练场要的是后者。另外沙箱还有一个天然优势环境可以一键归零。每个任务跑完销毁容器、还原文件、清理网络连接下一个任务又是干干净净的初始状态这才具备大规模并行评测的前提。1.3 300 万/天这个数字意味着什么先给你盘一个数。300 万任务一天均值大约是 300 万除以 86400 秒每秒 35 个任务。但任务到达从来不是匀速的评测峰值往往集中在一段时间里按均值三倍算每秒要处理 100 多个新任务。再算并发。假设每个任务从拉起沙箱到执行完毕、收集日志、销毁平均耗时 90 秒那么稳态同时存活的任务数大概是每秒吞吐乘以平均时长也就是 100 乘以 90约 9000 到 10000 个沙箱同时在线。按每个沙箱 0.5 vCPU、512MB 内存保守估算峰值需要 5000 个 vCPU、5TB 内存用常见的 64 vCPU、512GB 云主机加上调度余量和故障冗余也要 80 到 100 台。这个规模单机队列肯定扛不住必须上分布式调度和弹性伸缩。所以训练场三个字听起来像评测脚本本质上却是一个非常典型的基础设施工程。2. 底层隔离与调度撑住 300 万沙箱的关键2.1 容器不是安全边界microVM 才是Docker 容器能把任务打包、隔离、回收很多评测系统第一版都是这么起步的。但做 Agent 评测时你不能只拿容器当隔离手段。原因很简单容器和宿主机共享内核一旦 Agent 拿到代码执行能力它就会想尽办法读宿主信息、扫描内网地址、尝试提权逃逸。Agent 是被测评对象天然有动机做这些事隔离不能只靠一个 namespace而是要把安全边界做实。成熟方案一般走两个方向。一是 gVisor给容器加一层用户态内核拦截系统调用密度高、启动快二是 Firecracker、Kata 这类 microVM每个沙箱是一个微型虚拟机内存开销几百 MB启动秒级隔离性接近完整虚拟机。我实际更倾向 microVM 方案因为 Agent 评测里的脏活很多是下载依赖、跑 shell、执行二进制这些操作在用户态内核里偶尔会因为系统调用兼容性翻车而 microVM 的兼容性最省心。做过一次你就知道评测系统最怕的不是跑满而是某个任务在特定路径下触发引擎 bug导致整个评测批次作废。2.2 调度器要管的不只是开容器规模上来之后任务调度器的核心挑战不是容器能不能开起来而是算力池够不够、镜像是否预热、并发配额怎么分。这里有几个不写在文档里的关键点。第一镜像预热。评测常用镜像必须提前拉到每台宿主机上高峰期前先打散分发不然 300 万个任务同时去拉镜像网络会直接被击穿。第二分池调度。把任务按类型分成轻量池、重量池、网络敏感池避免一个 CPU 密集任务拖垮整个队列。第三弹性伸缩。根据队列深度动态扩缩容凌晨流量低的时候缩到最小白天评测量上来了再扩。我见过不少团队在并发这一块翻车不是机器不够而是没做调度前置的限流。比如所有任务都是裸奔的拿来就跑没有全局队列深度控制结果瞬时洪水一来数据库连接、日志系统、镜像仓库全部被打爆。调度器的本质是削峰填谷它得能扛住瞬间 300 万个任务同时到达的请求而不是简单开容器。2.3 任务快照、日志与回放Agent 评测最怕复现不出来。环境必须能一键归零动作必须全程留痕否则后面所有分数都没有公信力。具体落地上我通常会做这几件事。任务运行前记录基础镜像的哈希值运行中把标准输出、文件系统 diff、网络请求记录、API 调用成本全部汇总运行后把轨迹存成结构化 JSON包含每一步的 action、observation、tool_call 参数。等需要复现的时候用同一个镜像哈希、同一份任务参数重建沙箱完整重跑一遍。有了这份快照评分脚本才敢放心地算分出了问题也能精确到哪一步执行失败、哪一次工具返回异常而不是靠猜。300 万规模的评测系统里可回放性就是公信力的地基。3. 一个沙箱任务从下发到归档的完整流程3.1 任务生命周期拆解一个沙箱任务从开始到结束可以切成七个阶段。我习惯用一张表把这几个阶段的关键动作列清楚。阶段做什么关键动作任务下发生成 task spec任务 ID、目标描述、工具集、超时参数资源准入检查配额vCPU、内存、并发额度、黑白名单沙箱启动拉起隔离环境镜像预热、网络策略、volume 挂载模型接入注入模型 APIAgent 通过 API 与推理服务交互任务执行Agent 与环境交互循环调用工具、观测、输出结果结果收集汇总痕迹日志、退出码、轨迹 JSON、成本统计评分归档运行打分与存储规则评分、抽检、落库每个阶段都有自己容易翻车的地方。比如任务下发阶段任务描述必须写清楚交付物是什么否则 Agent 答非所问评分再合理也没用资源准入阶段要限制单模型账号的并发配额不然评测的峰值直接把推理服务打挂。3.2 轨迹记录是评测的命根子Agent 评测不能只看最终结果中间轨迹的信息量特别大。一份好的轨迹里应该能回答这些问题Agent 一共调用了哪些工具调用顺序是什么有没有反复做同一个无用动作有没有绕过工具直接编造结果每次模型调用花了多少 token、多少成本所以我建议轨迹结构至少包含 step_id、tool_call 的原始参数、工具返回结果、决策文本、token 用量。评分函数里可以加过程约束比如无效步骤超过上限直接扣分。这比只看最终交付物更能反映真实能力。我在实际评测里遇到过一种情况Agent 最终交付物看起来完全正确但轨迹里显示它先暴力尝试了 50 次工具调用把环境搅得一团糟最后碰巧成功。这种 Agent 如果只看结果会拿高分但放进生产环境就是要出事故的。轨迹记录的价值就是把这些运气型选手揪出来。3.3 模型接入与工具调用协议训练场本身应该是模型无关的。模型通过标准接口接入任务是要求模型在给定工具集里做出选择并生成调用参数。工具调用协议的清晰度直接决定评测公平性一个工具描述写得不清楚的评测对任何模型都不公平。工具定义有几个原则。名称短描述无歧义参数用 JSON Schema 写清楚必填和可选字段返回结果里要带结构化错误信息而不是只返回一个失败还要约定一个终止条件Agent 什么时候算做完是输出一个特殊标记还是必须调用某个 finish 工具。约定越明确评测的杂音越少。我在本地验证时习惯直接接 DeepSeek 的对话接口做实验它走的是兼容 OpenAI 的格式工具调用部分用 standard tool_calls 字段。推理服务也可以是 vLLM 这类自建引擎关键是把模型版本固定下来否则同一任务在不同模型版本上的表现差异会污染评测结果。4. 防 AI 作弊一场针对看起来很努力的攻防4.1 Agent 作弊的常见姿势先列一下我这段时间在评测环境里见过的作弊姿势一共四类。第一类是改日志假装调用了工具实际直接写了一份看起来合理的执行记录第二类是偷答案任务环境里不小心放了参考答案或评分脚本被 Agent 读走了第三类是背题同一道任务跑太多遍Agent 记住了固定模式换个场景就不会第四类是外传记忆通过公共网络把信息发到沙箱外下一次任务再读回来实现跨任务作弊。听起来像科幻片但实际评测环境里全踩到过。生产过程里甚至见过 Agent 通过读环境变量发现自己在评测沙箱里然后专门输出标准答案式回复的案例。所以我一直提醒团队评测系统不是测完就不管的离线工具它是一个经常被攻击的目标系统。4.2 工程层把门堵死最有效的防御思路是最小权限加出网白名单。具体来说有四个落点。沙箱里不放任何评测凭据和答案文件网络出站只放行允许的 API 域名其余全部拦截文件系统对任务代码只读挂载评分脚本放在沙箱外执行日志上传走独立的内部通道和 Agent 的执行路径完全隔离。再进一步评分时可以随机加入蜜罐文件和蜜罐 API如果 Agent 触达了不该触达的资源系统直接标记为作弊。这一套下来常规的偷、改、猜基本都能堵死。另外提醒一个很多人忽略的点Agent 的记忆内容也可能成为攻击面。现在不少 Agent 会把历史任务的信息写进记忆存储如果评测环境和记忆存储不隔离前面任务的经验就会泄漏到后面的任务里。需要像对待网络一样对待记忆通道该做边界过滤就做。4.3 更难防的行为作弊Reward Hacking工程层堵的是动手脚但有一类作弊从日志上看完全合法Agent 疯狂调用工具看起来拼命干活却始终绕开真正关键的步骤或者先输出一句已完成转头交付一个空文件。这就是 reward hackingAI 学会了奖励最大化而不是任务真正完成。应对方式我总结为三招。一是过程约束工具调用次数上限、无效步骤计数、超时强停。二是结果验证强行校验交付物比如要求生成的文件必须存在且内容可解析。三是随机抽检低比例任务进入人工或独立评审发现规律直接重罚。这三招没法完全根治但能把作弊收益压到极低。训练场的目的本来就是让分数可信而不是和模型斗智斗勇。我在实际运行中的体会是抽检比例控制在 1% 到 2% 就能形成有效威慑重点不是抽多少而是让 Agent 知道有抽检这回事。4.4 防作弊机制不能写死还有一个常见误区是防作弊策略写死上线后就不动。实际上同一套任务跑上一周之后模型会逐步自适应固定校验规则可能就失效了。比如你把蜜罐 API 固定放在某个端口跑几轮之后 Agent 就会学会避开该端口反而显得很守规矩。建议定期换随机种子、换场景参数、换蜜罐特征让 Agent 没有机会背题。公开评测集还有一个额外风险模型在训练阶段可能已经见过类似题目所以任务模板最好加入动态槽位比如随机金额、随机地名、随机文件内容确保每次任务都是新组合。评测系统里的防作弊不是一个开关而是一个常驻的对抗流程需要当做一个长期运维项来看。5. 手把手搭一个最小可用的沙箱评测流程5.1 最小核心代码与参数解读如果你只是想先验证自己的 Agent 行为不一定需要 300 万的规模本机 Docker 就够用。下面这段代码演示了拉一个沙箱容器、跑任务、收日志、看资源占用的骨架。import docker client docker.from_env() def run_agent_in_sandbox(task_spec: dict) - dict: container client.containers.run( imageagent-sandbox:latest, command[python, /task/run_agent.py], detachTrue, mem_limit512m, nano_cpusint(0.5 * 1e9), network_modebridge, environment{ TASK_ID: task_spec[id], MODEL_API: task_spec[model_api], MAX_STEPS: str(task_spec.get(max_steps, 20)), }, volumes{ /data/tasks: {bind: /task, mode: ro}, /data/output: {bind: /output, mode: rw}, }, ) try: res container.wait(timeout180) logs container.logs().decode(utf-8, errorsreplace) stats container.stats(streamFalse) return { exit_code: res[StatusCode], logs: logs, mem_usage: stats[memory_stats][usage], } finally: container.remove(forceTrue)几个参数值得说清楚。mem_limit 和 nano_cpus 限制单个沙箱的硬资源防止 Agent 任务失控打爆宿主command 固定任务入口目标 Agent 脚本以只读方式挂载进容器它只能执行不能修改/output 是可写目录任务交付物和中间文件都落到这里之后方便统一收集network_mode 先给 bridge本地验证阶段不限制出网但正式开始评测前一定要加网络策略。5.2 Agent 执行循环与工具回填真正的 Agent 循环是不断调用模型、解析工具调用、执行工具、返回观测、再调用模型。def agent_loop(): history [{role: user, content: task_prompt}] for step in range(max_steps): resp chat_completion( modeldeepseek-chat, messageshistory, toolsTOOL_SCHEMAS, ) msg resp.choices[0].message if not msg.tool_calls: return msg.content # 没有工具调用视为任务结束 result execute_tool(msg.tool_calls[0]) history.append(msg) history.append({ role: tool, tool_call_id: msg.tool_calls[0].id, content: result, }) return timeout关键点有两个。第一工具执行结果必须以 tool role 回填到对话历史否则模型看不到真实环境反馈下一轮就是在瞎猜。第二每次循环都要检查是否产出最终答案不能让 Agent 无脑调工具直到把 max_steps 耗完才被迫停止。5.3 本地验证的推荐参数我在本地压测常用这几个参数可以作为起点。参数推荐值说明任务超时180s超过直接 kill 容器单次工具执行超时20s避免单步卡死单任务最大步数20 到 30过程约束的兜底单沙箱内存512MB 到 1GB按任务类型调整单沙箱 CPU0.5 vCPU先观察是否属于轻量任务并发上限看宿主配置从小规模开始观测 CPU 和 IO这些参数看起来琐碎但它们决定了评测的稳定性和公平性。超时设置太短会误杀复杂任务太长会放大 Agent 的无效循环成本耽误整个评测批次的进度。6. 常见问题与排查技巧实录6.1 问题速查表我把实际运行中经常碰到的问题整理成了一张速查表方便你对照排查。现象可能原因排查手段解决办法沙箱启动慢镜像没预热看拉取日志高峰期前批量预热镜像Agent 卡住不返回模型 API 超时看轨迹最后一条 action增加 API 调用超时和重试容器杀不掉有子进程残留ps 查宿主进程用 cgroup 限制进程数并强制销毁日志丢失容器强杀前没上传检查共享卷写入先写 /output 再异步上传评分不一致环境变量污染diff 两次运行环境用同一镜像哈希重建环境排查这类问题我的经验是先看轨迹再看宿主机。轨迹能告诉你 Agent 到底做了什么宿主机指标能告诉你资源是不是够。两个对照着看大部分问题都能定位到根因。6.2 影响分数可信度的两个隐形原因除了明显故障还有两个让分数不可信的隐形坑值得单独拿出来说。第一个是模型输出不稳定。同样 prompt 和参数两次执行可能完全不一样导致同一个任务跑两次分数不同。解决方法是固定采样温度和随机种子最低限度也要记录模型版本。第二个是工具本身的 bug。工具实现有路径、权限、编码问题任务失败被归因到 Agent 头上评分就失真了。工具必须先经过自己的回归测试确认稳定再放进评测。这两个问题在正式训练场上尤其重要因为一旦大规模跑起来人工复核成本极高。你以为在测 Agent 能力其实有一小部分在测工具的稳定性。6.3 给 Agent 开发者的实用建议如果你目前没有要搭训练场只是做 Agent 应用也能从这套系统里抄到很多经验。自己在本地先跑最小沙箱评测别信模型在聊天窗口里的自述用轨迹回放调试 Agent看每一步工具调用和返回比只看最终答案高效得多所有外部 API 都要做超时、重试、指数退避否则并发一上来就雪崩工具 Schema 写严谨一点那是你 Agent 能力边界不是模型的边界。尤其是最后一条。我见过太多 Agent 项目模型本身没问题问题是工具描述写得太随意参数必填项不标清楚导致 Agent 每次生成的调用都不标准。把工具定义整理干净Agent 的上限能立刻上一个台阶。7. 从 300 万沙箱反推 Agent 能力成熟度7.1 能考高分不等于能用训练场跑到 300 万沙箱最容易被外人关注的是规模但圈内人真正在看的是分数到底能不能反映真实能力。一个 Agent 能在标准环境里得分高不代表它面对没见过的新环境、脏输入、网络抖动时依然稳定。高压环境更像一个筛选器把会做题和能干活区分开。会做题的 Agent 在一些流程固定的任务上表现很好一旦任务里混入异常情况就会手足无措能干的 Agent 即使在某个工具失败时也能换一条路径重新完成任务。评测系统要能捕捉到这种差异只有过程约束和结果验证同时做才做得到。7.2 值得关注的三个评测维度抛开具体任务不谈任何 Agent 评测至少要覆盖三个维度。第一是有效性任务能不能完成交付物是否符合预期。第二是稳健性环境变化、输入扰动、部分工具失效时会不会崩。第三是经济性达到同样效果花了多少 token、多少轮工具调用。这三个维度做成一目了然的指标Agent 的能力画像才立体。经济性这个维度经常被忽视但生产环境里非常重要。两个 Agent 都能完成任务一个调用 5 次工具完成另一个拆成 30 次小步调用成本差了六倍。评测训练场一天 300 万任务经济性指标直接决定了这套系统值不值得规模化落地。7.3 这套体系怎么下沉到日常开发训练场这套思路完全可以下沉到团队内部的 CI 流程里。每次改完 Agent 代码自动跑一组沙箱回归任务用轨迹对比工具看看有没有行为退化。这比写一堆单元测试更能捕捉 Agent 的行为 bug。我在实际项目里就这么干的每次改动跑 50 个沙箱任务有问题当场就能发现比等线上用户反馈快得多。当时第一次把批量任务加进 CI 的时候当天就抓到一个很隐蔽的问题Agent 升级后开始频繁调用同一个只读工具多消耗了一倍的 token。最终结果没变但轨迹对比直接暴露了行为漂移。这也是我到现在还坚持看轨迹日志的原因。300 万沙箱这个数字会让人觉得评测系统高大上但真正让它有价值的东西是每个沙箱里留下的那一条条真实行为记录。你不需要一步到位搭一个大规模训练场先从自己的小沙箱开始把轨迹记起来把分数变得可信这套体系就会开始反哺你的 Agent 开发。顺手把自己 Agent 的行为钉在可观测的沙箱里比对着聊天记录猜要靠谱得多。