跳转到主要内容
Agent Environment 是 agent 执行动作并获取观察结果的上下文。任务集提供任务,验证器判断是否完成。 当前发布格式把任务集和环境清单打包,以 <owner>/<name>@<version> 管理不可变版本。 清单声明如何连接或运行环境;发布包本身不是已经启动的沙箱。

布局

目录下的一切都会被上传。版本不可变。只有 deployment: local 需要 tasks.jsonl;远程服务和托管镜像自行管理任务数据。

tasks.jsonl

每行一个 JSON 对象:
train | eval
默认值:"train"
这一行属于任务集的哪一半。逐行声明。平台由操作本身决定一个作业看到哪一半,所以训练作业拿不到留出任务,评测也要不到训练任务。一次 评测索要环境从未声明过的 split 会被拒绝,而不是被悄悄喂上训练任务 —— 这就是这个字段存在要防的那 一种失败,而它恰好是那种看起来像好成绩的失败。
任务集从不发出。没有任何路由返回副本,也没有导出。一家企业认为什么算难,往往比它的训练数据更能 说明问题,所以作业引用一个环境,只在被批准的运行时里收到任务内容。

manifest.json

string
必填
永远是 tuneplane/environment/v1。
nemo-gym | openenv
必填
交互契约:OpenEnv 使用 reset / step / state;NeMo Gym 使用轨迹会话。
local | remote | container
必填
谁启动环境实现:local 在作业内运行;remote 连接已有服务;container 由执行后端托管镜像。 NeMo Gym 当前仅支持 local。v1 清单和原来混合部署方式的协议名称会被拒绝。
object
必填
{"kind": "rubric|plugin|endpoint", "ref": "..."} —— 由什么决定一个任务是否完成。见 判定器。
array
agent 能调什么:一个名字、一个端点,以及参数的 JSON Schema。
object
{"plugin": "<owner>/<name>", "version": "...", "entrypoint": "module:ClassName", "digest": "..."}。 nemo-gym 必填。代码属于一个 capability: environment 插件;平台最多写一个两行的 shim 去 import 它。
bool
默认值:"false"
harness 要跑模型生成代码时为 true。需要沙箱的作业落在没有配置沙箱提供方的部署上会被拒绝 —— 它不会退回到在训练容器里跑那些代码。
string
默认值:"other"
NeMo Gym 的指标分组类别。nemo-gym 必填并会被校验,其他协议下没有意义。取值为 math、 coding、agent、knowledge、instruction_following、long_context、safety、games、 translation、e2e、rlhf、other 之一。
string
openenv 环境的 OCI 镜像。像其他任何镜像一样按钉住的 runtime 产物解析;从不临时拉取。
url
仅适用于 deployment: remote。可以使用固定 endpoint、Fleet 或已注册 runner。endpoint 和 Fleet 不能同时指定。

协议与部署方式

两种交互契约与三种部署方式组成四种已支持的组合。Docker、E2B 等沙箱提供方是另一个选择,不是协议值。
回合级。平台从它持有的任务集起环境服务端,训练器通过 openenv-core 的客户端自己驱动 episode: reset、step、state。TRL、SkyRL、Unsloth 和 Axolotl 都用这种。不需要 harness —— 循环已经在训练器手里。

访问远程环境

openenv (deployment: remote) 环境能不能用,取决于训练作业能否向它发起连接。控制平面负责解析它在哪里应答 并把地址交出去,但它从不承载 episode 本身(ADR-0025)。 一次 episode 是一连串回合,每个生成轮一次;把它路由穿过那个负责判定准入的进程,等于在每一回合上 都加一跳,而那一跳离数据很远。 所以当环境位于集群路由不到的网络上时,下面三条至少要成立一条: 哪一条都不是”通过控制台代理”。如果你发现自己想要那个,答案通常是第一行。
或者让这个问题消失。 openenv (deployment: container) 环境跑在作业旁边的容器里,没有距离要跨,上面三行一行都 用不上。只要环境能容器化,这就是该优先考虑的路 —— OpenEnv 生态也正在往那个方向走。目前需要 kubernetes fleet。

Harness

驱动模型走完一个环境的代码,以 capability: environment 插件提供。 物化那条路需要它,框架会 import 并运行它。自服务的回合级那条路不需要,训练器自己驱动 episode。
plugin.yaml
manifest 里的 harness.digest 钉住这个环境所依据的 harness 包。团队把 harness 和环境一起发布时留空 它;两者分开做版本、且不匹配的 harness 会给出不同分数时,设上它。它在提交时校验,不在每次 rollout 时校验。

推送并引用

<owner>/<name> 或裸名字
必填
裸名字落进你自己的命名空间。
string
必填
推上去之后不可变。
flag
只在环境首次创建时生效。
同一份解析代码从一个模块跑在 CLI 里和控制面里 —— 所以能推上去的 manifest 就是能跑起来的 manifest。未知的协议或判定器 kind 在推送时就被拒绝,而不是在 rollout 时才发现,因为一个校验通过 却跑不起来的环境已经让某个人花掉了一次 GPU 分配。

确认成功

打印协议、判定器、工具,以及是否需要沙箱。控制台的环境页显示同样的信息,另外还有哪些运行引用过它。

下一步

判定器讲判定完成的三种方式 · 编写评分标准 · 使用环境

质量证据

tuneplane-examples 中的 common/envkit/quality.py 在用户项目内执行回调,再通过 Reporter.environment_quality() 上报。请接入环境实际使用的模型、判分器和 harness,固定 checkpoint,并在测量期间禁用模型更新;控制面不负责实现这些执行逻辑。 创建 my_quality:adapter 工厂,返回 measure() 的参数: 可调用 verifier_fixtures(verify, fixture_task, correct=..., incorrect=...),对真实判分器执行 正例、反例与执行检查。错误答案被正确拒绝时,反例应上报 fail。要求沙箱的环境还需要 egress_allowed、egress_denied、reference_isolation 回调,对实际运行时进行探测。 缺失检查不会视为成功;回调需自行设置网络和进程超时。 生成回调可返回字符串或 Prediction(text=..., tokens=...);缺失 token 用量显示为未知。 回调异常记为 infra_error,不算模型答错。入口保存全部计划试验的 JSON 报告及单独的本地验收证据文件, 然后上报元数据。原始验收证据留在本地,可能含敏感诊断信息,应妥善保管。上传失败会明确报错并保留本地报告。 上报内容不包含模型正文或参考答案。 在环境所有者的作业内固定环境版本后运行:
训练适用性测量使用训练作业,保留评估部分的测量使用评估作业,不能覆盖平台分配的 TUNEPLANE_JOB_ENVIRONMENT_SPLIT。本地执行时省略 --upload,将 --directory 指向原始编写目录。 这是现有项目作业中的函数/CLI 集成入口,不是新增的一键模型执行服务;GPU 生成和沙箱强制隔离仍由实际运行时负责。