Tool Calls
让模型调用外部工具来增强能力。模型只负责决定"调哪个、传什么参数",真正的执行在你的代码里。
流程
一轮完整的工具调用要走两次请求:
- 请求里带上
tools(函数名 + 描述 + 参数 JSON Schema); - 模型不直接回答,而是返回
tool_calls,告诉你调哪个函数、传什么参数; - 你的代码执行那个函数,把结果作为一条
role: "tool"的消息追加进messages; - 再发一次请求,模型基于结果给出最终的自然语言回答。
第一步:带上 tools 请求
curl https://open.feiyutoken.com/v1/chat/completions \
-H "Authorization: Bearer <你的飞鱼Token API Key>" \
-H "Content-Type: application/json" \
-d '{
"model": "<模型名>",
"messages": [
{ "role": "user", "content": "杭州现在天气怎么样?" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询某个城市的天气,需要先给出城市名",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "城市名,例如 杭州" }
},
"required": ["location"]
}
}
}
]
}'
模型返回什么
finish_reason 是 tool_calls,content 通常为空,工具调用在 tool_calls 里:
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"杭州\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
第二步:把执行结果发回去
把上一步返回的 assistant 消息原样追加进 messages,再追加一条 role: "tool" 的消息:
curl https://open.feiyutoken.com/v1/chat/completions \
-H "Authorization: Bearer <你的飞鱼Token API Key>" \
-H "Content-Type: application/json" \
-d '{
"model": "<模型名>",
"messages": [
{ "role": "user", "content": "杭州现在天气怎么样?" },
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"location\": \"杭州\"}" }
}
]
},
{ "role": "tool", "tool_call_id": "call_abc123", "content": "24℃" }
]
}'
这次模型会给出自然语言回答,finish_reason 回到 stop。
几个容易踩的点
- 函数是你自己执行的,模型不会替你跑任何一个函数。
arguments是字符串,不是对象 —— 先做一次 JSON 解析再取参数。- 回填结果时
tool_call_id必须和模型给的id对上,否则模型不知道这条结果对应哪次调用。 - 一次返回可能有多个
tool_calls,都要执行并逐条回填。 - 是否需要继续调用工具,由模型决定:也可能再多轮几次才给最终回答。
- 哪些模型支持工具调用,以控制台模型列表里的说明为准。