打破信息壁垒:手把手教你实现DeepSeek大模型的天气查询功能
在人工智能快速发展的今天,大型语言模型(LLM)如DeepSeek已经展现出令人惊叹的文本理解和生成能力。然而,这些模型有一个明显的局限性:它们只能基于训练时的数据进行回答,无法获取实时信息。本文将带你深入探索如何通过工具调用(Tool Calling)技术,让DeepSeek大模型具备查询实时天气的能力。
为什么大模型需要"工具调用"能力?
当我们询问DeepSeek"北京天气怎么样"时,它无法给出准确答案,因为它只知道训练时学习到的知识,而天气信息是实时变化的。这就是工具调用技术的用武之地。 工具调用相当于为LLM装上了"手和脚",让它能够与外部世界交互。通过这种方式,大模型可以:
- 查询实时信息(天气、股价、新闻等)
- 执行具体操作(发送邮件、控制智能设备等)
- 访问专业数据库(法律、医疗、金融等)
从"知识库"到"智能体"的转变
传统的LLM更像是一个庞大的知识库,而通过工具调用,我们将其转变为一个能够主动行动的"智能体"。这种转变的意义在于:
- 突破训练数据的时间限制:可以获取最新信息
- 扩展能力边界:超越纯文本处理,执行实际任务
- 提高实用性:从"能说"到"能做"的质变
环境准备与基础配置
在开始编码前,我们需要搭建开发环境。本文使用Jupyter Notebook作为开发工具,它具有交互式编程的优势,特别适合AI应用的实验和调试。
Jupyter Notebook的优势
bash
# Jupyter支持逐单元格执行,便于调试和实验
print("llm 调用 tools,让llm和外界交流")
Jupyter的.ipynb文件格式特别适合:
- 算法实验:逐步测试和调整代码
- 数据可视化:实时查看数据处理结果
- 模型调试:交互式地观察模型表现
安装必要的依赖包
yaml
# 安装requests库用于HTTP请求
!pip install requests
# 安装OpenAI SDK用于调用DeepSeek API
!pip install openai
模块化设计的重要性
Python的模块化设计让代码更清晰:
javascript
from openai import OpenAI
import requests
import json
模块化的好处:
- 分离关注点:每个模块专注特定功能
- 代码复用:工具函数可以在多个项目中共享
- 易于维护:问题定位和修复更高效
初始化DeepSeek客户端
ini
# 创建DeepSeek客户端实例
client = OpenAI(
api_key='你的apikey',
base_url='https://api.deepseek.com/v1'
)
这里使用的是OpenAI兼容的API接口,这是目前大多数大模型服务提供商遵循的事实标准。这种标准化降低了学习成本,提高了代码的可移植性。
实现天气查询工具函数
工具调用的核心是创建一个能够执行特定任务的函数。让我们先实现天气查询功能:
完整的天气查询实现
python
import requests
def get_weather(location: str) -> str:
"""
获取指定城市的当前天气情况
Args:
location: 城市名称,如'北京'
Returns:
天气信息的格式化字符串
"""
url = "https://api.seniverse.com/v3/weather/now.json"
params = {
"key": "你的key",
"location": location,
"language": "zh-Hans"
}
try:
# 设置超时时间,避免长时间等待
resp = requests.get(url, params=params, timeout=10)
data = resp.json()
if "results" in data:
result = data["results"][0]
city = result["location"]["name"]
now = result["now"]
weather_text = now["text"]
temperature = now["temperature"]
return f"{city}当前天气:{weather_text},气温{temperature}度"
else:
return "查询失败"
except requests.exceptions.Timeout:
return "天气查询超时,请稍后重试"
except Exception as e:
return f"异常:{e}"
# 测试天气查询函数
print(get_weather("抚州"))
代码细节解析
- 类型注解 :
location: str->str提高了代码可读性 - 异常处理:确保程序在网络异常时也能优雅处理
- 超时设置:避免因API响应慢而阻塞整个应用
定义工具描述:教LLM如何使用天气查询
大模型需要明确的指导才能正确使用工具。我们通过工具描述来告诉DeepSeek如何与我们的天气查询函数交互。
完整的工具定义
ini
# 来自openai接口定义
tools = [
{
# 一个工具就是一个函数
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
# 北京天气怎么样,提取北京
"description": "城市名称,如'北京'" # 告诉llm需要提取参数
}
},
"required": ["location"] # 指定必需参数
}
}
}
]
工具描述的关键要素
- 名称(name) :LLM调用时使用的标识符
- 描述(description) :告诉LLM什么情况下使用这个工具
- 参数定义:明确参数类型、格式和约束条件
实现完整的工具调用流程
工具调用的完整流程涉及多次API调用,体现了LLM的推理和执行过程:
完整的对话流程实现
ini
import json
def chat_with_weather_function(user_query):
"""
支持天气查询的对话函数
Args:
user_query: 用户输入的自然语言查询
Returns:
LLM生成的回复内容
"""
# 初始化消息队列
messages = [{"role": "user", "content": user_query}]
# 第一次调用:让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
print(response_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
# json字符串变成json对象
function_args = json.loads(tool_call.function.arguments)
if function_name == "get_weather":
# 执行实际的天气查询
function_response = get_weather(function_args["location"])
else:
function_response = "未知工具"
# 将工具执行结果添加到对话上下文
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response
})
else:
# 如果不需要工具,直接返回回复
print(response_message.content)
return response_message.content
# 第二次调用:让LLM基于工具结果生成最终回复
final_response = client.chat.completions.create(
model="deepseek-reasoner",
messages=messages,
temperature=0.3
)
return final_response.choices[0].message.content
# 测试完整的天气查询流程
result = chat_with_weather_function("北京天气怎么样")
print(result)
技术原理解析
两阶段调用过程
这个实现体现了LLM工具调用的典型两阶段过程: 第一阶段:推理与决策
- LLM分析用户问题:"北京天气怎么样"
- 识别意图:用户需要天气信息
- 提取参数:从问题中提取"北京"
- 决定行动:调用get_weather工具
第二阶段:执行与整合
- 执行工具函数:调用天气API获取真实数据
- 整合结果:将原始数据转化为自然语言回复
- 生成响应:提供友好、有用的天气信息
消息队列的智能管理
多轮消息传递是维持对话上下文的关键:
ini
messages = [
{"role": "user", "content": "北京天气怎么样"},
{"role": "assistant", "content": null, "tool_calls": [...]},
{"role": "tool", "name": "get_weather", "content": "北京当前天气:晴,气温1度"},
{"role": "assistant", "content": "北京当前天气晴朗,气温25摄氏度,适合出行!"}
]
这种结构让LLM能够理解整个交互过程,生成连贯的回复。
实际应用效果展示
当我们运行完整的天气查询流程时,可以看到详细的执行过程:
执行过程输出
python
ChatCompletionMessage(content='我来帮您查询北京的天气情况。', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_cHDBGfG3OMegtIaM4MdFqQNR', function=Function(arguments='{"location": "北京"}', name='get_weather'), type='function', index=0)])
{'results': [{'location': {'id': 'WX4FBXXFKE4F', 'name': '北京', 'country': 'CN', 'path': '北京,北京,中国', 'timezone': 'Asia/Shanghai', 'timezone_offset': '+08:00'}, 'now': {'text': '晴', 'code': '1', 'temperature': '1'}, 'last_update': '2025-11-18T22:37:37+08:00'}]}
根据查询结果,目前北京的天气情况是:
**🌤️ 天气状况:** 晴
**🌡️ 气温:** 1°C
今天北京天气晴朗,但气温较低,请注意保暖。如果您需要更详细的天气预报(比如未来几天的天气情况),请告诉我,我可以为您查询更多信息。
结果分析
- 工具调用决策:LLM正确识别需要调用天气查询工具
- 参数提取:准确提取了城市名称"北京"
- 数据整合:将原始API响应转化为用户友好的格式
- 贴心建议:加入了保暖提醒,体现AI的关怀
扩展应用场景与进阶功能
掌握了工具调用的基本原理后,我们可以轻松扩展更多实用功能:
多工具协同工作
ini
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
# ... 参数定义
}
},
{
"type": "function",
"function": {
"name": "get_air_quality",
"description": "获取指定城市的空气质量指数",
# ... 参数定义
}
}
]
支持复杂查询
ini
# LLM可以智能选择多个工具回答复杂问题
user_query = "北京今天的天气和空气质量怎么样?"
# LLM可能会依次调用get_weather和get_air_quality两个工具
错误处理与重试机制
python
def robust_tool_calling(user_query, max_retries=3):
for attempt in range(max_retries):
try:
return chat_with_weather_function(user_query)
except Exception as e:
if attempt == max_retries - 1:
return "抱歉,服务暂时不可用,请稍后重试"
time.sleep(1) # 等待后重试
开发技巧与最佳实践
1. 完善的错误处理
python
try:
# 工具调用代码
except requests.exceptions.Timeout:
return "天气查询超时,请稍后重试"
except requests.exceptions.ConnectionError:
return "网络连接异常,请检查网络设置"
except json.JSONDecodeError:
return "数据解析错误,请稍后重试"
except Exception as e:
return f"查询过程中出现错误:{str(e)}"
2. 参数验证与清洗
python
def validate_and_clean_location(location: str) -> str:
"""验证和清洗城市名称"""
# 去除前后空格
location = location.strip()
# 常见城市名称映射
city_mapping = {
"北京市": "北京",
"上海省": "上海",
"广州市": "广州"
}
return city_mapping.get(location, location)
3. 性能优化建议
python
import functools
import time
# 添加缓存减少API调用
@functools.lru_cache(maxsize=100)
def get_weather_cached(location: str) -> str:
return get_weather(location)
# 添加超时控制
def call_with_timeout(func, timeout=30, *args, **kwargs):
# 实现函数超时控制
pass
总结与展望
通过本文的详细实践,我们成功实现了让DeepSeek大模型具备实时天气查询能力的功能。这只是一个开始,工具调用技术为AI应用开辟了无限可能:
技术价值总结
- 实时信息获取:突破LLM的时间限制
- 能力扩展:从纯文本处理到实际任务执行
- 标准化接口:基于OpenAI标准,易于扩展和维护
未来发展方向
- 多模态工具:结合图像识别、语音处理等能力
- 复杂任务规划:支持多步骤、长周期的任务执行
- 自主决策:AI能够自主选择和使用工具组合
- 安全机制:确保工具调用的安全性和可控性