当前位置: 首页
AI教程
LangChain从入门到精通:工具与函数调用详解

LangChain从入门到精通:工具与函数调用详解

热心网友 时间:2026-05-28
转载

大模型的能力边界:时效性挑战与解决方案

先看一段代码,猜猜大模型会输出什么?

# 通义千问大模型model = get_lc_model_client()output_parser = JsonOutputParser()resp = model.invoke("今天是几月几号?")print(resp)

结果令人意外——AI竟然不知道今天是几月几号。再换一个模型(DeepSeek)试试:

model = get_ali_model_client()

没错,它确实给了一个日期,但那并不是真实的今天。之前讨论“为什么需要RAG”时,我们提到过大模型的时效性局限:训练成本极高,模型不可能实时更新。因此,那些最新的事件、最新的知识,大模型很可能一无所知。

这就是大模型的一个能力边界。要突破这一限制,除了RAG技术,还有另一个关键手段——Tool(工具调用)。

Tool:大模型的能力延伸

Tool(工具)是LangChain中的一个核心概念。它封装了一个具体功能(比如一个Python函数),包含名称、描述和参数模式(Schema)。开发者通过@tool装饰器或继承BaseTool来创建工具,本质上是在告诉模型:“我这里有这些能力可以调用。” 整个工作流程如下:

  • 定义工具:开发者将函数(例如get_date())及其描述、参数格式提前告知LLM。
  • 模型规划:用户提问后,LLM并不直接给出答案,而是分析用户意图,选择合适的工具,并严格按照格式生成一个结构化的调用请求。
  • 外部执行:程序解析这个请求,安全地在本地或远端执行真实的函数,获取结果。
  • 整合回复:将执行结果返回给LLM,由它组织成自然语言回复用户。

简单来说,LLM扮演“大脑”(负责理解和规划),外部函数扮演“手脚”(负责执行和获取信息),两者通过结构化的“神经接口”(Function Calling规范)协同工作。

bind_tools():动态绑定工具

bind_tools()的作用是把一个或多个工具(函数)转换成大模型能理解和遵循的“调用规范”(通常是JSON Schema格式),然后“绑定”到某个特定的对话模型实例上。绑定之后,这个模型在思考时,就具备了调用这些工具的能力。

  • 动态性与组合性bind_tools()的最大优势在于动态性。你可以在运行时根据不同的场景,为同一个模型绑定不同的工具集,实现高度灵活。
  • 底层协议屏蔽:它抽象了不同模型提供商(OpenAI、Anthropic、DeepSeek)在工具调用上的细节差异,提供统一接口。在OpenAI的上下文中,它本质上是在准备tools参数。

# 大模型客户端绑定工具tool_llm = model.bind_tools([get_date, open_browser])resp = tool_llm.invoke("今天是几月几号?")

Agent:工具调用的智能控制器

工具的选择和调用执行,最终是由Agent来完成的。

# 创建Agentagent = create_agent(model=llm,# 聊天模型tools=tools, # 工具列表system_prompt=system_prompt,checkpointer=memory# 传入记忆组件)

在大模型使用工具时,你可以用bind_tools进行工具绑定,但在工程实践中,推荐优先使用带tools参数的Agent,因为它提供了更完善的工具管理和执行流程。

方式一:@tool装饰器

代码示例

获取今天具体日期的自定义工具:

# 注意:函数的描述必须写在函数体中的第一行@tooldef get_date():# 文本描述相当于工具说明说,大模型正是依靠这段说明来选择对应工具""" 获取今天的具体日期 """# """ 获取今天的北京的天气 """return datetime.date.today().strftime("%Y-%m-%d")

获取浏览器并打开指定网站的工具:

mport webbrowser@tooldef open_browser(url, browser_name=None):# """ 获取浏览器,打开网站 """""" 获取浏览器,打开网站可以做很多事情,包括查询天气,汽车限号等 """if browser_name:# 获取特定浏览器的控制器browser = webbrowser.get(browser_name)else:# 使用默认浏览器browser = webbrowser# 打开浏览器并导航到指定的URLbrowser.open(url)

使用方式:

agent = create_agent(model=llm,# 聊天模型tools=[get_date, open_browser], # 工具列表system_prompt=system_prompt,checkpointer=memory# 传入记忆组件)# 获取今天的日期result = agent.invoke({"messages":[{"role":"user","content":"今天是几月几号?"}]})

注意事项

  1. 函数的描述必须写在函数体中的第一行,否则AI无法识别。
  2. 函数的描述必须准确,且与函数实际功能保持一致。否则会导致回答混乱。

比如,如果把get_date的描述改为“获取今天的北京的天气”:

@tooldef get_date():""" 获取今天的北京的天气 """return datetime.date.today().strftime("%Y-%m-%d")result = agent.invoke({"messages":[{"role":"user","content":"今天北京的天气怎么样?"}]})

用户问天气,结果却调用了日期函数——这就是描述错误带来的问题。

Log验证

前面我们已经介绍了核心流程,现在结合代码Debug来验证一下。从打印结果可以看到:

  1. 用户提问后,大模型发现自己无法直接回答。
  2. 它尝试寻找合适的工具,找到后触发了tool_callsfinesh_reason=tool_calls
  3. tool_calls信息显示name=get_date
  4. 调用get_date返回ToolMessage(2026-03-12)
  5. AI拿到日期信息后,就能给出正确答案了。

果然,和我们前面讲解的核心流程基本一致。

方式二:Tool()类

除了@tool装饰器,还可以通过Tool()类来显式定义工具。

外部函数定义

# 定义工具函数def get_current_time(input: str = "") -> str:"""获取当前时间"""current_datetime = datetime.now()formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')result = f"当前时间:{formatted_time}。"print(result)return resultdef recom_drink(input: str = "") -> str:"""推荐附近的饮品店"""result = '''距离您500米内有如下饮料店:n1、蜜雪冰城n2、茶颜悦色n另外距离您200米内有惠民便利店,里面应该有矿泉水或其他饮品'''return resultdef open_calc(input: str = "") -> str:"""打开计算器"""try:subprocess.Popen(['calc.exe'])return "计算器已打开"except Exception as e:return f"打开计算器失败: {str(e)}"def open_browser(url: str) -> str:"""打开浏览器访问指定网址"""try:webbrowser.open(url)return f"已打开浏览器访问 {url}"except Exception as e:return f"打开浏览器失败: {str(e)}"

Tool()定义

  • name:工具名称,可以自定义,但建议与函数名保持一致。
  • func:关联的函数名,务必准确。
  • description:函数的功能描述,作用与@tool中写在函数首行的描述相同,但此处函数首行就不必再写了。

# 创建LangChain工具列表# 方式二,自定义工具tools = [# 通过Tool来描述声明工具 name 工具名称 func 函数体 description 函数的功能描述Tool(name="get_current_time", #可以随意,但是建议跟函数名称一致func=get_current_time,# 函数的功能描述,说明书description="当你想知道现在的时间时非常有用。"),Tool(name="recom_drink",func=recom_drink,description="用户口渴,为其推荐附近的饮品店"),Tool(name="open_calc",func=open_calc,description="打开本地计算机上的计算器。"),Tool(name="open_browser",func=lambda url: open_browser(url),description="打开本地计算机上的网页浏览器,并接受网站的url作为参数。")]

Agent构建

# 这个时候函数工具选择和调用执行,都是通过Agent来完成的# 创建Agentagent = create_agent(model=llm,# 聊天模型tools=tools, # 工具列表system_prompt=system_prompt,checkpointer=memory# 传入记忆组件)

方式三:BaseTool继承

这种方式是将工具函数封装成一个类,必须继承自BaseTool。这样设计的目的是为了给AI工具调用建立一套“强类型、结构化”的输入契约。这绝不仅仅是语法规范,而是构建可靠AI Agent的工程基石。

BaseTool类定义

  • name:工具名称
  • description:工具描述

class DateTool(BaseTool):"""一个获取当前具体日期的简单工具。它是继承BaseTool类的最简示例。"""# 1. 定义工具名称。这将是Agent在思考时提到的名字。name: str = "get_date"# 2. 定义工具描述。清晰准确的描述直接决定了Agent能否在正确场景下想起并使用它。description: str = "当需要知道今天的准确日期(年月日)时,使用此工具。"

args_schema(BaseModel)

args_schema是一个强类型、可自描述的合约规范,专门用于约束和指导大模型如何生成调用该工具的参数。

args_schema告诉LangChain框架:“我这个工具的所有输入参数,其名称、类型、约束和描述,都完整地定义在这个Pydantic BaseModel里。” 这样框架能自动完成以下几件事:

  1. 生成准确的JSON Schema:这是与OpenAI等模型API进行“函数调用”通信的协议基础。
  2. 自动化验证:在工具执行前,框架自动用schema验证模型生成的参数,无效输入会被拦截,避免工具函数崩溃。
  3. 工具发现的元数据:框架可以收集所有工具的schema,自动生成工具目录或用于路由。

# 3. 定义参数模式。即使此工具无需参数,也最好显式定义一个空的Schema,这是良好的实践。args_schema: Type[BaseModel] = DateToolInput

# 使用Pydantic定义输入参数的模型。本例中无需输入,所以模型为空。class DateToolInput(BaseModel):# 这个工具不需要任何输入参数。# 如果未来需要扩展,可以在这里添加字段,例如:# format: str = Field("YYYY-MM-DD", description="日期格式")query: Optional[str] = Field(default=None,description="查询日期的提示词,可为空")

_run方法实现

_run函数是工具“能力”的具体实现,是连接AI决策与现实世界接口的唯一执行终点。我们这里获取日期的真正实现就在这个函数里。

# 4. 实现核心的 _run 方法。这里是所有业务逻辑存放的地方。def _run(self, query: Optional[str] = None) -> str:"""执行工具,返回当前日期字符串。"""# 使用datetime模块获取当前日期,并格式化为易读的字符串。current_date = datetime.date.today().strftime("%Y-%m-%d")return f"今天是:{current_date}"# 5. (可选)实现 _arun 方法以支持异步调用。简单工具可暂不实现。async def _arun(self, query: Optional[str] = None):raise NotImplementedError("此工具暂不支持异步调用。")

调用方式

# 实例化工具date_tool = DateTool()

方式一(invoke)

直接使用date_tool:

# 方式一:invokeresult = date_tool.invoke("今天是几月几号?")result = date_tool.invoke("")print(result) # 输出:今天是:2026-03-13

方式二(run)

同样是直接使用date_tool:

# 方式二:runresult = date_tool.run("今天是几月几号?")result = date_tool.run("")print(result)

方式三(Agent)

# 方式三:Agent# 获取模型model = get_lc_model_client()# 创建工具列表tools = [date_tool]# 使用ReAct提示模板,让Agent具备“思考-行动”的推理能力prompt = "你是人工智能助手。需要帮助用户解决各种问题。"# 大模型客户端绑定工具# 创建Agentagent = create_agent(model=model,# 聊天模型tools=tools, # 工具列表system_prompt=prompt)# 调用示例result = agent.invoke({"messages": [{"role": "user", "content": "今天是几月几号?"}]},)

带参数的demo示例

后续我们会在实战案例中进一步巩固tool的使用,其中会涉及带参数的场景,具体可参见源码 tools-get_weather_demo.py

自定义tool

这是开发者为了满足特定业务需求,通过继承BaseTool基类或使用@tool装饰器,自行创建的工具。它封装了专有的逻辑、数据或第三方服务,像上面举例的get_date/DateToolopen_browserrecom_drink都属于自定义工具。

  • 本质:是你为AI智能体量身定做的“专属装备”,是实现业务差异化和核心价值的关键。
  • 核心能力:连接一切——可以把任何函数、类方法、API、数据库查询、甚至遗留系统接口包装成一个工具。
  • 典型场景:查询内部知识库或CRM系统;调用公司内部的订单或天气API;执行特定的数据分析或业务流程。

预置tool

定义

这是LangChain官方或活跃社区预先封装好、可直接调用的工具集合。它们解决的是AI应用中最常见、最通用的需求,属于“开箱即用”的标准化组件。

  • 本质:经过良好测试、接口标准化的“功能黑盒”。只需关注配置(如API密钥),无需关心内部实现。
  • 典型代表WikipediaQueryRun(查询维基百科)、DuckDuckGoSearchRun(网络搜索)、ArxivQueryRun(学术论文搜索)、PythonREPLTool(安全沙箱中运行Python代码)等。

示例

ArxivQueryRun 为例,展示简单调用方法。

  1. 使用load_tools(["arxiv"])组装Agent:

# 组装Agentagent = create_agent( model=llm, tools=load_tools(["arxiv"]), #添加工具列表,绑定的论文查询的工具 system_prompt=system_prompt, checkpointer=memory# 传入记忆组件)

  1. 调用Agent查询论文:

# 调用Agent查询论文result = agent.invoke({"messages": [{"role": "user", "content": "请查询arxiv论文编号1605.08386的信息"}]},# 配置会话标识,用于区分不同用户config={"configurable": {"thread_id": "user_1"}}# 会话唯一标识,用于区分不同用户)

Function Calling:模型与工具的通信协议

Function Calling(函数调用)是模型在推理过程中生成的一个结构化输出。当模型决定要使用某个工具时,它不会直接执行代码,而是返回一个JSON对象,里面包含要调用的工具名称(name)和具体参数(arguments)。这是模型“思考”的结果。

  • 向模型描述一个工具:必须提供一个符合特定JSON Schema格式的工具描述列表,包括工具名、描述和参数模式。
  • 模型如何回应表示想要调用工具:模型不会在文本中说“请调用XXX工具”,而是在返回的特定结构(如OpenAI的tool_calls数组)中,输出一个标准的JSON对象,包含要调用的工具名和参数。

前面讲到的bind_tools,当调用bind_tools(get_date)时,LangChain会自动将工具定义(args_schemadescription)转换成底层模型(如GPT-4)所要求的Function Calling格式。

简单来说,Function Calling是“通信协议”,而LangChain Tool是“工程实现框架”。Tool是开发者提供的能力定义,Function Calling是模型发出的使用请求。在LangChain中,通过Tool来扩展Agent的能力,而Agent通过Function Calling来实际使用这些能力。

源码

github

来源:https://juejin.cn/post/7616201064984428554

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
什么是文本生成(Text Generation) 一文读懂概念与原理 AI百科知识

什么是文本生成(Text Generation) 一文读懂概念与原理 AI百科知识

文本生成作为自然语言处理领域的前沿技术,正深刻改变着人类与信息交互的方式。它使机器从被动响应进化为主动创造——既能撰写财经快讯、构思故事,也能模拟流畅的对话场景。这不仅是效率的飞跃,更为个性化沟通和创意表达开辟了新路径。随着算法持续迭代与数据不断积累,文本生成的边界持续拓展,其潜力令人振奋。今天,我

时间:2026-05-28 22:58
Gigopost首页官方入口

Gigopost首页官方入口

```html Gigopost Home 到底是什么?一文带你了解 简单来说,Gigopost Home 是 Gigopost 公司推出的一款集 AI 内容创作与社交媒体管理于一体的智能工具。它能够借助人工智能自动生成内容、优化搜索引擎排名,并支持跨多个社交平台一键分发。尤其适合那些希望在内容营销

时间:2026-05-28 22:58
AI技术如何提升工作效率与客户服务体验

AI技术如何提升工作效率与客户服务体验

AI技术的应用与实践:从理论到落地的全流程指南 数字化浪潮席卷而来,人工智能早已不再是科幻电影里的遥远概念,而是切切实实地重塑着各行各业的运行逻辑与商业模式。无论是提升内部运营效率,还是优化客户服务体验,掌握并落地AI应用,已经成为个人与组织抓住新一轮增长机遇的核心能力。今天,我们就来聊聊几个能够立

时间:2026-05-28 22:57
AI自动对齐打开教程与人工智能提效攻略

AI自动对齐打开教程与人工智能提效攻略

在当今商业环境中,如何开启AI的自动对齐功能,并充分运用人工智能技术来提升自动化对齐的效率,已成为各行各业共同探讨的核心议题。这项功能在现代办公中的价值不言而喻——它能显著提升工作效率,尤其是在处理文档和演示文稿时,可省去大量繁琐的手动格式调整工作。试想一下,如果没有它,我们还需额外投入多少时间与精

时间:2026-05-28 22:57
2024年AI绘画软件哪个好 10款实用推荐与横向评测

2024年AI绘画软件哪个好 10款实用推荐与横向评测

数据科学、算法等核心技术的持续演进,正在重新定义内容创作的方方面面。从AI抠图、智能识别,到近年来备受关注的AI绘画与智能问答,技术已渗透到各个领域。 AI绘画,尤其为创作者开辟了一扇全新的创意之窗。它让艺术创作变得前所未有地便捷且充满乐趣,也使独特的视觉表达成为现实。正因如此,越来越多的创新者与艺

时间:2026-05-28 22:54
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程