微软 Agent Lightning 深度实战:从零构建可进化的 AI Agent——强化学习训练框架的技术架构与生产级实践
前言:AI Agent 的「训练 gap」困境
过去两年,AI Agent 无疑是 LLM 应用领域最火的方向之一。从 LangChain 的横空出世到 AutoGen、CrewAI、OpenAI Agents SDK 的百花齐放,搭建一个能跑起来的 Agent 已经不是难事。但真正让所有 Agent 开发者头疼的问题藏在更深的地方——把 Agent 搭起来容易,让它真正「越用越好」却难如登天。
大多数 Agent 在上线之后就是「静态」的。Prompt 写死了,工具集固定了,遇到新场景只能人工调 Prompt、打补丁,效率极低。OpenAI 在 2025 年底提出的 Agents SDK 试图解决这个问题,提出了 Supervisor-Executor 的结构化模式,但离真正的自动化训练仍有距离。业界把这个问题称为 Agent 的 Training Gap——模型在预训练阶段学到了通用能力,但 Agent 的任务执行能力、工具调用精准度、多步骤推理质量,这些都取决于部署后的持续优化,而现有框架几乎没有提供这个能力。
微软在 2026 年初开源的 Agent Lightning(也叫 AGL,Agent Lightning Framework)正是瞄准这个痛点而来的。它宣称:几乎不需要改代码,就能把任何用 LangChain、AutoGen、CrewAI、LangGraph,甚至裸 Python 写的 Agent 变成可训练、可进化、可持续优化的系统。这个承诺听起来有点夸张,但它背后的技术实现相当扎实——核心是把 Agent 的执行过程建模为马尔可夫决策过程(MDP),用强化学习来训练 agent 的行为策略。
本文将从核心架构、核心概念、生产实践三个维度,对 Agent Lightning 进行全面深度的解析,并通过大量代码示例让你真正掌握这个框架。
一、Agent Lightning 是什么
1.1 定位与愿景
Agent Lightning 是微软开源的AI Agent 强化学习训练框架,GitHub 地址为 https://github.com/microsoft/agent-lightning。截至 2026 年 5 月,该项目在 GitHub 上已获得超过 11,500 颗星,且每日增长超过 300 颗,是当之无愧的 GitHub Trending 热门项目。
它的核心愿景是:让 Agent 的训练和优化从手动调 Prompt 的手工业,进化到数据驱动的自动化机器学习流程。在传统的 LLM 应用中,我们调优的手段只有换模型、换 Prompt。而在 Agent Lightning 中,你的 Agent 可以在真实任务执行中收集经验数据,通过强化学习算法自动优化行为策略——包括但不限于 Prompt 模板、工具选择偏好、多步骤规划路径等。
1.2 核心特性
Agent Lightning 的设计有几个鲜明特点:
框架无关(Framework Agnostic):不需要你重写任何业务逻辑。它通过 adapter 模式,将 LangChain、AutoGen、CrewAI、LangGraph 等主流框架封装的 Agent 作为「黑盒」接入训练流程。你不需要把代码从 LangChain 迁移到某个专用格式。
强化学习驱动(RL-powered):框架内置了微软自研的 LightningRL 算法族,支持 PPO、DQN、REINFORCE 等多种强化学习算法,并将 Agent 执行过程中的经验(experience)组织为标准的 (state, action, reward, next_state) 四元组进行训练。
多训练模式:不仅支持 RL,还支持 自动 Prompt 优化(Auto-Prompt Optimization) 和 监督微调(SFT),形成了完整的 Agent 训练工具体系。
分布式训练:训练 server 与 Agent 执行逻辑完全解耦,支持多 Agent 并发收集经验数据,支持分布式 RL 训练。
1.3 与现有方案对比
| 特性 | Agent Lightning | OpenAI Agents SDK | LangChain Agent | AutoGen |
|---|---|---|---|---|
| Agent 框架集成 | 全框架兼容 | 单一框架 | LangChain 原生 | AutoGen 原生 |
| 训练能力 | RL + SFT + Auto-Prompt | 无 | 无 | 无 |
| 框架无关性 | ✅ | ❌ | ❌ | ❌ |
| 分布式训练 | ✅ | ❌ | ❌ | ❌ |
| 零代码改造成本 | 极低 | N/A | N/A | N/A |
| 开源 | ✅ | ❌(闭源) | ✅ | ✅ |
二、核心架构解析
2.1 整体架构图
Agent Lightning 的架构可以分为两大核心组件:Python SDK 和 训练 Server。两者通过网络协议通信,Agent 的执行逻辑(Python SDK)负责收集经验数据并发送给 Server,Server 运行强化学习算法进行策略更新,再将更新后的策略(可能是新的 Prompt 模板、权重调整参数等)推送给 SDK。
┌─────────────────────────────────────────────────────────┐
│ 训练 Server(Training Server) │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ Experience │ │ LightningRL │ │ Policy │ │
│ │ Buffer │→ │ Engine │→ │ Updater │ │
│ │ (经验池) │ │ (PPO/DQN...) │ │ (策略更新) │ │
│ └─────────────┘ └──────────────┘ └───────────────┘ │
│ ↑ │ │
│ │ 新策略/Prompt 推送 │ │
└─────────┼───────────────────────────────────────────┘
│ gRPC / HTTP
┌─────────┼───────────────────────────────────────────┐
│ ↓ Python SDK │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ LitAgent │ │ Experience │ │ Framework │ │
│ │ Wrapper │→ │ Collector │← │ Adapter │ │
│ └─────────────┘ └──────────────┘ └─────────────┘ │
│ ↑ │ │
│ │ Agent 执行 │ 经验数据上报 │
│ ┌──────┴───────┐ ↓ │
│ │ 你的 Agent │ ← 实际执行业务逻辑 │
│ │ (LangChain/ │ │
│ │ AutoGen/... ) │
└──────────────────────────────────────────────────────┘
2.2 LitAgent:核心抽象
整个框架的核心抽象是 LitAgent——一个轻量级的 Wrapper 类,它将你已有的 Agent 逻辑包起来,同时赋予它「可训练」的能力。
from agentlightning import LitAgent, RLConfig
from langchain.agents import AgentExecutor
# 你的现有 Agent(可以是 LangChain AgentExecutor,也可以是 AutoGen 的 Agent)
existing_agent: AgentExecutor = ... # 已有代码,不需要修改
# 用 LitAgent 包装它,不需要重写任何业务逻辑
lit_agent = LitAgent(
agent=existing_agent,
config=RLConfig(
algorithm="PPO",
learning_rate=3e-4,
batch_size=64,
gamma=0.99, # 折扣因子
lambda_=0.95, # GAE 参数
clip_ratio=0.2,
value_coef=0.5, # 值函数损失系数
entropy_coef=0.01, # 熵正则化系数,防止过早收敛
),
reward_fn=my_reward_function, # 你定义的奖励函数
)
# 训练流程:框架自动处理经验收集和策略更新
for training_step in range(1000):
# Agent 在环境中执行任务,收集经验
experiences = lit_agent.collect_experiences(num_episodes=16)
# 推送到训练 Server 进行策略更新
lit_agent.update_policy(experiences)
这就是 Agent Lightning 宣称的「零代码变更」——你只需要把现有的 Agent 对象传进去,框架自己会处理剩下的训练逻辑。
2.3 Experience Collector:MDP 建模引擎
Agent Lightning 的核心创新之一,是把 Agent 的执行过程建模为标准的马尔可夫决策过程(MDP)。对于一个对话式 Agent 来说:
- 状态(State):当前的对话上下文(包含历史消息、工具执行结果、中间推理步骤)
- 动作(Action):Agent 决定执行的下一个动作——可以是调用某个工具、生成某段回复、或者继续推理
- 奖励(Reward):任务完成度指标——比如任务是否成功、响应质量评分、工具调用准确率等
- 下一状态(Next State):执行动作后的新对话上下文
框架内置的 ExperienceCollector 会自动在 Agent 执行过程中插入 hook,收集每个 step 的 (state, action, reward, next_state, done) 五元组,并进行信用分配(Credit Assignment)——即判断在多步骤任务中,哪些中间动作对最终奖励的贡献最大。这是 RL 训练中的核心难题,Agent Lightning 通过 GAE(Generalized Advantage Estimation)算法来处理。
from agentlightning.experience import ExperienceCollector
from agentlightning.reward import CompositeReward
# 自定义复合奖励函数:结合多个信号
reward_fn = CompositeReward(
[
# 主要奖励:任务是否完成
TaskCompletionReward(success_bonus=10.0, failure_penalty=-5.0),
# 辅助奖励:工具调用的准确性
ToolAccuracyReward(tool_correct_bonus=1.0, wrong_tool_penalty=-2.0),
# 惩罚:避免无意义的重复调用
EfficiencyPenalty(steps_per_task_weight=-0.5),
# 惩罚:避免生成过长、无关的响应
ConcisenessPenalty(threshold_tokens=2048, penalty=-0.1),
]
)
collector = ExperienceCollector(
reward_fn=reward_fn,
gamma=0.99, # 折扣因子
lambda_=0.95, # GAE 参数
max_experiences=100000, # 经验池大小
)
2.4 LightningRL:核心算法引擎
训练 Server 运行的核心算法称为 LightningRL,它实际上是 PPO(Proximal Policy Optimization)的改进版本,针对 Agent 场景做了特殊优化:
标准 PPO 的策略更新公式:
θ_{new} = θ_{old} * clip(π_θ(a|s) / π_{θ_old}(a|s), 1-ε, 1+ε) * Â(s,a)
LightningRL 的关键改进:
分层信用分配(Hierarchical Credit Assignment):在多步骤任务中,标准 PPO 难以区分不同 step 对最终结果的贡献。LightningRL 引入了任务分解信号,将长期任务的信用分配拆分为多个子目标,使训练更加稳定。
自适应 Clip 调整:标准 PPO 使用固定的 clip 范围 ε,LightningRL 根据策略更新幅度动态调整 ε,在训练初期使用较大的探索范围(ε=0.3),在后期收紧到 ε=0.1,实现自动的探索-利用平衡。
混合训练目标:LightningRL 不只优化策略 π,还同时优化值函数 V(s)(用于优势估计)和 Prompt 向量化表示,实现三位一体的端到端训练。
from agentlightning.algorithms import LightningRL
rl_engine = LightningRL(
# 基础 RL 参数
algorithm="PPO",
learning_rate=3e-4,
clip_ratio=0.2,
value_loss_coef=0.5,
entropy_coef=0.01,
# LightningRL 特有参数
hierarchical_credit=True, # 启用分层信用分配
adaptive_clip=True, # 启用自适应 clip
prompt_embedding_dim=768, # Prompt 向量化维度
mixed_training=True, # 混合训练(策略+值函数+Prompt)
# 训练稳定性
max_grad_norm=0.5, # 梯度裁剪,防止梯度爆炸
target_kl=0.01, # KL 散度约束目标
update_epochs=4, # 每次更新的 epoch 数
)
三、主流框架集成实战
Agent Lightning 的一大核心卖点就是框架无关性。微软为 LangChain、AutoGen、CrewAI 和 LangGraph 都提供了现成的 adapter。下面逐一演示。
3.1 集成 LangChain Agent
from agentlightning import LitAgent, RLConfig
from agentlightning.adapters import LangChainAdapter
from agentlightning.experience import ExperienceCollector
from langchain_openai import ChatOpenAI
from langchain.agents import load_tools, initialize_agent, AgentType
from langchain.prompts import PromptTemplate
# Step 1: 构建 LangChain Agent(你的现有代码)
llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = load_tools(["serpapi", "python_repl"])
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
# Step 2: 用 LangChainAdapter 包装(适配器模式,无需改动原有 agent)
adapter = LangChainAdapter(agent=agent)
# Step 3: 定义奖励函数
def langchain_reward_fn(trajectory: dict) -> float:
"""根据 Agent 执行轨迹计算奖励"""
final_output = trajectory.get("final_output", "")
task_success = trajectory.get("task_success", False)
num_steps = len(trajectory.get("steps", []))
reward = 0.0
if task_success:
reward += 10.0
# 效率奖励:步骤越少越好
reward += max(0, 10 - num_steps) * 0.5
else:
reward -= 5.0
# 惩罚过长输出
if len(final_output) > 5000:
reward -= 1.0
return reward
# Step 4: 创建可训练的 LitAgent
config = RLConfig(
algorithm="LightningRL",
learning_rate=2e-4,
batch_size=32,
gamma=0.99,
)
lit_agent = LitAgent(
agent=adapter,
config=config,
reward_fn=langchain_reward_fn,
)
# Step 5: 开始训练
for step in range(500):
experiences = lit_agent.collect_experiences(num_episodes=8)
metrics = lit_agent.update_policy(experiences)
if step % 50 == 0:
print(f"Step {step}: "
f"reward={metrics['mean_reward']:.2f}, "
f"policy_loss={metrics['policy_loss']:.4f}, "
f"value_loss={metrics['value_loss']:.4f}")
3.2 集成 AutoGen Agent
from agentlightning import LitAgent, RLConfig
from agentlightning.adapters import AutoGenAdapter
import autogen
from typing import Dict, Any
# Step 1: 构建 AutoGen 多代理系统
assistant = autogen.AssistantAgent(
name="coding_assistant",
system_message="你是一个专业的 Python 程序员。",
llm_config={
"model": "gpt-4o",
"temperature": 0.7,
}
)
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
max_consecutive_auto_reply=10,
code_execution_config={
"work_dir": "coding_workspace",
"use_docker": False,
}
)
# Step 2: 将 AutoGen agent groupchat 包装
agent_group = [assistant, user_proxy]
adapter = AutoGenAdapter(agents=agent_group, groupchat_mode=True)
# Step 3: 奖励函数(针对代码生成任务)
def code_quality_reward(trajectory: Dict[str, Any]) -> float:
"""
综合评估代码质量:
1. 代码是否执行成功(通过 stderr 判断)
2. 是否有适当的注释
3. 是否遵循了任务要求
"""
steps = trajectory.get("steps", [])
reward = 0.0
# 检查是否有代码执行记录
has_execution = any(
"code_execution" in str(step.get("action", ""))
for step in steps
)
if has_execution:
reward += 3.0
# 检查最终输出是否包含代码块
final_output = trajectory.get("final_output", "")
if "```python" in final_output or "```" in final_output:
reward += 2.0
# 任务成功奖励
if trajectory.get("task_success"):
reward += 10.0
# 步骤效率
reward -= len(steps) * 0.3
return reward
lit_agent = LitAgent(
agent=adapter,
config=RLConfig(algorithm="LightningRL", learning_rate=3e-4),
reward_fn=code_quality_reward,
)
3.3 集成 LangGraph(有状态工作流)
LangGraph 的优势在于支持有状态的多步骤工作流,Agent Lightning 对其也有原生支持:
from agentlightning import LitAgent, RLConfig
from agentlightning.adapters import LangGraphAdapter
from langgraph.graph import StateGraph
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
# Step 1: 构建 LangGraph Agent
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
tools = [...] # 你的工具列表
agent = create_react_agent(llm, tools, checkpointer=MemorySaver())
# Step 2: LangGraph adapter 特别处理状态序列化
# 因为 LangGraph 的状态是复杂对象,需要特殊处理才能用于 RL
adapter = LangGraphAdapter(
agent=agent,
state_serializer="json", # 状态序列化方式
max_state_history=20, # 保留多少步历史状态用于信用分配
checkpoint_every=5, # 每 5 步保存一次检查点
)
# Step 3: 奖励函数(针对有状态工作流)
def langgraph_reward_fn(trajectory: dict) -> float:
"""
LangGraph 场景的奖励函数需要特别处理:
1. 状态转换是否正确
2. 工具调用序列是否合理
3. 最终状态是否达到目标
"""
state_history = trajectory.get("state_history", [])
final_state = state_history[-1] if state_history else {}
reward = 0.0
# 检查是否走到了预定的结束节点
if final_state.get("finish_reason") == "task_completed":
reward += 10.0
elif final_state.get("finish_reason") == "max_iterations":
reward -= 3.0 # 走到最大步数限制,通常说明规划有问题
# 检查状态转换的合理性(通过工具调用序列)
tool_calls = [
step.get("tool_used")
for step in trajectory.get("steps", [])
if step.get("type") == "tool_call"
]
# 工具调用序列应该有明确的目标性,混乱的工具调用序列扣分
unique_tools = len(set(tool_calls))
if unique_tools > 0 and len(tool_calls) / unique_tools > 3:
reward -= 1.0 # 同一工具被重复调用多次,说明规划有问题
return reward
四、Auto-Prompt 优化:从经验中学习最佳 Prompt
除了 RL 训练策略之外,Agent Lightning 还提供了另一项强大能力:自动 Prompt 优化。这解决了一个实际痛点——很多团队在部署 Agent 时,Prompt 是工程师拍脑袋写的或者从网上抄的,没有经过系统性的验证和优化。
Agent Lightning 的 Auto-Prompt 优化模块会自动分析 Agent 的执行轨迹,找出成功率低、响应质量差的场景,然后生成改进后的 Prompt 候选,并通过 A/B 测试验证效果。
from agentlightning.prompt import PromptOptimizer, PromptEvolution
# 创建 Prompt 优化器
optimizer = PromptOptimizer(
agent=lit_agent,
base_prompt="""
你是一个专业的{domain}助手。
请根据用户的问题,提供准确、详细的回答。
回答要求:
1. 结构清晰,分点说明
2. 包含代码示例(如果适用)
3. 指出可能的常见错误
""",
optimization_metric="task_success_rate", # 优化指标:任务成功率
evolution_strategy=PromptEvolution.MUTATION, # 突变策略
)
# 运行 Prompt 进化
best_prompt, evolution_history = optimizer.evolve(
num_generations=20, # 生成 20 代候选
population_size=10, # 每代 10 个候选
mutation_rate=0.3, # 突变概率 30%
validation_episodes=50, # 每个候选用 50 个 episode 验证
convergence_threshold=0.02, # 连续 3 代改进不足则停止
)
print(f"最优 Prompt: {best_prompt}")
print(f"训练效率提升: {evolution_history.best_score() / evolution_history.baseline_score():.2f}x")
Auto-Prompt 进化的核心机制是变异+选择。系统会保留表现最好的 Prompt 作为「父本」,然后通过以下几种变异操作生成子代:
- 插入变体(Insertion):在 Prompt 中插入额外的指令或约束
- 重排序(Reordering):调整指令的优先级顺序
- 简化(Simplification):删除冗余表述,测试更简洁的 Prompt 是否同样有效
- 条件化(Conditionalization):将通用指令替换为针对不同场景的条件分支
五、分布式训练架构
对于需要处理大规模数据的生产环境,单机训练很快会成为瓶颈。Agent Lightning 支持分布式训练架构,核心思想是将经验收集(Actor)和策略更新(Learner)分离到不同的进程中:
┌──────────────┐
│ Learner │ ← 训练 Server(GPU,适合策略更新)
│ (策略更新) │
└──────┬───────┘
│ 策略参数同步(每隔 N 步)
↓
┌──────────────────────────────────────────┐
│ Actor 进程池(可水平扩展) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Actor 1 │ │ Actor 2 │ │ Actor N │ │ ← 并发收集经验数据
│ │ (CPU) │ │ (CPU) │ │ (CPU) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ↑ ↑ ↑ │
│ └──────────┴──────────┘ │
│ 经验数据上报(异步队列) │
└──────────────────────────────────────────┘
from agentlightning.distributed import DistributedTrainer, ActorPool
from multiprocessing import cpu_count
# 创建分布式训练器
trainer = DistributedTrainer(
rl_engine=rl_engine,
num_actors=cpu_count(), # 使用所有 CPU 核心作为 Actor
sync_interval=8, # 每 8 个 episode 同步一次策略
experience_queue_size=10000, # 经验队列大小
memory_limit_gb=16, # 每个 Actor 的内存限制
)
# 启动分布式训练
trainer.train(
total_timesteps=1_000_000, # 总训练步数
log_interval=100,
checkpoint_dir="./checkpoints",
save_interval=5000, # 每 5000 步保存一次
)
# 在训练过程中,可以动态调整 Actor 数量
trainer.scale_actors(new_count=cpu_count() * 2) # 扩展 Actor 进程
分布式训练的一个关键技术细节是策略同步的延迟补偿。当 Actor 从 Learner 获取最新策略时,网络延迟可能导致某些 Actor 仍在使用旧策略收集经验。Agent Lightning 通过 importance sampling 权重来校正这种偏差,保证训练稳定性。
六、生产级实践:避坑指南
6.1 奖励函数设计原则
奖励函数是 RL 训练的灵魂,也是最容易出问题的地方。根据我们的实践经验,有几条重要原则:
原则一:奖励要稀疏但不要太稀疏。 完全基于最终任务成功与否的稀疏奖励会导致训练极慢,因为 Agent 需要在巨大的搜索空间中随机探索。建议加入辅助奖励信号(如工具调用准确率、响应格式正确性、中间推理步骤质量等),但辅助奖励的权重不要超过主要奖励的 30%,否则 Agent 可能学会「作弊」——在辅助信号上表现好但实际任务完成度低。
原则二:加入效率惩罚防止 Agent 过度规划。 没有效率惩罚的 Agent 很容易出现「过度思考」——为了简单任务生成上百个推理步骤,浪费 token 成本。在奖励函数中加入步数惩罚是必要的。
原则三:奖励值要归一化。 不同奖励分量的量纲差异太大(比如成功率是 10.0 级别,而格式惩罚是 0.1 级别),会导致 RL 算法偏向于优化某个特定分量。建议在传入 RL 引擎之前,对奖励进行 min-max 归一化处理:
from agentlightning.reward import RewardNormalizer
normalizer = RewardNormalizer(method="running_mean_std")
# 在 ExperienceCollector 中集成归一化
collector = ExperienceCollector(
reward_fn=reward_fn,
normalizer=normalizer, # 奖励归一化,防止量纲失衡
gamma=0.99,
)
6.2 训练稳定性:探索与利用的平衡
RL 训练的一个经典难题是早期崩溃(Early Catastrophe)——Agent 在训练早期偶然探索到高奖励行为后,容易陷入局部最优,丧失探索能力。Agent Lightning 通过以下机制缓解这个问题:
config = RLConfig(
# 熵正则化:鼓励 Agent 保持探索
entropy_coef=0.02, # 较高的初始熵系数
entropy_decay=0.995, # 每步衰减 0.5%
# 探索噪声
exploration_noise=0.1, # 初始探索噪声
noise_decay=0.99, # 探索噪声衰减
# KL 散度约束:限制每次策略更新的幅度
target_kl=0.015,
max_kl=0.03,
# 早停机制:检测训练崩溃
early_stop_on_divergence=True,
divergence_threshold=0.5, # 如果 KL > 0.5 则早停
)
6.3 与 CI/CD 集成
在生产环境中,建议将 Agent Lightning 的训练结果自动部署到测试环境进行验证,再合并到主分支:
# .github/workflows/agent-training.yml
name: Agent RL Training Pipeline
on:
schedule:
# 每周日凌晨 2 点自动训练
- cron: '0 2 * * 0'
workflow_dispatch:
jobs:
train:
runs-on: [self-hosted, agent-gpu] # 需要 GPU 的 runner
steps:
- uses: actions/checkout@v4
- name: 拉取最新 Agent 代码
run: git pull origin main
- name: 运行 RL 训练
env:
CHENXUTAN_PUBLISH_TOKEN: ${{ secrets.CHENXUTAN_TOKEN }}
run: |
python -m agentlightning.train \
--config configs/production_rl.yaml \
--checkpoint-dir ./checkpoints \
--max-timesteps 500000
- name: 生成训练报告
run: python scripts/generate_training_report.py
- name: 部署到预发布环境
if: steps.train.outputs.improved == 'true'
run: |
kubectl set image deployment/agent \
agent=$(docker images --format '{{.Repository}}:{{.Tag}}' | head -1)
七、真实案例:用 Agent Lightning 训练 SQL 自校正 Agent
最后,我们用一个真实的生产级案例来收尾——用 Agent Lightning + LangGraph 训练一个 SQL 自校正 Agent。
这个 Agent 的任务是:接收自然语言查询 → 生成 SQL → 执行 SQL → 检查结果是否合理 → 如果不合理则修正 SQL → 重复直到成功或达到最大尝试次数。
7.1 架构设计
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import create_react_agent
from typing import TypedDict, Annotated
import operator
from agentlightning import LitAgent, RLConfig
from agentlightning.adapters import LangGraphAdapter
class SQLAgentState(TypedDict):
"""SQL 自校正 Agent 的状态定义"""
query: str # 自然语言查询
sql: str # 当前生成的 SQL
execution_result: str # SQL 执行结果
attempt: int # 当前尝试次数
history: list[str] # 历史 SQL 和结果的记录
final_answer: str # 最终答案(当任务成功时)
status: str # "generating" | "executing" | "correcting" | "success" | "max_attempts"
def generate_sql_node(state: SQLAgentState, llm) -> SQLAgentState:
"""生成 SQL 的节点"""
if state["attempt"] == 0:
prompt = f"根据以下自然语言查询生成 SQL:
{state['query']}"
else:
prompt = (
f"之前的 SQL 执行失败或不准确:
"
f"SQL: {state['sql']}
"
f"结果: {state['execution_result']}
"
f"请修正 SQL 后重新生成:
{state['query']}"
)
response = llm.invoke(prompt)
state["sql"] = extract_sql(response)
state["status"] = "executing"
return state
def execute_sql_node(state: SQLAgentState, db_connection) -> SQLAgentState:
"""执行 SQL 并检查结果"""
try:
result = db_connection.execute(state["sql"])
state["execution_result"] = str(result)
state["history"].append(
f"Attempt {state['attempt']}: {state['sql']} → {state['execution_result'][:200]}"
)
state["status"] = "correcting"
except Exception as e:
state["execution_result"] = f"Error: {e}"
state["status"] = "correcting"
return state
def judge_node(state: SQLAgentState, judge_llm) -> SQLAgentState:
"""判断当前 SQL 是否成功回答了问题"""
prompt = (
f"问题:{state['query']}
"
f"SQL:{state['sql']}
"
f"结果:{state['execution_result']}
"
f"这个 SQL 是否正确回答了问题?只回答 'YES' 或 'NO' 及简要理由。"
)
response = judge_llm.invoke(prompt).content.strip()
if response.startswith("YES"):
state["final_answer"] = state["execution_result"]
state["status"] = "success"
elif state["attempt"] >= 3:
state["status"] = "max_attempts"
else:
state["attempt"] += 1
state["status"] = "generating"
return state
def route_judge(state: SQLAgentState) -> str:
"""根据判断结果决定下一步"""
if state["status"] == "success":
return END
elif state["status"] == "max_attempts":
return END
else:
return "generate_sql"
7.2 训练流程
from agentlightning import LitAgent, RLConfig
from agentlightning.experience import ExperienceCollector
from agentlightning.adapters import LangGraphAdapter
# 构建 LangGraph
graph = StateGraph(SQLAgentState)
graph.add_node("generate_sql", lambda s: generate_sql_node(s, llm))
graph.add_node("execute_sql", lambda s: execute_sql_node(s, db_conn))
graph.add_node("judge", lambda s: judge_node(s, judge_llm))
graph.set_entry_point("generate_sql")
graph.add_edge("generate_sql", "execute_sql")
graph.add_edge("execute_sql", "judge")
compiled_graph = graph.compile()
# 包装为 LangGraphAdapter
adapter = LangGraphAdapter(
agent=compiled_graph,
state_serializer="json",
max_state_history=20,
)
# SQL Agent 的专用奖励函数
def sql_agent_reward(trajectory: dict) -> float:
"""
SQL 自校正 Agent 的奖励设计:
- 最终成功:+15
- 每次正确执行的中间步骤:+1
- 每次修正使结果更接近正确:+3
- 修正次数过多(超过 3 次):-2/次
- SQL 执行错误:-3
- 最终失败:-10
"""
state_history = trajectory.get("state_history", [])
final_state = state_history[-1] if state_history else {}
reward = 0.0
steps = trajectory.get("steps", [])
# 成功奖励
if final_state.get("status") == "success":
reward += 15.0
# 效率奖励:尝试次数越少越好
num_attempts = final_state.get("attempt", 0)
reward += max(0, 5 - num_attempts) * 2.0
return reward
# 失败惩罚
if final_state.get("status") == "max_attempts":
reward -= 10.0
return reward
# 中间步骤奖励:检查 SQL 是否在每次尝试后都有改善
for i, step in enumerate(steps):
if step.get("sql_executed_successfully"):
reward += 1.0
# 检查修正是否有效(结果中错误信息减少或数据行数合理化)
if i > 0 and step.get("result_quality", 0) > steps[i-1].get("result_quality", 0):
reward += 3.0
# 无效修正惩罚
num_attempts = final_state.get("attempt", 0)
if num_attempts > 3:
reward -= (num_attempts - 3) * 2.0
return reward
lit_agent = LitAgent(
agent=adapter,
config=RLConfig(
algorithm="LightningRL",
learning_rate=2e-4,
batch_size=16,
gamma=0.99,
entropy_coef=0.02,
adaptive_clip=True,
),
reward_fn=sql_agent_reward,
)
# 开始训练
for step in range(300):
experiences = lit_agent.collect_experiences(num_episodes=4)
metrics = lit_agent.update_policy(experiences)
if step % 30 == 0:
print(f"Step {step}: "
f"Mean Reward = {metrics['mean_reward']:.3f}, "
f"Success Rate = {metrics.get('success_rate', 0):.1%}, "
f"Avg Attempts = {metrics.get('avg_attempts', 0):.1f}")
训练 300 步之后,这个 SQL 自校正 Agent 的表现通常会有显著提升:任务成功率从初始的约 40% 提升到 75%+,平均尝试次数从 2.8 次降到 1.6 次,说明 Agent 学会了「一次写对」的能力,减少了不必要的修正循环。
八、总结与展望
Agent Lightning 的出现,填补了 AI Agent 从「能跑」到「能进化」之间的关键空白。它用强化学习的语言重新定义了 Agent 的优化问题——把 Agent 的行为看作策略,把任务完成度看作奖励,通过数据驱动的方式持续改进 Agent 的表现,而不再依赖工程师手动调 Prompt。
从技术角度看,Agent Lightning 有几个值得关注的创新点:
- 框架无关的 adapter 设计:让任何现有 Agent 零成本接入训练流程,这是工程上的巨大进步
- LightningRL 算法:针对 Agent 场景的分层信用分配和自适应 clip,是将学术 RL 算法工程化的有益尝试
- Auto-Prompt 优化:将 RL 的思想应用到 Prompt 工程中,让 Prompt 优化不再依赖玄学
- 分布式训练架构:为大规模生产训练提供了基础设施
当然,这个框架目前也有局限性:奖励函数的设计仍然需要大量人工介入,RL 训练本身的不稳定性也是业界难题,分布式训练对基础设施有一定要求。但瑕不掩瑜,Agent Lightning 已经在 GitHub 上获得了广泛的关注,预计在 2026 年底会成为 AI Agent 生产化部署的标准配置。
如果你正在构建需要持续优化的 AI Agent 系统,强烈建议你尝试将 Agent Lightning 集成到你的技术栈中——它可能是你解决「Agent 训练 gap」问题的最佳选择。