環境、基準測試與數據生成
Hermes Agent 包含一個完整的環境框架,將它的工具調用能力與 Atropos 強化學習訓練框架相連接。這支持三種工作流:
- 強化學習訓練 — 使用 GRPO 在多輪 Agent 任務上訓練語言模型
- 基準測試 — 在標準化的 Agent 基準上評估模型
- 數據生成 — 從 Agent 回放中生成 SFT 訓練數據
這三種工作流共享同一個核心:一個定義任務、運行 Agent 循環並評分輸出的 環境 類。
此處文檔中的 Python 環境框架位於倉庫的 environments/ 目錄下,是 Hermes/Atropos 集成的實現級 API。這與面向用戶的 rl_* 工具不同,後者作為遠程強化學習訓練工作流的編排接口。
架構
環境系統基於三層繼承鏈構建:
BaseEnv (Atropos)
atroposlib 的基礎類。提供:
- 服務器管理 — 連接到 OpenAI 兼容 API(VLLM、SGLang、OpenRouter)
- 工作器調度 — 並行回放協調
- Wandb 集成 — 指標日誌記錄與回放可視化
- CLI 界面 — 三個子命令:
serve、process、evaluate - 評估日誌 —
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(),根據啟用/禁用的工具集獲取正確的工具模式 - Agent 循環集成 —
collect_trajectory()運行HermesAgentLoop並評分結果 - 雙階段運行 — 第一階段(OpenAI 服務器)用於評估/SFT,第二階段(VLLM ManagedServer)用於完整強化學習(帶 logprobs)
- 異步安全補丁 — 對 Modal 後端進行猴子補丁,使其可在 Atropos 的事件循環內正常工作
具體環境
你的環境繼承自 HermesAgentBaseEnv,並實現以下五個方法:
| 方法 | 用途 |
|---|---|
setup() | 加載數據集,初始化狀態 |
get_next_item() | 返回下一項用於回放 |
format_prompt(item) | 將一項轉換為用戶消息 |
compute_reward(item, result, ctx) | 評分回放結果(0.0–1.0) |
evaluate() | 定期評估邏輯 |
核心組件
Agent 循環
HermesAgentLoop(environments/agent_loop.py)是可複用的多輪 Agent 引擎。其運行方式與 Hermes Agent 主循環中的工具調用模式一致:
- 通過
server.chat_completion()將消息 + 工具模式發送至 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 # 如果模型自行停止則為 True
reasoning_per_turn: List[Optional[str]] # 提取推理內容
tool_errors: List[ToolError] # tool 調度過程中遇到錯誤
managed_state: Optional[Dict] # VLLM ManagedServer 狀態(第 2 階段)
工具上下文
ToolContext(environments/tool_context.py)使獎勵函數可直接訪問 Agent 回放期間所用的 同一沙箱。task_id 的作用域意味著所有狀態(文件、進程、瀏覽器標籤頁)均被保留。
async def compute_reward(self, item, result, ctx: ToolContext):
# 在model的終端sandbox中運行測試
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_search(query)、web_extract(urls) |
| 瀏覽器 | browser_navigate(url)、browser_snapshot() |
| 通用 | call_tool(name, args) — 任意 Hermes Agent 工具的逃生通道 |
| 清理 | cleanup() — 釋放所有資源 |
工具調用解析器
對於 第二階段(VLLM ManagedServer),服務器返回原始文本,不包含結構化工具調用。客戶端解析器位於 environments/tool_call_parsers/ 中,用於從原始輸出中提取 tool_calls:
from environments.tool_call_parsers import get_parser
parser = get_parser("hermes") # 或“0”、“1”、“2”、“3”等。
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。
在第一階段(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
# 運行特定任務
python environments/benchmarks/terminalbench_2/terminalbench2_env.py evaluate \
--config environments/benchmarks/terminalbench_2/default.yaml \
--env.task_filter fix-git,git-multibranch
數據集:NousResearch/terminal-bench-2 在 HuggingFace 上。
TBLite(OpenThoughts Terminal Bench Lite)
100 個難度校準的任務 —— TerminalBench2 的快速 Agent。
| 測試內容 | 與 TB2 相同(編碼/系統管理),難度分級校準 |
| 評分方式 | 二元通過/失敗 |
| 沙箱環境 | 模態雲沙箱 |
| 工具 | 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 × survival + 0.5 × normalised_funds |
| 沙箱環境 | 本地終端(無需 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 個技能領域(研究、推理、數據環境、訓練)、聲望系統、員工管理以及財務壓力。與 TB2 的單任務二元評分不同,YC-Bench 衡量 Agent 是否能在數百個累積決策中保持連貫的戰略。
訓練環境
TerminalTestEnv
一個最小化的自包含環境,任務內聯(無需外部數據集)。用於端到端驗證完整系統。每個任務要求模型在已知路徑創建文件;驗證器檢查內容。
# 處理模式(將部署保存到 JSONL,無需訓練服務器)
python environments/terminal_test_env/terminal_test_env.py process \
--env.data_path_to_save_groups terminal_test_output.jsonl
# 服務模式(連接Atropos API進行RL訓練)
python environments/terminal_test_env/terminal_test_env.py serve
HermesSweEnv
類似 SWE-bench 的訓練環境。模型獲得編碼任務,使用終端 + 文件 + 網絡工具解決,獎勵函數在相同的模態沙箱中運行測試。
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 格式保存帶評分的軌跡。適用於在不進行完整強化學習循環的情況下生成訓練數據。
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 以進行強化學習訓練
將環境連接到正在運行的 Atropos API 服務器(run-api)。用於實時強化學習訓練。
# 端子1:啟動Atropos API
run-api
# 終端2:啟動環境
python environments/hermes_swe_env/hermes_swe_env.py serve \
--openai.model_name YourModel
環境從 Atropos 接收任務,運行 Agent 回放,計算獎勵,並將帶評分的軌跡返回用於訓練。
兩階段運行機制
階段 1:OpenAI 服務器(評估 / SFT)
使用 server.chat_completion() 並傳入 tools= 參數。服務器(VLLM、SGLang、OpenRouter、OpenAI)原生處理工具調用解析。返回帶有結構化 tool_calls 的 ChatCompletion 對象。
- 用途:評估、SFT 數據生成、基準測試、測試
- 佔位符令牌 用於 Atropos 流水線(因 OpenAI API 無法提供真實令牌 ID)
階段 2:VLLM ManagedServer(完整強化學習)
使用 ManagedServer 獲取精確的令牌 ID 和 logprobs(通過 /generate)。客戶端側的 工具調用解析器 從原始輸出重建結構化的 tool_calls。
- 用途:使用 GRPO/PPO 的完整強化學習訓練
- 真實令牌、掩碼和 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 提供對部署的 sandbox 的完全 Tool 訪問權限
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 - 存根訓練方法:
collect_trajectories()返回(None, []),score()返回None - 實現
rollout_and_score_eval(eval_item)—— 每項任務的智能體循環 + 評分 - 實現
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 | 每次推演的最大 LLM 調用次數 |
agent_temperature | float | 1.0 | 採樣溫度 |
system_prompt | str | None | 智能體的系統消息 |
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" | 第二階段原始輸出的解析器 |
extra_body | Dict | None | OpenAI API 的額外參數(例如 OpenRouter 提供商偏好) |
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 訓練 瞭解由智能體驅動的 RL 工作流。
目錄結構
environments/
├── hermes_base_env.py # 抽象基類(HermesAgentBaseEnv)
├── agent_loop.py # 多回轉agent發動機(HermesAgentLoop)
├── tool_context.py # 每次推出 tool 訪問獎勵功能
├── patches.py # Modal 後端的異步安全補丁
│
├── tool_call_parsers/ # 第 2 階段客戶端解析器
│ ├── hermes_parser.py # Hermes/ChatML <tool_call> 格式
│ ├── mistral_parser.py # 米斯特拉爾 [TOOL_CALLS] 格式
│ ├── llama_parser.py # 駱駝 3 JSON tool 呼叫
│ ├── qwen_parser.py # Qwen 格式
│ ├── deepseek_v3_parser.py # DeepSeek V3格式
│ └── ... # + like_k2、longcat、glm45/47 等
│
├── terminal_test_env/ # 堆棧驗證(內聯任務)
├── hermes_swe_env/ # SWE-臺架訓練環境
│
└── benchmarks/ # 評估基準
├── terminalbench_2/ # 89 個終端任務,模態沙箱
├── tblite/ # 100 個校準任務(快速 TB2 代理)
└── yc_bench/ # 長期戰略標杆