找回密码
 会员注册
查看: 32|回复: 0

LangChain(五)工具调用的底层原理进阶!依旧纯新手向

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64726
发表于 2024-9-3 21:42:34 | 显示全部楼层 |阅读模式
系列文章目录LangChain(一)构建本地数据检索问答Agent,新手向-CSDN博客LangChain(二)基础问答大模型,纯新手向-CSDN博客LangChain(三)基础问答大模型,从LLMchain开始了解chain!纯新手向-CSDN博客LangChain(四)工具调用的底层原理!给大模型按上双手吧!(新手向)-CSDN博客文章目录前言一、工具调用回顾二、自己构建工具调用!1.构建工具函数2.定义大模型3.设定工具选择模块4.  构建chain以及最后格式化输出5.函数调用!最终步骤!老规矩,全部代码展示!总结前言随着第三篇的内容,我们跟进到了大模型调用工具的开发与原理,并浅尝辄止了一下大模型调用工具的原理!本篇我们上接上文,继续此部分的内容,我们主要讲解有关大模型调用工具的原理!我们会尽可能的把LangChain高度抽象的代码还原,把每一个步骤都尽可能的说清楚!大家感兴趣的话可以看一下第四篇的内容~其实不看也没事啦,看了理解起来会更快而已。本篇最大的用途是,对于一些不支持LangChain工具调用的大模型,我们依旧可以使用本方案工具调用!一、工具调用回顾        在上一篇的内容中我们开发了一个基础的工具调用代码,Iknow大家对于代码更感兴趣,所以我把代码先粘过来~importosfromlangchain_community.chat_modelsimportQianfanChatEndpointfromlangchain_core.toolsimporttoolfromlangchain_core.messagesimportAIMessagefromlangchain_core.runnablesimportRunnable#设定百度千帆大模型的AK和SKos.environ["QIANFAN_AK"]="yourAK"os.environ["QIANFAN_SK"]="yourSK"#定义千帆大模型qianfan_chat=QianfanChatEndpoint(model="ERNIE-3.5-8K",temperature=0.2,timeout=30,)#设定两个函数,记得描述函数功能,这很重要@tooldeffunc1():'''uselessfunction'''return0@tooldefMultiply(a:int,b:int)->int:"""Multipliesaandb."""returna*b#工具集合tools=[Multiply,func1]#工具与大模型绑定,构建函数选择模块llm_with_tools=qianfan_chat.bind_tools(tools)#构建一一对应的maptool_map={tool.name:toolfortoolintools}#工具函数执行defcall_tools(msg:AIMessage)->Runnable:"""Simplesequentialtoolcallinghelper."""tool_calls=msg.tool_calls.copy()fortool_callintool_calls:tool_call["output"]=tool_map[tool_call["name"]].invoke(tool_call["args"])returntool_calls#构建链chain=llm_with_tools|call_toolsprint(chain.invoke("What's25times11?")[0]["output"])总而言之,上诉的代码主要经过了以下几个步骤:初始化内容定义工具函数与大模型初始化工具函数与大模型绑定构建函数选择模块:llm_with_tools构建工具调用模块:call_tools chain实际运行的数据流用户输入给到函数选择模块函数选择模块输出需要的函数和对应的参数工具调用模块进行工具调用并返回二、自己构建工具调用!不必担心,依旧很简单~1.构建工具函数fromlangchain_core.toolsimporttool@tooldefmultiply(first_int:int,second_int:int)->int:"""Multiplytwointegerstogether."""returnfirst_int*second_int@tooldefadd(first_int:int,second_int:int)->int:"""addtwointegerstogether."""returnfirst_int+second_int我们使用下面的代码查看一下具体的内容,这些内容就是真正需要给到大模型参考的函数描述 print(multiply.name)print(multiply.description)print(multiply.args) 函数输出如下:multiplymultiply(first_int:int,second_int:int)->int-Multiplytwointegerstogether.{'first_int':{'title':'FirstInt','type':'integer'},'second_int':{'title':'SecondInt','type':'integer'}} 可以查看一下第三行这是之前没有讲到的部分,此部分定义了函数输入参数的规格,用以提醒大模型。2.定义大模型直接用LangChain集成好的,依旧是千帆大模型~importosfromlangchain_community.chat_modelsimportQianfanChatEndpoint#设定百度千帆大模型的AK和SK-去百度千帆官网的控制台新建一个应用即可os.environ["QIANFAN_AK"]="yourAK“"os.environ["QIANFAN_SK"]="yourSK"#创建千帆LLM模型qianfan_chat=QianfanChatEndpoint(model="ERNIE-3.5-8K",temperature=0.2,timeout=30,)3.设定工具选择模块这部分是本篇精华,本篇和上一篇最大的区别就在于函数选择器,LangChain帮助我们把此部分高度抽象成了llm_with_tools。我们本篇将其拓写!①构建函数描述模块!fromlangchain.tools.renderimportrender_text_description#构建工具条件和调用描述rendered_tools=render_text_description([multiply,add])print("rendered_tools=",rendered_tools) 此部分需要好好讲解一下这是工具选择功能实现的核心!此部分render_text_description函数的作用是构建函数描述符,返回函数的头以及参数规格和函数的功能描述。其对应的输出如下:rendered_tools= multiply(first_int:int,second_int:int)->int-Multiplytwointegerstogether.add(first_int:int,second_int:int)->int-addtwointegerstogether.有关该函数,详情可见如下: LangChain中的render_text_description究竟做了什么操作?-CSDN博客②构建工具选择输入prompt模板!fromlangchain_core.promptsimportChatPromptTemplate#构建工具选择器的系统人设system_prompt=f"""Youareanassistantthathasaccesstothefollowingsetoftools.Herearethenamesanddescriptionsforeachtool:{rendered_tools}#构建输入的模板Giventheuserinput,returnthenameandinputofthetooltouse.ReturnyourresponseasaJSONblobwith'name'and'arguments'keys."""prompt=ChatPromptTemplate.from_messages([("system",system_prompt),("user","{input}")])        通过上诉文本的阅读,我想看客们此时应该已经反应过来了,大模型工具选择的原理就是根据之前传入的函数描述符和用户的输入,返回需要的函数名称和参数。实在是非常粗暴。很多看客想必此时心中一万匹草泥马奔腾而过……。 4.  构建chain以及最后格式化输出#构建chain以及最后格式化输出chain=prompt|qianfan_chatprint(chain.invoke({"input":"what'sthirteentimes4"}))构建链的过程应该无需我过多解释,若不明白的看客可以查看一下上一篇的内容~。此时的输出如下:content='```json\n{\n"name":"multiply",\n"arguments":{\n"first_int":13,\n"second_int":4\n}\n}\n```'additional_kwargs={'finish_reason':'normal','request_id':'as-mzhzznjcan','object':'chat.completion','search_info':[]}response_metadata={'token_usage':{'prompt_tokens':114,'completion_tokens':45,'total_tokens':159},'model_name':'ERNIE-3.5-8K','finish_reason':'normal','id':'as-mzhzznjcan','object':'chat.completion','created':1720599923,'result':'```json\n{\n"name":"multiply",\n"arguments":{\n"first_int":13,\n"second_int":4\n}\n}\n```','is_truncated':False,'need_clear_history':False,'usage':{'prompt_tokens':114,'completion_tokens':45,'total_tokens':159}}id='run-b141fa71-065b-41c0-baa1-6f6797e3ae0f-0'太复杂了对不对?我们可以对结果进行处理下,LangChain很贴心的提供了相关的内容: JsonOutputParser()!我们在链的末尾增加该函数!#构建chain以及最后格式化输出chain=prompt|qianfan_chat|JsonOutputParser()print(chain.invoke({"input":"what'sthirteentimes4"})) 此时输出如下:{'name':'multiply','arguments':[13,4]}完美!5.函数调用!最终步骤!tools=[add,multiply]tool_map={tool.name:toolfortoolintools}deftools_call(model_output):chosen_tool=tool_map[model_output["name"]]returnchosen_tool.invoke(model_output["arguments"])chain=prompt|qianfan_chat|JsonOutputParser()|tools_callprint(chain.invoke({"input":"what'sthirteentimes4"})) 如果理解了上一篇的内容,这部分毫无难度~。详情可以移步上一篇哦~老规矩,全部代码展示!fromlangchain_core.toolsimporttoolimportosfromlangchain_community.chat_modelsimportQianfanChatEndpoint#创建工具调用fromlangchain.tools.renderimportrender_text_descriptionfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.output_parsersimportJsonOutputParserfromoperatorimportitemgetter@tooldefmultiply(first_int:int,second_int:int)->int:"""Multiplytwointegerstogether."""returnfirst_int*second_int@tooldefadd(first_int:int,second_int:int)->int:"""addtwointegerstogether."""returnfirst_int+second_inttools=[add,multiply]tool_map={tool.name:toolfortoolintools}#设定百度千帆大模型的AK和SK-去百度千帆官网的控制台新建一个应用即可os.environ["QIANFAN_AK"]="yourAK"os.environ["QIANFAN_SK"]="yourSK"#创建千帆LLM模型qianfan_chat=QianfanChatEndpoint(model="ERNIE-3.5-8K",temperature=0.2,timeout=30,)#构建工具条件和调用描述rendered_tools=render_text_description([multiply,add])print("rendered_tools=",rendered_tools)#构建工具选择器的系统人设system_prompt=f"""Youareanassistantthathasaccesstothefollowingsetoftools.Herearethenamesanddescriptionsforeachtool:{rendered_tools}Giventheuserinput,returnthenameandinputofthetooltouse.ReturnyourresponseasaJSONblobwith'name'and'arguments'keys."""#构建输入的模板prompt=ChatPromptTemplate.from_messages([("system",system_prompt),("user","{input}")])#构建chain以及最后格式化输出chain=prompt|qianfan_chatprint(chain.invoke({"input":"what'sthirteentimes4"}))deftools_call(model_output):chosen_tool=tool_map[model_output["name"]]returnchosen_tool.invoke(model_output["arguments"])chain=prompt|qianfan_chat|JsonOutputParser()|tools_callprint(chain.invoke({"input":"what'sthirteentimes4"}))总结本篇我们更深一层的剥开抽象的LangChain.对于LangChain的工具调用原理有了更深入的了解。下一篇我们将继续我们的Chain之路~构建和尝试更多的Chain!有何问题和想要了解的内容敬请留言哦
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-28 20:20 , Processed in 0.477342 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表