关键词:LLM 工具调用(Function Calling)、DeepSeek API、心知天气 API、Python 实战、AI 联网能力
一、背景:为什么 LLM 需要“工具”?
大型语言模型(LLM)如 DeepSeek、GPT 等,虽然知识丰富、表达流畅,但存在两个天然局限:
- 知识截止:无法获取训练数据之后的信息;
- 无实时感知能力:无法知道“此刻北京的天气”或“当前股票价格”。
为突破这一限制,OpenAI 率先提出 Function Calling(函数调用) 机制——让 LLM 在需要时“主动调用外部工具”,从而与真实世界桥接。这标志着 “智能互联网”时代的开启:LLM 不再是封闭的语言模型,而是能与互联网服务协同的智能代理。
本文将带你用 Python 实现一个完整案例:用户问“北京天气怎么样?”,LLM 自动调用天气 API 获取实时数据,并返回自然语言回答。
二、技术栈概览
| 组件 | 作用 |
|---|---|
| 心知天气 API | 提供全球城市实时天气数据 |
| DeepSeek API | 提供支持 Function Calling 的大模型(deepseek-reasoner) |
| Python + requests | 实现 API 调用与数据处理 |
| OpenAI 兼容接口 | 使用标准 tools 格式定义函数 |
💡 注:DeepSeek 的 API 完全兼容 OpenAI 的 Function Calling 协议,因此可直接使用
openaiSDK。
三、第一步:封装天气查询工具函数
我们首先实现一个可靠的 get_weather 函数,用于调用心知天气的实时天气接口。
python
编辑
import requests
def get_weather(location: str) -> str:
"""获取指定城市的当前天气(返回自然语言描述)"""
url = "https://api.seniverse.com/v3/weather/now.json"
params = {
"key": "SaVSOt7sYbwpka9iv", # 替换为你自己的 API Key
"location": location,
"language": "zh-Hans"
}
try:
resp = requests.get(url, params=params, timeout=10)
data = resp.json()
if "results" in data:
r = data["results"][0]
city = r["location"]["name"]
now = r["now"]
text = now["text"]
temp = now["temperature"]
return f"{city}当前天气:{text}, 气温 {temp}度"
else:
return "查询失败,请检查城市名称或 API Key"
except Exception as e:
return f"异常:{e}"
✅ 关键点:
- 使用 类型提示(
location: str → str)提升代码可读性; - 对 API 响应做健壮性判断(检查
"results"是否存在); - 返回人类可读的字符串,便于 LLM 后续整合。
🔐 安全提醒:请勿在公开代码中硬编码 API Key!建议使用环境变量管理。
四、第二步:定义工具(Tool)Schema
为了让 LLM 知道“我能调用什么工具”,我们需要用 JSON Schema 描述 get_weather 函数:
python
编辑
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如'北京'"
}
},
"required": ["location"]
}
}
}
]
这个结构告诉 LLM:
- 有一个叫
get_weather的工具; - 它需要一个必填参数
location(字符串类型); - 它的作用是查天气。
五、第三步:实现完整的 Function Calling 流程
现在,我们将用户提问、LLM 决策、工具调用、结果整合串成完整流程:
python
编辑
from openai import OpenAI
import json
# 初始化 DeepSeek 客户端(兼容 OpenAI 接口)
client = OpenAI(
api_key='sk-a156e1c7e8e048c6a6b8e25338d3efc6',
base_url='https://api.deepseek.com/v1'
)
# 用户提问
messages = [{"role": "user", "content": "北京天气怎么样"}]
# 第一次调用:让 LLM 决定是否需要调用工具
response = client.chat.completions.create(
model='deepseek-reasoner',
messages=messages,
tools=tools,
tool_choice="auto",
temperature=0.3
)
response_message = response.choices[0].message
messages.append(response_message)
# 如果 LLM 要求调用工具
if response_message.tool_calls:
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# 执行本地函数
if function_name == "get_weather":
function_response = get_weather(function_args["location"])
else:
function_response = "未知工具"
# 将函数结果反馈给 LLM
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
})
# 第二次调用:让 LLM 根据工具结果生成最终回答
final_response = client.chat.completions.create(
model="deepseek-reasoner",
messages=messages,
temperature=0.3
)
print(final_response.choices[0].message.content)
else:
# 无需工具,直接输出
print(response_message.content)
🔄 执行流程图解:
text
编辑
用户提问 → LLM 分析 → [需查天气?] → 是 → 调用 get_weather("北京")
↓
获取实时数据 → 返回给 LLM
↓
LLM 整合信息 → “北京当前天气:晴,气温 22 度”
六、运行效果示例
当用户输入:
“抚州天气怎么样?”
程序输出:
抚州当前天气:多云, 气温 26度
整个过程对用户透明,仿佛 LLM “天生就知道天气”。
七、总结与展望
通过 Function Calling,我们成功实现了:
- ✅ LLM 与外部世界的连接
- ✅ 实时数据驱动的智能问答
- ✅ 模块化、可扩展的工具设计
未来,你可以轻松扩展更多工具:
- 查询股票价格(
get_stock_price(symbol)) - 翻译文本(
translate(text, target_lang)) - 控制智能家居(
turn_on_light(room))
🌐 真正的智能体(Agent)时代,始于一次函数调用。
八、附录:注意事项
- API Key 安全:务必通过
os.getenv("WEATHER_KEY")管理密钥; - 错误处理:生产环境需增加重试、限流、日志;
- 模型选择:
deepseek-reasoner支持复杂推理,普通对话可用deepseek-chat; - 字段一致性:确保
tools中的参数名(如location)与函数定义完全一致。
作者:一位探索 AI 与现实世界连接的开发者
时间:2025 年
适用读者:Python 工程师、AI 应用开发者、LLM 爱好者