首页
/ Transformers 聊天模型的 Tool Use 完全指南:从 Python 函数到 JSON Schema 的工具调用实现原理

Transformers 聊天模型的 Tool Use 完全指南:从 Python 函数到 JSON Schema 的工具调用实现原理

2026-09-06 12:49:48作者:卓炯娓

本文以 Transformers 官方的 Tool use(工具调用)文档 docs/source/en/chat_extras.md 为主体,系统讲解聊天模型的函数调用(function-calling)能力:如何定义工具、如何把工具传入 apply_chat_template、如何处理模型的 tool call 请求,以及底层 get_json_schema 的 schema 生成机制。读完本文,你将能够独立搭建一个带工具调用回环(tool loop)的本地聊天应用,并理解 Transformers 是如何把你的 Python 函数自动转成 JSON schema 的。

一、什么是 Tool Use

聊天模型(chat model)通常都在"function-calling"或"tool-use"场景上做过训练。所谓 Tool,就是由用户(开发者)提供的函数,模型可以在生成回复的过程中选择性地"调用"它。例如:给模型一个计算器工具,它就可以完成算术运算而不必在内部硬算;给一个天气查询工具,它就能获取实时温度。

官方文档将工具使用流程归纳为三个环节,也是本文的结构主线:

  1. 定义工具——用带类型注解和 Google 风格 docstring 的 Python 函数,或手写 JSON schema;
  2. 传入工具——通过 apply_chat_templatetools 参数交给模型;
  3. 处理工具调用——模型只"请求"调用,真正执行工具、把结果写回对话历史的是你的代码。

二、定义并传入工具(Passing tools)

当模型支持 tool-use 时,把函数传给 PreTrainedTokenizerBase.apply_chat_templatetools 参数即可。工具有两种传法:

  • JSON schema(dict 形式);
  • Python 函数:解析器会自动解析函数的参数名、参数类型和 docstring,生成 JSON schema。

2.1 函数式工具的标准写法

虽然直接传 Python 函数非常方便,但解析器只能处理 Google 风格 的 docstring(这一点在仓库中可证实:get_json_schema 内部用一组正则匹配 Args: / Returns: 块,见 chat_template_utils.py#L55-L69)。官方文档给出的两个工具示例如下,可直接复制使用:

def get_current_temperature(location: str, unit: str):
    """
    Get the current temperature at a location.

    Args:
        location: The location to get the temperature for, in the format "City, Country"
        unit: The unit to return the temperature in. (choices: ["celsius", "fahrenheit"])
    """
    return 22.  # A real function should probably actually get the temperature!

def get_current_wind_speed(location: str):
    """
    Get the current wind speed in km/h at a given location.

    Args:
        location: The location to get the wind speed for, in the format "City, Country"
    """
    return 6.  # A real function should probably actually get the wind speed!

tools = [get_current_temperature, get_current_wind_speed]

对函数格式的几条关键要求(均由 get_json_schema 的实现印证):

要求 说明
必须有 docstring 缺少 docstring 会直接抛出 DocstringParsingExceptionchat_template_utils.py#L357-L358
每个参数必须在 docstring 的 Args: 块中有描述 缺失参数描述会抛出 DocstringParsingExceptionchat_template_utils.py#L366-L370
每个参数必须有类型注解 缺少类型注解会抛出 TypeHintParsingExceptionchat_template_utils.py#L195-L196
Returns: 块和返回类型是可选的 可以添加,但多数模型的 chat template 根本不使用这些信息
函数体代码被完全忽略 解析器只看签名和 docstring,不看实际实现

docstring 中还有一个隐藏特性:参数描述行尾的 (choices: [...]) 会被解析成 schema 里的 enum 字段。文档示例中的 unit: ... (choices: ["celsius", "fahrenheit"]) 就是典型用法,对应实现位于 chat_template_utils.py#L372-L375

真正决定模型"是否调用该工具、如何填充参数"的"签名"是:函数名、参数名、参数类型、以及描述函数与参数用途的 docstring

三、完整工具调用示例(Tool-calling Example)

3.1 加载支持 tool-use 的模型

文档推荐加载如 NousResearch/Hermes-2-Pro-Llama-3-8B 这类支持工具调用的 checkpoint;如果硬件允许,也可以考虑 Command-R、Mixtral-8x22B 等大一些、工具调用能力更强的模型。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

checkpoint = "NousResearch/Hermes-2-Pro-Llama-3-8B"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint, dtype="auto", device_map="auto")

3.2 构造对话历史

messages = [
  {"role": "system", "content": "You are a bot that responds to weather queries. You should reply with the unit used in the queried location."},
  {"role": "user", "content": "Hey, what's the temperature in Paris right now?"}
]

注意 system 消息中的提示"回复时使用查询地点所在国家常用的温度单位"——这是让模型自己推断出 celsius 的关键上下文。

3.3 传入 tools 并生成响应

messages 和工具列表一起传给 apply_chat_template,然后 tokenize 并生成:

inputs = tokenizer.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_dict=True, return_tensors="pt")
outputs = model.generate(**inputs.to(model.device), max_new_tokens=128)
print(tokenizer.decode(outputs[0][len(inputs["input_ids"][0]):]))

模型的实际输出:

登录后查看全文
热门项目推荐
相关项目推荐