原文链接:Environments, Benchmarks & Data Generation sidebar position: 5 title: "Environments, Benchmarks & Data Generation" description: "Building RL training envir
> 原文链接:Environments, Benchmarks & Data Generation
sidebar_position: 5 title: "Environments, Benchmarks & Data Generation" description: "Building RL training environments, running evaluation benchmarks, and generating SFT data with the Hermes-Agent Atropos integration"
环境(Environment)、基准测试(Benchmark)与数据生成
Hermes Agent 包含一个完整的环境框架,将其工具调用能力连接到 Atropos RL 训练框架。这支持三种工作流:
- RL 训练 — 在多轮 Agent 任务上使用 GRPO 训练语言模型
- 基准测试 — 在标准化 Agent 基准上评估模型
- 数据生成 — 从 Agent rollout 生成 SFT 训练数据
三者共享相同的核心:一个**环境(Environment)**类,定义任务、运行 Agent 循环并评分输出。
:::info 仓库环境 vs RL 训练工具
本文档描述的 Python 环境框架位于仓库的 environments/ 目录下,是 Hermes/Atropos 集成的实现级 API。这与面向用户的 rl_* 工具不同,后者作为远程 RL 训练工作流的编排接口。
:::
:::tip 快速链接
架构
环境系统基于三层继承链构建:
classDiagram
class BaseEnv {
服务器管理
Worker 调度
Wandb 日志
CLI: serve / process / evaluate
}
class HermesAgentBaseEnv {
终端后端配置
工具解析
Agent 循环引擎
ToolContext 访问
}
class TerminalTestEnv {
堆栈测试
}
class HermesSweEnv {
SWE 训练
}
class TerminalBench2EvalEnv {
基准测试评估
}
class TBLiteEvalEnv {
快速基准测试
}
class YCBenchEvalEnv {
长期基准测试
}
BaseEnv <|-- HermesAgentBaseEnv
HermesAgentBaseEnv <|-- TerminalTestEnv
HermesAgentBaseEnv <|-- HermesSweEnv
HermesAgentBaseEnv <|-- TerminalBench2EvalEnv
TerminalBench2EvalEnv <|-- TBLiteEvalEnv
TerminalBench2EvalEnv <|-- YCBenchEvalEnv
BaseEnv (Atropos)
来自 atroposlib 的基础层。提供:
- 服务器管理 — 连接到 OpenAI 兼容 API(VLLM、SGLang、OpenRouter)
- Worker 调度 — 并行 rollout 协调
- Wandb 集成 — 指标日志和 rollout 可视化
- CLI 接口 — 三个子命令:
serve、process、evaluate - 评估日志 —
evaluate_log()将结果保存到 JSON + JSONL
HermesAgentBaseEnv
Hermes Agent 层(environments/hermes_base_env.py)。添加:
- 终端后端配置 — 设置
TERMINAL_ENV用于沙盒执行(local、Docker、Modal、Daytona、SSH、Singularity) - 工具解析 —
_resolve_tools_for_group()调用 Hermes Agent 的get_tool_definitions()获取基于启用/禁用工具集的正确工具 Schema - Agent 循环集成 —
collect_trajectory()运行HermesAgentLoop并评分结果 - 两阶段操作 — Phase 1(OpenAI 服务器)用于评估/SFT,Phase 2(VLLM ManagedServer)用于带 logprobs 的完整 RL
- 异步安全补丁 — 对 Modal 后端进行 monkey-patch 以在 Atropos 事件循环内工作
具体环境(Concrete Environments)
你的环境继承 HermesAgentBaseEnv 并实现五个方法:
| 方法 | 用途 |
|---|---|
setup() | 加载数据集,初始化状态 |
get_next_item() | 返回下一个 rollout 项 |
format_prompt(item) | 将项转换为用户消息 |
compute_reward(item, result, ctx) | 对 rollout 评分(0.0–1.0) |
evaluate() | 周期性评估逻辑 |
核心组件
Agent 循环
HermesAgentLoop(environments/agent_loop.py)是可复用的多轮 Agent 引擎。它运行与 Hermes Agent 主循环相同的工具调用模式:
- 通过
server.chat_completion()将消息 + 工具 Schema 发送到 API - 如果响应包含
tool_calls,通过handle_function_call()分发每个调用 - 将工具结果附加到对话中,返回步骤 1
- 如果没有
tool_calls,Agent 完成
工具调用在线程池(ThreadPoolExecutor(128))中执行,以便异步后端(Modal、Docker)不会在 Atropos 事件循环中死锁。
返回一个 AgentResult:
@dataclass
class AgentResult:
messages: List[Dict[str, Any]] # 完整对话历史
turns_used: int # LLM 调用次数
finished_naturally: bool # 模型是否自行停止
reasoning_per_turn: List[Optional[str]] # 提取的推理内容
tool_errors: List[ToolError] # 工具分发期间遇到的错误
managed_state: Optional[Dict] # VLLM ManagedServer 状态(Phase 2)
工具上下文(ToolContext)
ToolContext(environments/tool_context.py)为奖励函数提供对模型在 rollout 期间使用的相同沙盒的直接访问。task_id 作用域意味着所有状态(文件、进程、浏览器标签页)都被保留。
async def compute_reward(self, item, result, ctx: ToolContext):
# 在模型的终端沙盒中运行测试
test = ctx.terminal("pytest -v")
if test["exit_code"] == 0:
return 1.0
# 检查是否创建了文件
content = ctx.read_file("/workspace/solution.py")
if content.get("content"):
return 0.5
# 下载文件进行本地验证
ctx.download_file("/remote/output.bin", "/local/output.bin")
return 0.0
可用方法:
| 类别 | 方法 |
|---|---|
| 终端 | terminal(command, timeout) |
| 文件 | read_file(path)、write_file(path, content)、search(query, path) |
| 传输 | upload_file()、upload_dir()、download_file()、download_dir() |
| Web | web_search(query)、web_extract(urls) |
| 浏览器 | browser_navigate(url)、browser_snapshot() |
| 通用 | call_tool(name, args) — 调用任何 Hermes Agent 工具的万能接口 |
| 清理 | cleanup() — 释放所有资源 |
工具调用解析器
对于 Phase 2(VLLM ManagedServer),服务器返回没有结构化工具调用的原始文本。environments/tool_call_parsers/ 中的客户端解析器从原始输出中提取 tool_calls:
from environments.tool_call_parsers import get_parser
parser = get_parser("hermes") # 或 "mistral"、"llama3_json"、"qwen"、"deepseek_v3" 等
content, tool_calls = parser.parse(raw_model_output)
可用解析器:hermes、mistral、llama3_json、qwen、qwen3_coder、deepseek_v3、deepseek_v3_1、kimi_k2、longcat、glm45、glm47。
在 Phase 1(OpenAI 服务器类型)中,不需要解析器——服务器原生处理工具调用解析。
可用基准测试
TerminalBench2
89 个具有挑战性的终端任务,每个任务有独立的 Docker 沙盒环境。
| 测试内容 | 单任务编码/系统管理能力 |
| 评分方式 | 二元通过/失败(测试套件验证) |
| 沙盒 | Modal 云沙盒(每任务 Docker 镜像) |
| 工具 | terminal + file |
| 任务数 | 跨多个类别的 89 个任务 |
| 成本 | 完整评估约 $50–200(并行执行) |
| 时间 | 约 2–4 小时 |
python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \
--config environments/benchmarks/terminalbench_2/default.yaml
# 运行特定任务
python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \
--config environments/benchmarks/terminalbench_2/default.yaml \
--env.task_filter fix-git,git-multibranch
数据集:HuggingFace 上的 NousResearch/terminal-bench-2。
TBLite (OpenThoughts Terminal Bench Lite)
100 个难度校准的任务 — TerminalBench2 的更快代理。
| 测试内容 | 与 TB2 相同(编码/系统管理),校准难度层级 |
| 评分方式 | 二元通过/失败 |
| 沙盒 | Modal 云沙盒 |
| 工具 | terminal + file |
| 任务数 | 100 个任务:简单 (40)、中等 (26)、困难 (26)、极难 (8) |
| 相关性 | 与完整 TB2 的 r=0.911 |
| 速度 | 比 TB2 快 2.6–8 倍 |
python environments/benchmarks/tblite/tblite_env.py evaluate \
--config environments/benchmarks/tblite/default.yaml
TBLite 是 TerminalBench2 的轻量子类——只有数据集和超时不同。由 OpenThoughts Agent 团队(Snorkel AI + Bespoke Labs)创建。数据集:NousResearch/openthoughts-tblite。
YC-Bench
长期战略基准测试 — Agent 扮演 AI 初创公司的 CEO。
| 测试内容 | 数百轮的多轮战略一致性 |
| 评分方式 | 复合评分:0.5 × 生存 + 0.5 × 标准化资金 |
| 沙盒 | 本地终端(不需要 Modal) |
| 工具 | 仅 terminal |
| 运行数 | 默认 9 次(3 个预设 × 3 个种子),顺序执行 |
| 成本 | 完整评估约 $50–200 |
| 时间 | 约 3–6 小时 |
# 安装 yc-bench(可选依赖)
pip install "hermes-agent[yc-bench]"
# 运行评估
bash environments/benchmarks/yc_bench/run_eval.sh
# 或直接运行
python environments/benchmarks/yc_bench/yc_bench_env.py evaluate \
--config environments/benchmarks/yc_bench/default.yaml
# 快速单预设测试
python environments/benchmarks/yc_bench/yc_bench_env.py evaluate \
--config environments/benchmarks/yc_bench/default.yaml \
--env.presets '["fast_test"]' --env.seeds '[1]'
YC-Bench 使用 collinear-ai/yc-bench — 一个确定性模拟,包含 4 个技能领域(research、inference、data_environment、training)、声望系统、员工管理和财务压力。与 TB2 的每任务二元评分不同,YC-Bench 衡量 Agent 能否在数百个复合决策中保持一致的策略。
训练环境
TerminalTestEnv
一个最小化的自包含环境,带有内联任务(无外部数据集)。用于验证完整堆栈的端到端测试。每个任务要求模型在已知路径创建文件;验证器检查内容。
# process 模式(将 rollout 保存到 JSONL,不需要训练服务器)
python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups terminal_test_output.jsonl
# serve 模式(连接到 Atropos API 进行 RL 训练)
python environments/terminal_test_env/terminal_test_env.py serve
HermesSweEnv
SWE-bench 风格的训练环境。模型获得编码任务,使用 terminal + file + web 工具解决它,奖励函数在同一个 Modal 沙盒中运行测试。
python environments/hermes_swe_env/hermes_swe_env.py serve \
--openai.model_name YourModel \
--env.dataset_name bigcode/humanevalpack \
--env.terminal_backend modal
运行环境
每个环境都是独立的 Python 脚本,具有三个 CLI 子命令:
evaluate — 运行基准测试
用于仅评估的环境(基准测试)。运行所有项目,计算指标,记录到 wandb。
python environments/benchmarks/tblite/tblite_env.py evaluate \
--config environments/benchmarks/tblite/default.yaml \
--openai.model_name anthropic/claude-sonnet-4.6
不需要训练服务器或 run-api。环境处理一切。
process — 生成 SFT 数据
运行 rollout 并将带分数的轨迹保存到 JSONL。用于在没有完整 RL 循环的情况下生成训练数据。
python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups output.jsonl \
--openai.model_name anthropic/claude-sonnet-4.6
输出格式:每行是一个带分数的轨迹,包含完整对话历史、奖励和元数据。
serve — 连接到 Atropos 进行 RL 训练
将环境连接到运行中的 Atropos API 服务器(run-api)。用于实时 RL 训练期间。
# 终端 1:启动 Atropos API
run-api
# 终端 2:启动环境
python environments/hermes_swe_env/hermes_swe_env.py serve \
--openai.model_name YourModel
环境从 Atropos 接收项目,运行 Agent rollout,计算奖励,并将带分数的轨迹发回进行训练。
两阶段操作
Phase 1:OpenAI 服务器(评估 / SFT)
使用带有 tools= 参数的 server.chat_completion()。服务器(VLLM、SGLang、OpenRouter、OpenAI)原生处理工具调用解析。返回带有结构化 tool_calls 的 ChatCompletion 对象。
- 适用于:评估、SFT 数据生成、基准测试、测试
- 占位 token 为 Atropos 管道创建(因为 OpenAI API 不提供真实 token ID)
Phase 2:VLLM ManagedServer(完整 RL)
使用 ManagedServer 通过 /generate 获取精确的 token ID + logprobs。客户端工具调用解析器从原始输出重建结构化 tool_calls。
- 适用于:使用 GRPO/PPO 的完整 RL 训练
- 真实 token、掩码和 logprobs 流经管道
- 在配置中设置
tool_call_parser以匹配你的模型格式(例如"hermes"、"qwen"、"mistral")
创建环境
训练环境
from environments.hermes_base_env import HermesAgentBaseEnv, HermesAgentEnvConfig
from atroposlib.envs.server_handling.server_manager import APIServerConfig
class MyEnvConfig(HermesAgentEnvConfig):
my_custom_field: str = "default_value"
class MyEnv(HermesAgentBaseEnv):
name = "my-env"
env_config_cls = MyEnvConfig
@classmethod
def config_init(cls):
env_config = MyEnvConfig(
enabled_toolsets=["terminal", "file"],
terminal_backend="modal",
max_agent_turns=30,
)
server_configs = [APIServerConfig(
base_url="https://openrouter.ai/api/v1",
model_name="anthropic/claude-sonnet-4.6",
server_type="openai",
)]
return env_config, server_configs
async def setup(self):
from datasets import load_dataset
self.dataset = list(load_dataset("my-dataset", split="train"))
self.iter = 0
async def get_next_item(self):
item = self.dataset[self.iter % len(self.dataset)]
self.iter += 1
return item
def format_prompt(self, item):
return item["instruction"]
async def compute_reward(self, item, result, ctx):
# ctx 提供对 rollout 沙盒的完整工具访问
test = ctx.terminal("pytest -v")
return 1.0 if test["exit_code"] == 0 else 0.0
async def evaluate(self, *args, **kwargs):
# 训练期间的周期性评估
pass
if __name__ == "__main__":
MyEnv.cli()
仅评估基准测试
对于基准测试,遵循 TerminalBench2、TBLite 和 YC-Bench 使用的模式:
- 创建在
environments/benchmarks/your-benchmark/ - 设置仅评估配置:
eval_handling=STOP_TRAIN、steps_per_eval=1、total_steps=1 - Stub 训练方法:
collect_trajectories()返回(None, []),score()返回None - 实现
rollout_and_score_eval(eval_item)— 每项的 Agent 循环 + 评分 - 实现
evaluate()— 编排所有运行,计算汇总指标 - 添加流式 JSONL 用于崩溃安全的结果持久化
- 添加清理:
KeyboardInterrupt处理、cleanup_all_environments()、_tool_executor.shutdown() - 使用
evaluate子命令运行
请参阅 environments/benchmarks/yc_bench/yc_bench_env.py 作为清晰、文档完善的参考实现。
配置参考
HermesAgentEnvConfig 字段
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enabled_toolsets | List[str] | None(全部) | 要启用的 Hermes 工具集 |
disabled_toolsets | List[str] | None | 要过滤掉的工具集 |
distribution | str | None | 概率工具集分布名称 |
max_agent_turns | int | 30 | 每次 rollout 最大 LLM 调用数 |
agent_temperature | float | 1.0 | 采样温度 |
system_prompt | str | None | Agent 的系统消息 |
terminal_backend | str | "local" | local、docker、modal、daytona、ssh、singularity |
terminal_timeout | int | 120 | 每个终端命令的超时秒数 |
terminal_lifetime | int | 3600 | 最大沙盒生命周期 |
dataset_name | str | None | HuggingFace 数据集标识符 |
tool_pool_size | int | 128 | 工具执行线程池大小 |
tool_call_parser | str | "hermes" | Phase 2 原始输出的解析器 |
extra_body | Dict | None | OpenAI API 的额外参数(例如 OpenRouter Provider 偏好) |
eval_handling | Enum | STOP_TRAIN | STOP_TRAIN、LIMIT_TRAIN、NONE |
YAML 配置
环境可以通过 --config 传递 YAML 文件进行配置:
env:
enabled_toolsets: ["terminal", "file"]
max_agent_turns: 60
max_token_length: 32000
agent_temperature: 0.8
terminal_backend: "modal"
terminal_timeout: 300
dataset_name: "NousResearch/terminal-bench-2"
tokenizer_name: "NousResearch/Hermes-3-Llama-3.1-8B"
use_wandb: true
wandb_name: "my-benchmark"
openai:
base_url: "https://openrouter.ai/api/v1"
model_name: "anthropic/claude-sonnet-4.6"
server_type: "openai"
health_check: false
YAML 值覆盖 config_init() 默认值。CLI 参数覆盖 YAML 值:
python my_env.py evaluate \
--config my_config.yaml \
--openai.model_name anthropic/claude-opus-4.6 # 覆盖 YAML
前置条件
所有环境
- Python >= 3.11
atroposlib:pip install git+https://github.com/NousResearch/atropos.git- LLM API 密钥(OpenRouter、OpenAI 或自托管的 VLLM/SGLang)
Modal 沙盒基准测试(TB2、TBLite)
- Modal 账号和 CLI:
pip install "hermes-agent[modal]" MODAL_TOKEN_ID和MODAL_TOKEN_SECRET环境变量
YC-Bench
pip install "hermes-agent[yc-bench]"(安装 yc-bench CLI + SQLAlchemy)- 不需要 Modal — 使用本地终端后端运行
RL 训练
TINKER_API_KEY— Tinker 训练服务的 API 密钥WANDB_API_KEY— 用于 Weights & Biases 指标跟踪tinker-atropos子模块(位于仓库中的tinker-atropos/)
请参阅 RL 训练了解 Agent 驱动的 RL 工作流。
目录结构
environments/
├── hermes_base_env.py # 抽象基类 (HermesAgentBaseEnv)
├── agent_loop.py # 多轮 Agent 引擎 (HermesAgentLoop)
├── tool_context.py # 每 rollout 的工具访问(用于奖励函数)
├── patches.py # Modal 后端的异步安全补丁
│
├── tool_call_parsers/ # Phase 2 客户端解析器
│ ├── hermes_parser.py # Hermes/ChatML ⭐achat 格式
│ ├── mistral_parser.py # Mistral [TOOL_CALLS] 格式
│ ├── llama_parser.py # Llama 3 JSON 工具调用
│ ├── qwen_parser.py # Qwen 格式
│ ├── deepseek_v3_parser.py # DeepSeek V3 格式
│ └── ... # + kimi_k2, longcat, glm45/47 等
│
├── terminal_test_env/ # 堆栈验证(内联任务)
├── hermes_swe_env/ # SWE-bench 训练环境
│
└── benchmarks/ # 评估基准测试
├── terminalbench_2/ # 89 个终端任务,Modal 沙盒
├── tblite/ # 100 个校准任务(快速 TB2 代理)
└── yc_bench/ # 长期战略基准测试