开发接入
函数调用
让模型决定是否调用你定义的函数,附完整的两轮示例(deepseek-v3.2 实测)。
函数调用(Tool Calls)让模型决定“是否需要调用你定义的函数、传什么参数”。模型本身不会执行函数,由你的代码执行后,再把结果交还给模型。
流程:
- 请求里用
tools描述可用函数。 - 模型返回
tool_calls(函数名 + JSON 参数)。 - 你的代码执行函数,把结果以
role: "tool"消息追加到对话。 - 再请求一次,模型给出最终回答。
完整示例
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ATHANDRA_API_KEY"],
base_url="https://ai.athandra.com/v1",
)
model = os.environ.get("ATHANDRA_MODEL", "deepseek-v3.2")
def get_weather(city: str) -> str:
# 这里用假数据代替真实的天气接口
return json.dumps({"city": city, "weather": "晴", "temperature_c": 22}, ensure_ascii=False)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询城市当前天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "城市名,例如 北京"}},
"required": ["city"],
},
},
}
]
messages = [{"role": "user", "content": "北京现在天气怎么样?"}]
# 第 1 轮:模型决定要不要调用函数
first = client.chat.completions.create(model=model, messages=messages, tools=tools)
msg = first.choices[0].message
if not msg.tool_calls:
print(msg.content)
else:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(**args)
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
# 第 2 轮:把函数结果交还给模型,得到最终回答
final = client.chat.completions.create(model=model, messages=messages, tools=tools)
print(final.choices[0].message.content)
第 1 轮的原始返回
只看第 1 轮,可以用 curl:
#!/usr/bin/env bash
# 函数调用:模型返回 tool_calls,由你的代码执行函数
curl -sS https://ai.athandra.com/v1/chat/completions \
-H "Authorization: Bearer $ATHANDRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${ATHANDRA_MODEL:-deepseek-v3.2}"'",
"messages": [
{"role": "user", "content": "北京现在天气怎么样?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询城市当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,例如 北京"}
},
"required": ["city"]
}
}
}
]
}'
模型决定调用函数时,返回的 finish_reason 是 tool_calls:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "我来帮您查询北京的天气情况。\n\n",
"tool_calls": [
{
"id": "call_c816dd73...",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"city\": \"北京\"}" }
}
]
},
"finish_reason": "tool_calls"
}
]
}注意事项
arguments是 JSON 字符串,需要json.loads/JSON.parse后再用,并建议做异常处理,模型偶尔会给出不合法参数。- 第 2 轮请求要把第 1 轮模型返回的 assistant 消息(含
tool_calls)原样放回messages,再追加tool消息,tool_call_id要一一对应。 - 以上流程在
deepseek-v3.2上实测通过;其它模型是否支持函数调用以模型自身能力为准。