跳到内容

工具调用

vLLM 目前支持具名函数调用,以及在 Chat Completion API 的 tool_choice 字段中支持 autorequired(自 vllm>=0.8.3 起)和 none 选项。

快速入门

启动已启用工具调用的服务器。本示例使用 Meta 的 Llama 3.1 8B 模型,因此我们需要使用 vLLM 示例目录中的 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_url="https://:8000/v1", api_key="dummy")

def get_weather(location: str, unit: str):
    return f"Getting 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(
    model=client.models.list().data[0].id,
    messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
    tools=tools,
    tool_choice="auto",
)

tool_call = response.choices[0].message.tool_calls[0].function
print(f"Function called: {tool_call.name}")
print(f"Arguments: {tool_call.arguments}")
print(f"Result: {tool_functions[tool_call.name](**json.loads(tool_call.arguments))}")

示例输出

Function called: get_weather
Arguments: {"location": "San Francisco, CA", "unit": "fahrenheit"}
Result: Getting the weather for San Francisco, CA in fahrenheit...

本示例演示了:

  • 设置已启用工具调用的服务器
  • 定义处理工具调用的具体函数
  • 发送带有 tool_choice="auto" 的请求
  • 处理结构化响应并执行对应的函数

你也可以通过设置 tool_choice={"type": "function", "function": {"name": "get_weather"}} 来指定特定的具名函数调用。请注意,这将使用结构化输出后端,因此首次使用时,由于需要编译有限状态机(FSM)并进行缓存,会有几秒(或更长)的延迟。

请记住,调用者有责任:

  1. 在请求中定义适当的工具
  2. 在聊天消息中包含相关的上下文
  3. 在应用程序逻辑中处理工具调用

有关更高级的用法,包括并行工具调用和不同模型特定的解析器,请参阅下文。

具名函数调用

vLLM 默认支持 Chat Completion API 中的具名函数调用。这应适用于 vLLM 支持的大多数结构化输出后端。你将保证获得一个可解析的函数调用,但不能保证其质量。

vLLM 将利用结构化输出功能,确保响应符合 tools 参数中由 JSON Schema 定义的工具参数对象。为了获得最佳效果,我们建议在 prompt 中明确预期的输出格式/Schema,以确保模型预期的生成内容与结构化输出后端强制生成的 Schema 一致。

要使用具名函数,你需要在 Chat Completion 请求的 tools 参数中定义函数,并在 tool_choice 参数中指定其中一个工具的 name

强制函数调用

vLLM 支持 Chat Completion API 中的 tool_choice='required' 选项。与具名函数调用类似,它也使用结构化输出,因此默认启用,适用于任何支持的模型。然而,对其他解码后端的支持已列入 V1 引擎的路线图

当设置 tool_choice='required' 时,模型保证根据 tools 参数中指定的工具列表生成一个或多个工具调用。工具调用的数量取决于用户的查询。输出格式严格遵循 tools 参数中定义的 Schema。

无函数调用

vLLM 支持 Chat Completion API 中的 tool_choice='none' 选项。当设置此选项时,模型不会生成任何工具调用,只会返回常规文本内容,即使请求中定义了工具。

注意

当请求中指定了工具时,vLLM 默认会在 prompt 中包含工具定义,无论 tool_choice 的设置如何。若要在 tool_choice='none' 时排除工具定义,请使用 --exclude-tools-when-tool-choice-none 选项。

受限解码行为

vLLM 是否在生成过程中强制执行工具参数 Schema,取决于 tool_choice 模式。

tool_choice Schema 受限解码 行为
具名函数 是 (通过结构化输出后端) 保证参数是符合函数参数 Schema 的有效 JSON。
"required" 是 (通过结构化输出后端) 同具名函数。模型必须至少产生一个工具调用。
"auto" 模型自由生成。工具调用解析器从原始文本中提取工具调用。参数可能是格式错误的或不符合 Schema。
"none" 不适用 不产生任何工具调用。

当 Schema 合规性很重要时,优先选择 tool_choice="required" 或具名函数调用,而不是 "auto"

严格模式 (strict 参数)

OpenAI API 在函数定义上支持 strict 字段。当设置为 true 时,OpenAI 使用受限解码来保证工具调用参数符合函数 Schema,即使在 tool_choice="auto" 模式下也是如此。

vLLM 目前**尚未实现** strict 模式。请求中接受 strict 字段(以避免破坏设置该字段的客户端),但它对解码行为没有影响。在 auto 模式下,参数的有效性完全取决于模型的输出质量和解析器的提取逻辑。

跟踪问题:#15526, #16313

自动函数调用

要启用此功能,应设置以下标志:

  • --enable-auto-tool-choice —— **强制**自动工具选择。它告诉 vLLM,你希望启用模型在认为合适时生成自己的工具调用。
  • --tool-call-parser —— 选择要使用的工具解析器(列表如下)。未来将继续添加更多工具解析器。你也可以在 --tool-parser-plugin 中注册你自己的工具解析器。
  • --tool-parser-plugin —— **可选**,用于将用户定义的工具解析器注册到 vllm 的工具解析器插件,注册的工具解析器名称可以在 --tool-call-parser 中指定。
  • --chat-template —— **可选**,用于自动工具选择。它是处理 tool 角色消息和包含先前生成的工具调用的 assistant 角色消息的聊天模板路径。Hermes、Mistral 和 Llama 模型在其 tokenizer_config.json 文件中有工具兼容的聊天模板,但你可以指定自定义模板。如果你的模型在 tokenizer_config.json 中配置了特定的工具使用聊天模板,则此参数可设置为 tool_use。在这种情况下,它将按照 transformers 规范使用。有关更多信息,请参阅 HuggingFace 的 说明;你可以在此处找到 tokenizer_config.json 的示例。

如果你最喜欢的工具调用模型不受支持,请随时贡献解析器和工具使用聊天模板!

注意

tool_choice="auto" 下,工具调用参数由所选解析器从模型的原始文本输出中提取。解码期间不应用 Schema 级限制,因此参数偶尔可能会格式错误或违反函数的参数 Schema。详见受限解码行为

Hermes 模型 (hermes)

支持所有晚于 Hermes 2 Pro 的 Nous Research Hermes 系列模型。

  • NousResearch/Hermes-2-Pro-*
  • NousResearch/Hermes-2-Theta-*
  • NousResearch/Hermes-3-*

请注意,由于 Hermes 2 Theta 模型在创建过程中使用了合并步骤,其工具调用质量和能力已有所下降。.

标志:--tool-call-parser hermes

Mistral 模型 (mistral)

支持的模型:

  • mistralai/Mistral-7B-Instruct-v0.3 (已确认)
  • 其他 Mistral 函数调用模型也兼容。

已知问题:

  1. Mistral 7B 在正确生成并行工具调用方面存在困难。
  2. 仅限 Transformers 分词器后端:Mistral 的 tokenizer_config.json 聊天模板要求工具调用 ID 必须恰好为 9 位数字,这比 vLLM 生成的要短得多。由于不满足此条件会引发异常,因此提供了以下额外的聊天模板:

推荐标志:

  1. 要使用官方 Mistral AI 的格式:

    --tool-call-parser mistral

  2. 在可用时使用 Transformers 格式:

    --tokenizer_mode hf --config_format hf --load_format hf --tool-call-parser mistral --chat-template examples/tool_chat_template_mistral_parallel.jinja

注意

Mistral AI 官方发布的模型有两种可能的格式:

  1. 默认情况下使用 automistral 参数的官方格式:

    --tokenizer_mode mistral --config_format mistral --load_format mistral 此格式使用 Mistral AI 的分词器后端 mistral-common

  2. Transformers 格式(可用时),与 hf 参数一起使用:

    --tokenizer_mode hf --config_format hf --load_format hf --chat-template examples/tool_chat_template_mistral_parallel.jinja

Llama 模型 (llama3_json)

支持的模型:

支持所有 Llama 3.1、3.2 和 4 模型。

  • meta-llama/Llama-3.1-*
  • meta-llama/Llama-3.2-*
  • meta-llama/Llama-4-*

支持的工具调用是 基于 JSON 的工具调用。对于 Llama-3.2 模型引入的 Python 风格工具调用,请参阅下方的 pythonic 工具解析器。对于 Llama 4 模型,建议使用 llama4_pythonic 工具解析器。

不支持内置 Python 工具调用或自定义工具调用等其他工具调用格式。

已知问题:

  1. Llama 3 不支持并行工具调用,但在 Llama 4 模型中已支持。
  2. 模型可能会以错误的格式生成参数,例如将数组序列化为字符串而不是生成一个数组。

VLLM 为 Llama 3.1 和 3.2 提供了两个基于 JSON 的聊天模板:

推荐标志:--tool-call-parser llama3_json --chat-template {见上文}

VLLM 也为 Llama 4 提供了 Python 风格和 JSON 风格的聊天模板,但建议使用 Python 风格的工具调用。

对于 Llama 4 模型,请使用 --tool-call-parser llama4_pythonic --chat-template examples/tool_chat_template_llama4_pythonic.jinja

IBM Granite

支持的模型:

  • ibm-granite/granite-4.0-h-small 和其他 Granite 4.0 模型

    推荐标志:--tool-call-parser granite4

  • ibm-granite/granite-3.0-8b-instruct

    推荐标志:--tool-call-parser granite --chat-template examples/tool_chat_template_granite.jinja

    examples/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.jinja

    examples/tool_chat_template_granite_20b_fc.jinja:这是 Hugging Face 原始模板的修改版,该原始模板与 vLLM 不兼容。它融合了 Hermes 模板中的函数描述元素,并遵循与论文中“响应生成”模式相同的系统提示词。支持并行函数调用。

InternLM 模型 (internlm)

支持的模型:

  • internlm/internlm2_5-7b-chat (已确认)
  • 其他 internlm2.5 函数调用模型也兼容。

已知问题:

  • 虽然此实现也支持 InternLM2,但在测试 internlm/internlm2-chat-7b 模型时,工具调用结果并不稳定。

推荐标志:--tool-call-parser internlm --chat-template examples/tool_chat_template_internlm2_tool.jinja

Jamba 模型 (jamba)

支持 AI21 的 Jamba-1.5 模型。

  • ai21labs/AI21-Jamba-1.5-Mini
  • ai21labs/AI21-Jamba-1.5-Large

标志:--tool-call-parser jamba

xLAM 模型 (xlam)

xLAM 工具解析器旨在支持以各种 JSON 格式生成工具调用的模型。它检测几种不同输出风格的函数调用:

  1. 直接 JSON 数组:以 [ 开头并以 ] 结尾的 JSON 数组输出字符串。
  2. 思考标签:使用包含 JSON 数组的 <think>...</think> 标签。
  3. 代码块:代码块中的 JSON (json ...)。
  4. 工具调用标签:使用 [TOOL_CALLS]<tool_call>...</tool_call> 标签。

支持并行函数调用,且解析器能有效地将文本内容与工具调用分离。

支持的模型:

  • Salesforce Llama-xLAM 模型:Salesforce/Llama-xLAM-2-8B-fc-r, Salesforce/Llama-xLAM-2-70B-fc-r
  • Qwen-xLAM 模型:Salesforce/xLAM-1B-fc-r, Salesforce/xLAM-3B-fc-r, Salesforce/Qwen-xLAM-32B-fc-r

标志:

  • 对于基于 Llama 的 xLAM 模型:--tool-call-parser xlam --chat-template examples/tool_chat_template_xlam_llama.jinja
  • 对于基于 Qwen 的 xLAM 模型:--tool-call-parser xlam --chat-template examples/tool_chat_template_xlam_qwen.jinja

Qwen 模型

对于 Qwen2.5,tokenizer_config.json 中的聊天模板已经包含了对 Hermes 风格工具使用的支持。因此,你可以使用 hermes 解析器为 Qwen 模型启用工具调用。欲了解更多详细信息,请参考官方 Qwen 文档

  • Qwen/Qwen2.5-*
  • Qwen/QwQ-32B

标志:--tool-call-parser hermes

MiniMax 模型 (minimax_m1)

支持的模型:

标志:--tool-call-parser minimax --chat-template examples/tool_chat_template_minimax_m1.jinja

DeepSeek-V3 模型 (deepseek_v3)

支持的模型:

标志:--tool-call-parser deepseek_v3 --chat-template {见上文}

DeepSeek-V3.1 模型 (deepseek_v31)

支持的模型:

标志:--tool-call-parser deepseek_v31 --chat-template {见上文}

OpenAI OSS 模型 ('openai`)

支持的模型:

  • openai/gpt-oss-20b
  • openai/gpt-oss-120b

标志:--tool-call-parser openai

Kimi-K2 模型 (kimi_k2)

支持的模型:

  • moonshotai/Kimi-K2-Instruct

标志:--tool-call-parser kimi_k2

Hunyuan 模型 (hunyuan_a13b)

支持的模型:

  • tencent/Hunyuan-A13B-Instruct (聊天模板已包含在 Hugging Face 模型文件中。)

标志:

  • 非推理模式:--tool-call-parser hunyuan_a13b
  • 推理模式:--tool-call-parser hunyuan_a13b --reasoning-parser hunyuan_a13b

LongCat-Flash-Chat 模型 (longcat)

支持的模型:

  • meituan-longcat/LongCat-Flash-Chat
  • meituan-longcat/LongCat-Flash-Chat-FP8

标志:--tool-call-parser longcat

GLM-4.5 模型 (glm45)

支持的模型:

  • zai-org/GLM-4.5
  • zai-org/GLM-4.5-Air
  • zai-org/GLM-4.6

标志:--tool-call-parser glm45

GLM-4.7 模型 (glm47)

支持的模型:

  • zai-org/GLM-4.7
  • zai-org/GLM-4.7-Flash

标志:--tool-call-parser glm47

FunctionGemma 模型 (functiongemma)

Google 的 FunctionGemma 是一个轻量级(2.7亿参数)模型,专门为函数调用设计。它基于 Gemma 3 构建,并针对笔记本电脑和手机等设备的边缘部署进行了优化。

支持的模型:

  • google/functiongemma-270m-it

FunctionGemma 使用一种独特的输出格式,带有 <start_function_call><end_function_call> 标签。

<start_function_call>call:get_weather{location:<escape>London<escape>}<end_function_call>

该模型旨在针对特定的函数调用任务进行微调以获得最佳结果。

标志:--tool-call-parser functiongemma --chat-template examples/tool_chat_template_functiongemma.jinja

注意

FunctionGemma 旨在针对你的特定函数调用任务进行微调。基础模型提供通用的函数调用能力,但通过特定任务的微调可获得最佳效果。有关微调指南,请参阅 Google 的 FunctionGemma 文档

Qwen3-Coder 模型 (qwen3_xml)

支持的模型:

  • Qwen/Qwen3-Coder-480B-A35B-Instruct
  • Qwen/Qwen3-Coder-30B-A3B-Instruct

标志:--tool-call-parser qwen3_xml

Olmo 3 模型 (olmo3)

Olmo 3 模型输出的工具调用格式与 pythonic 解析器(见下文)预期的非常相似,只有少量差异。每个工具调用都是一个 Python 风格的字符串,但并行工具调用以换行符分隔,并且调用被包裹在 XML 标签 <function_calls>..</function_calls> 中。此外,解析器除了允许 Python 风格的字面量(True, False, 和 None)外,还允许 JSON 布尔值和 null 字面量(true, false, 和 null)。

支持的模型:

  • allenai/Olmo-3-7B-Instruct
  • allenai/Olmo-3-32B-Think

标志:--tool-call-parser olmo3

Gigachat 3 模型 (gigachat3)

使用 Hugging Face 模型文件中的聊天模板。

支持的模型:

  • ai-sage/GigaChat3-702B-A36B-preview
  • ai-sage/GigaChat3-702B-A36B-preview-bf16
  • ai-sage/GigaChat3-10B-A1.8B
  • ai-sage/GigaChat3-10B-A1.8B-bf16

标志:--tool-call-parser gigachat3

支持 Python 风格工具调用的模型 (pythonic)

越来越多的模型输出一个 Python 列表来表示工具调用,而不是使用 JSON。这具有固有支持并行工具调用以及消除围绕工具调用所需 JSON Schema 的歧义的优势。pythonic 工具解析器可以支持此类模型。

作为一个具体的例子,这些模型可以通过生成以下内容来查询旧金山和西雅图的天气:

[get_weather(city='San Francisco', metric='celsius'), get_weather(city='Seattle', metric='celsius')]

限制

  • 模型不得在同一次生成中既生成文本又生成工具调用。对于特定模型而言,更改这一点可能并不困难,但社区目前对于开始和结束工具调用时应发出哪些 token 尚未达成共识。(特别是 Llama 3.2 模型不发出此类 token。)
  • Llama 的较小模型在有效使用工具方面存在困难。

示例支持的模型:

标志:--tool-call-parser pythonic --chat-template {见上文}

警告

Llama 的较小模型经常无法以正确的格式发出工具调用。结果可能因模型而异。

如何编写工具解析器插件

工具解析器插件是一个包含一个或多个 ToolParser 实现的 Python 文件。你可以编写类似于 vllm/tool_parsers/hermes_tool_parser.pyHermes2ProToolParser 的 ToolParser。

以下是插件文件的摘要:

代码
# 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_called=False,
                                            tool_calls=[],
                                            content=text)
# register the tool parser to ToolParserManager
ToolParserManager.register_lazy_module(
    name="example",
    module_path="vllm.tool_parsers.example",
    class_name="ExampleToolParser",
)

然后,你可以像这样在命令行中使用此插件:

    --enable-auto-tool-choice \
    --tool-parser-plugin <absolute path of the plugin file>
    --tool-call-parser example \
    --chat-template <your chat template> \