Skip to content

Tool Calling 函数调用

什么是 Tool Calling

Tool Calling(函数调用)允许模型识别何时需要使用外部工具或函数,并生成符合工具 schema 的输出。通过函数调用,可以让模型与外部系统、API、数据库等进行交互。

工作原理

┌─────────────────────────────────────────────────────────────────┐
│                      Tool Calling 流程                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  用户请求 ──┐                                                    │
│             ▼                                                    │
│      ┌──────────────┐                                           │
│      │    LLM       │                                           │
│      │ 识别需要工具  │                                           │
│      └──────┬───────┘                                           │
│             │                                                    │
│             ▼                                                    │
│      ┌──────────────┐                                           │
│      │  返回函数调用 │ ← {name: "get_weather", args: {city: "北京"}} │
│      │   请求       │                                           │
│      └──────┬───────┘                                           │
│             │                                                    │
│             ▼                                                    │
│      ┌──────────────┐                                           │
│      │ 执行外部函数  │ ← 调用天气 API                            │
│      └──────┬───────┘                                           │
│             │                                                    │
│             ▼                                                    │
│      ┌──────────────┐                                           │
│      │ 返回结果给 LLM│ ← "北京今天晴,温度 25°C"                │
│      └──────┬───────┘                                           │
│             │                                                    │
│             ▼                                                    │
│      ┌──────────────┐                                           │
│      │  最终回复用户  │                                           │
│      └──────────────┘                                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

定义工具

工具 schema 示例

json
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "获取指定城市的天气信息",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "城市名称,如:北京、上海"
            },
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "description": "温度单位,默认为 celsius"
            }
          },
          "required": ["city"]
        }
      }
    }
  ]
}

完整调用示例

Python 示例

python
from openai import OpenAI

client = OpenAI(
    base_url="https://ai-tokenhub.com/v1",
    api_key="your_api_key"
)

# 定义工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"}
                },
                "required": ["city"]
            }
        }
    }
]

# 发送请求
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "北京今天天气怎么样?"}
    ],
    tools=tools,
    tool_choice="auto"
)

# 处理工具调用
tool_calls = response.choices[0].message.tool_calls
if tool_calls:
    for call in tool_calls:
        function_name = call.function.name
        arguments = json.loads(call.function.arguments)
        print(f"调用函数: {function_name}")
        print(f"参数: {arguments}")

        # 执行函数并获取结果
        if function_name == "get_weather":
            result = get_weather(arguments["city"])

        # 将结果返回给模型
        result_response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "user", "content": "北京今天天气怎么样?"},
                {"role": "assistant", "content": None, "tool_calls": tool_calls},
                {
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": json.dumps(result)
                }
            ]
        )
        print(result_response.choices[0].message.content)

常用工具场景

1. 天气查询

python
def get_weather(city: str, unit: str = "celsius"):
    """获取天气信息"""
    return {
        "city": city,
        "weather": "晴天",
        "temperature": 25,
        "unit": unit
    }

2. 搜索功能

python
def web_search(query: str, limit: int = 5):
    """网络搜索"""
    results = search_api(query, limit)
    return {
        "query": query,
        "results": results
    }

3. 数据库查询

python
def query_database(sql: str):
    """执行 SQL 查询"""
    result = db.execute(sql)
    return {
        "columns": result.columns,
        "rows": result.data
    }

4. 发送邮件

python
def send_email(to: str, subject: str, body: str):
    """发送邮件"""
    mail.send(to=to, subject=subject, body=body)
    return {"status": "sent", "message_id": "xxx"}

工具调用参数

tool_choice 参数

说明
auto模型自动决定是否调用工具
none禁止调用工具,直接生成文本
{"type": "function", "function": {"name": "get_weather"}}强制调用指定工具

parallel_tool_calls 参数

控制是否允许并行调用多个工具:

python
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "查一下北京和上海的天气"}],
    tools=tools,
    parallel_tool_calls=True  # 允许并行调用
)

最佳实践

1. 清晰的工具描述

json
{
  "name": "calculate",
  "description": "使用 Python 计算器进行数学运算,支持加减乘除、指数、开方等。输入应为标准的数学表达式,如 '2+2'、'sqrt(16)'、'10**2'"
}

2. 严格的参数校验

json
{
  "parameters": {
    "type": "object",
    "properties": {
      "date": {
        "type": "string",
        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        "description": "日期格式:YYYY-MM-DD"
      }
    }
  }
}

3. 错误处理

python
try:
    result = execute_tool(function_name, arguments)
except ToolExecutionError as e:
    return {"error": str(e), "fallback": "无法执行该操作,请稍后重试"}

常见问题

Q: 模型不调用工具?

可能原因:

  • 提示词不够明确
  • 工具描述不清晰
  • 设置了 tool_choice="none"

Q: 如何强制使用工具?

python
tool_choice = {"type": "function", "function": {"name": "get_weather"}}

Q: 工具调用超时怎么办?

设置超时机制:

python
import signal

def timeout_handler(signum, frame):
    raise TimeoutError("工具执行超时")

signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(30)  # 30秒超时

try:
    result = execute_tool(...)
finally:
    signal.alarm(0)