工具呼叫¶
vLLM 目前支援指定函式呼叫,以及聊天補全 API 中 tool_choice
欄位的 auto
、required
(自 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 首次編譯並快取以供後續請求使用之前,會有幾秒(或更長)的延遲。
請記住,呼叫者有責任:
- 在請求中定義適當的工具
- 在聊天訊息中包含相關上下文
- 在應用程式邏輯中處理工具呼叫
有關更高階的用法,包括並行工具呼叫和不同模型特定的解析器,請參閱以下部分。
指定函式呼叫¶
vLLM 預設支援聊天補全 API 中的指定函式呼叫。它透過引導式解碼使用 Outlines 實現此功能,因此預設啟用,並且適用於任何受支援的模型。你可以保證得到一個可有效解析的函式呼叫——而非一個高質量的函式呼叫。
vLLM 將使用引導式解碼來確保響應與 tools
引數中 JSON schema 定義的工具引數物件匹配。為了獲得最佳結果,我們建議確保在提示中指定預期的輸出格式/schema,以確保模型的預期生成與引導式解碼後端強制生成的 schema 對齊。
要使用指定函式,你需要在聊天補全請求的 tools
引數中定義函式,並在聊天補全請求的 tool_choice
引數中指定其中一個工具的 name
。
強制函式呼叫¶
vLLM 支援聊天補全 API 中的 tool_choice='required'
選項。與指定函式呼叫類似,它也使用引導式解碼,因此預設啟用並適用於任何受支援的模型。tool_choice='required'
的引導式解碼功能(例如帶有 anyOf
的 JSON schema)目前僅在 V0 引擎中與引導式解碼後端 outlines
一起支援。但是,對替代解碼後端的支援已列入 V1 引擎的路線圖。
當設定 tool_choice='required'
時,模型保證根據 tools
引數中指定的工具列表生成一個或多個工具呼叫。工具呼叫的數量取決於使用者的查詢。輸出格式嚴格遵循 tools
引數中定義的 schema。
無函式呼叫¶
vLLM 支援聊天補全 API 中的 tool_choice='none'
選項。當設定此選項時,即使請求中定義了工具,模型也不會生成任何工具呼叫,而只會響應常規文字內容。
注意
當請求中指定了工具時,vLLM 預設會在提示中包含工具定義,無論 tool_choice
設定如何。要在 tool_choice='none'
時排除工具定義,請使用 --exclude-tools-when-tool-choice-none
選項。
自動函式呼叫¶
要啟用此功能,你應該設定以下標誌:
--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
中找到一個示例,請參閱此處。
如果你喜歡的工具呼叫模型不受支援,請隨時貢獻一個解析器和工具使用聊天模板!
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 函式呼叫模型也相容。
已知問題:
- Mistral 7B 難以正確生成並行工具呼叫。
-
Mistral 的
tokenizer_config.json
聊天模板要求工具呼叫 ID 恰好為 9 位數字,這比 vLLM 生成的短得多。由於不滿足此條件時會丟擲異常,因此提供了以下附加聊天模板:- examples/tool_chat_template_mistral.jinja - 這是“官方”Mistral 聊天模板,但經過調整,使其與 vLLM 的工具呼叫 ID 相容(前提是
tool_call_id
欄位被截斷為最後 9 位數字) - examples/tool_chat_template_mistral_parallel.jinja - 這是一個“更好”的版本,在提供工具時添加了工具使用系統提示,從而在並行工具呼叫方面提高了可靠性。
- examples/tool_chat_template_mistral.jinja - 這是“官方”Mistral 聊天模板,但經過調整,使其與 vLLM 的工具呼叫 ID 相容(前提是
推薦標誌: --tool-call-parser mistral --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 模型引入的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 - 這在 Llama 3.1 聊天模板的基礎上增加了對影像的支援。
推薦標誌: --tool-call-parser llama3_json --chat-template {見上方}
VLLM 還為 Llama 4 提供了 Pythonic 和基於 JSON 的聊天模板,但推薦使用 Pythonic 工具呼叫。
- examples/tool_chat_template_llama4_pythonic.jinja - 這是基於 Llama 4 模型的官方聊天模板。
對於 Llama 4 模型,使用 --tool-call-parser llama4_pythonic --chat-template examples/tool_chat_template_llama4_pythonic.jinja
。
IBM Granite¶
支援的模型:
-
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
可以直接使用 Huggingface 上的聊天模板。支援並行函式呼叫。
-
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 格式生成工具呼叫的模型。它檢測多種不同輸出風格的函式呼叫:
- 直接 JSON 陣列:以
[
開頭和以]
結尾的 JSON 陣列輸出字串 - 思考標籤:使用包含 JSON 陣列的
<think>...</think>
標籤 - 程式碼塊:程式碼塊中的 JSON (
json ...
) - 工具呼叫標籤:使用
[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
)¶
支援的模型:
MiniMaxAi/MiniMax-M1-40k
(配合 examples/tool_chat_template_minimax_m1.jinja使用)MiniMaxAi/MiniMax-M1-80k
(配合 examples/tool_chat_template_minimax_m1.jinja使用)
標誌: --tool-call-parser minimax --chat-template examples/tool_chat_template_minimax_m1.jinja
DeepSeek-V3 模型 (deepseek_v3
)¶
支援的模型:
deepseek-ai/DeepSeek-V3-0324
(配合 examples/tool_chat_template_deepseekv3.jinja使用)deepseek-ai/DeepSeek-R1-0528
(配合 examples/tool_chat_template_deepseekr1.jinja使用)
標誌: --tool-call-parser deepseek_v3 --chat-template {見上方}
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 --enable_reasoning
支援 Pythonic 工具呼叫的模型 (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 的小型模型難以有效使用工具。
示例受支援的模型:
meta-llama/Llama-3.2-1B-Instruct
⚠️ (配合 examples/tool_chat_template_llama3.2_pythonic.jinja使用)meta-llama/Llama-3.2-3B-Instruct
⚠️ (配合 examples/tool_chat_template_llama3.2_pythonic.jinja使用)Team-ACE/ToolACE-8B
(配合 examples/tool_chat_template_toolace.jinja使用)fixie-ai/ultravox-v0_4-ToolACE-8B
(配合 examples/tool_chat_template_toolace.jinja使用)meta-llama/Llama-4-Scout-17B-16E-Instruct
⚠️ (配合 examples/tool_chat_template_llama4_pythonic.jinja使用)meta-llama/Llama-4-Maverick-17B-128E-Instruct
⚠️ (配合 examples/tool_chat_template_llama4_pythonic.jinja使用)
標誌: --tool-call-parser pythonic --chat-template {見上方}
警告
Llama 的小型模型經常無法以正確格式發出工具呼叫。結果可能因模型而異。
如何編寫工具解析器外掛¶
工具解析器外掛是一個 Python 檔案,包含一個或多個 ToolParser 實現。你可以編寫一個類似於 vllm/entrypoints/openai/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.
@ToolParserManager.register_module(["example"])
class ExampleToolParser(ToolParser):
def __init__(self, tokenizer: AnyTokenizer):
super().__init__(tokenizer)
# adjust request. e.g.: set skip special tokens
# to False for tool call output.
def adjust_request(
self, request: ChatCompletionRequest) -> ChatCompletionRequest:
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,
) -> Union[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)
然後你可以在命令列中使用此外掛,如下所示: