14.【LangChain学院】Foundation (1.2.1)- Tools | 原生Function call | @Tool装饰类 | 多模型适配 | 交互管理

张开发
2026/4/13 23:52:37 15 分钟阅读

分享文章

14.【LangChain学院】Foundation (1.2.1)- Tools | 原生Function call | @Tool装饰类 | 多模型适配 | 交互管理
这是这是我们《AI开发实践》系列的第14 篇我们继续学习Langchain。前一节我们使用了提出的“程序化提示词框架SPC-E” 基于12个基本语义运算单元以及22条黄金准则写一段langchain代码调用提示词来演示了一下提示词写作。这一节我们来学另一个重要的能力工具调用。大模型能调用已有的工具/用程序新写的工具能够大大的扩展模型的能力边界以及模型返回结果的可靠性。大模型调用工具与用程序来调用模型都是混合编程的基础。在这一篇中我们假设已经有了一个方法 calculate_square 现在需要让大模型能够使用它。我们分别通过原生的function call 调用与langchain调用工具来体验一下其间的关异体会langchain的易用性。一、原生function call如果使用原生的function call, 我们需要参考大模型提供方提供的办法来调用它以deepseek为例1. 将已有方法square_root定义为一个工具# 将已有方法square_root定义为一个工具tools[{type:function,function:{name:square_root,# 模型识别的函数名description:计算一个数字的平方根输入数字x返回平方根,parameters:{type:object,properties:{x:{type:number,description:需要计算平方根的数字如9、16}},required:[x],# 必传参数additionalProperties:False# 禁止额外参数}}}]2. 首次对话时将工具列表告诉模型system_prompt Role: 你是一个计算器仅使用本地提供的Tools进行计算 Problem: 回答用户提出的数值计算问题 Objective: 直接给出数字答案 Tools: square_root当你需要计算一个数的平方根的时候调用该工具。 # 第一次对话 messages [{role: user, content: 9的平方根是多少?}] response client.chat.completions.create( modeldeepseek-chat, messagesmessages, toolstools )3. 模型在通过提示词判断出来需要调用工具时停止并返回ChatCompletionMessage( content我来帮你计算9的平方根。, refusalNone, roleassistant, annotationsNone, audioNone, function_callNone, tool_calls[ ChatCompletionMessageFunctionToolCall( idcall_00_OaPgVZwyic6kLLKpxtfMQLSh, functionFunction(arguments{x: 9}, namesquare_root), typefunction, index0 ) ] )上述的ChatCompletionMessageFunctionToolCall说明要调一个叫做square_root的工具而参数为{x: 9}4. 本地client收到后开始调用工具fortool_callinmsg.tool_calls:func_nametool_call.function.name argsjson.loads(tool_call.function.arguments)iffunc_namesquare_root:resultcalculate_square(**args)messages.append({role:tool,tool_call_id:tool_call.id,content:str(result)})#message中加入工具执行结果在这里注意if func_name square_root: result calculate_square(**args)这段代码可以看到尽管工具名是square_root,但是我们需要将其适配为实际的方法calculate_square5. 本地客户端再将历史信息和本地工具执行结果打包再发给模型# 第二次对话返回自然语言结果finalclient.chat.completions.create(modeldeepseek-chat,messagesmessages#将第一次的请求返回工具执行结果 组装成第二次请求发给模型)print(final.choices[0].message.content)6. 模型返回第二次请求的响应9的平方根是**3**。上述的过程 需要程序员去定义工具去控制交互过程写多份代码去适配不同的模型。二、langchain封装tool在langchain中是通过tool这个装饰类来简化上面直接使用function call 的复杂问题的。在langchain中将一个已有的方法定义为tool来说只需要加一个tool注解并在创建本地client时声明进去。其它的都由langchain框架来负责处理。1. 添加tool注解tool(square_root,descriptionCalculate the square root of a number)defcalculate_square(x:float)-float:returnx**0.5其中1calculate_square是原始方法名称而square_root是工具名Calculate the square root of a number是对工具的描述参数是{x: {title: X, type: number}}2此时经过tool装饰类处理后calculate_square的类型已经不再是class function, 而是class langchain_core.tools.structured.StructuredTool。但是由于其内部也实现了_call_所以代码内部仍然可以像原先调普通函数一样调用。比如result calculate_square(4)2. 创建Agent时注入toolssystem_prompt Role: 你是一个计算器仅使用本地提供的Tools进行计算 Problem: 回答用户提出的数值计算问题 Objective: 直接给出数字答案 Tools: square_root当你需要计算一个数的平方根的时候调用该工具。 #创建Agent,传入toolsagentcreate_agent(modelmodel,tools[calculate_square],system_promptsystem_prompt,debugTrue)这里要注意的是传入工具时用的还是方法名calculate_square 不是square_root。3. 在首次请求时langchain将tools自动注入{method:post,url:/chat/completions,headers:{X-Stainless-Raw-Response:true},files:None,idempotency_key:stainless-python-retry-06e6f83a-a44e-4907-ba97-cd95834f299c,content:None,json_data:{messages:[{content:\nRole: 你是一个计算器仅使用本地提供的Tools进行计算\nProblem: 回答用户提出的数值计算问题\nObjective: 直接给出数字答案\nTools:\n square_root当你需要计算一个数的平方根的时候调用该工具。\n,role:system},{content:9的平方根是多少?,role:user}],model:deepseek-chat,max_tokens:1000,stream:False,temperature:0.1,tools:[{type:function,function:{name:square_root,description:计算一个给定数值的平方根,parameters:{properties:{x:{type:number}},required:[x],type:object}}}],top_p:0.3}}可以看到在tools中langchain自动注入了一个function , name是square_root, parameters为x3. langchain自动管理与工具的往返交互Langchain在收到模型的第一次返回后自动根据返回中的要求执行tools并将tool的执行结果与历史交互信息一起再次发给模型Request options:{method:post,url:/chat/completions,headers:{X-Stainless-Raw-Response:true},files:None,idempotency_key:stainless-python-retry-970833eb-8a87-483f-bbe0-9b149d748f6d,content:None,json_data:{messages:[{content:你是一个计算器使用本地提供的工具进行计算,role:system},{content:9的平方根是多少?,role:user},{content:我来帮你计算9的平方根。,role:assistant,tool_calls:[{type:function,id:call_00_3rI0JefVPBFEiUYov6KAW3Qf,function:{name:square_root,arguments:{x: 9}}}]},{content:3.0,role:tool,tool_call_id:call_00_3rI0JefVPBFEiUYov6KAW3Qf}],model:deepseek-chat,max_tokens:1000,stream:False,temperature:0.1,tools:[{type:function,function:{name:square_root,description:计算一个给定数值的平方根,parameters:{properties:{x:{type:number}},required:[x],type:object}}}],top_p:0.3}}可以看到第二次请求时langchain自动的附上了第一次模型的返回我来帮你计算9的平方根。 以及工具执行的结果3.0.模型根据第二次的请求给出最终的返回9的平方根是3。三、总结langchain 通过 tool 大幅简化了function call的调用避免了程序员再去写Tool 以及 管理交互过程。还是相当的简单的但是对于想了解背后原理的人一定要记住大模型是无状态的每次客户端与模型的交互都是一次独立行为。模型每一次的答复都取决于我们这一次给它喂了什么。最后的原点还是提示词。而对于tools相关的提示词一定要记住langchain注入的的包括工具名称、输入参数以及基本用途仅说明了工具是什么。这些对于大模型的理解和使用还并不完整 还需要提供一份”工具使用手册“调用条件流程、规则来详细说明工具怎么用 。 因此需要在提示词的Tools区域再针对于这个工具进行单独的说明包括什么时候用用完了该做什么与其它的工具如何配合等等。欢迎指导和探讨❤️ 求关注 ❤️ 新星创作者冲榜中✨点击下方关注我持续输出高质量技术干货✨

更多文章