乐于分享
好东西不私藏

Hermes 源码拆解|L8 RL 训练飞轮:让生产 Agent 一键变 SFT 数据集

Hermes 源码拆解|L8 RL 训练飞轮:让生产 Agent 一键变 SFT 数据集

模块规模:environments/ 5K+ 行 + 顶层 3245 行 + 11 种 parser + 2 个 benchmark前置阅读:L2 核心、L4 工具、L6 记忆、L7 技能

🎯 一、L8 是什么(60 秒读懂)

一句话定位

L8 是 Hermes 的"研究飞轮发动机"——把生产用户对话和 RL 训练用同一套工具代码串起来,让"用户跑 Hermes → 产生轨迹 → 训练新模型 → 推回产品"这个闭环成为一行代码的距离。

生活化类比 🏎

想象一家自己研发 F1 赛车的车队:

  • 赛道上的车(L2-L7)
     = 生产 Agent,每天跑真实用户任务
  • 环境工程师(environments/)
     = 把赛车改装成试车版(agent_loop.py),能在风洞反复跑
  • 数据采集员(batch_runner.py)
     = 把 10000 圈数据拖出来做 SFT 数据集
  • 轨迹压缩师(trajectory_compressor.py)
     = 把"录像 2 小时"剪成"关键动作 30 分钟"
  • 评分员(ToolContext)
     = 在车刚跑完一瞬间钻进同一 sandbox 检查底盘——和赛车手用同一套工具
  • 方言翻译(tool_call_parsers/)
     = 不管 Kimi/GLM/Qwen 用什么 tool call 格式都标准化

核心解决的痛点 🎯

痛点
L8 的解法
训练代码和生产代码是两套
handle_function_call()
 两边都用,改一处两边生效
训练得到的模型在生产里不 work
训练时就用生产的 Modal / Docker sandbox
换模型家族要重写 tool call 解析
11 个 parser 插件式注册
RL reward 函数像科研代码
ToolContext
 让 verify 也能 terminal("pytest")
批量跑数据手动 resume
BatchRunner
 内建 prompt 粒度 checkpoint
轨迹太长训练塞不下
TrajectoryCompressor
 保留头尾摘要中间
"训练个 GSM8k 模型" 要开 10 个终端
rl_cli.py
 让 Agent 自己完成整个 RL 流程

🏗️ 二、四层架构

应用层rl_cli.py (446 行) 让 Agent 自主跑 RL;batch_runner.py (1291 行) 多进程批量数据生成 + checkpoint。

训练层hermes_base_env.py (714 行) extends Atropos BaseEnv,按组采样 toolset,collect_trajectory 产 ScoredDataGroup。子环境包括 terminal_test_envhermes_swe_envweb_research_envagentic_opd_env (1214 行最复杂)。

Agent 循环层agent_loop.py (534 行) 是 L2 主循环简化版——去 memory/skills/fallback/interrupt/并行/压缩,全局 ThreadPoolExecutor(128) 桥接 sync sandbox。

Reward 层tool_context.py (474 行) 是给 compute_reward 的"VIP 通行证"——同 task_id 钻进 sandbox 用全套工具验证。

解析层tool_call_parsers/ 11 种独立实现(Hermes/Mistral/Llama/Qwen/Qwen3 Coder/DeepSeek V3/V3.1/Kimi K2/GLM 4.5/4.7/Longcat),全部 import-free

后处理层trajectory_compressor.py (1508 行) 压到 15250 token——Kimi tokenizer + Gemini-3-Flash summary + 50 并发。

研究到产品的数据飞轮

L2 生产 Agent → JSONL 轨迹 → batch_runner → trajectory_compressor → SFT 训练 → Atropos RL → benchmarks → 新模型 → 部署回 L2

全流程 3245 行顶层代码 + 5000 行 environments,一家公司能做到代码级闭环——开源 Agent 界独一份

🔀 三、关键设计权衡

3.1 Phase 1 vs Phase 2:两套世界

维度
Phase 1 (OpenAI)
Phase 2 (vLLM)
服务器
OpenAI/OpenRouter 等
vLLM/SGLang
Tool call 解析
服务端
客户端 parser
Token/logprob
占位估算
精确
训练可用
❌ 仅产 SFT 数据
✅ PPO/GRPO

精髓同一个 env 类支持两种——原型用 Phase 1,正式训练切 Phase 2。

3.2 训练循环的"纯洁性"——敢砍才能训

HermesAgentLoop 比 L2 主循环砍掉 memory / skills / fallback / interrupt / 并行 / 压缩。为什么?

  • Memory 引入 session 串扰
     → 破坏可复现性
  • Fallback 让有的样本用 Claude 有的用 GPT
     → 破坏 on-policy 假设
  • 运行时压缩改变 token 序列
     → 破坏 RL log-prob 计算

启示生产主循环的复杂度对训练是毒药。300 行简化版 vs 3300 行完整版——敢砍才能训得动。

3.3 ToolContext:开放 vs 封闭的 Reward 接口

传统派def verify(state, action) -> reward——安全封闭但每加验证方式要改框架。

Hermes 派:reward 函数能调任意工具——ctx.terminal("pytest") / ctx.read_file() / ctx.web_search()同 task_id = 同 sandbox,验证器看到的状态就是模型跑完的状态。

理由:训练场景作弊是研究人员责任,框架不该设防。生产级 sandbox 隔离保证不污染生产环境。

3.4 轨迹 Summary 作为 "human" 角色

trajectory_compressor 把压掉的中段塞回去时——

  • 作为 "assistant" → summary 文本进 loss,模型学习"模仿 Gemini Flash 文风" ❌
  • 作为 "system" → 破坏对话结构(system 只能在最前)❌
  • 作为 "human" → 合理:前面的事我来告诉你 ✅

启示训练数据的角色标记是 loss 信号的门——错一个全盘皆输。

💡 四、AI 产品经理视角的特别洞察

4.1 可借鉴点(搬到你的产品)

🎯 生产代码 = 训练代码:所有工具走同一 handle_function_call() 入口——修 bug 和改训练行为是同一个 PR
🎯 同 task_id = 同 sandbox:让验证器在模型跑完后钻进去——QA 检 DB / Coding 跑测试 / Browse 看 cookie 通用模式。
🎯 Parser 插件化:ABC + 装饰器注册,无 vLLM 依赖——只用 stdlib re/json/uuid,任何环境都能跑。
🎯 Checkpoint 用 item 粒度:不要 batch 粒度——让用户 kill 再 resume 不丢 9 个好样本。
🎯 归一化 schema for Parquet:进 HuggingFace datasets 的 JSONL 必须每行 schema 一致,否则 load 时崩。
🎯 binary-safe 上传:base64 + chunked printf——heredoc 会坏 binary,每个 RL 框架都掉过这坑。

4.2 差异化启发(Hermes 做对了)

⭐ 研究到产品飞轮 = 单仓库:很多公司"研究代码"和"产品代码"分两个 repo——永远对不上。Hermes 把它们做成 L2 生产 + L8 研究 + 复用 L4 工具——同一 registry 同一 dispatcher。
⭐ rl_cli.py = Agent 做 MLE:用户说一句"训练个 GSM8k 模型",Agent 自己完成 list_environments → 改 config → test_inference → start_training → check_status(30 分钟一查)→ 早停判断。这是 AI 替代 MLE 的最直接演示
⭐ 11 个 parser 全部独立重写:不是"装个 vLLM 就能解析"——而是"在客户端调试、离线分析也能解析"。真正的多模型支持而不是市场话术。
⭐ 数据集可指定 per-prompt container image:SWE-Bench 每道题有自己的 repo 镜像——batch_runner 提前 docker pull,失败直接 skip。生产级容错

4.3 局限与边界

❌ 简化循环 ≠ L2,训练过的模型在生产可能遇到没见过的状态——生产端要禁掉未训练的功能。
❌ Phase 2 只支持 vLLM/SGLang,用 TensorRT/MLC 要自己实现 ManagedServer。
❌ 11 个 parser 维护成本——每出新模型要写一个。
❌ trajectory_compressor 调 Gemini API,付费 + 外部依赖。

🌟 结语:L8 是 Hermes 最独特的护城河

读完 L8 你会理解一个反直觉的事实:

Hermes 最大的竞争优势不是"55+ 工具",而是"训练和生产代码是同一份"

LangChain 只有生产代码,AutoGen 只有研究代码,CrewAI 两者都没做——只有 Hermes 把两个世界用同一个 handle_function_call() 串起来。

这意味着:用户在产品里跑 Hermes → 真实轨迹 → batch_runner 放大 → Atropos RL → 新 checkpoint → 部署回产品 → 新能力。

L4 让 Agent 能做事(工具)L6 让 Agent 记得事(记忆)L7 让 Agent 学到事 + 传承事(技能)L8 让 Agent 自我进化(训练)

一家研究机构(Nous Research)能把产品和研究做到代码级闭环——开源 Agent 界独一份。

产品启示:想做"越用越懂我"的 AI 产品护城河?

别只做产品功能,做"产品数据 → 训练数据"的飞轮。

点击左下方“阅读原文”查看完整拆解内容

源码拆解 | 2026-05-08 | by 赛博裕王朱载垕