当前位置: 首页 > news >正文

LangChain【7】之工具创建和错误处理策略

文章目录

  • 一 LangChain 自定义工具概述
  • 二创建自定义工具的三种方法
    • 2.1 方法一:@tool 装饰器
      • 2.1.1 同步方法案例
      • 2.1.2 工具描述方式1:传参
      • 2.1.3 工具描述方式2:文档字符串
    • 2.2 方法二:StructuredTool类
      • 2.2.1 StructuredTool创建自定义工具
      • 2.2.2 StructuredTool配置信息
    • 2.3 方法三:BaseTool类
  • 三 异步工具的实现
  • 四 工具错误处理策略

一 LangChain 自定义工具概述

  • LangChain提供了一套工具、组件和接口,可简化创建由大型语言模型(LLM)和聊天模型提供支持的应用程序的过程。
  • 在构建智能代理时,为其提供合适的工具是确保其强大功能的关键,LangChain作为一个支持创建和管理工具的框架,能让开发者以模块化方式扩展代理的能力。

  • 当构建代理时,需要为其提供一组工具列表,代理可以使用这些工具。除了调用的实际函数之外,工具由几个组件组成:
    • name(str)是必需的,并且在提供给代理的工具集中必须是唯一的;
    • description(str)是可选的但建议的,因为代理使用它来确定工具的使用方式;
    • return_direct(bool)默认为False;
    • args_schema(PydanticBaseModel)是可选的但建议的,可以用于提供更多信息或用于验证预期参数。

二创建自定义工具的三种方法

  • LangChain为开发人员提供了不同的方式来创建工具,这些工具可以被智能代理或语言模型调用。
    • 第一种方法是使用@tool装饰器(定义自定义工具的最简单方法);
    • 第二种方法是使用StructuredTool类,允许更细粒度的配置而无需过多的代码;
    • 第三种方法是基于BaseTool类构造子类显式自定义工具,工具定义提供最大限度的把控,但需要做更多的工作。

2.1 方法一:@tool 装饰器

  • 使用@tool修饰符是自定义工具最简单的方法。默认情况下修饰符用函数的名字作为工具名称,但传字符串作为第一个参数可以重命名工具名称。例如,可以创建一个总是返回字符串"LangChain"的虚构搜索函数,或者将两个数字相乘的乘法函数。这些函数最大的区别是第一个函数只有一个输入,第二个函数需要多个输入。

2.1.1 同步方法案例

from langchain_core.tools import tool
@tool
def multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*bprint(multiply.name) # multiply
print(multiply.description) # Multiply two numbers
print(multiply.args) # {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}

2.1.2 工具描述方式1:传参

  • 通过将工具名称和 JSON 参数传递给工具装饰器进行自定义
from langchain_core.tools import tool
from pydantic import BaseModel, Fieldclass CalculatorInput(BaseModel):a: int = Field(description="The first number")b: int = Field(description="The second number")@tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True)
def multiply(a: int, b: int) -> int:"""Multiply two numbers"""return a * bprint(multiply.name)  # multiplication-tool
print(multiply.description)  # Multiply two numbers
print(multiply.args)  # {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
print(multiply.return_direct)  # True

2.1.3 工具描述方式2:文档字符串

  • @tool 可以选择性地解析 Google 风格文档字符串,并将文档字符串组件(如参数描述)与工具模式的相关部分关联起来。
@tool(parse_docstring=True)
def foo(bar: str, baz: int) -> str:"""The foo.Args:bar: The bar.baz: The baz."""return bar
foo.args_schema.schema()
{'description': 'The foo.','properties': {'bar': {'description': 'The bar.','title': 'Bar','type': 'string'},'baz': {'description': 'The baz.', 'title': 'Baz', 'type': 'integer'}},'required': ['bar', 'baz'],'title': 'fooSchema','type': 'object'}

2.2 方法二:StructuredTool类

  • 使用StructuredTool类,允许更细粒度的配置而无需过多的代码

2.2.1 StructuredTool创建自定义工具

  • 使用StructuredToolfrom_function可以创建自定义工具,包含两个参数func,coroutine,分别指定同步方法和异步方法。
import asyncio
from langchain_core.tools import StructuredTooldef multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*b
async def a_multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*basync def main():calculator=StructuredTool.from_function(func=multiply,coroutine=a_multiply)print(calculator.run({"a":2, "b":3}))print(calculator.invoke({"a":2, "b":3}))print(await calculator.ainvoke({"a":2, "b":5}))asyncio.run(main())

2.2.2 StructuredTool配置信息

import asyncio
from langchain_core.tools import StructuredTool
from pydantic import Field, BaseModelclass CalculatorInput(BaseModel):a: int = Field(description="The first number")b: int = Field(description="The second number")#创建同步、异步包装器函数
def multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*b
async def async_multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*basync def main():calculator=StructuredTool.from_function(func=multiply,name="calculator",description="Multiply two numbers",args_schema=CalculatorInput,coroutine=async_multiply,return_direct=True)print(calculator.name)print(calculator.description)print(calculator.args)asyncio.run(main())

2.3 方法三:BaseTool类

  • 接受字符串或 dict 输入的 LangChain Runnables 可以使用 as_tool 方法转换为工具,该方法允许为参数指定名称、描述和其他模式信息。
# 导入所需的模块
from langchain_core.language_models import GenericFakeChatModel  # 导入一个假的聊天模型,用于测试
from langchain_core.output_parsers import StrOutputParser  # 导入字符串输出解析器
from langchain_core.prompts import ChatPromptTemplate  # 导入聊天提示模板# 创建一个聊天提示模板,包含一个占位符 {answer_style}
prompt = ChatPromptTemplate.from_messages([("human", "Hello. Please respond in the style of {answer_style}.")]
)# 创建一个假的聊天模型实例,并提供一个固定的响应
llm = GenericFakeChatModel(messages=iter(["hello matey"]))# 构建一个链式调用:先应用提示模板,然后调用 LLM,最后解析输出为字符串
chain = prompt | llm | StrOutputParser()# 将 chain 转换为一个工具(Tool),并指定名称和描述
as_tool = chain.as_tool(name="Style responder", description="Description of when to use tool."
)# 打印工具的参数信息
print(as_tool.args) # {'answer_style': {'title': 'Answer Style', 'type': 'string'}}

三 异步工具的实现

  • LangChain的工具可以实现异步版本,以节省计算资源和提高效率。在定义异步工具时,需要使用async/await语法,并确保函数和工具名准确反映功能,提供详细的文档字符串。对于涉及外部API调用的工具,建议使用API代理服务来提高访问的稳定性,并确保异步工具充分利用并发优势,避免阻塞操作。
from langchain_core.tools import tool@tool
async def multiply(a:int,b:int)->int:"""Multiply two numbers"""return a*bprint(multiply.name) # multiply
print(multiply.description) # Multiply two numbers
print(multiply.args) # {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}

四 工具错误处理策略

  • 为了让代理能从错误中恢复并继续执行,需要特定的错误处理策略。可以抛出ToolException并定义错误处理函数,设置handle_tool_error属性来定义工具错误的应对策略,可以是字符串、布尔值或函数。需要注意的是仅引发ToolException是无效的,需要先设置该工具的handle_tool_error,因为它的默认值为False
from langchain_core.tools import StructuredTool
from langchain_core.tools import ToolExceptiondef get_weather(city: str) -> str:"""获取给定城市的天气。"""raise ToolException(f"错误:没有名为{city}的城市。")get_weather_tool = StructuredTool.from_function(func=get_weather,# 默认情况下,如果函数抛出TooLException,则将TooLException的message作为响应。# 如果设置为True,则将返回TooLException异常文本,False将会抛出TooLExceptionhandle_tool_error=True,
)response = get_weather_tool.invoke({"city":"天京"})
print(response) # 错误:没有名为天京的城市。
  • 定义异常处理
from langchain_core.tools import StructuredTool
from langchain_core.tools import ToolExceptiondef get_weather(city: str) -> str:"""获取给定城市的天气。"""raise ToolException(f"错误:没有名为{city}的城市。")get_weather_tool = StructuredTool.from_function(func=get_weather,handle_tool_error="没有找到这个城市",
)response = get_weather_tool.invoke({"city":"天京"})
print(response) # 没有找到这个城市
  • 异常个性化处理
from langchain_core.tools import StructuredTool
from langchain_core.tools import ToolExceptiondef get_weather(city: str) -> str:"""获取给定城市的天气。"""raise ToolException(f"错误:没有名为{city}的城市。")def _handle_tool_error(error: ToolException) -> str:"""处理工具错误。"""return f"工具执行期间发生以下错误:`{error.args[0]}`"get_weather_tool = StructuredTool.from_function(func=get_weather,handle_tool_error=_handle_tool_error
)response = get_weather_tool.invoke({"city":"天京"})
print(response) # 工具执行期间发生以下错误:`错误:没有名为天京的城市。`
http://www.xdnf.cn/news/905563.html

相关文章:

  • Linux 内核性能分析确保成效的关键知识点总结
  • Redis 过期了解
  • ​​TLV4062-Q1​​、TLV4082-Q1​​迟滞电压比较器应用笔记
  • MySQL 高级学习篇
  • 【SpringBoot自动化部署】
  • 【WebSocket】SpringBoot项目中使用WebSocket
  • 主流定位技术:Zigbee、蓝牙、UWB、RFID、5G通信介绍及对比
  • Day 41 训练
  • 鸿蒙图片缓存(一)
  • 2025年7月-12月【CISP】考试计划时间
  • 全新Xsens Animate版本是迄今为止最大的软件升级,提供更清晰的数据、快捷的工作流程以及从录制开始就更直观的体验
  • C++11 Move Constructors and Move Assignment Operators 从入门到精通
  • 现代Web安全实践:基于Token与Refresh Token的单点登录(SSO)实现
  • Java常用的判空方法
  • 数据库学习(一)——MySQL基础
  • 信息化安全与自主可控需求:国产飞腾D2000 VPX3U主板设计与实践
  • 多种风格导航菜单 HTML 实现(附源码)
  • 增量式网络爬虫通用模板
  • 嵌入式学习之系统编程(十一)网络编程之协议头,测试命令及工具
  • 可视化图解算法49:滑动窗口的最大值
  • 大话软工笔记—需求工程概述
  • day45_Tensorborad使用介绍
  • 4G网络中频段的分配
  • 进行用户VMware官网注重中一直无法登录,该怎么处理
  • Java下载文件(特殊字符编码处理)
  • 基于React + FastAPI + LangChain + 通义千问的智能医疗问答系统
  • QT: `long long` 类型转换为 `QString` 2025.6.5
  • ruoyi-plus-could 负载均衡 通过 Gateway模块配置负载均衡
  • Curtain MonGuard:智能水印颜色适配,提升屏幕信息安全
  • LabVIEW实时系统数据监控与本地存储