打破信息壁垒:手把手教你实现DeepSeek大模型的天气查询功能

打破信息壁垒:手把手教你实现DeepSeek大模型的天气查询功能

在人工智能快速发展的今天,大型语言模型(LLM)如DeepSeek已经展现出令人惊叹的文本理解和生成能力。然而,这些模型有一个明显的局限性:它们只能基于训练时的数据进行回答,无法获取实时信息。本文将带你深入探索如何通过工具调用(Tool Calling)技术,让DeepSeek大模型具备查询实时天气的能力。

为什么大模型需要"工具调用"能力?

当我们询问DeepSeek"北京天气怎么样"时,它无法给出准确答案,因为它只知道训练时学习到的知识,而天气信息是实时变化的。这就是工具调用技术的用武之地。 工具调用相当于为LLM装上了"手和脚",让它能够与外部世界交互。通过这种方式,大模型可以:

  • 查询实时信息(天气、股价、新闻等)
  • 执行具体操作(发送邮件、控制智能设备等)
  • 访问专业数据库(法律、医疗、金融等)

从"知识库"到"智能体"的转变

传统的LLM更像是一个庞大的知识库,而通过工具调用,我们将其转变为一个能够主动行动的"智能体"。这种转变的意义在于:

  1. 突破训练数据的时间限制:可以获取最新信息
  2. 扩展能力边界:超越纯文本处理,执行实际任务
  3. 提高实用性:从"能说"到"能做"的质变

环境准备与基础配置

在开始编码前,我们需要搭建开发环境。本文使用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("抚州"))

代码细节解析

  1. 类型注解location: str-> str提高了代码可读性
  2. 异常处理:确保程序在网络异常时也能优雅处理
  3. 超时设置:避免因API响应慢而阻塞整个应用

定义工具描述:教LLM如何使用天气查询

大模型需要明确的指导才能正确使用工具。我们通过工具描述来告诉DeepSeek如何与我们的天气查询函数交互。

完整的工具定义

ini 复制代码
# 来自openai接口定义
tools = [
    {
        # 一个工具就是一个函数
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的当前天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        # 北京天气怎么样,提取北京
                        "description": "城市名称,如'北京'"  # 告诉llm需要提取参数
                    }
                },
                "required": ["location"]  # 指定必需参数
            }
        }
    }
]

工具描述的关键要素

  1. 名称(name) :LLM调用时使用的标识符
  2. 描述(description) :告诉LLM什么情况下使用这个工具
  3. 参数定义:明确参数类型、格式和约束条件

实现完整的工具调用流程

工具调用的完整流程涉及多次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

今天北京天气晴朗,但气温较低,请注意保暖。如果您需要更详细的天气预报(比如未来几天的天气情况),请告诉我,我可以为您查询更多信息。

结果分析

  1. 工具调用决策:LLM正确识别需要调用天气查询工具
  2. 参数提取:准确提取了城市名称"北京"
  3. 数据整合:将原始API响应转化为用户友好的格式
  4. 贴心建议:加入了保暖提醒,体现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应用开辟了无限可能:

技术价值总结

  1. 实时信息获取:突破LLM的时间限制
  2. 能力扩展:从纯文本处理到实际任务执行
  3. 标准化接口:基于OpenAI标准,易于扩展和维护

未来发展方向

  1. 多模态工具:结合图像识别、语音处理等能力
  2. 复杂任务规划:支持多步骤、长周期的任务执行
  3. 自主决策:AI能够自主选择和使用工具组合
  4. 安全机制:确保工具调用的安全性和可控性
相关推荐
鱼骨不是鱼翅2 小时前
力扣hot100----1day
python·算法·leetcode·职场和发展
2501_941236212 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
程序猿_极客2 小时前
【2025 最新】 Python 安装教程 以及 Pycharm 安装教程(超详细图文指南,附常见问题解决)
开发语言·python·pycharm·python安装以及配置
b***66612 小时前
Python 爬虫实战案例 - 获取社交平台事件热度并进行影响分析
开发语言·爬虫·python
chushiyunen2 小时前
django使用笔记
笔记·python·django
2501_941111343 小时前
实战:用OpenCV和Python进行人脸识别
jvm·数据库·python
ada7_3 小时前
LeetCode(python)——73.矩阵置零
python·算法·leetcode·矩阵
程序员爱钓鱼3 小时前
Python编程实战:用好 pdb 和 logging,程序再也不黑箱运行了
后端·python·trae
程序员爱钓鱼3 小时前
Python编程实战:从 timeit 到 cProfile,一次搞懂代码为什么慢
后端·python·trae