前言
本系列分享前四期分别讲述了
学完以上内容我们掌握了LangChain代码编写的基本能力。近年来大模型如火如荼的发展,能力范围也不再局限于智能问答。在Function Calling功能、MCP协议的加持下,当下主流大模型包括Qwen、DeepSeek等已经成为能够调用各种各样工具的多面手,是智能体开发的基石。作为智能体开发当之无愧的第一框架,在MCP爆火之前,LangChain就已经可以搭建链将工具封装在对应的工作流中,也能借助LangChain Agent功能实时灵活创建不同的Chain完成复杂工具调用。从本期分享开始,我们将介绍如何在LangChain中接入工具,并进一步介绍如何使用LangChain Agent库来搭建更加复杂的工作流。
本系列分享是笔者结合自己学习工作中使用LangChain&LangGraph经验倾心编写,力求帮助大家体系化快速掌握LangChain&LangGraph AI Agent智能体开发的技能!大家感兴趣可以关注笔者掘金账号和系列专栏。更可关注笔者同名微信公众号: 大模型真好玩, 每期分享涉及的代码均可在公众号私信: LangChain智能体开发获得。
一、LangChain接入内置工具
首先我们介绍最基本的LangChain接入工具流程。LangChain生态从建立起就内置集成了非常多的实用工具,开发者可以快速调用这些工具完成更加复杂工作流的开发。大家可访问官方文档python.langchain.com/docs/integr… 查看LangChain内置工具列表。LangChain内置工具可分为Search在线搜索工具
、Code Interpreter代码解释器工具
、Productivit自动化工具
、WebBrowsing浏览器自动化工具
、Database数据库工具
等多种类别。
本实例我们以Python代码解释器工具为例,介绍如何将内置工具接入LangChain工作流中:
1.1 环境搭建与数据准备
在我们创建的名为langchainenv
的anaconda
虚拟环境下执行pip install langchain-community langchain-experimental
命令安装内置工具的依赖包。
本次分享通过一个“各城市基本情况表”测试LangChain内置代码解释器工具功能, 表格不同列的含义如下表所示,具体数据大家可以关注笔者的同名微信公众号:大模型真好玩, 并私信: LangChain智能体开发 免费获得。
列名 | 中文含义 | 说明 |
---|---|---|
jisuCity | 城市名称 | 城市的标准名称,例如东京、德里、上海等。 |
Country | 国家 | 城市所属的国家,例如日本、印度、中国等。 |
Continent | 大洲 | 城市所在的大洲,例如亚洲、南美洲、非洲等。 |
Population | 人口 | 城市的人口数量,单位为“人”。 |
GDP_Billion_USD | GDP(十亿美元) | 城市的国内生产总值,单位为“十亿美元”。 |
Avg_Temperature_C | 平均气温(摄氏度) | 城市的年平均气温,单位为“摄氏度”。 |
Annual_Rainfall_mm | 年降雨量(毫米) | 城市的年降雨量,单位为“毫米”。 |
Cost_of_Living_Index | 生活成本指数 | 城市的生活成本指数,数值越高表示生活成本越高(基准通常为纽约=100)。 |
Happiness_Index | 幸福指数 | 城市的居民幸福指数,数值越高表示居民幸福感越强。 |
Year | 年份 | 数据对应的年份,例如2023年。 |
Area_km2 | 面积(平方公里) | 城市的面积,单位为“平方公里”。 |
Literacy_Rate | 识字率(百分比) | 城市居民的识字率,单位为“百分比”。 |
Internet_Penetration | 互联网普及率(百分比) | 城市中使用互联网的人口比例,单位为“百分比”。 |
1.2 测试LangChain内置代码解释器工具功能
首先我们学习LangChain中工具调用的基本方法,执行如下代码调用LangChain的代码解释器求取不同城市的GDP均值:
import pandas as pdfrom langchain_experimental.tools import PythonAstREPLTool # 从LangChain依赖库引入Python代码解释器df = pd.read_csv('global_cities_data.csv')tool = PythonAstREPLTool(locals={"df": df}) # 传递给代码解释器的局部变量,这里是读取表格内容的pandas对象res = tool.invoke("df['GDP_Billion_USD'].mean()") # 计算变量GDP的均值print(res)
上述代码通过指定LangChain代码解释器的变量内容,并调用tool.invoke()
执行表达式语句。LangChain代码解释器执行并返回结果。
1.3 创建LangChain工作流并绑定内置工具
LangChain代码解释器工具不但可以执行代码,还可以通过model.bind()
与大模型组件绑定,让大模型具备调用工具的能力。
import pandas as pdfrom langchain.chat_models import init_chat_modelfrom langchain_experimental.tools import PythonAstREPLTool # 从LangChain依赖库引入Python代码解释器df = pd.read_csv('global_cities_data.csv')tool = PythonAstREPLTool(locals={"df": df}) # 传递给代码解释器的局部变量,这里是读取表格内容的pandas对象# 使用 硅基流动 模型model = init_chat_model( model="Qwen/Qwen3-8B", model_provider="openai", base_url="https://api.siliconflow.cn/v1/", api_key="",)llm_with_tools = model.bind_tools([tool]) # 将工具与大模型绑定response = llm_with_tools.invoke( "我有一张表,名为'df',请帮我计算GDP_Billion_USD字段的均值。")print(response)
以上代码的执行结果如下,此时我们发现LangChain回复的结果不再是简单的文字内容,而是一条调用外部工具的消息,可以看到function
字段内容中的name
指明了调用工具的名称,query
指明了要执行的代码。
有了要执行的代码,下一步要将消息中涉及到的代码运行的核心参数提取出来, 在上述代码中添加如下内容:
from langchain_core.output_parsers.openai_tools import JsonOutputKeyToolsParserparser = JsonOutputKeyToolsParser(key_name=tool.name, first_tool_only=True)llm_with_tools = model.bind_tools([tool]) # 将工具与大模型绑定llm_chain = llm_with_tools | parserresponse = llm_chain.invoke( "我有一张表,名为'df',请帮我计算GDP_Billion_USD字段的均值。")print(response)
执行结果如下, JsonOutputKeyToolsParser
将核心代码提取出来
这就完啦?别忘了我们还没有做到LangChain代码的自动执行呢,进一步优化代码。首先增加提示词模板,让模型知道目前运行环境,从而无需反复提示df变量
:
# 添加提示词模板system = f"""你可以访问一个名为 `df` 的 pandas 数据框,你可以使用df.head().to_markdown() 查看数据集的基本信息, \请根据用户提出的问题,编写 Python 代码来回答。只返回代码,不返回其他内容。只允许使用 pandas 和内置库。"""prompt = ChatPromptTemplate([ ("system", system), ("user", "{question}")])# 在链中加入提示词组件llm_chain = prompt | llm_with_tools | parserresponse = llm_chain.invoke( "我有一张表,名为'df',请帮我计算GDP_Billion_USD字段的均值。")print(response)
执行结果如下所示:
然后继续在“链”中将tool
工具引入让代码自动执行(大家回顾我们所讲内容,发现LangChain工具tool
也是通过invoke
方法进行调用,这表明tool
也是Runnable
组件,可以无缝接入LangChain“链”中)。修改“链”代码如下:
llm_chain = prompt | llm_with_tools | parser | toolresponse = llm_chain.invoke( "我有一张表,名为'df',请帮我计算GDP_Billion_USD字段的均值。")print(response)
执行结果如下, 可看到目前LangChain已经能够准确自动执行代码。
完整的代码如下,大家可以仔细阅读。本系列分享所有的代码和数据大家均可关注笔者的同名微信公众号:大模型真好玩, 并私信: LangChain智能体开发 免费获得。
import pandas as pdfrom langchain.chat_models import init_chat_modelfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_experimental.tools import PythonAstREPLTool # 从LangChain依赖库引入Python代码解释器from langchain_core.output_parsers.openai_tools import JsonOutputKeyToolsParserdf = pd.read_csv('global_cities_data.csv')tool = PythonAstREPLTool(locals={"df": df}) # 传递给代码解释器的局部变量,这里是读取表格内容的pandas对象# 使用 硅基流动 模型model = init_chat_model( model="Qwen/Qwen3-8B", model_provider="openai", base_url="https://api.siliconflow.cn/v1/", api_key="",)# 添加提示词模板system = f"""你可以访问一个名为 `df` 的 pandas 数据框,你可以使用df.head().to_markdown() 查看数据集的基本信息, \请根据用户提出的问题,编写 Python 代码来回答。只返回代码,不返回其他内容。只允许使用 pandas 和内置库。"""prompt = ChatPromptTemplate([ ("system", system), ("user", "{question}")])parser = JsonOutputKeyToolsParser(key_name=tool.name, first_tool_only=True)llm_with_tools = model.bind_tools([tool]) # 将工具与大模型绑定llm_chain = prompt | llm_with_tools | parser | toolresponse = llm_chain.invoke( "我有一张表,名为'df',请帮我计算GDP_Billion_USD字段的均值。")print(response)
大家可以多测几组验证我们代码执行的正确性:
二、 LangChain接入自定义工具
能调用外部工具,是大模型进化为智能体Agent的关键,如果不能使用外部工具,大模型就只能是个简单的聊天机器人,甚至连查询天气都做不到。由于底层技术限制,大模型本身是无法和外部工具直接通信的,因此Function calling
的思路,就是创建一个外部函数(function)作为中介,一边传递大模型的请求,另一边调用外部工具,最终让大模型能够间接的调用外部工具。关于Function Calling的知识这里不加赘述,大家可以阅读我的爆款文章从0到1开发DeepSeek天气助手智能体——你以为大模型只会聊天?Function Calling让它“上天入地”
除了使用LangChain的内部工具,我们还可以自行创建外部函数并将其封装为一个LangChain“链”可调用的tool
组件。具体的步骤如下:
2.1 环境准备
本次分享同样使用从0到1开发DeepSeek天气助手智能体——你以为大模型只会聊天?Function Calling让它“上天入地”文章中介绍的心知天气api, 大家登录心知天气官网并在控制台申请免费的api key即可,具体步骤可见笔者文章。
编写获取天气函数,只要传入城市名,即可获得相应的温度和天气状况:
import requestsdef get_weather(loc): url = "https://api.seniverse.com/v3/weather/now.json" params = { "key": "你注册的心知天气api_key", "location": loc, "language": "zh-Hans", "unit": "c", } response = requests.get(url, params=params) temperature = response.json() return temperature['results'][0]['now']print(get_weather('北京'))
执行结果如下:
2.2 LangChain接入天气函数
LangChain接入自定义函数的流程比较简单:
首先引入tool
装饰器,让LangChain能够识别外部函数,注意函数介绍注释必须完整,装饰器通过读取注释提炼识别函数的内容:
import requestsfrom langchain_core.tools import tool@tooldef get_weather(loc): """ 查询即时天气函数 :param loc: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\ :return:心知天气 API查询即时天气的结果,具体URL请求地址为:"https://api.seniverse.com/v3/weather/now.json" 返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息 """ url = "https://api.seniverse.com/v3/weather/now.json" params = { "key": "你注册的心知天气api key", "location": loc, "language": "zh-Hans", "unit": "c", } response = requests.get(url, params=params) temperature = response.json() return temperature['results'][0]['now']print(get_weather.name)print(get_weather.description)print(get_weather.args)
同样的我们引入大模型并使用bind_tools
方法将工具绑定到大模型上,接下来就可以通过“链”的invoke
方法调用模型, 代码如下:
from langchain.chat_models import init_chat_model# 使用 硅基流动 模型model = init_chat_model( model="Qwen/Qwen3-8B", model_provider="openai", base_url="https://api.siliconflow.cn/v1/", api_key="",)tools = [get_weather]llm_with_tools = model.bind_tools(tools)response = llm_with_tools.invoke("你好, 请问北京的天气怎么样?")print(response)
调用结果显示大模型产生了一个tool_calls
响应,其中包含了要执行的函数名称和参数名称:
同样的我们调用JsonOutputKeyToolsParser
输出解析器来处理模型响应将函数参数提取出来
parser = JsonOutputKeyToolsParser(key_name=get_weather.name, first_tool_only=True)llm_chain = llm_with_tools | parserresponse = llm_chain.invoke("你好, 请问北京的天气怎么样?")print(response)
将我们的函数组件接入链,完成模型的的自动运行,添加如下代码:
get_weather_chain = llm_chain | get_weatherresponse = get_weather_chain.invoke("请问上海今天天气如何?")print(response)
以上就是我们今天分享的全部内容,整体的流程还是比较清晰的,大家下来尝试编写函数并接入LangChain吧!
三、总结
本期内容分享了LangChain接入内部工具和自定义工具函数的方法,也是LangChain智能体开发最重要的内容之一。整体的流程一致:先将工具使用model.bind()
绑定到大模型上,然后通过JsonOutputKeyToolsParser
解析返回结果,最后经过工具函数自动执行。下一期的内容我们将学习LangChain智能体对工具函数串联、并联等结构编排的知识,大家一起期待吧!
本系列分享预计会有20节左右的规模,保证大家看完一定能够掌握LangChain&LangGraph的开发能力,大家感兴趣可关注笔者掘金账号和专栏,更可关注笔者的同名微信公众号:大模型真好玩, 本系列分享的全部代码均可在微信公众号私信笔者: LangChain智能体开发 免费获得。