函数调用与工具使用 实用技巧
所属主题:Claude 提示词工程完全指南
函数调用与工具使用的核心价值在于:让 AI 模型能够主动触发外部 API、查询数据库或执行本地代码,从而突破纯文本生成的局限,获取实时数据、执行精确计算或操作第三方系统。本文提供一套从定义、配置到调试的完整实用指南,包含可直接复用的检查清单、常见错误分析和一个完整的工作示例。
开始前的准备
在尝试实现函数调用之前,请确认以下前提条件,否则即便写对了代码也会遇到无响应的状况:
- API 版本支持:函数调用功能在 2023 年 11 月之后的 API 版本(如 Claude 3 系列、GPT-4 Turbo)中才完整可用。旧版本(如 GPT-3.5 Turbo 0301)可能支持但结果不稳定。建议直接查阅对应模型的最新官方文档确认支持状态。
- 工具定义格式正确:大多数平台要求工具定义遵循 JSON Schema 格式。常见陷阱是忘记在
parameters对象中声明type: "object",或者缺少required字段导致模型跳过必填参数。 - 输入消息必须包含
user或system角色:纯assistant消息的对话轮次不会触发函数调用。至少需要一条用户输入来指明任务。 - API 密钥权限:部分服务(如 Azure OpenAI)需要在部署层面单独启用函数调用功能,光有密钥不够。
实施函数调用的标准流程
以下流程适用于大多数主流 LLM API(OpenAI、Anthropic、Google),具体参数名可能略有差异。
第一步:定义工具(Tool Definition)
用 JSON Schema 描述每个可调用的函数。以下是一个获取天气数据的函数定义示例:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,例如 '北京' 或 'Tokyo'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["location"]
}
}
}
关键点:
description字段对模型至关重要——清晰地说明函数的功能、参数含义及调用时机,能显著提升模型判断的准确性。required仅列出真正必须的参数。可选参数放入properties但不加入required。- 使用枚举值(
enum)可有效减少模型生成非法输入的概率。
第二步:在 API 请求中传入工具
将工具定义作为请求体的一部分发送。不同平台的参数名对比如下:
| 平台 | 参数名 | 备注 |
|---|---|---|
| OpenAI | tools |
替代旧的 functions 参数,推荐使用新格式 |
| Anthropic Claude | tools |
同样使用 tools 数组 |
| Google Gemini | tools.functionDeclarations |
结构稍有不同,但 JSON Schema 逻辑一致 |
| Azure OpenAI | tools |
与 OpenAI 相同,但需检查部署版本 |
请求示例(简化):
POST /v1/chat/completions
{
"model": "gpt-4-turbo",
"messages": [{"role": "user", "content": "北京今天多少度?"}],
"tools": [<上一步定义的工具>],
"tool_choice": "auto"
}
tool_choice 参数控制模型行为:
"auto"(默认):模型自行判断是否调用工具。"none":强制不调用,即使任务需要。{"type": "function", "function": {"name": "get_weather"}}:强制调用指定函数,适用于测试或流程控制场景。
第三步:解析模型的函数调用响应
如果模型决定调用工具,返回值中会包含 tool_calls(或 content 中的工具使用块)。典型的输出结构如下:
{
"choices": [{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\":\"北京\",\"unit\":\"celsius\"}"
}
}]
}
}]
}
注意事项:arguments 是 JSON 字符串,必须先解析为对象再传入实际函数。
第四步:执行实际函数并返回结果
在代码中执行真实的函数逻辑,然后将结果以 tool 角色消息返回给模型:
# 伪代码示例
tool_call = response.choices[0].message.tool_calls[0]
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
if function_name == "get_weather":
result = call_weather_api(arguments["location"], arguments.get("unit", "celsius"))
# 将结果追加到对话
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
新手最常见错误:忘记将 tool_call_id 原样传回。模型通过此 ID 将结果匹配到对应的调用。
第五步:让模型用自然语言总结结果
将工具返回的数据(通常是 JSON)作为新消息发送给模型,模型会据此生成人类可读的回答。此步骤无需额外参数,模型会自动理解工具返回的内容并组织语言。
配置验证检查清单
在进入复杂场景之前,使用以下清单快速定位问题:
- 工具定义的
name是否与代码中调用的名称完全一致(大小写敏感) - 函数
arguments在发送前是否经过json.loads()解析而非直接使用 -
tool_call_id是否从模型响应中原样取出并传入tool角色消息 - 当模型一次返回多个
tool_calls时,是否循环处理了每一个 - 工具执行结果是否返回了有效的 JSON 字符串(模型期望
content是字符串) - 是否检查了 API 返回的
finish_reason——值为"tool_calls"表示模型要求调用工具
常见问题与排查
模型从不调用函数
- 检查
tool_choice是否设置为"auto",显式设为"none"会阻止所有调用。 - 检查用户提示是否足够明确。提出“帮我查一下”比简单说“你好”更容易触发函数调用。可在 system prompt 中明确指示:“当你需要实时数据时,请使用可用的工具。”
- 检查工具定义中的
description是否足够清晰。模型依赖描述来理解何时调用。
调用时生成的参数不正确
- 检查 JSON Schema 是否定义了正确的枚举值和格式约束。例如,让模型从
["celsius", "fahrenheit"]中选择,而不是猜测。 - 检查参数名是否与函数内部期望的名称完全一致(下划线 vs 驼峰命名是常见陷阱)。
错误:'tool_calls' 字段不存在
- 确认使用了支持函数调用的模型版本和 API 端点。
- 确认消息列表的第一条是
user或system角色。
多轮函数调用的状态管理
当模型需要依赖前一个函数的结果来决定是否调用另一个函数时,务必保留之前的所有消息(包括 assistant、tool、user)在 messages 数组中一起发送。丢失上下文是导致流程中断的最常见原因。
完整示例:一次天气查询与数据库查询的复合任务
以下是一个可复现的场景,你可以在本地模拟执行。假设你需要模型先查天气,再根据天气推荐活动并查询数据库确认场地可用性:
- 用户输入:“北京明天天气怎么样?适合户外活动吗?”
- 模型调用
get_weather函数,返回包含天气信息的 JSON。 - 模型根据天气结果生成初步回答,并调用
check_venue_availability(参数为日期和场地类型)。 - 模型综合天气结果和场地数据输出最终答案。
关键检查点:在步骤 3 中,对话历史必须包含:用户消息、第一次助理的 tool_calls、第一次 tool 结果。缺少任何一环,模型就无法理解为什么需要查询场地。
常见问题解答(FAQ)
函数调用与工具使用的概念是什么?
函数调用与工具使用是指大型语言模型在生成回复时,能够识别需要从外部获取信息或执行操作,并返回结构化的函数调用请求。开发者据此执行真实的 API 调用或代码逻辑,再将结果交还给模型生成最终回答。这种模式让 AI 从“纯粹的文字生成器”升级为“能够操作真实系统的智能代理”。
函数调用与工具使用的具体操作步骤?
标准流程包含五个步骤:定义工具(JSON Schema)、在请求中传入工具、解析模型的调用请求、执行实际函数、将结果返回给模型。