LangChain系列文章超链接:

《Python+LangChain+大模型实战:使用通用配置加载器的Few‑Shot小样本提示词教程》

《使用Python版LangChain调用外部函数实战:实现智能天气查询》

《Python + LangChain Agent 实战:从单城市查询到多城市天气智能对比》

《Python+LangChain Agent 工具选择逻辑深度解析》

在大模型应用开发中,单纯依赖模型自身的知识库往往无法满足实时数据查询需求(比如天气、股票、快递信息等)。LangChain 作为大模型应用开发框架,提供了灵活的工具调用能力,能让大模型 “调用外部函数” 获取实时数据,大幅拓展应用边界。本文将以 “实时天气查询” 为例,详解如何基于 LangChain 实现大模型调用外部 API 函数的完整流程。

一、核心场景与技术栈

场景目标

让大模型能够响应 “查询某城市天气” 的指令,不再依赖内置数据,而是调用 OpenWeatherMap 的公开 API 获取实时天气数据,并以自然语言解析返回结果。

技术栈

  • 框架:LangChain(版本号1.2.15)
  • 大模型:OpenAI 兼容接口(本文使用小米大模型)
  • 外部 API:OpenWeatherMap(地理编码 + 天气数据接口)
  • 编程语言:Python 3.12

前期准备

  • 大模型API key获取:本文使用的是小米mimo-v2-flash模型,自行去Mimo官网注册
  • OpenWeather  API key获取:可以免费注册,自行去OpenWeather官网注册

二、核心实现步骤

步骤 1:封装外部天气查询函数(Tool 定义)

首先需要封装调用 OpenWeatherMap API 的函数,并通过 LangChain 的 @tool 装饰器将其标记为 “可被大模型调用的工具”。

新建 weather_util.py,实现核心逻辑:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Project :pythonProject
@File    :weather_util.py
@Author  :BillFang
@Date    :2026/4/15 09:19
@Description :
"""

import requests
from langchain_core.tools import tool

class OpenWeather():
    def __init__(self, APPID):
        self.app_id = APPID


    def get_lat_lon(self, city_name):
        geo_url = "http://api.openweathermap.org/geo/1.0/direct"
        params = {
            "q": city_name,
            "limit": 1,
            "appid": self.app_id,
        }
        try:
            res = requests.get(geo_url, params=params)
            res.raise_for_status()
            data = res.json()
            if not data:
                print("未找到该城市")
                return None, None
            lat = data[0]["lat"]
            lon = data[0]["lon"]
            name = data[0]["name"]
            country = data[0]["country"]
            print(f"定位成功:{name}, {country}")
            return lat, lon
        except Exception as e:
            print("获取经纬度失败:", e)
            return None, None
@tool
def get_city_weather_data(city_name) -> dict:
    """
        调用 OpenWeatherMap API 获取指定经纬度的天气信息
        :param lat: 纬度
        :param lon: 经度
        :param appid: OpenWeatherMap 申请的 API Key
        :return: 天气数据字典 / None
        """
    weather_client = OpenWeather(APPID='')
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    lat, lon = weather_client.get_lat_lon(city_name)
    # 请求参数
    params = {
        "lat": lat,
        "lon": lon,
        "appid": weather_client.app_id,
        "units": "metric",  # 单位:metric=摄氏度,imperial=华氏度,默认开尔文
        "lang": "zh_cn"  # 返回中文描述
    }

    try:
        # 发送 GET 请求
        response = requests.get(base_url, params=params)
        # 检查请求是否成功
        response.raise_for_status()
        # 解析 JSON 数据
        weather_data = response.json()
        return weather_data

    except requests.exceptions.RequestException as e:
        print(f"请求出错:{e}")
        return None

if __name__ == '__main__':
    #方法加上@tool时必须使用.invoke方法调用
    print(get_city_weather_data.invoke('扬州'))

关键要点

  • @tool 装饰器:将普通函数转化为 LangChain 可识别的 Tool,大模型能解析函数描述、参数并主动调用;
  • 分层设计:先通过地理编码接口获取城市经纬度,再调用天气接口,保证查询准确性;

步骤 2:LangChain 整合大模型与工具调用

新建 langchain_skill.py,实现 “大模型 + 工具调用 + 结果解析” 的完整流程:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Project :pythonProject
@File    :langchain_skill.py
@Author  :BillFang
@Date    :2026/4/15 09:37
@Description :
"""
from langchain_core.output_parsers import JsonOutputKeyToolsParser
from langchain_core.prompts import ChatPromptTemplate

from config_loader import ConfigLoader
import openai
from langchain_openai import ChatOpenAI
from utils.weather_util import get_city_weather_data

def direct_question(client):
    chat_template = ChatPromptTemplate.from_messages([
        ("system", "你是一个全能的智能助手。"),
        ("system", "请你查一下{city}的天气。")
    ])

    message = chat_template.format_messages(city="扬州")

    response = client.invoke(message)

    return response.content

def analyse_weather_chains(client, ai_msg):
    chat_template = ChatPromptTemplate.from_messages([
        ("system", "这是实时的{city}的天气数据,信息来源于Openweather API:https://api.openweathermap.org/data/2.5/weather,详细数据为:{detail}。"),
        ("system", "请你解析一下该数据,以自然语言的形式输出。")
    ])

    message = chat_template.format_messages(city=ai_msg["name"], detail=ai_msg)
    response = client.invoke(message)

    return response.content


if __name__ == '__main__':
    # 1. 加载配置(第一次会读文件,之后直接用缓存)
    config = ConfigLoader()
    xiaomi_cfg = config.get_xiaomi_config()

    openai.api_key = xiaomi_cfg["api_key"]
    openai.api_base_url = xiaomi_cfg["api_base_url"]
    client = ChatOpenAI(api_key=openai.api_key, base_url=openai.api_base_url, model=xiaomi_cfg["model"])

    tools = [get_city_weather_data]

    #绑定tools
    client_with_tool = client.bind_tools(tools)

    get_weather_data_chain= client_with_tool | JsonOutputKeyToolsParser(key_name="get_city_weather_data", first_tool_only=True) | get_city_weather_data

    weather_str = get_weather_data_chain.invoke("今天扬州天气怎么样?")
    print(weather_str)
    # 数据增强
    reponse = analyse_weather_chains(client, weather_str)

    print("使用天气查询skill返回的结果:")
    print(reponse)
    print("+++++++++++++++++++++++++++++++++++++++++")
    print("+++++++++++++++++++++++++++++++++++++++++")
    print("+++++++++++++++++++++++++++++++++++++++++")
    direct_answer = direct_question(client)
    print("直接询问大模型天气得到的结果:")
    print(direct_answer )

核心逻辑拆解

  1. 配置与客户端初始化:加载大模型的 API Key、地址等配置,初始化 ChatOpenAI 客户端;
  2. 工具绑定:通过 bind_tools 将天气查询函数绑定到大模型客户端,让大模型知道 “可以调用这个工具”;
  3. 链式调用
    • client_with_tool:大模型接收用户问题后,判断需要调用 get_city_weather_data 工具;
    • JsonOutputKeyToolsParser:解析大模型输出,提取工具调用的参数(如城市名);
    • get_city_weather_data:执行工具函数,获取实时天气数据;
  4. 结果解析:将原始天气数据传入大模型,生成自然语言回答;
  5. 对比验证:展示 “工具调用(实时数据)” 与 “直接询问(模型内置数据)” 的差异。

步骤 3:运行效果对比

E:\workSoft\python3.12\python.exe D:\pythonCode\pythonProject\langchain\langchain_skill.py 
定位成功:Yangzhou City, CN
{'coord': {'lon': 119.4078, 'lat': 32.3969}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': '阴,多云', 'icon': '04d'}], 'base': 'stations', 'main': {'temp': 22.69, 'feels_like': 22.58, 'temp_min': 22.69, 'temp_max': 22.69, 'pressure': 1013, 'humidity': 60, 'sea_level': 1013, 'grnd_level': 1011}, 'visibility': 10000, 'wind': {'speed': 4.34, 'deg': 102, 'gust': 4.93}, 'clouds': {'all': 99}, 'dt': 1776240999, 'sys': {'country': 'CN', 'sunrise': 1776202415, 'sunset': 1776249061}, 'timezone': 28800, 'id': 1787227, 'name': 'Yangzhou', 'cod': 200}
使用天气查询skill返回的结果:
根据您提供的实时数据,以下是扬州市当前的天气情况解析:

**总体天气状况:**
扬州市目前的天气为**阴天,伴有厚重的云层**。

**具体气象数据:**
*   **气温:** 当前气温为 **22.69°C**,体感温度与实际气温基本一致(22.58°C)。
*   **湿度:** 空气相对湿度为 **60%**,体感较为舒适。
*   **风况:** 正吹着**东南风**(风向角度约102度),风速为 **4.34米/秒**,瞬时阵风风速可达 **4.93米/秒**。
*   **气压:** 大气压强为 **1013 hPa**(海平面气压),处于标准大气压范围。
*   **能见度:** 能见度为 **10公里**,视野良好。
*   **云量:** 云层覆盖率为 **99%**,几乎完全被云层覆盖。

**日出与日落时间(基于时间戳解析):**
*   **日出时间:** 当地时间约 05:33
*   **日落时间:** 当地时间约 18:31

**数据更新时间:**
数据获取自 OpenWeather API,当前为实时观测值。
+++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++
直接询问大模型天气得到的结果:
我是MiMo,小米的AI助手。我目前无法直接访问实时天气数据,所以无法为您提供扬州当前的天气情况。

建议您通过以下方式查询:
1. 使用手机自带的天气应用查看
2. 访问中国天气网等专业气象网站
3. 在搜索引擎中搜索"扬州天气"

如果您有其他问题,我很乐意帮助您。

进程已结束,退出代码为 0

使用LangChain + 调用外部天气函数返回真实实时 JSON 天气数据(温度、湿度、风速、气压、日出日落等),并通过大模型分析数据天气,以自然语言的方式返回回答。 直接询问大模型,大模型明确回复:“我无法直接访问实时天气数据”,并让你去用天气 APP、网站查询

三、关键知识点总结

1. LangChain Tool 核心特性

  • @tool 装饰器:自动生成工具的描述、参数元数据,大模型能基于这些信息判断是否调用、如何传参;
  • 工具调用流程:大模型 → 决策调用工具 → 解析参数 → 执行工具 → 处理结果;
  • 输出解析器:JsonOutputKeyToolsParser 专门用于解析工具调用的输出,提取目标工具的执行参数 / 结果。

2. 实时数据 vs 模型内置数据

  • 直接询问大模型:依赖训练时的历史数据,无实时性,可能出错;
  • 工具调用:调用外部 API 获取实时数据,结果精准、时效性强。

3. 拓展方向

  • 多工具整合:除了天气,可添加快递查询、股票查询等工具,让大模型根据问题自动选择工具;
  • 错误重试:给工具调用添加重试逻辑,处理网络波动、城市名错误等场景;
  • 工具参数校验:在工具函数中增加参数合法性校验(如城市名非空、经纬度范围);
  • 多轮对话:结合 LangChain 的对话记忆,实现 “先问城市,再查天气” 的多轮交互。

四、总结

LangChain 的工具调用能力是连接大模型与外部世界的核心桥梁,通过将外部 API 封装为 Tool,能让大模型突破 “知识库过期” 的限制,实现实时数据查询、业务系统交互等复杂场景。本文以天气查询为例,从工具封装、大模型绑定、链式调用到结果解析,完整展示了 LangChain 调用外部函数的流程,希望能为大家开发大模型应用提供参考。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐