大闹天庭情迷龙女果盘礼包版
94.18MB · 2025-11-28
在人工智能快速发展的今天,大型语言模型(LLM)如DeepSeek已经展现出令人惊叹的文本理解和生成能力。然而,这些模型有一个明显的局限性:它们只能基于训练时的数据进行回答,无法获取实时信息。本文将带你深入探索如何通过工具调用(Tool Calling)技术,让DeepSeek大模型具备查询实时天气的能力。
当我们询问DeepSeek“北京天气怎么样”时,它无法给出准确答案,因为它只知道训练时学习到的知识,而天气信息是实时变化的。这就是工具调用技术的用武之地。 工具调用相当于为LLM装上了“手和脚”,让它能够与外部世界交互。通过这种方式,大模型可以:
传统的LLM更像是一个庞大的知识库,而通过工具调用,我们将其转变为一个能够主动行动的“智能体”。这种转变的意义在于:
在开始编码前,我们需要搭建开发环境。本文使用Jupyter Notebook作为开发工具,它具有交互式编程的优势,特别适合AI应用的实验和调试。
# Jupyter支持逐单元格执行,便于调试和实验
print("llm 调用 tools,让llm和外界交流")
Jupyter的.ipynb文件格式特别适合:
# 安装requests库用于HTTP请求
!pip install requests
# 安装OpenAI SDK用于调用DeepSeek API
!pip install openai
Python的模块化设计让代码更清晰:
from openai import OpenAI
import requests
import json
模块化的好处:
# 创建DeepSeek客户端实例
client = OpenAI(
api_key='你的apikey',
base_url=''
)
这里使用的是OpenAI兼容的API接口,这是目前大多数大模型服务提供商遵循的事实标准。这种标准化降低了学习成本,提高了代码的可移植性。
工具调用的核心是创建一个能够执行特定任务的函数。让我们先实现天气查询功能:
import requests
def get_weather(location: str) -> str:
"""
获取指定城市的当前天气情况
Args:
location: 城市名称,如'北京'
Returns:
天气信息的格式化字符串
"""
url = ""
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提高了代码可读性大模型需要明确的指导才能正确使用工具。我们通过工具描述来告诉DeepSeek如何与我们的天气查询函数交互。
# 来自openai接口定义
tools = [
{
# 一个工具就是一个函数
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
# 北京天气怎么样,提取北京
"description": "城市名称,如'北京'" # 告诉llm需要提取参数
}
},
"required": ["location"] # 指定必需参数
}
}
}
]
工具调用的完整流程涉及多次API调用,体现了LLM的推理和执行过程:
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工具调用的典型两阶段过程: 第一阶段:推理与决策
第二阶段:执行与整合
多轮消息传递是维持对话上下文的关键:
messages = [
{"role": "user", "content": "北京天气怎么样"},
{"role": "assistant", "content": null, "tool_calls": [...]},
{"role": "tool", "name": "get_weather", "content": "北京当前天气:晴,气温1度"},
{"role": "assistant", "content": "北京当前天气晴朗,气温25摄氏度,适合出行!"}
]
这种结构让LLM能够理解整个交互过程,生成连贯的回复。
当我们运行完整的天气查询流程时,可以看到详细的执行过程:
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
今天北京天气晴朗,但气温较低,请注意保暖。如果您需要更详细的天气预报(比如未来几天的天气情况),请告诉我,我可以为您查询更多信息。
掌握了工具调用的基本原理后,我们可以轻松扩展更多实用功能:
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
# ... 参数定义
}
},
{
"type": "function",
"function": {
"name": "get_air_quality",
"description": "获取指定城市的空气质量指数",
# ... 参数定义
}
}
]
# LLM可以智能选择多个工具回答复杂问题
user_query = "北京今天的天气和空气质量怎么样?"
# LLM可能会依次调用get_weather和get_air_quality两个工具
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) # 等待后重试
try:
# 工具调用代码
except requests.exceptions.Timeout:
return "天气查询超时,请稍后重试"
except requests.exceptions.ConnectionError:
return "网络连接异常,请检查网络设置"
except json.JSONDecodeError:
return "数据解析错误,请稍后重试"
except Exception as e:
return f"查询过程中出现错误:{str(e)}"
def validate_and_clean_location(location: str) -> str:
"""验证和清洗城市名称"""
# 去除前后空格
location = location.strip()
# 常见城市名称映射
city_mapping = {
"北京市": "北京",
"上海省": "上海",
"广州市": "广州"
}
return city_mapping.get(location, location)
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应用开辟了无限可能: