Agent微调
预计学习时间:90分钟
Agent微调(Agentic RL)是将大语言模型扩展为可与环境交互的智能体,通过强化学习优化其多轮决策轨迹,使 Agent 在动态任务中持续改进策略能力。本节内容参考实践案例:「量化龙虾」训练实验:基于 Ascend 的 Agentic RL 实践记录。
前言
从 Claude Code 到 OpenClaw,越来越多开发者尝试用大模型驱动 Agent 系统,让 AI 能够自主、长时间地完成特定领域的工作。但在这些 Agent 应用背后,支撑模型进行多步决策和环境交互的关键技术之一——Agentic Reinforcement Learning(Agentic-RL)——目前仍较少被系统化讨论。
Agentic-RL 本身就是一个高度复杂的系统工程,它不仅涉及 Agent 架构设计、上下文管理、工具调用与环境构建,还需要解决 RL 训练中的反馈设计、轨迹采样、长链路稳定性等一系列问题。更现实的是,这套流程对算力、框架和工程能力都有较高要求。
本节将通过一个完整的实践案例——基于 Qlib 与 Qwen3.5 构建能够模拟股票投资决策的「量化龙虾」——帮助理解 Agentic-RL 的训练流程与关键设计取舍。
实践资源:
- 代码仓库:Trade-Agent-RL (GitCode) / GitHub
- 数据集:trade-agent-data
本教程借用股票交易作为演示 Agentic-RL 的训练场景,使用较简化的分析+挂单模型。不能用于真实股票交易,也不能用作投资建议。
Agentic-RL 基本原理
与大模型强化学习的区别
经典的大模型强化学习(以 GSM8k 数学题为例)流程如下:
- 同一道题,模型给出多个作答过程和答案(rollout)
- 将多次作答与正确答案对比,分别给出得分(Reward)
- 将一批问题及对应轨迹加权进行微调训练
与大模型微调不同,大语言模型强化学习是以轨迹为单位训练的,而不是逐个 token 对齐。
什么是「轨迹」? 对语言模型来说,轨迹不是某一个 token,而是模型完成一次任务时产生的完整序列。例如 Claude Code 独立完成代码修改:理解需求 → 读取文件 → 调用工具 → 修改文件 → 运行测试 → 给出结果。模型生成的所有文本 token、工具调用、工具返回结果及后续决策步骤,合在一起构成一次完整的「轨迹」。
Agentic-RL 的核心思想
Agentic-RL 将 LLM 扩展为一个 Agent 进行训练,这个 Agent 除了能够回答问题,还可以根据环境反馈进行决策、生成动作,完成更复杂的任务。
| 对比维度 | 标准 RL 训练 | Agentic-RL |
|---|---|---|
| 训练对象 | 静态文本输出 | 完整行为轨迹 |
| 交互方式 | 一问一答 | 多轮工具调用与环境交互 |
| 优化目标 | 答案正确性 | 长期累积奖励 |
| 环境 | 固定数据集 | 动态可交互环境 |
结合股票交易任务:模型需要不断获取新信息,根据环境变化动态调整策略。在 Agentic-RL 中:
- o_t(观察):输入给模型的文本,可来自工具返回、大盘变化、环境状态或前一步执行结果
- a_t(动作):模型输出,可以是调用工具、执行交易、停止任务,或返回给用户的文本
训练目标从「输出答案正确」变为「主动决定下一步该做什么」。模型可能需要额外调用工具、消耗更多上下文,但如果这些行为帮助获得更准确的市场判断,长期收益反而会更高。
Agentic-RL 框架选择
框架需要解决的核心挑战
| 挑战 | 说明 |
|---|---|
| 轨迹生成 | Agent 需多次调用工具并根据响应继续决策,需处理工具超时、环境崩溃等异常 |
| 长文本吞吐 | 多轮工具调用和思考模型会产生超长上下文,需灵活并行策略避免 OOM |
| 训练-采样协同 | 需将 NPU 算力、PPO/GRPO 训练逻辑与多轮工具调用、环境结算稳定衔接 |
常见框架对比
| 框架 | 特点 | 适用场景 |
|---|---|---|
| TRL | 上手简单,适合小规模验证 | 8 卡以内、7B 以下、上下文 < 16k 的简单 Agent 任务 |
| Verl | 昇腾适配完善,并行策略灵活 | 大规模训练、长上下文、RL 算法研发 |
| AReal | 支持 OpenAI Agents 接入,轨迹生成代码简洁 | 已在 OpenAI Agents / Camel-AI 上搭建好 Agent 的场景 |
对于使用昇腾算力进行 Agent 强化学习微调的开发者:若更关注 Agent 搭建或已使用 OpenAI Agents 框架,建议选用 AReal;若更关注 RL 算法开发或模型参数量/上下文较长,建议重点评估 Verl(对 MindSpeed 支持更好)。
量化龙虾 Agent 设计
任务设定
「量化龙虾」被设定为一名负责单日调仓的量化交易分析师。每条训练样本对应一个交易日,Agent 收到当天的大盘状态、初始持仓、可用现金和可交易股票池。
期望 Agent 形成的工作链路:
- 理解账户状态:持仓、现金、可交易股票池
- 观察市场环境:大盘趋势、波动率、市场宽度、成交活跃度
- 调用工具分析:查看价格走势、技术指标或 Alpha 因子
- 执行交易动作:买入、卖出或停止交易,并在 reasoning 字段说明决策依据
四大核心工具
| 工具 | 功能 |
|---|---|
GetPriceDataTool | 获取指定股票的价格数据、区间统计及技术指标 |
GetMacroIndicatorsTool | 获取市场指数(如沪深300)行情及波动率 |
ComputeAlphaFactorTool | 计算各股票的 Alpha 因子,提供额外决策信号 |
TakeAction | 执行交易决策(买入、卖出或停止) |
前三个工具提供交易信息,最后一个完成交易决策。行情、指标和因子来自工具(环境事实),模型负责组织判断并落到可执行动作上,奖励函数才能根据真实价格变化检验决策有效性。
提示词设计要点
- System / User 分离:角色信息放 SYSTEM PROMPT,随交易动态变化的信息放 USER PROMPT,符合 Qwen 模型的 system-user-assistant 交替模式
- 工作流程约束:除角色信息和规则约束外,增加人工定义的工作流程以提高训练稳定性(可能限制探索空间)
- 大盘信息注入:在系统提示词中直接注入当日大盘信息,有助于提升表现
- 工具描述重复注入:对 Qwen3 模型,将函数工具描述再次注入系统提示词,有助于提升调用准确率
奖励函数设计
核心目标
奖励函数的核心目标不是追求绝对收益,而是判断:模型提出的新交易策略,是否比「保持原始持仓不变」更好。
- T0:模型决策和交易执行的日期
- 所有中间步骤不产生有效奖励,仅当轨迹结束时根据最终组合计算一次
r_outcome - 前瞻收益使用 T+1、T+2、T+3 收盘价按 0.5、0.3、0.2 加权
最终奖励信号为相对原始策略的前瞻收益提升:
r_outcome = 新策略前瞻收益 - 原始策略前瞻收益
分桶奖励策略
将连续收益分桶为离散奖励,避免模型过度拟合微小收益差异:
| r_outcome 范围 | 奖励 |
|---|---|
| ≥ +0.80% | +3(强于原始策略) |
| ≥ +0.40% | +2(明显优于原始策略) |
| ≥ +0.10% | +1(小幅优于原始策略) |
| ≥ -0.10% | 0(基本持平) |
| ≥ -0.30% | -1(小幅弱于原始策略) |
| < -0.30% | -2(明显弱于原始策略) |
| 轨迹未完成(无有效终止) | -3(工具调用或轨迹失败) |
基于 Verl 框架的实现
需要实现的三个核心部分
- Agent 工具:继承
verl.tools.base_tool.BaseTool,返回文本格式信息供 LLM 上下文使用 - 奖励函数:在
reward_fn.py中评估 Agent 整条轨迹的工作质量 - Agent 循环:继承
verl.experimental.agent_loop.tool_agent_loop.ToolAgentLoop,实现从提示词到奖励计算的完整流程
Agent 循环流程
初始提示词 → LLM 生成回复
↓ 检测到 FUNCTION_CALL
├─ 数据工具 → 执行 → 结果返回 → 继续生成
└─ TakeAction
├─ buy/sell → 更新持仓 → 继续生成
└─ stop → 轨迹结束 → 计算 Reward → GRPO 训练
Verl 框架基于 Ray 实现跨节点多卡计算调度,统一管理分布式计算、PPO/GRPO 算法和 Agent 异步采样流程。
数据工具格式化示例
工具返回格式化文本而非原始矩阵,便于模型理解:
## SH600519 近5个交易日行情
最新:2024-01-15 开1680.00 高1720.00 低1675.00 收1710.00 量2.5万手
区间:最高1720.00 最低1675.00 涨跌幅+2.1%
技术指标(最新值):
- MA5: 1695.50
- RSI_14: 58.32
训练环境搭建
硬件与软件要求
| 项目 | 配置 |
|---|---|
| 硬件 | 8 卡昇腾 910 NPU |
| 驱动 | NPU driver + CANN 8.5.0 + Docker |
| 框架 | Verl + vLLM + Ray + SwanLab |
| 基座模型 | Qwen3-4B / Qwen3.5-4B / Qwen3.5-35B-A3B |
环境安装步骤
# 拉取项目代码
git clone https://gitcode.com/SwanHubX/Trade-Agent-RL
# 拉取 Verl 镜像并启动容器
docker pull quay.io/ascend/verl:verl-8.5.0-910-ubuntu22.04-py3.11-latest
# 升级 transformers 至 5.0+(支持 Qwen3.5)
pip install -U transformers
pip install pyqlib swanlab modelscope
# 下载股票数据
bash scripts/download_data.sh
# 下载基座模型
modelscope download --model Qwen/Qwen3.5-4B --local_dir ./models/Qwen3.5-4B
数据集划分
按时间划分,避免数据泄漏:
| 数据集 | 时间范围 | 用途 |
|---|---|---|
| 训练集 | 2025-01-01 ~ 2025-06-15 | 模型学习 |
| 验证集 | 2025-06-16 ~ 2025-07-30 | 反映学习情况 |
| 回测集 | 2025-06-20 起 60 个交易日 | 模拟实盘评估 |
运行训练与评估
启动训练
bash run_grpo.sh MODEL_PATH=~/models/Qwen3-4B
Qwen3-4B 在 8 卡 NPU 上完整训练约需 15 小时,Qwen3.5-4B 约需 20+ 小时。
核心监控指标
通过 SwanLab 跟踪以下关键指标:
| 指标 | 含义 |
|---|---|
val-aux/a_stock_single_day/reward/mean | 验证集平均奖励 |
response_length 系列 | 响应长度,反映推理输出量 |
num_turns 系列 | 多轮交互次数 |
actor/entropy | 策略熵,衡量探索程度 |
actor/pg_loss | 策略梯度损失 |
actor/ppo_kl | PPO KL 散度,监控策略变化 |
回测实验
训练中的验证集 Reward 只能反映单条轨迹表现。回测实验验证模型连续多日管理持仓的能力:
# 1. 合并 FSDP 权重为 HuggingFace 格式
python -m verl.model_merger merge \
--backend fsdp \
--local_dir ./checkpoints \
--target_dir ./final_vllm_model_weights
# 2. 启动 vLLM 推理服务
python -m vllm.entrypoints.openai.api_server \
--model ./final_vllm_model_weights \
--served-model-name trader_agent \
--port 8001 \
--max-model-len 20480 \
--enable-auto-tool-choice \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder
# 3. 运行回测
cd rollout_dashboard
uv run python backtest_cli.py \
--base-url http://localhost:8001/v1 \
--model trader_agent \
--start-date 2025-06-20 \
--num-days 60 \
--initial-cash 1000000 \
--temperature 0.7
训练结果
在 60 个交易日回测中(2025-06-20 ~ 2025-09-11,初始资金 100 万元):
| 模型 | 期末 NAV | 累计收益 |
|---|---|---|
| Qwen3.5-4B 原始模型 | 1,053,220 元 | +5.32% |
| Agentic-RL 训练后 | 1,093,474 元 | +9.35% |
训练后模型在交易机会识别和收益捕捉上有一定改善,但该结果仍有提升空间,作为入门教程主要用于说明 Agentic-RL 训练和评估的基本流程。
拒绝采样微调(进阶)
为探索更大规模模型效果,可将 Agentic-RL 训练后模型生成的连续回测轨迹数据用于对更大模型(如 Qwen3.5-35B-A3B)进行 LoRA 微调。
轨迹过滤规则
# 拒绝采样过滤条件
# 1. 去除 function calling 行为异常的轨迹
# 2. 去除未调用 TakeAction(type="stop") 主动结束的轨迹
# 3. 删除 NAV 收益 < 0 的轨迹(只保留盈利策略)
MS-Swift LoRA 微调
swift sft \
--model '/models/Qwen/Qwen3.5-35B-A3B' \
--tuner_type lora \
--dataset './data/synth_grpo_filtered.jsonl' \
--torch_dtype bfloat16 \
--num_train_epochs 4 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 4 \
--learning_rate 1e-4 \
--lora_rank 32 \
--lora_alpha 64 \
--target_modules all-linear \
--max_length 20480 \
--report_to swanlab
拒绝采样微调使更大模型学习到高质量 Agent 轨迹中的决策模式,是一种将 RL 探索成果蒸馏到更大模型的有效路径。
Agent 微调 vs 传统微调
若不具备 RL 训练条件,可先通过 Agent持续演进 中的记忆沉淀、技能提炼和 Benchmark 回归提升 Agent 表现;触及瓶颈后再考虑本节的 Agentic RL 训练。
| 维度 | 传统 SFT 微调 | Agentic-RL 微调 |
|---|---|---|
| 训练数据 | 静态输入-输出对 | 动态环境交互轨迹 |
| 反馈信号 | 人工标注答案 | 环境奖励函数 |
| 优化单位 | token 级别 | 轨迹级别 |
| 探索能力 | 无 | 通过策略熵鼓励探索 |
| 适用场景 | 格式遵循、知识注入 | 多步决策、工具使用、策略优化 |
| 工程复杂度 | 较低 | 较高(需搭建环境+框架) |
小结
Agentic-RL 训练既有不少探索空间,也包含繁琐的工程实现。通过「量化龙虾」案例,我们可以理解:
- 任务设计:将真实场景抽象为可训练的 Agent 任务,平衡真实性与可训练性
- 框架选择:根据算力、模型规模和 Agent 复杂度选择合适的训练框架
- 奖励设计:相对基线的收益提升比绝对收益更适合作为 RL 信号
- 轨迹质量:拒绝采样可将 RL 探索成果蒸馏到更大模型
随着 Qwen3.5 等模型在 Post-training 阶段对各类 RL 任务和环境的扩展,基座模型已具备较好的通用 Agent 能力。Agentic-RL 在此基础上进一步针对特定业务场景优化决策策略,是构建垂域 Agent 应用(如 OpenClaw-like 应用、软件助手等)的关键技术路径。