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

系列文章目录

LangChain(一)构建本地数据检索问答Agent,新手向-CSDN博客

LangChain(二)基础问答大模型,纯新手向-CSDN博客

LangChain(三)基础问答大模型,从LLMchain开始了解chain!纯新手向-CSDN博客

LangChain(四)工具调用的底层原理!给大模型按上双手吧!(新手向)-CSDN博客


文章目录

前言

一、工具调用回顾

二、自己构建工具调用!

1.构建工具函数

2.定义大模型

3.设定工具选择模块

4.  构建chain以及最后格式化输出

5. 函数调用!最终步骤!

老规矩,全部代码展示!

总结


前言

随着第三篇的内容,我们跟进到了大模型调用工具的开发与原理,并浅尝辄止了一下大模型调用工具的原理!

本篇我们上接上文,继续此部分的内容,我们主要讲解有关大模型调用工具的原理!我们会尽可能的把LangChain高度抽象的代码还原,把每一个步骤都尽可能的说清楚!大家感兴趣的话可以看一下第四篇的内容~

其实不看也没事啦,看了理解起来会更快而已。本篇最大的用途是,对于一些不支持LangChain工具调用的大模型,我们依旧可以使用本方案工具调用!

一、工具调用回顾

        在上一篇的内容中我们开发了一个基础的工具调用代码,I know大家对于代码更感兴趣,所以我把代码先粘过来~

import os
from langchain_community.chat_models import QianfanChatEndpoint
from langchain_core.tools import tool
from langchain_core.messages import AIMessage
from langchain_core.runnables import Runnable# 设定百度千帆大模型的AK和SK
os.environ["QIANFAN_AK"] = " your AK"
os.environ["QIANFAN_SK"] = " your SK"# 定义千帆大模型
qianfan_chat = QianfanChatEndpoint(model="ERNIE-3.5-8K",temperature=0.2,timeout=30,
)# 设定两个函数,记得描述函数功能,这很重要
@tool
def func1():''' useless function '''return 0@tool
def Multiply(a: int, b: int) -> int:"""Multiplies a and b."""return a * b# 工具集合
tools = [Multiply, func1]
# 工具与大模型绑定,构建函数选择模块
llm_with_tools = qianfan_chat.bind_tools(tools)
# 构建一一对应的map
tool_map = {tool.name: tool for tool in tools}# 工具函数执行
def call_tools(msg: AIMessage) -> Runnable:"""Simple sequential tool calling helper."""tool_calls = msg.tool_calls.copy()for tool_call in tool_calls:tool_call["output"] = tool_map[tool_call["name"]].invoke(tool_call["args"])return tool_calls# 构建链
chain = llm_with_tools | call_toolsprint(chain.invoke("What's 25 times 11?")[0]["output"])

总而言之,上诉的代码主要经过了以下几个步骤:

初始化内容

  • 定义工具函数与大模型初始化
  • 工具函数与大模型绑定构建函数选择模块:llm_with_tools
  • 构建工具调用模块:call_tools

 chain实际运行的数据流

  • 用户输入给到函数选择模块
  • 函数选择模块输出需要的函数和对应的参数
  • 工具调用模块进行工具调用并返回

二、自己构建工具调用!

不必担心,依旧很简单~

1.构建工具函数

from langchain_core.tools import tool
@tool
def multiply(first_int: int, second_int: int) -> int:"""Multiply two integers together."""return first_int * second_int@tool
def add(first_int: int, second_int: int) -> int:"""add two integers together."""return first_int + second_int

我们使用下面的代码查看一下具体的内容,这些内容就是真正需要给到大模型参考的函数描述 

print(multiply.name)
print(multiply.description)
print(multiply.args)

 函数输出如下:

multiply
multiply(first_int: int, second_int: int) -> int - Multiply two integers together.
{'first_int': {'title': 'First Int', 'type': 'integer'}, 'second_int': {'title': 'Second Int', 'type': 'integer'}}

 可以查看一下第三行这是之前没有讲到的部分,此部分定义了函数输入参数的规格,用以提醒大模型。

2.定义大模型

直接用LangChain集成好的,依旧是千帆大模型~

import os
from langchain_community.chat_models import QianfanChatEndpoint# 设定百度千帆大模型的AK和SK-去百度千帆官网的控制台新建一个应用即可
os.environ["QIANFAN_AK"] = "your AK“"
os.environ["QIANFAN_SK"] = "your SK"#创建千帆LLM模型
qianfan_chat = QianfanChatEndpoint(model="ERNIE-3.5-8K",temperature=0.2,timeout=30,
)

3.设定工具选择模块

这部分是本篇精华,本篇和上一篇最大的区别就在于函数选择器,LangChain帮助我们把此部分高度抽象成了 llm_with_tools 。我们本篇将其拓写!

①构建函数描述模块!

from langchain.tools.render import render_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 - Multiply two integers together.
add(first_int: int, second_int: int) -> int - add two integers together.

有关该函数,详情可见如下: 

LangChain中的render_text_description究竟做了什么操作?-CSDN博客 

②构建工具选择输入prompt模板!

from langchain_core.prompts import ChatPromptTemplate# 构建工具选择器的系统人设
system_prompt = f"""You are an assistant that has access to the following set of tools. Here are the names and descriptions for each tool:{rendered_tools}# 构建输入的模板
Given the user input, return the name and input of the tool to use. Return your response as a JSON blob with 'name' and 'arguments' keys."""prompt = ChatPromptTemplate.from_messages([("system", system_prompt), ("user", "{input}")]
)

        通过上诉文本的阅读,我想看客们此时应该已经反应过来了,大模型工具选择的原理就是根据之前传入的函数描述符和用户的输入,返回需要的函数名称和参数。实在是非常粗暴。很多看客想必此时心中一万匹草泥马奔腾而过……。 

4.  构建chain以及最后格式化输出

# 构建chain以及最后格式化输出
chain = prompt | qianfan_chat
print(chain.invoke({"input": "what's thirteen times 4"}))

构建链的过程应该无需我过多解释,若不明白的看客可以查看一下上一篇的内容~。

此时的输出如下:

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's thirteen times 4"}))

 此时输出如下:

{'name': 'multiply', 'arguments': [13, 4]}

完美!

5. 函数调用!最终步骤!

tools = [add, multiply]
tool_map = {tool.name: tool for tool in tools}def tools_call(model_output):chosen_tool = tool_map[model_output["name"]]return chosen_tool.invoke(model_output["arguments"])chain = prompt | qianfan_chat | JsonOutputParser() | tools_call
print(chain.invoke({"input": "what's thirteen times 4"}))

 如果理解了上一篇的内容,这部分毫无难度~。详情可以移步上一篇哦~


老规矩,全部代码展示!

from langchain_core.tools import tool
import os
from langchain_community.chat_models import QianfanChatEndpoint
#创建工具调用
from langchain.tools.render import render_text_description
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from operator import itemgetter@tool
def multiply(first_int: int, second_int: int) -> int:"""Multiply two integers together."""return first_int * second_int@tool
def add(first_int: int, second_int: int) -> int:"""add two integers together."""return first_int + second_inttools = [add, multiply]
tool_map = {tool.name: tool for tool in tools}# 设定百度千帆大模型的AK和SK-去百度千帆官网的控制台新建一个应用即可
os.environ["QIANFAN_AK"] = "your AK"
os.environ["QIANFAN_SK"] = "your SK"#创建千帆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"""You are an assistant that has access to the following set of tools. Here are the names and descriptions for each tool:{rendered_tools}Given the user input, return the name and input of the tool to use. Return your response as a JSON blob with 'name' and 'arguments' keys."""# 构建输入的模板
prompt = ChatPromptTemplate.from_messages([("system", system_prompt), ("user", "{input}")]
)# 构建chain以及最后格式化输出
chain = prompt | qianfan_chat 
print(chain.invoke({"input": "what's thirteen times 4"}))def tools_call(model_output):chosen_tool = tool_map[model_output["name"]]return chosen_tool.invoke(model_output["arguments"])chain = prompt | qianfan_chat | JsonOutputParser() | tools_call
print(chain.invoke({"input": "what's thirteen times 4"}))

总结

本篇我们更深一层的剥开抽象的LangChain.对于LangChain的工具调用原理有了更深入的了解。

下一篇我们将继续我们的Chain之路~构建和尝试更多的Chain!

有何问题和想要了解的内容敬请留言哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/44240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字人+展厅互动体验方案:多元化互动方式,拓宽文化文娱新体验

数字化创新已成为推动展厅可持续发展,创造全新消费体验,满足游客多元化需求的关键力量。 “数字人数字互动展厅”可以适应年轻一代的文化传播与多媒体互动新体验趋势,打造新生代潮玩聚集地,促进文化创意传播与互动体验场景创新&a…

CC2530寄存器编程学习笔记_按键中断

目录 无中断按键 第一步 分析原理图 电路工作原理 第二步 配置寄存器 第一步 配置为通用IO口 第二步 配置为输入 第三步 输入模式选择 按键抖动 中断按键 第一步中断寄存器的配置 上升沿 下降沿 第一步 开启总中断使能 第二步 开启端口中断使能 第三步 开启端口引…

Android知识收集

文章列表 Android 高版本 HTTPS 抓包解决方案!链接关于RecyclerView你知道的不知道的都在这了 链接 工具列表 抓包工具-Reqable下载. 链接阿里云云效Maven 链接Android各尺寸图标生成 链接App Icon Generator,图标生成支持android, ios 链…

传统中小企业如何布局短视频矩阵?云微客说别踩坑

如今社会,不管是老少都在刷短视频,短视频已经成为大家受欢迎的内容形式之一了。很多企业和个人看到了短视频赛道的这个商机,纷纷投身于短视频制作中,都想为了能够在竞争激烈的市场中脱颖而出。 但是,短视频账号并不是一…

精益思维驱动未来:人工智能产品设计的新篇章

在科技日新月异的今天,人工智能(AI)已经渗透到我们生活的方方面面,从智能家居到自动驾驶,从医疗诊断到金融服务,AI的应用场景越来越广泛。然而,如何确保AI产品在设计之初就具备高效、灵活和可持…

ITIL4认证考试注意事项(附考试答题攻略)

作为一位持有ITIL4中级认证的IT服务管理专家,我深知备考ITIL4认证考试的重要性。在此分享我的复习备考经验,帮助你顺利通过考试。 1. 制定复习计划 制定详细的复习计划是备考的第一步。合理安排每天的复习时间,重点复习ITIL4的关键概念、四个…

CSS 【实用教程】(2024最新版)

CSS 简介 CSS 是层叠样式表( Cascading Style Sheets ) 的简写,用于精确控制 HTML 页面的样式,以便更好地展示图文信息或产生炫酷/友好的交互体验。 没有必要让所有浏览器都显示得一模一样的,好的浏览器有更好的显示,糟糕的浏览器…

E. Beautiful Array(cf954div3)

题意:给定一个数组,可以先对数组进行任意排序,每次操作可以选择一个ai,将它变成aik, 想让这个数组变成一个美丽数组(回文数组),求最少操作次数 分析: 先找出相同的数字…

C++Windows环境搭建(CLion)

文章目录 CLion下载安装CLion下载CLion安装新建项目新建一个文件基础设置字体设置clion中单工程多main函数设置 参考 CLion下载安装 CLion下载 打开网址:https://www.jetbrains.com/clion/download/ 点击Download进行下载。 CLion安装 双击下载好的安装包&…

华为浏览器,Chrome的平替,插件无缝连接

文章目录 背景插件书签 背景 不知道各位小伙伴有没有这样的痛点,办公电脑、家里的电脑还有手机、平板等,收藏了一个网址或者在手机上浏览了某个网页,保存起来,可是一换平台或者换个电脑,在想要浏览之前收藏的东西&…

伺服【禾川X6】

驱动器: A:脉冲 B:EtherCAT // SV-X6 FB 040 AA 一套360 N:CANopen R:PROFINET 电机: SV-X6 MA 040A-B2 KA

中小商家怎么做短视频矩阵?2人美甲店轻松100w+视频曝光量

最近有一个小魔推的合作伙伴问:我能开拓哪些商家? 市场部同学回答道:小魔推几乎没有行业限制,什么行业的商家都可以开拓,像餐饮、酒店、景区、游乐园、教育培训、驾校、4S店、母婴店、商超等等,还有很多传…

将windows下载的包传到linux服务器上

以一个例子说明。 要将下面的docker压缩包上传到对应的172.39.18.2ip的服务器上。 使用如下命令 scp F:\下载内容\docker-20.10.7.tgz root172.39.18.2:/root/test/ 注意是在windows的cmd命令行中。

在 ARM64 系统上使用 AddressSanitizer (ASan) 进行C/C++内存错误检测

文章目录 概要ASan 的配置与运行时优化CMake 配置运行时环境变量 ARM64 ASan库交叉编译动态链接 VS 静态链接示例:内存泄漏检测ASan 检测结果 概要 AddressSanitizer(ASan)是内存错误检测的强大工具,本文将介绍如何在 ARM64 系统…

新版FMEA培训未能达到预期效果怎么办?

在制造业的质量管理中,FMEA(Failure Mode and Effects Analysis,失效模式与影响分析)是一项至关重要的工具,它帮助企业识别和评估产品或过程中潜在的失效模式,以及这些失效模式可能导致的后果。然而&#x…

查看操作系统版本

查看操作系统版本 cat /etc/os-release 显示操作系统相关信息,包括发行版、版本号、ID等NAME"kos"VERSION"5.8"ID"kos"ID_LIKE"anolis rhel fedora centos"VERSION_ID"5.8"PLATFORM_ID"platform:an8"P…

FastAPI 学习之路(三十六)引入APIRouter

本次调整后的目录如下: 我们可以使用APIRouter来声明路径操作,我们先看下如何去使用。 我们根据选择划分为users和items来细分。 具体实现如下: ①先看items实现 from fastapi import APIRouter from fastapi import Depends from models.…

对称加密与非对称加密如何实现密钥交换

目录 一、对称加密中的密钥交换二、非对称加密中的密钥交换三、结合使用 对称加密与非对称加密在实现密钥交换时有着本质的不同方法。 一、对称加密中的密钥交换 由于对称加密使用相同的密钥进行加密和解密,因此密钥本身的安全传输是一个挑战。以下是一些常用的方…

面试题009-Java-MyBatis

面试题009-Java-MyBatis 目录 面试题009-Java-MyBatis题目自测题目答案1. 什么是MyBatis?它与Hibernate有什么区别?2. 说一下MyBatis的执行流程?3. MyBatis是否支持延迟加载?4. MyBatis中一级缓存和二级缓存的区别?5. …

Unity AssetsBundle 详解

文章目录 1.AssetBundle 概念2.AssetBundle 优势3.AssetBundle 特性4.AssetBundle 使用流程4.1 分组4.2 打包4.3 加载包4.4 加载资源4.5 卸载资源 5.AssetBundleManifest6.AssetBundle的内存占用7.AB包资源加密 1.AssetBundle 概念 AssetBundle又称AB包,是Unity提供…