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

【大模型】-LangChain自定义工具调用

文章目录

        • 10.1 @tool 装饰器
        • 10.2 StructuredTool
        • 10.3 处理工具错误
        • 10.4 调用内置工具包和拓展工具
        • 10.5 自定义默认工具
        • 10.6 如何使用内置工具包

方案:普通函数 + Tool对象(最简单)
fromlangchain.toolsimportTool# 1. 定义普通函数defweather_query(city:str)->str:"""查询天气 - 普通函数"""weather_data={"北京":{"temperature":"25°C","weather":"晴"},"上海":{"temperature":"28°C","weather":"多云"},}ifcityinweather_data:data=weather_data[city]returnf"{city}:{data['temperature']},{data['weather']}"returnf"未找到{city}天气"defattraction_search(query:str)->str:"""搜索景点 - 普通函数"""returnf"找到了关于'{query}'的5个景点:..."# 2. 创建Tool对象weather_tool=Tool(name="weather_query",description="查询城市天气",func=weather_query# 直接传入函数)attraction_tool=Tool(name="attraction_search",description="搜索旅游景点",func=attraction_search)# 3. 使用工具列表tools=[weather_tool,attraction_tool]

LangChain 提供了三种创建工具的方式:

  • 使用 @tool装饰器 – 定义自定义工具的最简单方式。
  • 使用 StructuredTool.from_function 类方法 – 这类似于@tool装饰器,但允许更多配置和同步和异步实现的规范。
  • 通过子类化BaseTool – 这是最灵活的方法,它提供了最大程度的控制,但需要更多的工作量和代码。@tool 或 StructuredTool.from_function 类方法对于大多数用例应该足够了。 提示 如果工具具有精心选择的名称、描述和 JSON 模式,模型的性能会更好。
10.1 @tool 装饰器

这个@tool装饰器是定义自定义工具的最简单方式。该装饰器默认使用函数名称作为工具名称,但可以通过传递字符串作为第一个参数来覆盖。此外,装饰器将使用函数的文档字符串作为工具的描述 - 因此必须提供文档字符串。

同步如下:

#示例:tools_decorator.pyfromlangchain_core.toolsimporttool@tooldefmultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*b# 检查与该工具关联的一些属性print(multiply.name)print(multiply.description)print(multiply.args)#输出结果multiply multiply(a:int,b:int)->int-Multiply two numbers.{'a':{'title':'A','type':'integer'},'b':{'title':'B','type':'integer'}}

创建一个异步实现,如下所示:

#示例:tools_async.pyfromlangchain_core.toolsimporttool@toolasyncdefamultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*b

您还可以通过将它们传递给工具装饰器来自定义工具名称和 JSON 参数

frompydanticimportBaseModel,FieldclassCalculatorInput(BaseModel):a:int=Field(description="first number")b:int=Field(description="second number")@tool("multiplication-tool",args_schema=CalculatorInput,return_direct=True)defmultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*b# 检查与该工具关联的一些属性print(multiply.name)print(multiply.description)print(multiply.args)print(multiply.return_direct)#结果multiplication-tool multiplication-tool(a:int,b:int)->int-Multiply two numbers.{'a':{'title':'A','description':'first number','type':'integer'},'b':{'title':'B','description':'second number','type':'integer'}}True
10.2 StructuredTool

StructuredTool.from_function类方法提供了比@tool装饰器更多的可配置性,而无需太多额外的代码。

fromlangchain_core.toolsimportStructuredToolimportasynciodefmultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*basyncdefamultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*basyncdefmain():calculator=StructuredTool.from_function(func=multiply,coroutine=amultiply)print(calculator.invoke({"a":2,"b":3}))print(awaitcalculator.ainvoke({"a":2,"b":5}))# 运行异步主函数asyncio.run(main())#结果610

可以配置自定义参数

fromlangchain_core.toolsimportStructuredToolfrompydanticimportBaseModel,FieldimportasyncioclassCalculatorInput(BaseModel):a:int=Field(description="first number")b:int=Field(description="second number")defmultiply(a:int,b:int)->int:"""Multiply two numbers."""returna*b# 创建一个异步包装器函数asyncdefasync_addition(a:int,b:int)->int:"""Multiply two numbers."""returna+basyncdefmain():calculator=StructuredTool.from_function(func=multiply,name="Calculator",description="multiply numbers",args_schema=CalculatorInput,return_direct=True,#coroutine= async_addition# coroutine= ... <- 如果需要,也可以指定异步方法)print(calculator.invoke({"a":2,"b":3}))#print(await calculator.ainvoke({"a": 2, "b": 5}))print(calculator.name)print(calculator.description)print(calculator.args)# 运行异步主函数asyncio.run(main())
10.3 处理工具错误

如果您正在使用带有代理的工具,您可能需要一个错误处理策略,以便代理可以从错误中恢复并继续执行。 一个简单的策略是在工具内部抛出 ToolException,并使用 handle_tool_error 指定一个错误处理程序。 当指定了错误处理程序时,异常将被捕获,错误处理程序将决定从工具返回哪个输出。 您可以将 handle_tool_error 设置为 True、字符串值或函数。如果是函数,该函数应该以 ToolException 作为参数,并返回一个值。 请注意,仅仅抛出 ToolException 是不会生效的。您需要首先设置工具的 handle_tool_error,因为其默认值是 False。

fromlangchain_core.toolsimportToolExceptiondefget_weather(city:str)->int:"""获取给定城市的天气。"""raiseToolException(f"错误:没有名为{city}的城市。")# 示例:tools_exception.pyget_weather_tool=StructuredTool.from_function(func=get_weather,handle_tool_error=True,)get_weather_tool.invoke({"city":"foobar"})#结果'错误:没有名为foobar的城市。'

可以将handle_tool_error设置为一个始终返回的字符串。

# 示例:tools_exception_handle.pyget_weather_tool=StructuredTool.from_function(func=get_weather,handle_tool_error="没找到这个城市",)get_weather_tool.invoke({"city":"foobar"})#结果'没找到这个城市'

使用函数处理错误:

# 示例:tools_exception_handle_error.pydef_handle_error(error:ToolException)->str:returnf"工具执行期间发生以下错误:`{error.args[0]}`"get_weather_tool=StructuredTool.from_function(func=get_weather,handle_tool_error=_handle_error,)get_weather_tool.invoke({"city":"foobar"})#结果'工具执行期间发生以下错误:错误:没有名为foobar的城市。'
10.4 调用内置工具包和拓展工具

使用维基百科工具包

# 示例:tools_wikipedia.pyfromlangchain_community.toolsimportWikipediaQueryRunfromlangchain_community.utilitiesimportWikipediaAPIWrapper api_wrapper=WikipediaAPIWrapper(top_k_results=1,doc_content_chars_max=100)tool=WikipediaQueryRun(api_wrapper=api_wrapper)print(tool.invoke({"query":"langchain"}))#结果Page:LangChain Summary:LangChainisa framework designed to simplify the creation of applicationsprint(f"Name:{tool.name}")print(f"Description:{tool.description}")print(f"args schema:{tool.args}")print(f"returns directly?:{tool.return_direct}")#结果Name:wikipedia Description:A wrapper around Wikipedia.Usefulforwhen you need to answer general questions about people,places,companies,facts,historical events,orother subjects.Input should be a search query.args schema:{'query':{'title':'Query','description':'query to look up on wikipedia','type':'string'}}returns directly?:False
10.5 自定义默认工具

我们还可以修改内置工具的名称、描述和参数的 JSON 模式。

在定义参数的 JSON 模式时,重要的是输入保持与函数相同,因此您不应更改它。但您可以轻松为每个输入定义自定义描述。

#示例:tools_custom.pyfromlangchain_community.toolsimportWikipediaQueryRunfromlangchain_community.utilitiesimportWikipediaAPIWrapperfrompydanticimportBaseModel,FieldclassWikiInputs(BaseModel):"""维基百科工具的输入。"""query:str=Field(description="query to look up in Wikipedia, should be 3 or less words")tool=WikipediaQueryRun(name="wiki-tool",description="look up things in wikipedia",args_schema=WikiInputs,api_wrapper=api_wrapper,return_direct=True,)print(tool.run("langchain"))#结果Page:LangChain Summary:LangChainisa framework designed to simplify the creation of applicationsprint(f"Name:{tool.name}")print(f"Description:{tool.description}")print(f"args schema:{tool.args}")print(f"returns directly?:{tool.return_direct}")#结果Name:wiki-tool Description:look up thingsinwikipedia args schema:{'query':{'title':'Query','description':'query to look up in Wikipedia, should be 3 or less words','type':'string'}}returns directly?:True
10.6 如何使用内置工具包

工具包是一组旨在一起使用以执行特定任务的工具。它们具有便捷的加载方法。

要获取可用的现成工具包完整列表,请访问集成。

所有工具包都公开了一个get_tools方法,该方法返回一个工具列表。

# 初始化一个工具包toolkit=ExampleTookit(...)# 获取工具列表tools=toolkit.get_tools()

使用SQLDatabase toolkit 读取 langchain.db 数据库表结构:

fromlangchain_community.agent_toolkits.sql.toolkitimportSQLDatabaseToolkitfromlangchain_community.utilitiesimportSQLDatabasefromlangchain_openaiimportChatOpenAIfromlangchain_community.agent_toolkits.sql.baseimportcreate_sql_agentfromlangchain.agents.agent_typesimportAgentType db=SQLDatabase.from_uri("sqlite:///langchain.db")toolkit=SQLDatabaseToolkit(db=db,llm=ChatOpenAI(temperature=0))print(toolkit.get_tools())#结果[QuerySQLDataBaseTool(description="Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.",db=<langchain_community.utilities.sql_database.SQLDatabaseobjectat0x000001D15C9749B0>),InfoSQLDatabaseTool(description='Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3',db=<langchain_community.utilities.sql_database.SQLDatabaseobjectat0x000001D15C9749B0>),ListSQLDatabaseTool(db=<langchain_community.utilities.sql_database.SQLDatabaseobjectat0x000001D15C9749B0>),QuerySQLCheckerTool(description='Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!',db=<langchain_community.utilities.sql_database.SQLDatabaseobjectat0x000001D15C9749B0>,llm=ChatOpenAI(client=<openai.resources.chat.completions.Completionsobjectat0x000001D17B4453D0>,async_client=<openai.resources.chat.completions.AsyncCompletionsobjectat0x000001D17B446D80>,temperature=0.0,openai_api_key=SecretStr('**********'),openai_proxy=''),llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['dialect','query'],template='\n{query}\nDouble check the {dialect} query above for common mistakes, including:\n- Using NOT IN with NULL values\n- Using UNION when UNION ALL should have been used\n- Using BETWEEN for exclusive ranges\n- Data type mismatch in predicates\n- Properly quoting identifiers\n- Using the correct number of arguments for functions\n- Casting to the correct data type\n- Using the proper columns for joins\n\nIf there are any of the above mistakes, rewrite the query. If there are no mistakes, just reproduce the original query.\n\nOutput the final SQL query only.\n\nSQL Query: '),llm=ChatOpenAI(client=<openai.resources.chat.completions.Completionsobjectat0x000001D17B4453D0>,async_client=<openai.resources.chat.completions.AsyncCompletionsobjectat0x000001D17B446D80>,temperature=0.0,openai_api_key=SecretStr('**********'),openai_proxy='')))]agent_executor=create_sql_agent(llm=ChatOpenAI(temperature=0,model="gpt-4"),toolkit=toolkit,verbose=True,agent_type=AgentType.OPENAI_FUNCTIONS)# %%agent_executor.invoke("Describe the full_llm_cache table")#结果Entering new SQL Agent Executor chain...Invoking:sql_db_schemawith`{'table_names':'full_llm_cache'}` CREATE TABLE full_llm_cache(prompt VARCHAR NOT NULL,llm VARCHAR NOT NULL,idx INTEGER NOT NULL,response VARCHAR,PRIMARY KEY(prompt,llm,idx))/*3rowsfromfull_llm_cache table:prompt llm idx response[{"lc":1,"type":"constructor","id":["langchain","schema","messages","HumanMessage"],"kwargs {"id": ["langchain", "chat_models", "openai", "ChatOpenAI"], "kwargs": {"max_retries": 2, "model_nam0{"lc":1,"type":"constructor","id":["langchain","schema","output","ChatGeneration"],"kwargs"*/The `full_llm_cache` table has the following structure:-`prompt`:A VARCHAR field thatispart of the primary key.It cannot be NULL.-`llm`:A VARCHAR field thatisalso part of the primary key.It cannot be NULL.-`idx`:An INTEGER field thatispart of the primary keyaswell.It cannot be NULL.-`response`:A VARCHAR field that can contain NULL values.Here are some sample rowsfromthe `full_llm_cache` table:|prompt|llm|idx|response||--------|-----|-----|----------||[{"lc":1,"type":"constructor","id":["langchain","schema","messages","HumanMessage"],"kwargs | {"id": ["langchain", "chat_models", "openai", "ChatOpenAI"], "kwargs": {"max_retries": 2, "model_nam|0|{"lc":1,"type":"constructor","id":["langchain","schema","output","ChatGeneration"],"kwargs"|>Finished chain.
http://www.cnnetsun.cn/news/51810.html

相关文章:

  • 【大模型】-LangChain--stream流式同步异步
  • 兜兜英语每日短语:逃单篇
  • 计算机毕业设计springboot汽车智慧检修系统 基于SpringBoot的智能汽车故障预测与维修管理平台 融合IoT的SpringBoot车辆健康监测与维修决策系统
  • python3
  • 【3D图像技术分析与实现】Apple Vision Pro三维成像技术栈深度解析
  • 经典算法题详解之统计重复个数(三)
  • 移动应用开发实验室大一上考核
  • 云数据库服务(如AWS RDS)的优势和考虑因素?
  • 【设计模式|第四篇】适配器模式:让不兼容的接口协同工作
  • asgiref终极指南:高效解决Python异步通信难题
  • 医学影像深度学习知识点总结
  • 从零到一:自动化3D建模的免代码解决方案
  • Kali中生成被控端
  • 13、Linux 文本编辑与命令操作实用指南
  • 20、Linux 备份全攻略
  • 22、Debian系统管理与安全保障全解析
  • 32、Debian变体与基于Debian的其他操作系统
  • 50、无线传感器网络部署方案与加密算法研究
  • 51、无线传感器网络部署方案与LEACH协议优化研究
  • 54、垃圾邮件和即时通讯垃圾信息的分类与控制措施
  • 如何通过AutoGPT生成高质量技术博客为GPU算力引流
  • 多目标蜣螂优化算法NSDBO:微电网多目标优化调度的利器
  • 本研究基于分形纤维丛统一场论,构建了黑洞时空的几何模型,揭示了奇点消解、霍金辐射修正及信息守恒的新机制。该模型的优势在于将宏观时空的广义相对论效应与微观量子的分形特性实现了有机融合。
  • 好写作AI语言侦探:你的论文严谨性“隐形把关人”
  • 解放双手!钉钉智能打卡神器完全上手手册
  • DMXAPI全球模型API调用完全指南:从入门到精通
  • 告别“翻墙“烦恼:DMXAPI让Gemini-3-pro-thinking调用快如闪电
  • leetcode 744. Find Smallest Letter Greater Than Target 寻找比目标字母大的最小字母-耗时100%
  • Home Assistant通知系统:3步打造智能家居提醒中心
  • 学Simulink——机器人轨迹跟踪场景实例:基于Simulink的永磁同步电机笛卡尔空间圆弧轨迹跟踪仿真