LLM Agent 训练基础设施的架构设计、核心原理与工程实践全景解析
基于 VERL / ROLL / RAGEN / Agent-R1 / VerlTool 等前沿框架,结合 ProtAgent 实战经验
Agent Harness 是 LLM Agent 训练过程中管理交互循环、环境沙箱、轨迹收集和 Reward 计算的训练层基础设施,区别于面向应用层的 Agent Framework。
代表:VERL、ROLL、RAGEN、Agent-R1
代表:LangChain、AutoGen、CrewAI、Coze
LangChain 相当于 PyTorch 的 nn.Module(定义模型结构),Harness 相当于 PyTorch 的 Trainer(管理训练循环)。二者是上下游关系,不是竞争关系。
管理多轮交互循环:LLM 生成 Action → 解析 → 路由到工具 → 拿回 Observation → 拼入上下文 → 下一轮推理
创建/销毁/监控隔离执行环境,确保工具调用不会影响宿主系统或其他轨迹
收集和缓存完整的 Agent 交互轨迹(Thought + Action + Observation 序列),供训练使用
对轨迹进行多维度打分:Step Reward(逐步即时反馈)+ Episode Reward(终局目标导向)
管理训练端与推理端之间的策略权重同步(NCCL broadcast),确保 Rollout 使用最新策略
一个完整的 Agent Harness 从底层到顶层分为四层,各层通过标准化接口解耦,支持独立演进和替换。
class InferenceBackend(Protocol):
"""后端可切换:vLLM / SGLang / TensorRT-LLM"""
def generate(self, prompts: list[str], stop_tokens: list[str]) -> list[str]: ...
def get_logprobs(self, prompts: list[str], completions: list[str]) -> list[float]: ...
def update_weights(self, state_dict: dict) -> None: ...
class AgentEnv:
"""reset/step/close — 与 Gym 同构的 Agent 环境接口"""
def reset(self, seed=None):
# 加载任务样本 → skill 路由 → 构造 system prompt
return messages_list, {"tools": schema, "sample_id": id}
def step(self, action: str):
# 解析 action → 执行工具 → 终止判断 → 计算 reward
return observation, reward, terminated, truncated, info
内部可以任意复杂(各自演进),对外必须接口统一(可组合)。每一层只关心自己的职责,通过标准化的接口与上下游通信。新增工具不需要改推理引擎,切换推理后端不需要改训练框架。
Agent 训练中最核心的工程挑战:工具调用期间 GPU 不能空等。异步 Rollout 是提升 GPU 利用率的关键。
GRPO 对每个 prompt 采 G=8 条轨迹,每条轨迹平均 5 轮工具调用,一个 batch 32 个 prompt = 1280 次工具调用。同步执行时工具 latency 累积到分钟级,GPU 几乎全在等待。
所有轨迹等最慢的那条完成。GPU 利用率 ~50%。简单但严重浪费计算资源。
轨迹 A 等工具返回时,GPU 处理轨迹 B/C/D 的推理。GPU 利用率 >85%。
[GPU: vLLM Server]
↕ (gRPC)
[CPU: AsyncRolloutEngine]
├── InferenceWorker (batch requests)
└── ToolWorker (concurrent calls)
└── SandboxPool (process-level)
适合单机 8 卡场景。延迟低,实现简单。
[Ray Cluster] ├── InferenceActors (4 GPUs) ├── RolloutActors (CPU, agent loops) ├── ToolActors (CPU + Docker) └── TrainerActors (4 GPUs, FSDP2)
每层独立 scale。GPU/CPU 不互相争抢。适合大规模训练。
[Inference Server] ←HTTP→ [Rollout Controller]
(SGLang) (orchestrator)
↕ HTTP
[Tool Server]
(Docker + K8s)
推理后端完全解耦,可独立扩容和替换。
class AsyncRolloutEngine:
async def collect_batch(self, prompts, group_size=8):
# 每个 prompt 展开 group_size 条轨迹
for prompt in prompts:
for _ in range(group_size):
traj = Trajectory(prompt=prompt)
await self.pending_inference.put(traj)
# 双 worker 并行:推理 + 工具执行
await asyncio.gather(
self._inference_worker(),
self._tool_worker()
)
async def _inference_worker(self):
"""批量合并推理请求,最大化 GPU throughput"""
while self.active_trajectories:
batch = self._collect_batch(max_size=32)
responses = self.inference.generate(
[t.current_prompt for t in batch],
stop_tokens=["Observation:"]
)
for traj, resp in zip(batch, responses):
action = parse_action(resp)
if action is None or traj.is_terminal():
traj.finalize()
else:
traj.add_step(resp, action)
await self.pending_tool.put(traj)
async def _tool_worker(self):
"""并发执行工具调用,完成后送回推理队列"""
while self.active_trajectories:
traj = await self.pending_tool.get()
observation = await self.env.execute(traj.last_action)
traj.add_observation(observation)
await self.pending_inference.put(traj)
ROLL Flash(arXiv:2510.11345)通过环境级异步并行 rollout + 异步训练,进一步加速 Agentic Training。RollPacker(arXiv:2509.21009)解决长尾轨迹拖垮整个 batch 的问题。
Registry + Executor 两层抽象是 Agent 工具系统的核心设计模式,实现"热插拔":新增工具无需改任何已有代码。
class BaseTool:
def get_schema(self) -> dict: # JSON Schema 给 LLM 理解工具能力
def validate(self, params) -> bool: # 参数校验(constrained decoding 兜底)
def execute(self, params) -> str: # 实际执行(API / CLI / Python 各自实现)
def format_output(self, raw) -> str: # 结果标准化(截断 + 提取关键字段)
| Runtime | 实现方式 | 隔离级别 | 适用场景 | 示例 |
|---|---|---|---|---|
| native_backend | subprocess | 进程级 | CLI 工具、GPU 密集计算 | mmseqs2, SignalP6, tmbed |
| heuristic | in-process Python | 无隔离 | 轻量计算、规则匹配 | seq_props, go_term |
| api_backend | HTTP 请求 | 网络隔离 | 外部 REST API | UniProt, STRING-DB |
新增一个工具只需 三步,不改任何已有代码:
注册后,system prompt 自动包含新工具的描述和参数规范。模型无需重训即可尝试调用。
根据用户意图先分类,只暴露相关工具子集(5-10 个)。
效果:首轮工具选择准确率 65% → 90%
Embedding 相似度 retrieve top-10 → Agent 在 top-10 中精细选择。类似 RAG 的 retrieve-then-read。
每个工具一行摘要,选定后再展开完整 Schema。100 个工具的 token 开销从 5000+ 降到 ~1000。
| 失败类型 | 处理方式 | Agent 行为 |
|---|---|---|
| 超时 | 返回 TIMEOUT observation | 学会切换到更轻量的替代工具 |
| 参数错误 | 返回 INVALID_PARAMS + schema 提示 | 学会修正参数后重试 |
| API 异常 | 返回 ERROR: {msg} | 学会换工具或直接给答案 |
Sandbox 提供工具执行的隔离环境,确保训练过程中的工具调用安全、可控、互不影响。
class SandboxPool:
"""预创建 N 个 sandbox 实例,按需分配/回收"""
def __init__(self, pool_size=16, image='agent-tools:v1'):
self.available = asyncio.Queue()
for _ in range(pool_size):
sb = Sandbox(image=image, timeout=90)
self.available.put_nowait(sb)
async def acquire(self) -> Sandbox:
return await asyncio.wait_for(
self.available.get(), timeout=30
)
async def release(self, sandbox: Sandbox):
await sandbox.reset() # 清理状态
self.available.put_nowait(sandbox)
Agent 训练时不能接触真实用户数据(GDPR/隐私合规),只能访问脱敏数据或合成数据。
训练时调用"下单 API"不能真产生订单。需要 Mock API 模拟真实响应但不产生副作用。
"查看商品" 低风险 → "修改价格" 高风险 → "发起退款" 极高风险。高风险操作需要 confirm/rollback 机制。
Agent 的 Reward 设计是 RL 训练成功的关键。两层 Reward 体系:Step 行为约束 + Episode 目标导向。
+0.10 正确工具首次调用(在 skill 白名单中)
-0.30 任意历史重复调用(any-prev 全历史去重)
+0.15 首次使用新工具 diversity bonus
-0.20 格式错误(tool_call JSON 解析失败)
每个 Action-Observation 对独立评分,归因精确。
R_episode =
2.0 × token_overlap(answer, gold)
+ 1.0 × tool_recall(实际 ∩ 预期工具集)
+ 0.5 × reasoning_quality
+ 0.3 × efficiency([3,6] 得满分)
× min(1, len/200) ← answer-length scaling
+ 0.3 × gated_bonus(长度≥50 且 工具≥1)
- 1.5 × truncation_penalty
轨迹结束时叠加,目标导向。
| 机制 | 应对的 Hacking 行为 | 实现 |
|---|---|---|
| any-prev 全历史去重 | 模型学会"隔步重复"绕过相邻检测 | -0.30 惩罚 |
| diversity bonus | 只用一个工具的 hacking | +0.15 首次使用新工具 |
| answer-length scaling | 空 answer 但工具调用正确 | min(1, len/200) 线性缩放 |
| gated bonus 门控 | 只调工具不给答案 | 必须调工具且写答案才给 +0.3 |
| KL 约束 | 格式漂移 / 输出风格崩溃 | β=0.03 KL penalty |
Group Relative Policy Optimization — 用组内相对比较替代 Critic Network 的策略优化算法,是 Agent RL 的主流选择。
| 维度 | PPO | GRPO |
|---|---|---|
| Critic | 需要 V(s)(7B = 14GB 额外显存) | 不需要 — 节省 ~50% 显存 |
| Advantage | GAE(λ) 依赖 V(s) 精度 | Group 内归一化排名 |
| 数据效率 | 1 prompt → 1 信号 | 1 prompt → G=8 信号 |
| LLM 适配 | state 是变长文本 → V(s) 很难训准 | 无需建模 state value |
| 推理预算 | rollout 1 次/prompt | rollout G 次(用推理换 Critic) |
# Step 1: 按步归一化(同一步位置 G 条轨迹互比)
A_{i,t} = (r_{i,t} - μ_t) / (σ_t + 1e-8)
# Step 2: Generation Mask
mask_t[k] = 1 if token k ∈ {Thought, Action} # LLM 生成
mask_t[k] = 0 if token k ∈ {Observation, System} # 环境/系统
# Step 3: Clipped Policy Ratio
ratio = π_θ(token|ctx) / π_ref(token|ctx)
clipped = clip(ratio, 1-ε, 1+ε)
# Step 4: Final Loss
L = -(1/N) Σᵢ Σ_t Σ_k [mask · min(ratio·A_{i,t}, clipped·A_{i,t})]
+ β · D_KL(π_θ ∥ π_ref)
区分 LLM 生成 vs 环境返回 → 只对模型行为计算梯度。Observation token 全 mask。
限制策略更新步长 → 防止单次大更新导致策略崩溃。ε=0.2 是标准设置。
全局锚定 → 保证模型不偏离基础语言能力。β=0.01~0.03。
不同步的 reward 分布不同(第 1 步信息少 → reward 低,最后步有 answer → reward 高)。混合归一化会让早期步永远负 advantage,模型永远不学"怎么开头"。
论文 arXiv:2503.20783 发现 GRPO 存在优化偏差会人为膨胀响应长度(尤其对错误输出)。Dr. GRPO 通过无偏优化变体提升 token 效率,7B 模型在 AIME 2024 上达到 43.3%。
Agent Harness 最难的工程问题之一 —— 如何在多轮交互中精确区分哪些 token 是模型生成的、哪些是环境注入的。
多轮交互的完整 sequence 中:
如果把 Observation 的 token 也纳入 loss,等于在"奖励环境的输出",没有意义且浪费梯度信号。
Token: [Thought: 我需要查询...] [Action: {"tool":"search"...}] [Observation: 找到3条结果...] [Thought: 根据结果...]
Mask: [1 1 1 1 1 1 1 ] [1 1 1 1 1 1 1 1 ] [0 0 0 0 0 0 0 0 ] [1 1 1 1 1 ]
↑ 环境返回,不计入 loss
Loss = -Σ(generation_mask × log_prob × advantage) / Σ(generation_mask)
Agent-R1(arXiv:2511.14460)提出更彻底的解决方案:Step-level MDP——每个交互步是独立的 RL transition(obs → action → step → next_obs),避免 Token → Text → Token 的不可逆转换(retokenization drift)。上下文可以在步间被截断/摘要/重写,而非仅仅追加。
2024-2026 年涌现了多个 Agentic RL 训练框架,各有设计哲学和适用场景。
| 框架 | 组织 | 核心设计 | 训练范式 | 推理后端 | 亮点 |
|---|---|---|---|---|---|
| VERL | ByteDance Seed | 3D-HybridEngine + Hybrid Controller | GRPO, PPO, DAPO | vLLM, SGLang | 大规模(671B)、灵活 RL dataflow |
| ROLL | Alibaba | Multi-role Ray + AgenticPipeline | StarPO, GiGPO, GRPO | vLLM, SGLang, Megatron | 10+ 算法、ROLL Flash 异步加速 |
| RAGEN | Northwestern U. | StarPO 统一框架 | StarPO (PPO/GRPO) | vLLM | SNR-Adaptive Filtering、Echo Trap 诊断 |
| Agent-R1 | Independent | Step-level MDP | StepPO, GRPO, RLOO | vLLM | 解决 retokenization drift |
| VerlTool | TIGER-AI-Lab | Tool-as-Environment | GRPO (基于 VERL) | vLLM | 轨迹级异步 rollout 2x 加速 |
| TRL | HuggingFace | 单卡简单实现 | PPO, DPO, GRPO | HF Transformers | 入门快、教学友好 |
vLLM 和训练共用 GPU,通过时分复用减少跨节点通信。
适合中等规模(7B-30B)+ 单集群。
Inference Server 和 Trainer 分开成两个 Actor Group,通过 HTTP 通信。
适合大规模(70B+)+ 多集群。
| 层级 | 框架 | 职责 | 类比 |
|---|---|---|---|
| L1 业务逻辑层 | ROLL AgenticPipeline | 定义训练流程、角色生命周期、权重同步 | 管弦乐团的乐谱 |
| L2 分布式调度层 | Ray | 创建 worker 进程、分配 GPU、跨节点通信 | 场地管理 |
| L3 单卡训练/推理层 | FSDP2 + vLLM | 模型分片、显存管理、推理加速 | 演员的表演 |
完整的 Agent 训练 pipeline 分为四个阶段:SFT 冷启动 → RL 强化 → Self-Play Bootstrap → DPO 偏好微调。
Teacher Rollout(如 DeepSeek-V3.2)生成高质量轨迹 → Evaluator 多维打分 → 筛选进入 SFT 训练。
关键:Observation Mask(工具返回不计 loss),把格式正确率提到 ~85%。
Step-level GRPO + clip + KL 双约束。在 SFT 模型基础上进一步优化工具选择和推理能力。
前提:Base model 必须有 ~20%+ 的 zero-shot 成功率,否则 GRPO 无法学习。
RL 训后模型 rollout → reward 打分 → 选 top-k → 再 SFT。比纯 RL 更稳定,适合数据有限时增广。
好轨迹 vs 差轨迹做偏好对。适合推荐话术等主观性强的维度。
最优方案:GRPO + DPO 混合 — 操作类用 GRPO(rule-based),对话类用 DPO(人类偏好)。
Agent RL 训练中的典型问题和防御方案。
模型学会"模板攻击"——每次先调某个工具搜索 → 直接复制结果。reward 高但实质是 shortcut。
Fix:工具多样性 reward + any-prev 重复惩罚
输出风格渐变——Action 前加无意义 padding,格式飘移,偏离基础语言能力。
Fix:KL β 从 0.01 → 0.03 + 格式 reward 子项
G=8 条轨迹 reward 几乎相同,advantage ≈ 0,梯度为 0,训练停滞。
Fix:temperature 0.7 → 0.9 + curriculum + prompt filtering
| 失败模式 | 描述 | 防御 |
|---|---|---|
| 环境静默升级 | 工具 API 版本变了但没通知 Agent | Pin 版本 + 回归测试 |
| 目标漂移 | 长对话中 Agent 被中间结果带偏 | 周期性检查当前行动与原始 goal 的相关性 |
| Compounding Errors | 每步小误差累积,10 步后完全偏离 | 设 MAX_STEPS + Verification Loop |
| Dead Loops | 重复调用同一工具但不改变策略 | 连续 3 次相同 action → 强制切换 |
模型过拟合到局部 reward pattern → reward 方差坍缩 → 梯度尖峰 → 训练崩溃。RAGEN-2 引入 SNR-Adaptive Filtering(基于 reward 方差的信噪比自适应过滤),只用 reward 方差最大的 top-p% 轨迹训练,缓解回声陷阱。
从 Demo 到生产的三大 Gap 和解决方案。
Demo 80%+ 成功率看似不错。每天 10 万请求 × 1% 失败 = 1000 个失败 case。
解决:Guardrails + Fallback + 人工兜底 + 审计日志
用户期望 2-3 秒。多轮工具调用的累积延迟可能 30 秒+。
解决:并行工具调用 + 缓存 + 流式输出 + 小模型 Router
10 万请求 × 5 轮 = 50 万次 LLM 调用,成本爆炸。
解决:SFT 蒸馏 + Router 用小模型 + 缓存常见 pattern
Agentic RL 四大流派 + Agent Reasoning + 关键论文速查。
| 流派 | 代表 | 核心思路 | 适用场景 |
|---|---|---|---|
| Trajectory GRPO | DeepSeek-R1, DAPO | 单轮生成,outcome reward,组内比较 | 数学推理 / 代码生成 |
| Multi-Turn GRPO | RAGEN/StarPO, ProtAgent | 多轮交互,step/episode reward,环境反馈 | Agent 工具调用 |
| Process Reward RL | VERL-Tool, TORL | 每步工具成功率作中间 reward | 工具密集型任务 |
| Self-Play Bootstrap | Agent-R1, OpenClaw-RL | RL 训后模型生成新数据 → 再训 | 数据稀缺场景 |
论文 arXiv:2504.13837 指出:当前 RLVR(单轮 + 可验证 reward)并不能激发根本性的新推理能力——它只是锐化已有能力(pass@1 提升,但 pass@k 被 base model 上界限制)。多轮 agent-environment 交互是解锁真正新推理的必要下一范式。
| 论文 | 年份 | 核心贡献 | 链接 |
|---|---|---|---|
| DeepSeek-R1 | 2025.01 | 纯 RL 训练涌现推理能力 | 2501.12948 |
| DeepSeekMath (GRPO) | 2024.02 | GRPO 算法提出 | 2402.03300 |
| VERL | 2024.09 | 大规模 RL 训练框架 | 2409.19256 |
| RAGEN / StarPO | 2025.04 | 统一 Agent RL 框架 + Echo Trap | 2504.20073 |
| ROLL | 2025.06 | 多角色 Ray + AgenticPipeline | 2506.06122 |
| Agent-R1 | 2025.11 | Step-level MDP 解决 retokenization | 2511.14460 |
| VerlTool | 2025.09 | Tool-as-Environment + 异步 rollout | 2509.01055 |
| Dr. GRPO | 2025.03 | GRPO 长度偏差修正 | 2503.20783 |
| PRIME | 2025.02 | 隐式过程奖励 (无需 PRM) | 2502.01456 |
| ReSearch | 2025.03 | RL 学习推理+搜索交织 | 2503.19470 |
基于 Qwen2.5-7B 的蛋白质功能理解 Agent,端到端打通 Teacher Rollout → SFT → GRPO 训练闭环,在 5 类蛋白任务上取得 7B 开源 SOTA。
┌────────────────── ProtAgent System Architecture ──────────────────┐ │ │ │ L1 Training Framework ROLL AgenticPipeline + FSDP2 │ │ ───────────────────── ───────────────────────────── │ │ 角色编排 / 权重同步 / 数据流 训练端: FSDP2 (8×A100, 7B 全参) │ │ │ │ L2 Rollout Engine vLLM Server (async, PagedAttention) │ │ ───────────────── ─────────────────────────────── │ │ batch 采样 / KV Cache / G=8 异步多轨迹并行, GPU 利用率 >85% │ │ │ │ L3 Tool Environment 12 异构生信工具 + 进程级 Sandbox │ │ ──────────────────── ───────────────────────────── │ │ BaseTool 抽象 / timeout 60s API(REST) + CLI + Python 三类统一 │ │ │ └────────────────────────────────────────────────────────────────────┘
780 条种子题 × ~10 条 Teacher Rollout 轨迹
两层筛选(7 项 Evaluator + Task Audit)6310 条进入 SFT
Step-level GRPO 最终在 OOD benchmark 上 F1 领先 ≥ 10pp
12 个异构工具通过 BaseTool 抽象统一为一个接口
skill_name: enzyme_catalysis
available_tools: [CLEAN, mmseqs2, UniProt_API]
max_rounds: 8
answer_format:
required_fields: ["ec_number", "substrate", "product"]
audit_rules:
- field: "ec_number"
pattern: "^\\d+\\.\\d+\\.\\d+\\.\\d+$"
reward_weights:
tool_accuracy: 0.3
answer_f1: 0.4
reasoning_quality: 0.3
新增任务类型只需加 YAML,不改代码。Git 版本控制每次 skill 调整,研究人员和工程同学职责解耦。
本节展示 Agent 实验课的典型任务结构,以"智能体个体模拟"为例,涵盖 Memory 系统、角色模拟训练和评估。
本实验围绕基于大语言模型的个体模拟展开,包含 角色记忆构建 → Memory-Augmented Agent → SFT/DPO 训练 → 综合评测 四个递进任务。
实现轻量级角色记忆检索模块:综合 semantic_similarity(cosine)、lexical_overlap(词重叠)、importance(重要性打分),三维加权 top-k 检索。
构建 Memory-Augmented Role-Playing Agent,根据用户问题检索相关记忆,以角色身份回答。对比:只问题 / Persona+问题 / Persona+Memory+问题 三种配置。
构造 SFT/DPO 训练数据,训练不依赖外部 Memory 的角色化模型。方案 A: instruction-response 从对话提取;方案 B: chosen/rejected 偏好对构造。
将训练模型 + Memory 系统结合,对比 4 种配置(Base/SFT × ±Memory)。挑战任务:同时保持角色模拟 + 通用指令能力。
score = α × semantic_similarity # cosine(query_emb, memory_emb), α=0.65
+ β × lexical_overlap # |query_words ∩ memory_words| / |query_words|, β=0.25
+ γ × importance # 预设的记忆重要性分数, γ=0.10
| 评估维度 | 描述 |
|---|---|
| Memorisation | 回答是否正确使用角色背景、经历、关系和历史记忆 |
| Values | 回答是否符合角色的价值观、偏好和行为倾向 |
| Personality | 回答是否保持角色的性格特征、语气和说话风格 |
| Hallucination | 回答是否避免与角色设定或已知记忆相矛盾的内容 |
这个实验展示了 Agent 系统的核心组件:Memory 检索模块(对应 Harness 的 Context Management)、角色 Persona 注入(对应 System Prompt 编排)、SFT/DPO 训练(对应 Post-Training Pipeline 的 Stage 1/4)、LLM-as-Judge 评估(对应 Evaluator 多维打分)。它是从"应用侧"理解 Agent 训练全链路的入口。