开发文档
工具调用
工具调用(Function Calling)让模型按你定义的格式请求调用外部函数,比如查天气、查数据库、执行代码。模型只负责决定「调用哪个工具、传什么参数」,真正执行由你的代码完成。
基本流程
- 在请求里用 JSON Schema 描述可用的工具。
- 模型判断需要时,返回工具名和参数,而不是直接回答。
- 你的代码执行工具,把结果作为新消息发回。
- 模型根据结果给出最终回答。如果还需要别的工具,会继续请求,循环直到完成。
OpenAI 兼容格式
tools_openai.py
import json
from openai import OpenAI
client = OpenAI(api_key="sk-...", base_url="https://api.flyrouter.ai/v1")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询某个城市当前的天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "城市名,如 北京"}},
"required": ["city"],
},
},
}]
messages = [{"role": "user", "content": "上海现在天气怎么样?"}]
resp = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = {"city": args["city"], "weather": "多云", "temperature": 22} # 换成你的实现
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
resp = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
print(resp.choices[0].message.content)Anthropic 原生格式
Claude 的工具定义用 input_schema,模型请求调用时返回 tool_use 内容块,你用 tool_result 块回传结果:
tools_claude.py
from anthropic import Anthropic
client = Anthropic(api_key="sk-...", base_url="https://api.flyrouter.ai")
tools = [{
"name": "get_weather",
"description": "查询某个城市当前的天气",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}]
messages = [{"role": "user", "content": "上海现在天气怎么样?"}]
resp = client.messages.create(model="claude-sonnet-5-5", max_tokens=4096, tools=tools, messages=messages)
while resp.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": resp.content})
results = []
for block in resp.content:
if block.type == "tool_use":
output = '{"weather": "多云", "temperature": 22}' # 换成你的实现
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
messages.append({"role": "user", "content": results})
resp = client.messages.create(model="claude-sonnet-5-5", max_tokens=4096, tools=tools, messages=messages)
print(next(b.text for b in resp.content if b.type == "text"))实用建议
- 把
description写清楚:工具做什么、什么时候该用、参数格式,这比任何参数都影响调用质量。 - 并行调用:模型可能一次请求多个工具。请全部执行,并把所有结果放在同一条消息里回传。
- 执行失败也要回传:OpenAI 格式回传错误说明;Anthropic 格式在
tool_result上加"is_error": true。不要直接丢掉。 - 参数一律按 JSON 解析:用
json.loads/JSON.parse解析参数,不要对原始字符串做匹配。
新款 Claude 不支持强制调用
claude-opus-5-5、claude-sonnet-5-5、claude-fable-5-1 不接受 tool_choice 为 any 或指定工具(会返回 400)。请使用默认的 auto,并在提示词里说明应该调用哪个工具;需要保证参数严格符合 Schema 时,在工具定义上加 "strict": true。