跳到主要内容

环境、基准测试与数据生成

Hermes Agent 包括一个完整的环境框架,将其工具调用功能连接到 Atropos RL 训练框架。这实现了三个工作流程:

  1. RL 训练 — 使用 GRPO 训练多轮代理任务的语言模型
  2. 基准 — 根据标准化代理基准评估模型
  3. 数据生成 — 从代理部署中生成 SFT 训练数据

这三个共享相同的核心:定义任务、运行代理循环并对输出进行评分的环境类。

Repo 环境与 RL 训练工具

此处记录的 Python 环境框架位于存储库的 environments/ 目录下,是 Hermes/Atropos 集成的实现级 API。这与面向用户的 rl_* 工具是分开的,后者作为远程 RL 训练工作流程的编排界面运行。

:::提示快速链接

建筑学

环境系统构建在三层继承链之上:

BaseEnv (阿特罗波斯)

基础来自atroposlib。提供:

  • 服务器管理 — 连接到 OpenAI 兼容的 API(VLLM、SGLang、OpenRouter)
  • 工作人员调度 — 并行部署协调
  • Wandb 集成 — 指标记录和推出可视化
  • CLI 界面 — 三个子命令:serveprocessevaluate
  • 评估日志记录evaluate_log() 将结果保存为 JSON + JSONL

HermesAgentBaseEnv

Hermes Agent 层 (environments/hermes_base_env.py)。补充:

  • 终端后端配置 — 设置 TERMINAL_ENV 进行沙盒执行(本地、Docker、Modal、Daytona、SSH、Singularity)
  • 工具解析_resolve_tools_for_group() 调用 Hermes-agent 的 get_tool_definitions() 以根据启用/禁用的工具集获取正确的工具模式
  • 代理循环集成collect_trajectory() 运行 HermesAgentLoop 并对结果进行评分
  • 两阶段操作 - 第 1 阶段(OpenAI 服务器)用于 eval/SFT,第 2 阶段(VLLM ManagedServer)用于带有 logprobs 的完整 RL
  • 异步安全补丁 — 猴子补丁 Modal 后端在 Atropos 的事件循环内工作

具体环境

您的环境继承自 HermesAgentBaseEnv 并实现五个方法:

方法目的
setup()setup()加载数据集,初始化状态
get_next_item()get_next_item()返回下一个项目以进行部署
format_prompt(item)format_prompt(item)将项目转换为用户消息
compute_reward(item, result, ctx)compute_reward(item, result, ctx)对首次推出进行评分 (0.0–1.0)
evaluate()evaluate()定期评估逻辑

核心组件

代理循环

HermesAgentLoop (environments/agent_loop.py) 是可重用的多轮代理引擎。它运行与 Hermes-agent 的主循环相同的工具调用模式:

1.通过server.chat_completion()发送消息+工具模式到API 2. 如果响应包含 tool_calls,则通过 handle_function_call() 分派每个 3. 将工具结果附加到对话中,返回步骤 1 4.如果没有tool_calls,则代理完成

工具调用在线程池 (ThreadPoolExecutor(128)) 中执行,以便异步后端(Modal、Docker)不会在 Atropos 的事件循环内出现死锁。

返回 AgentResult

@dataclass
class AgentResult:
messages: List[Dict[str, Any]] # Full conversation history
turns_used: int # Number of LLM calls made
finished_naturally: bool # True if model stopped on its own
reasoning_per_turn: List[Optional[str]] # Extracted reasoning content
tool_errors: List[ToolError] # Errors encountered during tool dispatch
managed_state: Optional[Dict] # VLLM ManagedServer state (Phase 2)

工具上下文

ToolContext (environments/tool_context.py) 使奖励函数可以直接访问模型在推出期间使用的相同沙箱task_id 范围意味着保留所有状态(文件、进程、浏览器选项卡)。

async def compute_reward(self, item, result, ctx: ToolContext):
# Run tests in the model's terminal sandbox
test = ctx.terminal("pytest -v")
if test["exit_code"] == 0:
return 1.0

# Check if a file was created
content = ctx.read_file("/workspace/solution.py")
if content.get("content"):
return 0.5

# Download files for local verification
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_search(query)web_extract(urls)
浏览器browser_navigate(url)browser_snapshot()
通用call_tool(name, args) — 任何 Hermes-agent 工具的逃生舱口
清理cleanup() — 释放所有资源

工具调用解析器

对于阶段 2 (VLLM ManagedServer),服务器返回原始文本,无需结构化工具调用。 environments/tool_call_parsers/ 中的客户端解析器从原始输出中提取 tool_calls

from environments.tool_call_parsers import get_parser

parser = get_parser("hermes") # or "mistral", "llama3_json", "qwen", "deepseek_v3", etc.
content, tool_calls = parser.parse(raw_model_output)

可用解析器:hermesmistralllama3_jsonqwenqwen3_coderdeepseek_v3deepseek_v3_1kimi_k2longcatglm45glm47

在第 1 阶段(OpenAI 服务器类型),不需要解析器 - 服务器本身处理工具调用解析。

可用的基准

TerminalBench2

89 个具有挑战性的终端任务,具有每个任务的 Docker 沙箱环境。

它测试什么单任务编码/系统管理能力
评分二进制通过/失败(测试套件验证)
沙盒模态云沙箱(每个任务 Docker 镜像)
工具terminal + file
任务跨多个类别的 89 项任务
成本完整评估(并行执行)约 50–200 美元
时间约 2–4 小时
python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \
--config environments/benchmarks/terminalbench_2/default.yaml

# Run specific tasks
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(编码/系统管理员)相同,校准难度等级
评分二进制通过/失败
沙盒模态云沙箱
工具terminal + file
任务100 个任务:简单 (40)、中等 (26)、困难 (26)、极限 (8)
相关性r=0.911 满 TB2
速度比 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 长凳

长期战略基准——代理人扮演人工智能初创公司的首席执行官。

它测试什么数百回合多回合战略连贯
评分复合:0.5 × survival + 0.5 × normalised_funds
沙盒本地终端(无需模态)
工具仅限 terminal
运行9 个默认值(3 个预设 × 3 个种子),顺序
成本全面评估约 50–200 美元
时间~3–6 小时
# Install yc-bench (optional dependency)
pip install "hermes-agent[yc-bench]"

# Run evaluation
bash environments/benchmarks/yc_bench/run_eval.sh

# Or directly
python environments/benchmarks/yc_bench/yc_bench_env.py evaluate \
--config environments/benchmarks/yc_bench/default.yaml

# Quick single-preset test
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 个技能领域(研究、推理、数据环境、培训)、声望系统、员工管理和财务压力的确定性模拟。与 TB2 的每任务二元评分不同,YC-Bench 衡量智能体是否能够在数百个复合决策中保持一致的策略。

训练环境

终端测试环境

具有内联任务的最小独立环境(无外部数据集)。用于端到端验证完整堆栈。每个任务都要求模型在已知路径创建一个文件;验证者检查内容。

# Process mode (saves rollouts to JSONL, no training server needed)
python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups terminal_test_output.jsonl

# Serve mode (connects to Atropos API for RL training)
python environments/terminal_test_env/terminal_test_env.py serve

HermesSweEnv

SWE-台式训练环境。该模型获得一个编码任务,使用终端+文件+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 数据

运行部署并将评分轨迹保存到 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 训练期间使用。

# Terminal 1: Start the Atropos API
run-api

# Terminal 2: Start the environment
python environments/hermes_swe_env/hermes_swe_env.py serve \
--openai.model_name YourModel

该环境从 Atropos 接收项目,运行代理部署,计算奖励,并将评分轨迹发送回进行训练。

两阶段操作

第 1 阶段:OpenAI 服务器(评估/SFT)

server.chat_completion()tools= 参数结合使用。服务器(VLLM、SGLang、OpenRouter、OpenAI)本地处理工具调用解析。返回具有结构化 tool_callsChatCompletion 对象。

  • 用途:评估、SFT 数据生成、基准测试、测试
  • 占位符令牌是为 Atropos 管道创建的(因为 OpenAI API 无法提供真正的令牌 ID)

第 2 阶段:VLLM 托管服务器(完整 RL)

通过 /generate 使用 ManagedServer 获取准确的令牌 ID + logprobs。客户端 tool call parser 从原始输出重建结构化 tool_calls

  • 用途:使用 GRPO/PPO 进行全面强化学习训练
  • 真实令牌、掩码和日志概率流过管道
  • 在配置中设置 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 gives full tool access to the rollout's sandbox
test = ctx.terminal("pytest -v")
return 1.0 if test["exit_code"] == 0 else 0.0

async def evaluate(self, *args, **kwargs):
# Periodic evaluation during training
pass

if __name__ == "__main__":
MyEnv.cli()

仅评估基准

对于基准测试,请遵循 TerminalBench2、TBLite 和 YC-Bench 使用的模式:

  1. environments/benchmarks/your-benchmark/下创建
  2. 设置仅评估配置eval_handling=STOP_TRAINsteps_per_eval=1total_steps=1
  3. 存根训练方法collect_trajectories()返回(None, [])score()返回None
  4. 实现 rollout_and_score_eval(eval_item) — 每项代理循环 + 评分
  5. 实施 evaluate() — 编排所有运行,计算聚合指标
  6. 添加流式 JSONL 以实现崩溃安全的结果持久性
  7. 添加清理KeyboardInterrupt 处理、cleanup_all_environments()_tool_executor.shutdown()
  8. 使用 evaluate 子命令运行

请参阅 environments/benchmarks/yc_bench/yc_bench_env.py 以获得干净、记录良好的参考实现。

配置参考

HermesAgentEnvConfig 字段

领域类型默认描述
enabled_toolsetsenabled_toolsets List[str]List[str] None(全部)启用哪些 Hermes 工具集
disabled_toolsetsdisabled_toolsets List[str]List[str] NoneNone过滤掉的工具集
distributiondistribution strstr NoneNone概率工具集发行版名称
max_agent_turnsmax_agent_turns intint 3030每次部署的最大 LLM 调用次数
agent_temperatureagent_temperature floatfloat 1.01.0取样温度
system_promptsystem_prompt strstr NoneNone代理的系统消息
terminal_backendterminal_backend strstr "local""local" localdockermodaldaytonasshsingularity
terminal_timeoutterminal_timeout intint 120120每个终端命令的秒数
terminal_lifetimeterminal_lifetime intint 36003600最大沙箱寿命
dataset_namedataset_name strstr NoneNone HuggingFace 数据集标识符
tool_pool_sizetool_pool_size intint 128128工具执行的线程池大小
tool_call_parsertool_call_parser strstr "hermes""hermes"第 2 阶段原始输出的解析器
extra_bodyextra_body DictDict NoneNone OpenAI API 的额外参数(例如 OpenRouter 提供商首选项)
eval_handlingeval_handling EnumEnum STOP_TRAINSTOP_TRAIN STOP_TRAINLIMIT_TRAINNONE

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 # overrides 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_IDMODAL_TOKEN_SECRET 环境变量

对于 YC Bench

  • pip install "hermes-agent[yc-bench]"(安装 yc-bench CLI + SQLAlchemy)
  • 无需模态 - 使用本地终端后端运行

用于强化学习训练

  • TINKER_API_KEYTinker 培训服务的 API 密钥
  • WANDB_API_KEY — 用于权重和偏差指标跟踪
  • tinker-atropos 子模块(位于存储库中的 tinker-atropos/ 处)

请参阅 RL Training 了解代理驱动的 RL 工作流程。

目录结构

environments/
├── hermes_base_env.py # Abstract base class (HermesAgentBaseEnv)
├── agent_loop.py # Multi-turn agent engine (HermesAgentLoop)
├── tool_context.py # Per-rollout tool access for reward functions
├── patches.py # Async-safety patches for Modal backend

├── tool_call_parsers/ # Phase 2 client-side parsers
│ ├── hermes_parser.py # Hermes/ChatML <tool_call> format
│ ├── mistral_parser.py # Mistral [TOOL_CALLS] format
│ ├── llama_parser.py # Llama 3 JSON tool calling
│ ├── qwen_parser.py # Qwen format
│ ├── deepseek_v3_parser.py # DeepSeek V3 format
│ └── ... # + kimi_k2, longcat, glm45/47, etc.

├── terminal_test_env/ # Stack validation (inline tasks)
├── hermes_swe_env/ # SWE-bench training environment

└── benchmarks/ # Evaluation benchmarks
├── terminalbench_2/ # 89 terminal tasks, Modal sandboxes
├── tblite/ # 100 calibrated tasks (fast TB2 proxy)
└── yc_bench/ # Long-horizon strategic benchmark