🌤️ 让大模型“感知现实世界”:通过 Function Calling 实现 LLM 与天气 API 的智能交互

64 阅读4分钟

关键词:LLM 工具调用(Function Calling)、DeepSeek API、心知天气 API、Python 实战、AI 联网能力


一、背景:为什么 LLM 需要“工具”?

大型语言模型(LLM)如 DeepSeek、GPT 等,虽然知识丰富、表达流畅,但存在两个天然局限:

  1. 知识截止:无法获取训练数据之后的信息;
  2. 无实时感知能力:无法知道“此刻北京的天气”或“当前股票价格”。

为突破这一限制,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 协议,因此可直接使用 openai SDK。


三、第一步:封装天气查询工具函数

我们首先实现一个可靠的 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)时代,始于一次函数调用。


八、附录:注意事项

  1. API Key 安全:务必通过 os.getenv("WEATHER_KEY") 管理密钥;
  2. 错误处理:生产环境需增加重试、限流、日志;
  3. 模型选择deepseek-reasoner 支持复杂推理,普通对话可用 deepseek-chat
  4. 字段一致性:确保 tools 中的参数名(如 location)与函数定义完全一致。

作者:一位探索 AI 与现实世界连接的开发者
时间:2025 年
适用读者:Python 工程师、AI 应用开发者、LLM 爱好者