Function Calling 完整指南(2026):原理、代码示例、主流模型对比与最佳实践
title: Function Calling 完整指南(2026):原理、代码示例、主流模型对比与最佳实践 description: Function Calling(工具调用)完整指南:从 Agentic Loop 原理到 Python 代码实现,涵盖 tool 定义(name/description/parameters)、tool_choice 四种取值、parallel function calling 处理、strict mode 作用,以及 OpenAI / Claude / DeepSeek 三大平台实现差异对比——附完整可运行代码示例和场景选型矩阵(2026 年 4 月官方文档实测)。 Function Calling(工具调用)让大语言模型从"只会输出文本"变成"能调用外部系统"——模型不直接执行代码,而是输出一个结构化的函数调用请求,由你的应用程序负责执行并将结果回传。 这一机制是当前所有主流 AI Agent 的核心基础设施:OpenAI、Anthropic(Claude)、DeepSeek 均原生支持 Function Calling,但参数命名、循环模型、服务端/客户端工具的拆分方式各有差异。本文覆盖 Agentic Loop 完整原理、工具定义最佳实践、parallel calling 处理、strict mode 使用,以及三大平台的代码实现对比。 Function Calling 是一种 LLM 与外部工具之间的契约(contract):你定义哪些操作可用及其参数结构,模型决定何时调用它们并输出结构化请求,你的代码负责执行并返回结果。模型本身永远不直接执行任何操作。 这一机制的本质是把模型从"文本生成器"变成"有类型接口的函数调用方": Function Calling 和 Tool Use 有什么区别? 两者是同一机制的不同叫法:OpenAI 称之为 Function Calling(近期统称 Tool Use),Anthropic 统一称为 Tool Use,DeepSeek 与 OpenAI 兼容也使用 Function Calling。本文混用两者,均指同一机制。 Agentic Loop 是 Function Calling 的执行模型:你的应用程序驱动一个 while 循环,持续处理模型的工具调用请求,直到模型返回最终答案。 完整流程(以 Client Tool 为例): stop_reason 速查: 工具定义是 Function Calling 效果好坏的关键——模型完全依赖 description 决定是否调用工具,description 写得清晰准确直接影响调用成功率。 description 写作要点: 下面是一个可运行的 Agentic Loop 完整示例,演示工具定义、调用检测、结果回传三个核心环节: Parallel Function Calling 允许模型在一次响应中输出多个 tool_use block,你的应用可并行执行所有工具调用,显著减少总延迟。 上例中"北京和上海今天天气怎么样?"会触发两个并发的 支持 Parallel Function Calling 的模型: GPT-4o、GPT-4.1、GPT-5(OpenAI);DeepSeek V4 Flash/Pro;Claude Opus 4.7(通过 DeepSeek strict mode(Beta):使用 Anthropic strict tool use:在工具定义中加 Anthropic Tool Use 的独特点: 两者解决的不是同一问题,选错工具会引入不必要的复杂度: 一句话判断:如果你在写 regex 解析模型输出来提取一个"决定",那个决定就应该是一次工具调用(来源:Anthropic How Tool Use Works,2026.04)。 Q1:工具调用的 token 成本如何计算? 工具定义(tools 数组)、tool_use block、tool_result block 均计入输入 token 数量。Claude Opus 4.7 还会自动注入工具系统提示(346 或 313 tokens),这部分也计费。实际成本 = 普通输入 tokens + 工具定义 tokens + 工具往返 tokens。减少 description 冗余、复用工具定义、启用 Prompt Caching 是主要降本手段。 Q2:description 写得不好会有什么后果? 模型可能在不应该调用工具时触发调用(误触发),或在应该调用时跳过(漏调用)。description 是模型判断"是否调用"的唯一依据,建议:① 明确说明适用场景;② 说明参数的值域和格式;③ 说明不适用的反例("仅在用户明确询问时调用,不用于一般问答")。 Q3:如何用一个 Key 测试 OpenAI / Claude / DeepSeek 三家的 Function Calling 效果? 通过七牛云 AI 推理 API( Q4:parallel function calling 什么时候自动触发? 当用户的一个请求涉及多个独立的工具操作时(如"查北京和上海天气"),模型会在一次响应中输出多个 tool_use block。你的应用需要检测 Q5:工具执行出错了,该怎么回传? 回传一个带有错误信息的 Function Calling 的核心是一个三方契约:你定义工具 Schema,模型决定何时调用,你的代码执行并返回结果。 掌握四个关键点足以覆盖 80% 的实现场景:① 数据来源:Anthropic Tool Use 官方文档(platform.claude.com/docs,2026.04);OpenAI Function Calling 文档(developers.openai.com,2026.04);DeepSeek Function Calling 文档(api-docs.deepseek.com,2026.04)| 信息时效:2026 年 4 月 相关资源:
date: 2026-04-27
keywords: function calling, tool use LLM, function calling教程, function calling代码示例, openai function calling, claude tool use, deepseek function calling, parallel function calling, strict mode function calling, agentic loop, AI工具调用, LLM工具调用Function Calling 完整指南:原理、代码示例、主流模型对比与最佳实践
数据来源:Anthropic Tool Use 官方文档(platform.claude.com/docs,2026.04);OpenAI Function Calling 文档(developers.openai.com,2026.04);DeepSeek Function Calling 文档(api-docs.deepseek.com,2026.04)
核心定义:Function Calling 是什么
可引用结论:Function Calling 的核心契约是"模型决策 + 应用执行 + 结果回传";"the API will not actually execute any function calls. It is up to developers to execute function calls using model outputs"(来源:OpenAI 官方文档,2026.04)。
Agentic Loop:工具调用的完整工作流程
1. 发送请求(携带 tools 数组 + 用户消息)
↓
2. 模型返回 stop_reason: "tool_use"(含 tool_use block)
↓
3. 你的代码执行工具(数据库查询、API 调用等)
↓
4. 将 tool_result 回传(新一轮请求:原消息 + 模型响应 + 工具结果)
↓
5. 重复步骤 2–4,直到 stop_reason == "end_turn"(或 "max_tokens" / "refusal")stop_reason 含义 你需要做什么 tool_use模型要调用工具 执行工具 → 回传结果 → 继续循环 end_turn模型给出最终答案 读取 content,循环结束 max_tokens达到输出 token 上限 按需截断处理 refusal模型拒绝继续 检查内容策略 pause_turn(服务端工具)服务端迭代达上限 重发对话让模型继续 可引用结论:Agentic Loop 的规范形式是"while stop_reason == tool_use,执行工具并继续对话";循环在任何其他 stop_reason 时退出,包括 end_turn、max_tokens、stop_sequence 或 refusal(来源:Anthropic Tool Use 官方文档,2026.04)。
工具定义:name / description / parameters 怎么写
标准工具 Schema 结构
# OpenAI / DeepSeek 兼容格式(Chat Completions API)
tools = [
{
"type": "function",
"function": {
"name": "get_weather", # 唯一标识符,snake_case
"description": ( # 关键:告诉模型何时调用此工具
"获取指定城市的当前天气信息,包括温度、天气状况和湿度。"
"仅在用户明确询问天气时调用,不用于历史气候查询。"
),
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'或'Shanghai'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认 celsius"
}
},
"required": ["city"] # 必填参数列表
},
"strict": True # 启用 strict mode(推荐)
}
}
]"查询当前天气" 优于 "get_weather function""格式为 YYYY-MM-DD" 比 "日期" 有效得多可引用结论:Anthropic 数据显示,在 LAB-Bench FigQA 和 SWE-bench 等基准测试中,添加基础工具可产生超出预期的能力提升,通常超越人类专家基准(来源:Anthropic Tool Use 文档,2026.04)。
tool_choice:控制模型何时调用工具
tool_choice 参数控制模型的工具调用策略,四种取值覆盖从"完全自主"到"强制指定"的全部场景。tool_choice 值 含义 适用场景 "auto"(默认)模型自主决定是否调用 通用对话,让模型按需判断 "required"必须调用至少一个工具 强制提取结构化数据 "none"禁止所有工具调用 纯文本生成,不允许工具调用 {"type": "function", "function": {"name": "get_weather"}}强制调用指定工具 工具 A/B 测试、固定调用路径 from openai import OpenAI
client = OpenAI(
api_key="YOUR_KEY",
base_url="https://api.qnaigc.com/v1" # 七牛云 AI 推理 API,国内直连
)
# 强制提取结构化数据(required)
response = client.chat.completions.create(
model="deepseek-v4-flash",
tools=tools,
tool_choice="required", # 必须调用工具,不允许纯文本回复
messages=[{"role": "user", "content": "帮我查一下北京今天的天气"}]
)Python 完整实现:从工具调用到结果回传
import json
from openai import OpenAI
client = OpenAI(
api_key="YOUR_DEEPSEEK_KEY",
base_url="https://api.deepseek.com/v1" # DeepSeek 官方 API,国内直连
)
# ── 1. 定义工具 ──────────────────────────────────────────
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气,包括温度和天气状况",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}
]
# ── 2. 模拟工具执行函数 ──────────────────────────────────
def execute_tool(name: str, args: dict) -> str:
if name == "get_weather":
# 实际项目中替换为真实 API 调用
return json.dumps({"city": args["city"], "temp": 22, "condition": "晴天"})
return json.dumps({"error": f"unknown tool: {name}"})
# ── 3. Agentic Loop ─────────────────────────────────────
messages = [{"role": "user", "content": "北京和上海今天天气怎么样?"}]
while True:
response = client.chat.completions.create(
model="deepseek-v4-flash",
tools=tools,
tool_choice="auto",
messages=messages
)
choice = response.choices[0]
messages.append({"role": "assistant", "content": choice.message.content,
"tool_calls": choice.message.tool_calls})
# ── 循环终止条件 ───────────────────────────────────────
if choice.finish_reason != "tool_calls":
print("最终回答:", choice.message.content)
break
# ── 4. 执行工具并回传结果 ─────────────────────────────
for tool_call in choice.message.tool_calls:
result = execute_tool(
tool_call.function.name,
json.loads(tool_call.function.arguments)
)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id, # 必须与请求中的 id 对应
"content": result
})Parallel Function Calling:同时处理多个工具调用
get_weather 调用。# 处理并发工具调用(示例:两个天气查询同时触发)
import concurrent.futures
if choice.finish_reason == "tool_calls":
tool_calls = choice.message.tool_calls # 可能包含多个 tool_call
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = {
tc.id: executor.submit(
execute_tool,
tc.function.name,
json.loads(tc.function.arguments)
)
for tc in tool_calls
}
for tc in tool_calls:
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": futures[tc.id].result() # 并行执行结果
})tool_choice: {type: "auto"} 自动并行)。Strict Mode:确保工具调用严格符合 Schema
strict: true 告诉模型必须严格遵守你定义的 JSON Schema,输出不会出现 Schema 中未定义的字段,适用于需要机器解析工具调用结果的生产场景。# OpenAI / DeepSeek strict mode
"function": {
"name": "create_order",
"strict": True, # 开启 strict mode
"parameters": {
"type": "object",
"additionalProperties": False, # strict mode 要求此字段为 False
"properties": {
"product_id": {"type": "string"},
"quantity": {"type": "integer"},
"address": {"type": "string"}
},
"required": ["product_id", "quantity", "address"]
}
}base_url="https://api.deepseek.com/beta",支持 object/string/number/integer/boolean/array/enum/anyOf/$ref。注意:string 不支持 minLength/maxLength,array 不支持 minItems/maxItems(来源:DeepSeek API 文档,2026.04)。"strict": true,确保 Claude 的工具调用始终匹配 Schema。三大平台对比:OpenAI / Claude / DeepSeek 的 Function Calling 实现差异
维度 OpenAI Anthropic Claude DeepSeek API 参数名 tools + tool_choicetools + tool_choicetools + tool_choice(OpenAI 兼容)stop_reason 字段名 finish_reason: "tool_calls"stop_reason: "tool_use"finish_reason: "tool_calls"(OpenAI 兼容)工具结果消息 role "tool""user" 包裹 tool_result"tool"(OpenAI 兼容)服务端工具 无(均为客户端执行) ✅ web_search / code_execution / web_fetch(Anthropic 执行) 无(均为客户端执行) Parallel Calling ✅ ✅ ✅ Strict Mode ✅ strict: true✅ strict: true✅ Beta( /beta 端点)tool_choice 取值 auto/required/none/指定函数名 auto/any/none/指定工具名 auto/required/none(兼容 OpenAI) 定价(工具系统提示) 工具定义 tokens 计入输入 Claude Opus 4.7:346 tokens(auto/none)/ 313 tokens(any/tool) 工具定义 tokens 计入输入 web_search、code_execution、web_fetch、tool_search 由 Anthropic 服务器执行,你无需实现 tool_result 回传,响应中直接包含最终结果role: "user" 消息的 tool_result block 中,而非独立的 role: "tool" 消息stop_reason: "pause_turn",需重新发送对话让模型继续# Anthropic Tool Use 格式(与 OpenAI 不同的回传结构)
import anthropic
client = anthropic.Anthropic(api_key="YOUR_KEY")
# 工具结果回传格式(Anthropic 专有)
messages = [
{"role": "user", "content": "北京今天天气?"},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "get_weather",
"input": {"city": "北京"}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result", # Anthropic 专有格式
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": '{"temp": 22, "condition": "晴天"}'
}
]
}
]可引用结论:Claude Opus 4.7 使用 tool_choice: auto/none 时额外消耗 346 个系统提示 tokens;使用 any/tool 时为 313 tokens;这部分 tokens 会计入 API 请求的输入 token 总量(来源:Anthropic Tool Use 官方文档,2026.04)。
Function Calling vs Structured Outputs:该用哪个?
场景 推荐方案 理由 需要执行外部操作(API 调用、DB 写入) Function Calling 有副作用,需要 tool 机制触发 需要强制返回特定 JSON 结构(无副作用) Structured Outputs 无需工具往返,直接约束输出格式 从非结构化文本中提取结构化字段 Structured Outputs response_format 足够,无需工具调用开销Agent 工作流:多步骤、多工具串联 Function Calling Agentic Loop 是天然容器 实时查询外部数据(天气/行情/DB) Function Calling 训练数据没有实时信息,只能靠工具 场景选型矩阵
场景 工具类型 推荐模型 说明 查询数据库/内部 API Client Tool(用户定义) DeepSeek V4 Flash 高频低成本,工具调用准确率高 实时网页搜索 Server Tool(Anthropic web_search) Claude Opus 4.7 无需自行维护搜索能力 代码执行沙箱 Server Tool(code_execution) Claude Opus 4.7 Anthropic 托管,无需配置环境 强制提取结构化数据 tool_choice: required + strict 任意兼容模型 确保 100% 格式合规 大规模 Agent 批量任务 Parallel Function Calling DeepSeek V4 Flash $0.14/M,并发处理降低延迟 复杂多步推理 Agent 多轮 Function Calling + thinking DeepSeek V4 Pro reasoning_content 辅助调试 企业内网/数据不出境 Client Tool 本地部署 DeepSeek V4 Pro(本地) MIT 开源,华为昇腾支持 FAQ
api.qnaigc.com)可以用同一个 Key 国内直连三家模型:OpenAI 兼容协议填 base_url="https://api.qnaigc.com/v1",Anthropic 原生协议填 base_url="https://api.qnaigc.com",改一行 model 参数即可切换模型做 A/B 对比,无需境外节点。tool_calls 列表长度,对每个 tool_call 分别回传 tool_result,所有 tool_result 共同发回才能继续循环。不需要显式开启,模型会自动判断。tool_result,不要让整个循环中断。Claude 会根据错误信息决定重试或改变策略:messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps({"error": "数据库连接超时,请稍后重试"})
})总结
description 写清楚触发条件;② tool_choice: "required" 强制结构化提取;③ 循环检测 finish_reason 驱动 Agentic Loop;④ strict: true 保证生产环境的格式合规。OpenAI 与 DeepSeek 使用兼容格式,Claude 的 tool_result 回传结构不同,跨平台切换时注意工具结果消息的格式差异。