跳到主要内容

数据截至 (上游 commit 352f1bd7c1a0)

Agent Lightning — 架构与原理

30 秒导读: Agent Lightning 是微软研究院的 agent 强化学习训练框架。v1.0 做了一次彻底重写(旧版 v0.x 的 LightningStore/LitAgent/Tracer 等机制已整体删除,见仓库 README “completely refactored in v1.0”,README.md:11)——现在的思路极简:你的 agent 不改一行代码,只要把它的 OpenAI base_url 指向框架的 API Gateway,框架就能在旁边把每次模型调用(连同推理引擎真正采样的 token id 和 logprobs)录成事件,等 agent 报出奖励后,这些记录被自动加工成 RL 训练样本,喂给基于 verl 的训练器更新模型权重。

本页是总入口:先讲清「这是什么」(零基础也能懂),再给一张顶层全景图和一条主线走查,最后是各章阅读地图。想深入某个机制,按地图跳对应章节。


1. 这是什么(零基础也能懂)

一句话定义

Agent Lightning 是一个agent 训练框架:它把你已经写好的 AI agent 当成一个「黑盒」照常运行,在旁边观测它、给它打分,然后用强化学习(RL)反过来优化它背后的语言模型权重。

v1.0 的自我定位是一句口号——“3,500-Line Lightweight Agentic RL Framework”(3500 行的轻量 agent RL 框架,README.md:5),版本 1.0.0(依据:pyproject.toml:3 version)。旧版那套「中央 store + span + 三元组」的复杂机制被整体移除,换来的是三个各司其职的小组件。

它想解决什么问题

先说痛点。你想用 RL 训一个真实 agent(带工具调用、多轮交互、复杂 harness 的那种),通常会遇到两难:

  • 传统 RL 框架——要你把 agent 逻辑重写进它的训练循环,多轮工具调用、真实环境几乎塞不进去。
  • 现成 sandbox 服务——agent 得跑在别人家的托管环境里,环境依赖搬不动。

Agent Lightning v1.0 的主张(依据:README.md:15-18 Key Features):

  • 零代码改动:agent 通过一个 OpenAI 兼容代理访问模型,工具、上下文、控制流、环境全部留在自己的 harness 里。
  • 原生 Kubernetes:agent 直接作为 K8s Job 跑在你自己的集群上,不依赖商业 sandbox 服务。
  • 真实收益:官方用 6K 训练样本把一个编码 agent 在 SWE-bench Verified 上从 41.8% 提到 56.4%(依据:README.md:18)。

给谁用

读者用它来做什么
做 agent 的工程师手上有个能跑的 agent,想用 RL 调模型权重,但不想重写 agent
RL / LLM 研究者想在真实多轮 agent 轨迹上跑 GRPO/PPO,验证新算法
平台工程师想在自己的 K8s 集群上规模化地「跑 agent + 采数据 + 训模型」

用起来什么样

agent 侧的全部改动,就是读两个环境变量(依据:examples/calc_x/calc_agent.py:29-30):

# 示意,改编自 examples/calc_x/calc_agent.py
openai_base_url = os.environ["AGL_OPENAI_BASE_URL"] # 框架注入的代理地址
event_url = os.environ["AGL_EVENT_URL"] # 框架注入的报分地址

client = OpenAI(base_url=openai_base_url, ...) # 照常调模型,工具照常用
answer = await solve(question) # agent 逻辑一行不改
httpx.post(event_url, json={"event_type": "reward",
"data": {"value": 1.0}}) # 结束时报一个分

训练侧则是一个普通的 verl 风格脚本(依据:examples/calc_x/train_calc_agent.py:192run_ppo),三个组件各自一条命令启动(依据:examples/calc_x/run_local.sh 依次起 agl-serveragl-controller、训练入口)。

一句话直觉

把它想成给 agent 修了个「驾校考场」

  • 考场门卫(API Gateway)——agent 的每次「问模型」都得过这道门,门卫顺手把问答原原本本记下来(连模型真正说的每个 token 都记)。
  • 调度台(Rollout Controller)——按考卷发车:把每道题变成一个真实进程或 K8s Job,跑完收回结果。
  • 教练(Trainer)——攒够一批考卷成绩,算出「哪些开法值得强化」,更新模型权重,再发下一批。

2. 顶层全景(它大概怎么转)

怎么读这张图

从中间的 API Gateway 看起——它是唯一的「账本 + 转发台」。左边是学习侧(Trainer),右边是执行侧(Controller + 你的 agent)。三条线:黑实线是控制流(创建/查询/注册),代理那条是 agent 的模型调用流,虚线是数据回流。

学习侧(训) 中央:账本 + 模型代理 执行侧(跑)
┌─────────────────┐ ┌──────────────────────────┐ ┌──────────────────────┐
│ Trainer │ │ API Gateway │ │ Rollout Controller │
│ (verl + vLLM, │──①注册──▶│ rollouts / events / │◀─③领任务─│ (local 子进程 / │
│ GPU 集群) │ │ models 三本内存账 │ │ K8s Job) │
│ │──②排队──▶│ │──④发环境变量─▶ 你的 agent │
│ GRPO 算优势、 │ │ OpenAI 兼容反向代理 ★ │ │ (AutoGen/LangChain/ │
│ 更新权重 │◀─⑥拉事件─│ return_token_ids+ │◀─────│ 裸 OpenAI 都行) │
│ │ │ logprobs 连 token 记账 │ ⑤每次模型调用走代理 + │
└─────────────────┘ └──────────────────────────┘ 结束报 reward 事件 │
└──────────────────────┘

部件一句话职责

部件干什么在哪个文件
API GatewayFastAPI 服务:存 rollout/事件/模型端点;反向代理模型请求并自动记账agentlightning/server/app.py
反向代理路由按 rollout 归账转发模型调用,统一采样参数,捕获 token idagentlightning/server/proxy.py
Rollout Controller调谐器:把 QUEUING rollout 变成子进程或 K8s Job 并回收状态agentlightning/controller/local_reconciler.py
K8s 调谐器同上,但执行单元是 K8s Job(模板渲染 + watch)agentlightning/controller/k8s_reconciler.py
Trainer继承 verl 的 RayPPOTrainer,驱动 rollout、转训练样本、更新权重agentlightning/verl/trainer.py
Rollout 管理器Trainer 的 HTTP 客户端层:排队、等待、拉事件、组装 Tripletagentlightning/verl/agl_rollout_manager.py
样本适配器把完成 rollout 的事件流转成 verl 的 DataProto 训练批agentlightning/verl/rollout_adapter.py
轻量 HTTP 客户端带鉴权与重试的 httpx 封装agentlightning/client.py
生命周期钩子排队前改写请求、成败后回写自定义事件agentlightning/hooks.py

主线走一遍(一次训练循环,高层不进代码)

跟着上图编号走一圈,就是 v1.0 的心跳:

  1. ① 注册模型:每个训练步开始,Trainer 把自己 vLLM 推理引擎的地址注册到 Gateway(register_modelagentlightning/verl/agl_rollout_manager.py:171)——agent 后续所有模型调用都会被转发到这个引擎。
  2. ② 排队任务:Trainer 把一批训练样本逐个 POST /api/rollouts 排进队列(GRPO 下每样本排 n 份),状态 QUEUING
  3. ③ 领任务:Controller 轮询到 QUEUING 的任务,spawn 一个子进程(local 模式)或创建一个 K8s Job(k8s 模式),并把它 PATCH 成 RUNNING
  4. ④ 注入环境:Controller 在子进程/Job 里注入 AGL_OPENAI_BASE_URL(指向 Gateway 的 rollout 专属代理 URL)、AGL_EVENT_URL(报分地址)和 AGL_KEY,然后把控制权交给你的 agent。
  5. ⑤ 跑 + 记账:agent 照常发起 OpenAI 请求——但 URL 里有 rollout_id,Gateway 转发给 vLLM 时强制要求 return_token_ids=True 和 logprobs,并把完整问答连 token id 录成一条 model_request 事件;agent 结束时往 AGL_EVENT_URL POST 一条 reward 事件。
  6. ⑥ 拉事件转样本:Trainer 轮询到 rollout 进入终态,用 format=triplet 拉回精简后的事件(只剩 token id/logprobs/奖励),拼成 (prompt, response, reward) 三元组,再由样本适配器组装成 verl 训练批——算优势、更新权重,回到第 ① 步。

关键心智模型:三个组件互相只认 HTTP,谁也不 import 谁。 Gateway 是唯一的共享状态(内存里三本账),Controller 和 Trainer 都是它的客户端。agent 更是只知道「一个 OpenAI 端点 + 一个报分 URL」。这就是「零改动」的架构根基。


3. 阅读地图(建议顺序)

按「由浅入深」推荐这样读:

  1. 01 — Rollout 与事件:中央账本:先搞懂账本记了什么——Rollout 的四态状态机、Event 的插入序模型、两种「知名事件」(model_request/reward)、以及幂等创建和完成序游标这些工程细节。
  2. 02 — API Gateway 与模型代理:全框架的心脏。rollout_id 进 URL 的归账设计、稳定哈希选端点、统一采样参数与 token id 捕获(agent RL 正确性的命根子)、上游重试、暂停/排空。
  3. 03 — Rollout Controller:执行侧。local 子进程模式的 spawn/超时/进程组击杀,K8s 模式的 Jinja2 模板渲染、双循环调谐与限速。
  4. 04 — Trainer 与 verl:学习侧。GRPO 分组排队、同步/异步两种等待策略、事件→训练样本的两种聚合粒度(transition/trajectory)、rollout 级优势与逐 rollout 损失这两个默认创新。
  5. 05 — 深入、边界与代码地图:可借鉴的巧妙设计、它刻意不做什么/会在哪崩、和同书架兄弟项目的对比、以及一张给人和 agent 用的跳转表。

赶时间的话:只读 01 + 02 就能抓住 v1.0 的精髓——账本 + 会记账的代理。