1、Tools概述1.1 介绍要构建更强大的AI工程应用只有生成文本这样的“ 纸上谈兵 ”能力自然是不够的。工具Tools不仅仅是“肢体”的延伸更是为“大脑”插上了想象力的“翅膀”。借助工具才能让AI应用的能力真正具备无限的可能才能从“ 认识世界 ”走向“ 改变世界 ”Tools 用于扩展大语言模型LLM的能力使其能够与外部系统、API 或自定义函数交互从而完成仅靠文本生成无法实现的任务如搜索、计算、数据库查询等。特点增强 LLM 的功能 让 LLM 突破纯文本生成的限制执行实际操作如调用搜索引擎、查询数据库、运行代码等支持智能决策 在Agent 工作流中LLM 根据用户输入动态选择最合适的 Tool 完成任务。模块化设计 每个 Tool 专注一个功能便于复用和组合例如搜索工具^ 计算工具^ 天气查询工具LangChain 拥有大量第三方工具。请访问工具集成查看可用工具列表。https://python.langchain.com/v0.2/docs/integrations/tools/1.2 Tool 的要素Tools 本质上是封装了特定功能的可调用模块是Agent、Chain或LLM可以用来与世界互动的接口。Tool 通常包含如下几个要素name 工具的名称description 工具的功能描述该工具输入的 JSON模式要调用的函数return_direct 是否应将工具结果直接返回给用户仅对Agent相关实操步骤步骤1将name、description 和 JSON模式作为上下文提供给LLM步骤2LLM会根据提示词推断出 需要调用哪些工具 并提供具体的调用参数信息步骤3用户需要根据返回的工具调用信息自行触发相关工具的回调注意如果⼯具具有 精心选择 的名称、描述和JSON模式则模型的性能将更好。下⼀章内容我们可以看到⼯具的调⽤动作可以通过Agent⾃主接管。2、自定义工具2.1 两种自定义方式第1种使用tool装饰器自定义工具的最简单方式装饰器默认使用函数名称作为工具名称但可以通过参数 name_or_callable 来覆盖此设置。同时装饰器将使用函数的 文档字符串 作为 工具的描述 因此函数必须提供文档字符串。第2种使用StructuredTool.from_function类方法这类似于 tool 装饰器但允许更多配置和同步/异步实现的规范。2.2 几个常用属性Tool由几个常用属性组成属性类型描述namestr必选的在提供给LLM或Agent的工具集中必须是唯一的。descriptionstr可选但建议描述工具的功能。LLM或Agent将使用此描述作为上下文使用它确定工具的使用args_schemaPydanticBaseModel可选但建议可用于提供更多信息例如few-shot示例或验证预期参数。return_directboolean仅对Agent相关。当为True时在调用给定工具后Agent将停止并将结果直接返回给用户。2.3 具体实现方式1tool 装饰器举例1fromlangchain_core.toolsimporttooltool(name_or_callableadd_two_number,descriptionadd two numbers,return_directTrue)defadd_number(a:int,b:int)-int:计算两个整数的和returnabprint(fname {add_number.name})#add_two_numberprint(fargs {add_number.args})print(fdescription {add_number.description})#add two numbersprint(freturn_direct {add_number.return_direct})#Truenameadd_two_number args{a:{title:A,type:integer},b:{title:B,type:integer}}descriptionadd two numbers return_directTrue说明 return_direct参数 的默认值是False。当return_directΘ\mathit { \Theta } ΘFalse时工具执行结果会返回给Agent让Agent决定下一步操作而return_direc:: :True则会中断这个循环直接结束流程返回结果给用户。举例2通过tool的参数设置进行重置frompydanticimportFieldfromlangchain_core.toolsimporttoolfrompydanticimportBaseModelclassFieldInfo(BaseModel):a:intField(description第1个整型参数)b:intField(description第2个整型参数)tool(name_or_callableadd_two_number,descriptionadd two numbers,return_directTrue,args_schemaFieldInfo)defadd_number(a:int,b:int)-int:计算两个整数的和returnabprint(fname {add_number.name})#add_two_numberprint(fargs {add_number.args})print(fdescription {add_number.description})#add two numbersprint(freturn_direct {add_number.return_direct})#Truenameadd_two_number args{a:{title:A,type:integer},b:{title:B,type:integer}}descriptionadd two numbers return_directTrue方式2StructuredTool的from_function()StructuredTool.from_function 类方法提供了比 tool 装饰器更多的可配置性而无需太多额外的代码。举例1fromlangchain_core.tools.structuredimportStructuredTool# 声明一个函数defsearch_google(query:str):return最后查询的结果# 定义一个工具search01StructuredTool.from_function(funcsearch_google,nameSearch,description查询google搜索引擎并将结果返回)print(fname {search01.name})print(fargs {search01.args})print(fdescription {search01.description})print(freturn_direct {search01.return_direct})nameSearch args{query:{title:Query,type:string}}description查询google搜索引擎并将结果返回 return_directFalse举例2fromlangchain_core.tools.structuredimportStructuredToolfrompydanticimportBaseModel,FieldclassFieldInfo(BaseModel):query:strField(description要检索的关键词)# 声明一个函数defsearch_google(query:str):return最后查询的结果# 定义一个工具search02StructuredTool.from_function(funcsearch_google,nameSearch,description查询google搜索引擎并将结果返回,return_directTrue,args_schemaFieldInfo)print(fname {search02.name})print(fargs {search02.args})print(fdescription {search02.description})print(freturn_direct {search02.return_direct})nameSearch descriptionusefulforwhen you need to answer questions about current events args{query:[description:要检索的关键词,title:Query,type:string]}return_directTrueLangChain2.4 工具调用举例我们通过大模型分析用户需求判断是否需要调用指定工具。举例1大模型分析调用工具# 1、获取大模型#导入相关依赖fromlangchain_community.toolsimportMoveFileToolfromlangchain_core.messagesimportHumanMessagefromlangchain_core.toolsimportStructuredToolfromlangchain_core.utils.function_callingimportconvert_to_openai_functionimportosimportdotenvfromlangchain_openaiimportChatOpenAI dotenv.load_dotenv()os.environ[OPENAI_API_KEY]os.getenv(OPENAI_API_KEY1)os.environ[OPENAI_BASE_URL]os.getenv(OPENAI_BASE_URL)# 定义LLM模型chat_modelChatOpenAI(modelgpt-4o-mini,temperature0)# 2、获取工具的列表tools[MoveFileTool()]# 3、因为大模型invoke调用时需要传入函数的列表所以需要将工具转换为函数:convert_to_openai_function()functions[convert_to_openai_function(t)fortintools]# 4、获取消息列表messages[HumanMessage(content将文件a移动到桌面)]# 5、调用大模型传入消息列表、工具的列表responsechat_model.invoke(inputmessages,# tools tools, #不支持functionsfunctions,)print(response)# 获取消息列表messages[HumanMessage(content查询一下明天北京的天气)]# 调用大模型传入消息列表、工具的列表responsechat_model.invoke(inputmessages,# tools tools, #不支持functionsfunctions,)print(response)