让 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 助手!

相关推荐
用户5191495848452 小时前
信号、Shell与Docker:层层嵌套的陷阱剖析
人工智能·aigc
文心快码BaiduComate2 小时前
Comate Figma2Code智能体升级,畅享Figma2Code不受限
人工智能·程序员·前端框架
天草二十六_简村人2 小时前
docker安装MoneyPrinterTurbo,实现文本转视频的本地私有化部署
后端·docker·ai·容器·ai编程
一RTOS一2 小时前
工业AI安监超脑,为智能建造打造“安全数字底座”
人工智能·安全
云安全联盟大中华区2 小时前
构建AI原生工程组织:关于速度、文化与安全的经验
人工智能·安全·web安全·网络安全·ai·ai-native
nju_spy2 小时前
论文阅读 - 深度学习端到端解决库存管理问题 - 有限时间范围内的多周期补货问题(Management Science)
人工智能·深度学习·动态规划·端到端·库存管理·两阶段pto·多周期补货问题
u***j3242 小时前
深度学习实践
人工智能·深度学习
爱分享的鱼鱼2 小时前
Srpingboot入门:通过实践项目系统性理解Springboot框架
spring boot·后端·spring
r***d8652 小时前
深度学习挑战
人工智能·深度学习