资讯动态

vLLM Tool Calling 完全指南:从自动函数调用到自研工具解析器插件

发布时间:2026/9/7 2:49:19 来源:尧图企业网站定制
vLLM Tool Calling 完全指南从自动函数调用到自研工具解析器插件【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm本文以 vLLM 官方文档 docs/features/tool_calling.md 为主体系统讲解 vLLM 在 Chat Completion API 中的工具调用Tool Calling能力tool_choice的auto、required、none及命名函数四种模式的实现机制与约束解码行为覆盖 Llama、Mistral、Hermes、DeepSeek、GLM 等 20 余种模型族的解析器配置方式并结合vllm/tool_parsers/源码剖析解析器注册机制最后给出编写自定义 Tool Parser 插件的完整实践步骤与性能基准测试方法。快速上手一分钟跑通工具调用vLLM 支持命名函数调用并支持auto、requiredvllm0.8.3起以及none三种tool_choice取值。以 Meta 的 Llama 3.1 8B 为例由于该模型的tokenizer_config.json中不包含 vLLM 所需的工具调用模板需要显式指定 vLLM examples 目录中的llama3_json工具调用聊天模板vllm serve meta-llama/Llama-3.1-8B-Instruct \ --enable-auto-tool-choice \ --tool-call-parser llama3_json \ --chat-template examples/tool_chat_template_llama3.1_json.jinja然后发送一个能触发工具调用的请求from openai import OpenAI import json client OpenAI(base_urlhttp://localhost:8000/v1, api_keydummy) def get_weather(location: str, unit: str): return fGetting the weather for {location} in {unit}... tool_functions {get_weather: get_weather} tools [ { type: function, function: { name: get_weather, description: Get the current weather in a given location, parameters: { type: object, properties: { location: {type: string, description: City and state, e.g., San Francisco, CA}, unit: {type: string, enum: [celsius, fahrenheit]} }, required: [location, unit], }, }, }, ] response client.chat.completions.create( modelclient.models.list().data[0].id, messages[{role: user, content: Whats the weather like in San Francisco?}], toolstools, tool_choiceauto, ) tool_call response.choices[0].message.tool_calls[0].function print(fFunction called: {tool_call.name}) print(fArguments: {tool_call.arguments}) print(fResult: {tool_functionstool_call.name)})预期输出Function called: get_weather Arguments: {location: San Francisco, CA, unit: fahrenheit} Result: Getting the weather for San Francisco, CA in fahrenheit...这个例子完整演示了四个环节启用工具调用启动服务端、定义实际的函数处理工具调用、以tool_choiceauto发起请求、解析结构化响应并执行对应函数。也可以指定调用某个特定函数命名函数调用tool_choice{type: function, function: {name: get_weather}}注意命名函数调用会走结构化输出structured outputs后端首次使用时 FSM 需要现场编译会有数秒甚至更长的额外延迟之后编译结果被缓存后续请求不再有该开销。最后必须明确调用方需要自行负责——(1) 在请求中定义合适的 tools(2) 在聊天消息中包含相关上下文(3) 在应用逻辑中处理返回的工具调用。vLLM 本身只负责生成并解析工具调用不执行函数。四种 tool_choice 模式与约束解码行为这是理解 vLLM 工具调用语义的核心。是否对模型生成施加工具参数 schema 约束取决于tool_choice模式与每个工具上的strict字段tool_choice取值是否 schema 约束解码行为命名函数named function是经由 structured outputs 后端参数保证是符合该函数参数 schema 的合法 JSONrequired是经由 structured outputs 后端与命名函数相同且模型必须至少产出一个工具调用auto仅当至少一个工具设置了strict: true结构化标签解析器在工具显式声明strict: true时约束工具调用参数否则模型自由生成工具调用从原始文本中提取none不适用不产生任何工具调用三种模式的具体语义命名函数调用默认即可用vLLM 使用结构化输出保证响应匹配tools参数中 JSON schema 定义的工具参数对象。文档强调一句话原则you are guaranteed a validly-parsable function call — not a high-quality one保证可解析不保证质量。为了效果最好建议在 prompt 中同样写明期望的输出格式/schema让模型本意生成与强制约束的 schema 保持一致。tool_choicerequired与命名函数一样走结构化输出默认启用、适用于任何受支持模型。设置后模型保证基于tools列表生成一个或多个工具调用调用数量由用户查询决定输出格式严格遵循tools中的 schema。替代解码后端的支持列入 V1 引擎路线图。tool_choicenone即使请求中定义了 tools模型也不会产生任何工具调用只返回普通文本。官方文档特别提醒默认情况下只要请求中带了 tools无论tool_choice为何值工具定义都会被渲染进 prompt若在tool_choicenone时希望连工具定义也排除需要加--exclude-tools-when-tool-choice-none启动参数。该参数在 启动参数定义 中对应exclude_tools_when_tool_choice_none字段。从源码结构看auto模式下的约束能力由 ToolParser 基类 中的两个类属性驱动structural_tag_model标记该解析器对应 xgrammar 内置结构化标签模型和supports_required_and_named。基类的adjust_request方法abstract_tool_parser.py#L118-L165会把tools参数转换成 JSON schema 并注入请求的structured_outputs字段——这正是命名函数与required模式获得 schema 约束的内部实现路径。Strict 模式对tool_choicerequired或命名函数调用无论strict字段如何结构化标签约束始终生效对tool_choiceauto至少一个工具设置strict: true即加入结构化标签约束否则模型自由生成、工具调用从原始文本提取strict字段在 Chat Completion、Responses、Anthropic Messages 三个 API 面均受支持。为获得与严格 schema 强制最好的兼容性工具参数 schema 建议采用 OpenAI strict-schema 风格书写每个 object 的parameters中设置additionalProperties: falseproperties中的全部字段都列入required可选字段用允许null表示例如{type: [string, null]}。此外 vLLM 提供全局开关环境变量VLLM_ENFORCE_STRICT_TOOL_CALLING默认true。设为false时vLLM 不再为工具调用附加结构化标签与逐工具的strict字段无关。该开关只影响基于结构化标签的工具调用不改变命名函数调用与tool_choicerequired所使用的 schema 派生式结构化输出。源码中默认值定义见 vllm/envs.py#L240 与 vllm/envs.py#L1777-L1778且ToolParser.get_structural_tag在 abstract_tool_parser.py#L167-L184 中会先检查该环境变量为false时直接返回None。VLLM_ENFORCE_STRICT_TOOL_CALLINGfalse vllm serve ...tool_choiceauto时 schema 级约束同时要求VLLM_ENFORCE_STRICT_TOOL_CALLINGtrue默认值且至少一个工具声明strict: true两者都满足且所选解析器支持结构化标签时vLLM 才约束工具调用参数。否则 vLLM 从原始文本提取工具调用参数偶尔会格式错误或不满足函数参数 schema。自动函数调用的启动参数要启用auto自动函数调用需设置以下标志--enable-auto-tool-choice——必选。告诉 vLLM 允许模型在合适时机自主生成工具调用--tool-call-parser—— 选择工具解析器可选清单见下文。源码中的校验逻辑要求二者必须同时提供cli_args.py#L431-L432 中--enable-auto-tool-choice若缺少--tool-call-parser会直接抛TypeError--tool-parser-plugin——可选用于把用户自定义的工具解析器注册进 vLLM注册后的解析器名可被--tool-call-parser引用--chat-template——可选。指向处理tool角色消息与携带历史工具调用的assistant消息的聊天模板路径。Hermes、Mistral、Llama 模型的tokenizer_config.json自带兼容工具调用的模板但也可以指定自定义模板。若模型的tokenizer_config.json中配置了专门用于工具调用的聊天模板该参数可设为tool_usevLLM 会按 transformers 的规范选用它。当前仓库内置解析器名注册表见 vllm/tool_parsers/init.py其中--tool-call-parser可填的每一个名字都通过ToolParserManager.register_lazy_module惰性注册——首次使用时才真正 import 对应模块避免启动时加载全部解析器依赖。各模型族解析器配置以下配置均继承自官方文档并按仓库实际文件核实模板路径。Hermes 模型hermes适用于 Hermes 2 Pro 之后的所有 Nous Research Hermes 系列模型NousResearch/Hermes-2-Pro-*NousResearch/Hermes-2-Theta-*NousResearch/Hermes-3-*注意Hermes 2Theta模型因创建过程中的 merge 步骤工具调用质量与能力已知退化。启动标志--tool-call-parser hermesMistral 模型mistralmistralai/Mistral-7B-Instruct-v0.3已确认其他 Mistral 函数调用模型同样兼容已知问题Mistral 7B 难以正确生成并行工具调用仅针对 Transformers 分词后端Mistral 的tokenizer_config.json聊天模板要求工具调用 ID 恰好为 9 位数字远短于 vLLM 生成的 ID不满足会抛异常。为此 vLLM 额外提供两个模板examples/tool_chat_template_mistral.jinja —— 官方 Mistral 聊天模板的微调版配合 vLLM 工具调用 ID 工作要求tool_call_id字段截断到末 9 位examples/tool_chat_template_mistral_parallel.jinja —— 更好的版本在提供 tools 时追加一条工具使用系统提示显著提升并行工具调用的可靠性。推荐标志使用 Mistral AI 官方格式--tool-call-parser mistral可用 Transformers 格式时--tokenizer_mode hf --config_format hf --load_format hf --tool-call-parser mistral --chat-template examples/tool_chat_template_mistral_parallel.jinjaMistral AI 官方发布的模型有两种格式默认auto/mistral参数走官方格式--tokenizer_mode mistral --config_format mistral --load_format mistral基于 mistral-common 分词后端可用 Transformers 格式时走hf参数并配合上述 parallel 模板。Llama 模型llama3_jsonLlama 3.1、3.2 和 4 系列均受支持meta-llama/Llama-3.1-*、meta-llama/Llama-3.2-*、meta-llama/Llama-4-*。受支持的是 JSON 形式的工具调用Llama-3.2 引入的 pythonic 工具调用见下文pythonic解析器Llama 4 模型建议使用llama4_pythonic解析器。内建 python 工具调用或自定义工具调用格式不受支持。已知问题Llama 3 不支持并行工具调用Llama 4 支持模型可能以错误格式生成参数例如把数组序列化成字符串而非数组。vLLM 为 Llama 3.1 / 3.2 提供两个 JSON 模板examples/tool_chat_template_llama3.1_json.jinja —— Llama 3.1 官方模板的微调版与 vLLM 配合更好examples/tool_chat_template_llama3.2_json.jinja —— 在 3.1 模板基础上增加图片支持。推荐标志--tool-call-parser llama3_json --chat-template {见上}针对 Llama 4vLLM 提供 pythonic 与 JSON 两种模板推荐 pythonicexamples/tool_chat_template_llama4_pythonic.jinja。Llama 4 使用--tool-call-parser llama4_pythonic --chat-template examples/tool_chat_template_llama4_pythonic.jinja。IBM Graniteibm-granite/granite-4.0-h-small及其他 Granite 4.0 模型--tool-call-parser granite4ibm-granite/granite-3.0-8b-instruct--tool-call-parser granite --chat-template examples/tool_chat_template_granite.jinjaexamples/tool_chat_template_granite.jinja 为 Hugging Face 原始模板的修改版支持并行函数调用ibm-granite/granite-3.1-8b-instruct--tool-call-parser granite可直接用 Hugging Face 上的聊天模板支持并行函数调用ibm-granite/granite-20b-functioncalling--tool-call-parser granite-20b-fc --chat-template examples/tool_chat_template_granite_20b_fc.jinjaexamples/tool_chat_template_granite_20b_fc.jinja 融合了 Hermes 模板的函数描述元素并遵循其论文Response Generation模式的系统提示支持并行函数调用InternLM 模型internlminternlm/internlm2_5-7b-chat已确认其他 internlm2.5 函数调用模型亦兼容已知问题internlm/internlm2-chat-7b上工具调用结果不稳定推荐标志--tool-call-parser internlm --chat-template examples/tool_chat_template_internlm2_tool.jinjaJamba 模型jamba支持 AI21 Jamba-1.5 系列ai21labs/AI21-Jamba-1.5-Mini、ai21labs/AI21-Jamba-1.5-Large。标志--tool-call-parser jambaxLAM 模型xlamxLAM 解析器专门处理以多种 JSON 风格生成工具调用的模型可检测四种输出样式直接 JSON 数组以[开头]结尾的输出字符串思考标签think.../think标签内含 JSON 数组代码块json ...中的 JSON工具调用标签[TOOL_CALLS]或tool_calls.../tool_calls标签。支持并行函数调用且能有效分离文本内容与工具调用。支持模型Salesforce Llama-xLAMSalesforce/Llama-xLAM-2-8B-fc-r、Salesforce/Llama-xLAM-2-70B-fc-r与 Qwen-xLAMSalesforce/xLAM-1B-fc-r、Salesforce/xLAM-3B-fc-r、Salesforce/Qwen-xLAM-32B-fc-r。标志Llama 基底--tool-call-parser xlam --chat-template examples/tool_chat_template_xlam_llama.jinjaQwen 基底--tool-call-parser xlam --chat-template examples/tool_chat_template_xlam_qwen.jinjaQwen 模型Qwen2.5 的tokenizer_config.json聊天模板已包含 Hermes 风格工具调用支持直接复用hermes解析器即可。支持Qwen/Qwen2.5-*与Qwen/QwQ-32B。标志--tool-call-parser hermesDeepSeek-V3 模型deepseek_v3deepseek-ai/DeepSeek-V3-0324配合 examples/tool_chat_template_deepseekv3.jinjadeepseek-ai/DeepSeek-R1-0528配合 examples/tool_chat_template_deepseekr1.jinja标志--tool-call-parser deepseek_v3 --chat-template {见上}DeepSeek-V3.1 模型deepseek_v31deepseek-ai/DeepSeek-V3.1配合 examples/tool_chat_template_deepseekv31.jinja。标志--tool-call-parser deepseek_v31 --chat-template {见上}OpenAI OSS 模型openaiopenai/gpt-oss-20b、openai/gpt-oss-120b。标志--tool-call-parser openaiKimi-K2 模型kimi_k2moonshotai/Kimi-K2-Instruct。标志--tool-call-parser kimi_k2Hunyuan 模型hunyuan_a13btencent/Hunyuan-A13B-Instruct聊天模板已包含在 Hugging Face 模型文件中。标志非推理--tool-call-parser hunyuan_a13b推理模式追加--reasoning-parser hunyuan_a13bCohere Command A Reasoningcohere_command3CohereLabs/command-a-reasoning-08-2025。标志--tool-call-parser cohere_command3 --reasoning-parser cohere_command3。注意该解析器依赖cohere_melody包vLLM 默认不安装使用前需自行安装。LongCat-Flash-Chat 模型longcatmeituan-longcat/LongCat-Flash-Chat及其 FP8 版本。标志--tool-call-parser longcatGLM-4.5 / GLM-4.7 模型GLM-4.5zai-org/GLM-4.5、zai-org/GLM-4.5-Air、zai-org/GLM-4.6--tool-call-parser glm45GLM-4.7zai-org/GLM-4.7、zai-org/GLM-4.7-Flash--tool-call-parser glm47从源码注册表看两个解析器名实际映射到同一个类Glm47MoeModelToolParser见 vllm/tool_parsers/init.py#L57-L64说明 vLLM 已将 GLM 4.5/4.7 的工具调用处理统一到同一个 MoE 工具解析器实现中。FunctionGemma 模型functiongemmaGoogle FunctionGemma 是 2.7 亿参数的轻量函数调用专用模型基于 Gemma 3面向笔记本、手机等边缘设备部署支持google/functiongemma-270m-it。它使用独特的输出格式start_function_callcall:get_weather{location:escapeLondonescape}end_function_call官方建议针对具体函数调用任务微调以获得最佳效果。标志--tool-call-parser functiongemma --chat-template examples/tool_chat_template_functiongemma.jinjaQwen3-Coder 模型qwen3_xmlQwen/Qwen3-Coder-480B-A35B-Instruct、Qwen/Qwen3-Coder-30B-A3B-Instruct。标志--tool-call-parser qwen3_xmlOlmo 3 模型olmo3Olmo 3 的工具调用输出与pythonic解析器期望的格式高度相似但有差异每次工具调用仍是 pythonic 字符串但并行调用以换行分隔并包裹在function_calls../function_callsXML 标签内此外解析器额外接受 JSON 布尔与空值字面量true、false、null以及 pythonic 的True、False、None。支持allenai/Olmo-3-7B-Instruct、allenai/Olmo-3-32B-Think。标志--tool-call-parser olmo3GigaChat 3 模型gigachat3聊天模板来自 Hugging Face 模型文件。支持ai-sage/GigaChat3-702B-A36B-preview含-bf16变体与ai-sage/GigaChat3-10B-A1.8B含-bf16变体。标志--tool-call-parser gigachat3Apertus 模型apertusswiss-ai/Apertus-8B-Instruct-2509、swiss-ai/Apertus-70B-Instruct-2509。需使用 examples 目录的聊天模板修复了若干 OpenAI 兼容性问题--tool-call-parser apertus --chat-template examples/tool_chat_template_apertus.jinjaPythonic 工具调用模型pythonic越来越多模型直接输出 python 列表而非 JSON来表示工具调用天然支持并行工具调用且消除了 JSON schema 歧义。例如查询旧金山与西雅图天气时模型可能生成[get_weather(citySan Francisco, metriccelsius), get_weather(citySeattle, metriccelsius)]限制模型不能在同一次生成中同时输出文本和工具调用。对特定模型这也许不难改变但社区对工具调用起止应发射哪些 token 尚无共识Llama 3.2 尤其不发射任何此类 tokenLlama 小模型使用工具的能力较弱。示例支持模型⚠️ 表示小模型经常无法以正确格式发出工具调用结果因模型而异meta-llama/Llama-3.2-1B-Instruct⚠️配 examples/tool_chat_template_llama3.2_pythonic.jinjameta-llama/Llama-3.2-3B-Instruct⚠️同上Team-ACE/ToolACE-8B配 examples/tool_chat_template_toolace.jinjafixie-ai/ultravox-v0_4-ToolACE-8B配 examples/tool_chat_template_toolace.jinjameta-llama/Llama-4-Scout-17B-16E-Instruct⚠️配 examples/tool_chat_template_llama4_pythonic.jinjameta-llama/Llama-4-Maverick-17B-128E-Instruct⚠️配 examples/tool_chat_template_llama4_pythonic.jinja标志--tool-call-parser pythonic --chat-template {见上}工具调用性能基准测试要度量真实工具调用流量下的服务延迟与吞吐可使用 BFCLBerkeley Function Calling Leaderboard数据集配合vllm bench serve。完整的服务端 客户端命令见 docs/benchmarking/cli.md 中的 BFCL 基准小节。编写工具解析器插件如果目标模型不在上表支持范围内官方鼓励社区贡献解析器与工具调用聊天模板。工具解析器插件是一个包含一个或多个ToolParser实现的 Python 文件可参考 vllm/tool_parsers/hermes_tool_parser.py 中的Hermes2ProToolParser编写。插件文件结构如下# import the required packages # define a tool parser and register it to vllm # the name list in register_module can be used # in --tool-call-parser. you can define as many # tool parsers as you want here. class ExampleToolParser(ToolParser): def __init__(self, tokenizer: TokenizerLike): super().__init__(tokenizer) # adjust request. e.g.: set skip special tokens # to False for tool call output. def adjust_request(self, request: ChatCompletionRequest | ResponsesRequest) - ChatCompletionRequest | ResponsesRequest: return request # implement the tool call parse for stream call def extract_tool_calls_streaming( self, previous_text: str, current_text: str, delta_text: str, previous_token_ids: Sequence[int], current_token_ids: Sequence[int], delta_token_ids: Sequence[int], request: ChatCompletionRequest, ) - DeltaMessage | None: return delta # implement the tool parse for non-stream call def extract_tool_calls( self, model_output: str, request: ChatCompletionRequest, ) - ExtractedToolCallInformation: return ExtractedToolCallInformation(tools_calledFalse, tool_calls[], contenttext) # register the tool parser to ToolParserManager ToolParserManager.register_lazy_module( nameexample, module_pathvllm.tool_parsers.example, class_nameExampleToolParser, )然后即可在命令行中加载该插件vllm serve model \ --enable-auto-tool-choice \ --tool-parser-plugin absolute path of the plugin file \ --tool-call-parser example \ --chat-template your chat template插件机制源码剖析结合仓库源码可以理解这套插件机制的三个关键点必须实现的两个解析入口extract_tool_calls处理非流式响应拿到完整模型输出后一次性解析extract_tool_calls_streaming处理流式响应增量解析需要状态——当前 token/差异及已解析内容因此基类构造函数维护了prev_tool_call_arr、current_tool_id、streamed_args_for_tool等流式状态见 abstract_tool_parser.py#L72-L81。可选覆写的adjust_request用于调整请求例如把工具调用输出的skip special tokens设为False。注意基类默认实现还会做一件重要的事当tool_choice为命名函数或required时自动从tools提取 JSON schema 写入request.structured_outputsabstract_tool_parser.py#L118-L165这正是命名函数/required 模式保证可解析的底层机制。惰性注册ToolParserManagerabstract_tool_parser.py#L222-L262同时支持即时注册register_module可作装饰器与惰性注册register_lazy_module仅记录name - (module_path, class_name)首次通过get_tool_parser访问时才 import 并缓存。vLLM 内置的 40 余个解析器hermes、llama3_json、pythonic、glm45、kimi_k2等全部走惰性注册插件加载则由import_tool_parser方法调用import_plugin完成用户文件的导入。小结tool_choice的四种取值对应两套不同机制命名函数与required走结构化输出后端schema 强约束首次有 FSM 编译延迟auto依赖解析器从模型自由生成文本中提取工具调用仅当strict: true与VLLM_ENFORCE_STRICT_TOOL_CALLING默认开同时满足才附加结构化标签约束none完全关闭工具调用需要时可加--exclude-tools-when-tool-choice-none排除 prompt 中的工具定义启用auto必须成对提供--enable-auto-tool-choice与--tool-call-parser聊天模板按模型族选择对应模板本仓库 examples/ 目录提供了 Mistral、Llama、Granite、DeepSeek、xLAM 等全部官方模板文件支持模型不在清单中时通过--tool-parser-plugin注册自定义ToolParser子类即可扩展惰性注册机制保证插件不影响启动性能性能评估可用 BFCL 数据集配合vllm bench serve方法见 docs/benchmarking/cli.md。【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价