用Agent Lightning训练Agent
Agent Lightning通过VERL为Agent启用GRPO微调。它从执行多步推理和工具调用的Agent中收集轨迹允许模型学习诸如SQL ReAct agent的工作流这些agent使用工具进行模式搜索、列检查、SQL生成和查询执行。然而官方的Agent Lightning文本到SQL示例主要展示了LangGraph推理流而在推出过程中没有实际使用工具。在实践中默认的vLLM工具解析器无法可靠地与某些模型一起工作例如Qwen2.5-Coder-1.5B-Instruct这会阻止在训练期间检测到工具调用。在本文中我们创建一个自定义vLLM工具解析器以便使用Agent Lightning和VERL将带有Qwen2.5-Coder-1.5B的agent训练为多工具ReAct agent。像Qwen3这样的较新模型在vLLM中已经有内置解析器qwen3_coder和qwen3_xml支持不需要此自定义。1、工具解析问题当训练带有多个工具的agent时训练系统必须正确检测模型产生的工具调用。在推出过程中模型生成表示工具调用的文本。推理服务器必须解析此文本并将其转换为结构化的tool_call对象以便agent运行时可以执行工具并将观察结果返回给模型。然而在使用Qwen2.5-Coder-1.5B-Instruct进行训练期间模型生成的工具调用经常以纯文本形式返回。默认的vLLM Hermes解析器期望特定的tool_call格式但Qwen经常产生不同的格式例如tools标签、JSON块或原始JSON对象。由于这些格式不被默认解析器识别工具调用被忽略并且agent在推出期间从不执行它们。因此agent循环塌陷为单轮。不执行任何工具轨迹仅包含一个响应并且强化学习信号变得非常弱。两种可能的方法可以解决这个问题。解决方案1是创建一个自定义工具解析器它可以识别模型产生的多种工具调用格式。解决方案2是在GRPO之前进行简短的SFT冷启动阶段以便模型学习一致地生成vLLM使用的正确Hermestool_call格式。通过此冷启动GRPO训练可以专注于改进推理和工具使用而不是学习工具调用的语法。在本文中我们采用解决方案1实现自定义解析器以处理训练期间的格式变化。2、创建自定义vLLM工具解析器在本节中我们实现一个自定义vLLM工具解析器它检测这些Qwen风格的变体并将它们规范化为vLLM期望的标准tool_calls结构。默认的vLLM工具解析器是为Hermes工具调用格式设计的它期望以下输出tool_call{name: ..., arguments: {...}}自定义解析器qwen25_coder_parser.py扫描模型输出以查找已知模式提取函数名称和参数并将它们作为结构化ToolCall对象返回Custom vLLM tool parser for Qwen2.5-Coder tool-call variants. import json import re from vllm.entrypoints.openai.protocol import ( DeltaMessage, ExtractedToolCallInformation, FunctionCall, ToolCall, ) from vllm.entrypoints.openai.tool_parsers.abstract_tool_parser import ( ToolParser, ToolParserManager, ) # Common Qwen variants we observed in rollouts _PATTERNS [ re.compile(rtool_call\s*(.*?)\s*/tool_call, re.DOTALL), re.compile(rtools\s*(.*?)\s*/tools, re.DOTALL), re.compile(r(?:json)?\s*\n?(.*?)\n?\s*, re.DOTALL), ] def _normalize(obj): Return a list of tool call dicts from multiple JSON shapes. if isinstance(obj, dict): if isinstance(obj.get(tool_calls), list): return obj[tool_calls] if name in obj or function in obj: return [obj] if isinstance(obj, list): return [x for x in obj if isinstance(x, dict) and (name in x or function in x)] return None def _extract_calls(text: str): Parse tool call dicts from tagged blocks, fenced JSON, or raw JSON. for p in _PATTERNS: matches p.findall(text) if not matches: continue calls [] for m in matches: try: obj json.loads(m.strip()) except json.JSONDecodeError: continue norm _normalize(obj) if norm: calls.extend(norm) if calls: return calls # last resort: entire text is JSON try: obj json.loads(text.strip()) return _normalize(obj) except json.JSONDecodeError: return None class Qwen25CoderToolParser(ToolParser): def __init__(self, tokenizer): super().__init__(tokenizer) def adjust_request(self, request): return request def extract_tool_calls(self, model_output: str, request): parsed _extract_calls(model_output) if not parsed: return ExtractedToolCallInformation( tools_calledFalse, tool_calls[], contentmodel_output, ) tool_calls [] for call in parsed: fn_name call.get(name) or (call.get(function) or {}).get(name) args ( call.get(arguments) or call.get(parameters) or (call.get(function) or {}).get(arguments) or {} ) if not fn_name: continue if not isinstance(args, str): args json.dumps(args, ensure_asciiFalse) tool_calls.append( ToolCall( typefunction, functionFunctionCall(namefn_name, argumentsargs), ) ) return ExtractedToolCallInformation( tools_calledbool(tool_calls), tool_callstool_calls, contentNone, # tool-only output during training ) def extract_tool_calls_streaming( self, previous_text, current_text, delta_text, previous_token_ids, current_token_ids, delta_token_ids, request, ): # Keep streaming simple; tool extraction happens in non-streaming rollouts return DeltaMessage(contentdelta_text) def register(): ToolParserManager.register_module( qwen25_coder, moduleQwen25CoderToolParser )3、在vLLM和VERL中注册解析器实现自定义解析器后下一步是使其在训练期间可用于vLLM。这是使用vLLM插件系统完成的该系统允许外部模块注册自定义组件如工具解析器。在基于uv的Python项目中这是在pyproject.toml中使用vllm.general_plugins组下的Python入口点配置的。当vLLM启动时它会自动发现这些插件并执行它们的register()函数该函数向ToolParserManager注册解析器。[project.entry-points.vllm.general_plugins] qwen25_coder_parser src.vllm_plugins.qwen25_coder_parser:register在自定义解析器脚本内解析器插件注册如下ToolParserManager.register_module( qwen25_coder, moduleQwen25CoderToolParser )注册后可以通过在VERL训练配置中设置来启用解析器multi_turn: {format: hermes}, engine_kwargs: { vllm: { enable_auto_tool_choice: True, tool_call_parser: qwen25_coder, ... } }, ...安装插件包后当VERL推理worker启动时vLLM通过vllm.general_plugins入口点机制自动发现并注册解析器。项目布局project/ pyproject.toml src/ vllm_plugins/ __init__.py qwen25_coder_parser.py4、多工具Agent的上下文要求现在工具调用被正确解析和执行下一个考虑是多轮工具交互如何在训练期间增加上下文大小。训练多工具agent需要比单步任务如模式链接更大的上下文。每个工具调用将新信息附加到对话中包括生成的SQL、工具响应有时还有错误消息。由于agent携带前几轮上下文在轨迹上快速增长。例如典型的SQL agent推出可能如下所示Turn 1: prompt (~4K) SQL generation (~200) tool result (~500) Turn 2: prompt (~4.7K) revised SQL (~200) tool result (~500) Turn 3: prompt (~5.4K) final SQL (~200) Total trajectory: ~6K tokens由于每一轮都包括以前的对话历史多工具工作流可以超过用于更简单任务的上下文限制。这就是为什么在训练具有多个工具调用的SQL agent时通常需要增加VERL配置参数如max_prompt_length、max_model_len和ppo_max_token_len_per_gpu。例如SQL ReAct agent通常在推出期间与几个工具交互例如search_schema、get_columns和execute_sql。每个工具调用返回一个观察结果在下一个推理步骤之前附加到对话中。User: Find top 5 customers by total claim amount. Agent → search_schema(claim) Tool → tables: claim, claim_payment Agent → get_columns(claim_payment) Tool → columns: customer_id, claim_amount, claim_date Agent → execute_sql( SELECT customer_id, SUM(claim_amount) FROM claim_payment GROUP BY customer_id ORDER BY SUM(claim_amount) DESC LIMIT 5 ) Tool → result rows每一步都向上下文添加新token。由于agent携带前几轮上下文随着每次工具交互而增长。对于这种类型的agent典型配置可能会增加上下文限制以支持多轮轨迹data: { max_prompt_length: 8192, max_response_length: 1024, }, actor_rollout_ref: { rollout: { engine_kwargs: { vllm: { max_model_len: 8192, enable_auto_tool_choice: True, tool_call_parser: qwen25_coder } } }, }, actor: { ppo_max_token_len_per_gpu: 32768 }这些更大的限制确保多步工具交互可以在GRPO训练期间适应模型上下文。请注意这些更大的上下文限制也会增加KV缓存使用因此最大上下文大小最终受到可用GPU VRAM的限制这可能需要调整诸如gpu_memory_utilization之类的参数或减少批量大小以避免内存不足。以下是用于GRPO训练和LoRA微调的完整VERL配置VERL_CONFIG { algorithm: { adv_estimator: grpo, use_kl_in_reward: False, }, data: { train_files: data/sql_train.jsonl, val_files: data/sql_val.jsonl, train_batch_size: 8, max_prompt_length: 8192, max_response_length: 1024, truncation: error, }, actor_rollout_ref: { rollout: { name: vllm, n: 2, tensor_model_parallel_size: 1, gpu_memory_utilization: 0.6, log_prob_micro_batch_size_per_gpu: 2, multi_turn: {format: hermes}, enforce_eager: True, engine_kwargs: { vllm: { enable_auto_tool_choice: True, tool_call_parser: qwen25_coder, max_model_len: 8192, enforce_eager: True, num_gpu_blocks_override: 256, } }, }, actor: { ppo_mini_batch_size: 16, ppo_micro_batch_size_per_gpu: 1, ppo_max_token_len_per_gpu: 32768, optim: {lr: 1e-5}, use_kl_loss: False, kl_loss_coef: 0.0, entropy_coeff: 0, clip_ratio_low: 0.2, clip_ratio_high: 0.28, fsdp_config: { param_offload: True, optimizer_offload: True, }, }, ref: { log_prob_micro_batch_size_per_gpu: 2, fsdp_config: {param_offload: True}, }, model: { path: os.getenv( SFT_MODEL_PATH, Qwen/Qwen2.5-Coder-1.5B-Instruct, ), lora_rank: 16, lora_alpha: 32, use_remove_padding: False, enable_gradient_checkpointing: True, override_config: { attn_implementation: sdpa, }, }, }, trainer: { n_gpus_per_node: 1, total_epochs: 3, val_before_train: True, test_freq: 16, project_name: sql-agent-grpo, logger: [console, wandb], }, }5、结束语这种方法通过使用自定义解析器扩展vLLM来为不严格遵循Hermes工具调用格式的模型实现了使用Agent Lightning和VERL的可靠多工具agent训练。有关Agent Lightning、VERL和vLLM工具解析的更多详细信息请参阅官方文档。原文链接用Agent Lightning训练Agent - 汇智网

相关新闻

基于TMS320F28335与AD2S1210的SPI通信实现方案

基于TMS320F28335与AD2S1210的SPI通信实现方案

一、硬件连接配置TMS320F28335引脚AD2S1210引脚功能说明GPIO54 (SPISIMO)SCLK串行时钟(主出从入)GPIO55 (SPISOMI)SDI串行数据输入(主入从出)GPIO56 (SPICLK)CS片选信号(低电平有效)GPIO57 (SPISTE)SAMPLE采…

2026/7/2 21:48:46 阅读更多 →
《宇宙闪烁请注意》从霸总对戏到五米跳台,黄晓明这一期综艺表现太全面了

《宇宙闪烁请注意》从霸总对戏到五米跳台,黄晓明这一期综艺表现太全面了

在这个综艺扎堆的初春,如果你还没看过《宇宙闪烁请注意》第十三期,那你可能真的错过了一场教科书级别的“快乐风暴”。随着“宇宙杯”农田运动会和水乡摸鱼大赛的火热开赛,这一期节目不仅有少年的热血,更让我们看到了一个前所未有…

2026/7/3 1:22:31 阅读更多 →
Suno Lyrics Generation API

Suno Lyrics Generation API

Suno 歌词生成 API 对接说明 如果你想自定义生成歌曲,但又不太想自己编写歌词,可以使用 AceDataCloud 提供的歌词生成 API 来通过 prompt 生成歌词,API 是 Suno Lyrics Generation API。 该 API 主要输入参数是 prompt,可选 mod…

2026/5/17 10:22:05 阅读更多 →

最新新闻

Python+Django商铺管理系统毕业设计实战指南

Python+Django商铺管理系统毕业设计实战指南

1. 项目背景与核心价值去年指导计算机专业毕业设计时,发现商铺管理系统是经管类院校的热门选题。这类系统看似简单,实则完整涵盖了进销存管理、会员体系、财务统计等商业场景的数字化需求。PythonDjango的组合既能快速实现基础功能,又留有足够…

2026/7/3 12:08:03 阅读更多 →
三步解锁Wand专业版功能:免费畅享完整游戏修改体验的终极指南

三步解锁Wand专业版功能:免费畅享完整游戏修改体验的终极指南

三步解锁Wand专业版功能:免费畅享完整游戏修改体验的终极指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否厌倦了Wand(…

2026/7/3 12:06:02 阅读更多 →
如何快速实现Unity游戏自动翻译:XUnity.AutoTranslator完整配置指南

如何快速实现Unity游戏自动翻译:XUnity.AutoTranslator完整配置指南

如何快速实现Unity游戏自动翻译:XUnity.AutoTranslator完整配置指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语游戏的语言障碍而烦恼吗?XUnity.AutoTranslator为你…

2026/7/3 12:06:02 阅读更多 →
本地AI编程助手搭建指南:Gemma 2+Ollama+Gradio三步落地

本地AI编程助手搭建指南:Gemma 2+Ollama+Gradio三步落地

1. 项目概述:为什么一个本地AI编程助手值得你花两小时搭起来Gemma 4不是某个神秘新模型的代号,而是指Google最新发布的Gemma 2系列中面向开发者优化的7B参数版本——准确说是Gemma 2 7B Instruct。它被设计成轻量、开源、可商用的代码理解与生成基座&…

2026/7/3 12:02:01 阅读更多 →
3步实现完美网页长截图:告别拼接烦恼的终极解决方案

3步实现完美网页长截图:告别拼接烦恼的终极解决方案

3步实现完美网页长截图:告别拼接烦恼的终极解决方案 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-extensi…

2026/7/3 12:02:01 阅读更多 →
读懂Qwen3 Benchmark:不是比分数,而是看能力适配

读懂Qwen3 Benchmark:不是比分数,而是看能力适配

1. 看懂Qwen3报告里的Benchmark,不是看分数高低,而是看它在解决什么问题最近阿里通义实验室发布的Qwen3系列模型,在开源大模型圈里掀起了不小波澜。朋友圈刷屏的“登顶全球最强开源模型”“全面超越Llama-405B”这类标题很抓眼球,…

2026/7/3 11:57:57 阅读更多 →

日新闻

Nginx防御TLS重协商攻击实战:从原理到配置与监控

Nginx防御TLS重协商攻击实战:从原理到配置与监控

1. 项目概述:为什么TLS重协商攻击至今仍需警惕十多年前的CVE-2011-1473,一个关于TLS/SSL协议重协商机制的漏洞,现在提起来还有必要吗?很多运维和开发朋友可能会觉得,这都老掉牙了,现代服务器和客户端不都默…

2026/7/3 0:03:59 阅读更多 →
华为防火墙双通道远程管理实战:Web与SSH配置详解

华为防火墙双通道远程管理实战:Web与SSH配置详解

1. 项目概述:为什么需要双通道远程管理防火墙?在任何一个稍具规模的企业网络里,防火墙都是那个默默守护在边界的关键角色。作为网络工程师,我们不可能每次都跑到机房,插上console线去配置它。远程管理能力,…

2026/7/3 0:03:59 阅读更多 →
AD74413R与PIC18F65K40的高精度工业数据采集方案

AD74413R与PIC18F65K40的高精度工业数据采集方案

1. 项目概述:AD74413R与PIC18F65K40的协同工作在工业自动化和精密测量领域,同时实现高精度模数转换(ADC)和数模转换(DAC)功能是许多复杂系统的核心需求。AD74413R作为一款四通道可配置模拟输入/输出器件,与PIC18F65K40微控制器的组合&#xf…

2026/7/3 0:05:59 阅读更多 →

周新闻

月新闻