在当前的大模型(LLM)应用开发中,一个普遍存在的问题是:大模型本身不具备获取实时信息的能力。无论是天气、股价、新闻还是航班状态,这些动态数据都无法直接被训练完成后的模型所掌握。然而,通过 OpenAI 定义的 Tools(工具)机制,我们可以让大模型“学会”调用外部接口,从而真正实现“智能互联网”的愿景。
本文将基于我在实际开发中的学习和实践,介绍如何使用 Python + DeepSeek API + 自定义函数,构建一个支持工具调用的聊天系统,并以“查询天气”为例,展示整个流程。
一、为什么需要工具调用?
大模型如 GPT、DeepSeek 等,都是在大量历史文本上训练而成的。它们擅长理解语言、推理逻辑、生成内容,但无法访问互联网或数据库。这意味着:
- 用户问:“北京今天天气怎么样?” → 模型无法回答,除非你告诉它。
- 用户问:“特斯拉最新股价是多少?” → 模型只能给出训练截止前的数据(甚至可能错误)。
为了解决这个问题,OpenAI 在其 API 中引入了 Function Calling(现称为 Tools) 功能。核心思想是:
当模型判断需要外部信息时,它会返回一个“调用指令”,而不是直接回答。开发者根据该指令执行本地函数(如发起 HTTP 请求),再将结果反馈给模型,由模型组织最终回答。
这相当于给 LLM 装上了“手脚”,让它能主动“上网查资料”。
二、准备工作:安装依赖与定义工具函数
首先,我们需要安装必要的 Python 包。虽然你在 Node.js 中可能用 npm install,但在 Python 中我们使用 pip:
!pip install requests
!pip install openai
接着,定义一个用于查询天气的函数。这里我使用了 心知天气 的免费 API:
import requests
def get_weather(location: str) -> str:
url = "https://api.seniverse.com/v3/weather/now.json"
params = {
"key": "my_api_key", # 替换为你自己的 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 "查询失败"
except Exception as e:
return f"异常:{e}"
这个函数接收城市名,返回格式化的天气字符串。注意:Python 支持类型注解(如 -> str),虽非强制,但有助于代码可读性和 IDE 提示。
三、向大模型“注册”工具
接下来,我们要告诉大模型:“你可以调用一个叫 get_weather 的函数来查天气”。这通过 Tools 描述 实现:
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如'北京'"
}
},
"required": ["location"]
}
}
}
]
这段 JSON 告诉模型:
- 有一个可用函数
get_weather - 它需要一个必填参数
location(字符串) - 用途是查天气
只要模型理解了这个结构,它就能在合适的时候“请求调用”。
四、与模型交互:两阶段对话
完整的工具调用流程分为两个阶段:
第一阶段:模型决定是否调用工具
from openai import OpenAI
import json
client = OpenAI(
api_key="your_deepseek_api_key",
base_url="https://api.deepseek.com/v1"
)
messages = [{"role": "user", "content": "北京天气怎么样?"}]
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) # 将模型回复加入历史
此时,如果模型认为需要查天气,response_message.tool_calls 将不为空。
第二阶段:执行工具并返回结果
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 = "未知工具"
# 将工具执行结果作为“tool”角色消息加入对话
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response
})
第三阶段:模型生成最终回答
final_response = client.chat.completions.create(
model="deepseek-reasoner",
messages=messages,
temperature=0.3
)
print(final_response.choices[0].message.content)
最终输出可能是:
根据最新数据,北京当前的天气:多云,气温:18℃。
整个过程实现了 “用户提问 → 模型决策 → 调用工具 → 获取数据 → 生成自然语言回答” 的闭环。
五、为什么选择 DeepSeek?
DeepSeek 是国内优秀的开源大模型系列,其 Reasoner 版本 特别擅长逻辑推理和工具调用。更重要的是,它兼容 OpenAI API 协议,只需修改 base_url 即可无缝切换:
client = OpenAI(
api_key="你的 DeepSeek API Key",
base_url="https://api.deepseek.com/v1"
)
这种模块化设计极大提升了代码的可移植性。未来若想换用 Moonshot、通义千问等其他兼容模型,几乎无需改动业务逻辑。
六、总结与展望
通过工具调用,我们成功让大模型突破了“静态知识”的限制,具备了访问实时世界的能力。这不仅是技术上的进步,更是 LLM 应用落地的关键一步。
在实际项目中,你可以扩展更多工具:
- 查询股票价格
- 搜索维基百科
- 控制智能家居
- 调用企业内部 API
而这一切的核心,都建立在 清晰的工具描述 + 可靠的本地函数实现 + 正确的消息传递机制 之上。
正如我在笔记中所写:“让 LLM 和原有的互联网文明桥接起来”——这正是智能体(Agent)时代的开端。借助像 DeepSeek 这样的强大模型,配合简单的 Python 脚本,我们每个人都能构建属于自己的“智能互联网助手”。
提示:本文所有代码均可在 Jupyter Notebook(.ipynb)中逐行运行,非常适合实验和调试。推荐结合 ModelScope(魔搭)平台,快速体验各类开源模型。
通过这次实践,我深刻体会到:大模型不是终点,而是连接人类与数字世界的桥梁。而工具调用,正是这座桥的第一块基石。