让 LLM 与外界对话:使用 Function Calling 实现天气查询工具

引言

大型语言模型(LLM)虽然拥有强大的文本生成和理解能力,但它本质上是一个"封闭系统"------无法直接访问互联网、数据库或实时数据。为了让 LLM 真正具备"感知世界"的能力,我们需要为其配备"工具"(Tools),并通过 Function Calling(函数调用) 机制实现与外部世界的交互。

本文将带你从零开始,使用 Python + OpenAI 兼容 API(以 DeepSeek 为例),实现一个能自动查询天气的智能助手。你将学到:

  • 如何定义并注册工具(Tool)
  • 如何解析 LLM 的工具调用请求
  • 如何执行真实函数并将结果返回给模型
  • 如何完成完整的"用户提问 → 模型决策 → 调用工具 → 返回答案"闭环

1. 准备工作

安装依赖

复制代码
pip install requests openai

导入必要库

javascript 复制代码
import requests
import json
from openai import OpenAI

2. 编写天气查询工具函数

我们使用 心知天气 的免费 API 获取实时天气数据。

python 复制代码
def get_weather(location: str) -> str:
    """
    根据城市名称查询当前天气
    :param location: 城市名,如 "北京"
    :return: 天气描述字符串
    """
    url = "https://api.seniverse.com/v3/weather/now.json"
    params = {
        "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}"

3. 配置 LLM 客户端(以 DeepSeek 为例)

DeepSeek 的 API 兼容 OpenAI 协议,因此我们可以直接使用 openai SDK。

ini 复制代码
client = OpenAI(
    api_key='---',  # 替换为你的 DeepSeek API Key
    base_url='https://api.deepseek.com'
)

4. 定义工具(Tool)Schema

为了让 LLM 知道它可以调用哪些函数,我们需要提供结构化的工具描述:

ini 复制代码
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的当前天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,如'北京'"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

这个 JSON Schema 告诉模型:

  • 有一个叫 get_weather 的函数可用
  • 它需要一个 location 字符串参数
  • 它的作用是查天气

5. 实现完整的 Function Calling 流程

现在,我们模拟一次完整的对话:

ini 复制代码
# 用户提问
messages = [{"role": "user", "content": "北京天气怎么样?"}]

# 第一次调用:让模型决定是否需要调用工具
response = client.chat.completions.create(
    model="deepseek-reasoner",
    messages=messages,
    tools=tools,
    tool_choice="auto",
    temperature=0.1
)

# 获取模型返回的消息
response_message = response.choices[0].message
messages.append(response_message)  # 将模型消息加入对话历史

# 检查是否需要调用工具
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)
else:
    # 不需要工具,直接输出模型回答
    print(response_message.content)

6. 运行效果

当用户输入:

复制代码
北京天气怎么样?

程序输出:

复制代码
根据最新天气数据,北京当前天气:多云,气温 5℃。

整个过程如下:

  1. 用户提问
  2. LLM 判断需要调用 get_weather("北京")
  3. 程序执行该函数,获取真实天气
  4. 将结果喂回 LLM
  5. LLM 生成自然语言回答

7. 关键点总结

步骤 说明
工具定义 使用 JSON Schema 描述函数签名
第一次调用 设置 toolstool_choice="auto",让模型决定是否调用
解析 tool_calls response_message.tool_calls 中提取函数名和参数
执行真实函数 在本地运行 Python 函数(如网络请求)
返回结果 role="tool" 的消息格式追加到对话历史
第二次调用 让模型基于工具结果生成最终回答

8. 扩展思考

  • 可以注册多个工具(如查股票、发邮件、查数据库)
  • 结合 LangChain 或 LlamaIndex 可构建更复杂的 Agent
  • 注意控制上下文长度,避免因消息过长导致 token 超限
  • 敏感操作需加入权限校验和安全过滤

结语

Function Calling 是 LLM 走出"幻觉牢笼"、连接现实世界的关键桥梁。通过本文的实践,你已经掌握了如何让大模型"动手做事"。下一步,不妨尝试接入更多 API,打造属于你自己的 AI 助手!

相关推荐
晚霞的不甘1 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
jiang_changsheng2 分钟前
RTX 2080 Ti魔改22GB显卡的最优解ComfyUI教程
python·comfyui
JoySSLLian8 分钟前
手把手教你安装免费SSL证书(附宝塔/Nginx/Apache配置教程)
网络·人工智能·网络协议·tcp/ip·nginx·apache·ssl
BestSongC9 分钟前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
喵叔哟12 分钟前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
模型时代16 分钟前
Anthropic明确拒绝在Claude中加入广告功能
人工智能·microsoft
夕小瑶19 分钟前
OpenClaw、Moltbook爆火,算力如何48小时内扩到1900张卡
人工智能
一枕眠秋雨>o<21 分钟前
透视算力:cann-tools如何让AI性能调优从玄学走向科学
人工智能
那个村的李富贵35 分钟前
昇腾CANN跨行业实战:五大新领域AI落地案例深度解析
人工智能·aigc·cann
集简云-软件连接神器38 分钟前
技术实战:集简云语聚AI实现小红书私信接入AI大模型全流程解析
人工智能·小红书·ai客服