LangChain大型语言模型(LLM)应用开发(六):Agents

LangChain是一个基于大语言模型(如ChatGPT)用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互,将多个组件链接在一起,以便在不同的应用程序中使用。
今天我们来学习DeepLearning.AI的在线课程:LangChain for LLM Application Development的第六门课:Agents, 所谓Agents可以理解为那些可以代替你来完成各种任务的人,即代理人(agent)。agent在执行各种任务的时候可能会用到各种工具,那么今天我们就来讨论agent及其工具的使用。

 

首先我们还是要做一些基础性工作,比如设置openai的api key:

import osfrom dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env fileimport warnings
warnings.filterwarnings("ignore")

Langchain的内置工具

首先我们解释两个简单的Langchain的内置工具“llm-math”和"wikipedia",这里的llm-math工具具有做数学运算的能力,当我们有时候希望llm完成某些数学计算问题时就可以让llm使用该工具来获得准确的答案,而wikipedia工具则是著名的“维基百科”的查询工具,例如当我们希望llm能够准确回答一些关于历史问题时,我们就可以让llm使用该工具来查询“维基百科”从而获取准确的答案,下面我们来创建一个代理(agent),并让这个代理使用llm-math和wikipedia来完成某些特定任务:

from langchain.agents.agent_toolkits import create_python_agent
from langchain.agents import load_tools, initialize_agent
from langchain.agents import AgentType
from langchain.tools.python.tool import PythonREPLTool
from langchain.python import PythonREPL
from langchain.chat_models import ChatOpenAI#创建llm
llm = ChatOpenAI(temperature=0)#定义工具
tools = load_tools(["llm-math","wikipedia"], llm=llm)#创建代理
agent= initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,handle_parsing_errors=True,verbose = True)

这里对上述代码稍加解释,首先我们创建了一个openai的LLM, 接着我们创建了一个工具集tools,该工具集包含了"llm-math"和"wikipedia"这两个工具,最后我们创建了一个代理(agent), 在创建代理时我们将llm 和tools作为参数传递给了代理,我们还设置了代理的类型为AgentType.ZERO_SHOT_REACT_DESCRIPTION,接下来我们来看一下agent的内置prompt模板:

print(agent.agent.llm_chain.prompt.template)

 

 在该模板中LLM被告知要使用计算器工具和维基百科工具,并说明了这两个工具的使用场景,然后对完成任务的工作流程进行了介绍。

完成了创建代理的工作以后,我们就可以让代理来回答一些数学或者历史问题:

agent("300的25%是多少?")

 我们看到代理在执行这个数学计算问题的时候有一个工作流程,这个流程主要包含下面几个阶段:

  1. Action: 行动要使用的工具
  2. Action Input: 行动的输入条件
  3. Observation:行动完成后的观察到的结果
  4. Thought: 思考观察到的结果是否满足要求
  5. Final Answer: 最终的答案

这里需要说明的,从Action到Thought这四个阶段是可以重复多次执行的,当Thought(思考)观察到的结果不能满足要求,就会开始下一轮的Action到Thought的执行过程,直到最后思考观察到的结果满足要求以后才会结束Action到Thought的执行过程,最后输出最终答案,下面我们来询问一个历史相关的问题:

agent("西游记的作者是谁?请用中文回答我")

 这里我们看到代理认为这是一个“人物的问题”,因此它去搜索了英文版的维基百科,最后找到了西游记的作者是吴承恩。

Python Agent

前面我们在代理中使用了"llm-math","wikipedia"这两个Langchain内置工具,接下来我们来使用langchain的内置python工具PythonREPLTool,在下面这个例子中我们让agent对一组外国人姓名进行排序,排序的顺序是先last name后 first name:

#创建python agent
agent = create_python_agent(llm,tool=PythonREPLTool(),verbose=True
)#待排序的customer_list 
customer_list = [["Harrison", "Chase"], ["Lang", "Chain"],["Dolly", "Too"],["Elle", "Elem"], ["Geoff","Fusion"], ["Trance","Former"],["Jen","Ayai"]]#对customer_list安last name,first name次序排序
agent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""") 

 从上面返回的结果中,Action是 Python_REPL,在Action Input中是一段python代码,也就是说代理通过python工具Python_REPL执行了这段python代码,最后得到了按last name排序的结果。

下面我们来手动执行一下Action Input中的这段代码:

sorted([['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']], key=lambda x: (x[1], x[0]))

 

 这里我们可以看到Action Input中的这段代码是有效的。

查看输出细节

下面我们来查看一下这个python agent在执行的时候所隐藏的细节,只不过我们需要打开langchain的debug功能:

import langchain
langchain.debug=Trueagent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""") langchain.debug=False

 上图是我们截取的部分agent在执行过程中返回的部分细节信息,这里我们注意到细节信息中存在两个prompt, 这也就是说agent访问了两次LLM,我们把两个prompt的内容整理如下:

从上面的第一个prompt可知,我们告知LLM,它是一个执行python代码的代理,它可以通过使用python REPL工具来执行python代码,然后我们告诉LLM必须按照一套流程来完成接下来的任务,这个流程是:Question->Thought->Action->Action Input->Oberservation->Thought->Final Answer,其中 Thought/Action/Action Input/Observation 可以重复N次,在prompt的最后,我们抛出了Question, 最后留下空白的Thought等待LLM来回答。

下面是第二个经过整理的prompt内容:

 从上面的prompt中可知第二个prompt比第一个prompt又向前迈了一步,因为第二个prompt中已经有了Thought, Action 和Action Input三个步骤的内容,接下来就需执行Action Input中的代码,来完成Observation和Thought这两个步骤了。

通过上面的分析可知agent通过两次访问LLM后才完成了这个python编程的任务。其中第一次访问LLM时只是告诉LLM任务的内容是什么(也就是question)以及完成这个任务的基本流程,随后LLM返回了完成任务所需要的python 代码,然后调用python工具Python_REPL来执行代码, 第二次访问LLM时我们已经拿到了所需要的代码,还剩下Observation和Thought的步骤需要完成。最后LLM返回了代码的执行结果,并得到了最后的Final Answer。

这里我需要说明的是整个代理的执行过程是有点复杂的,我只是把里面的重点部分说明了一些,如果想仔细研究,那还需要自己亲手跑一下代码。

自定义工具

前面我们演示的都是Langchain的内置工具,其实我们还可以自定义工具,比如下面我们自定义了一个获取当前日期的函数time, 当我们向LLM询问当前日期的时候,代理都会执行这个自定义的函数:

from langchain.agents import tool
from datetime import date@tool
def time(text: str) -> str:"""Returns todays date, use this for any \questions related to knowing todays date. \The input should always be an empty string, \and this function will always return todays \date - any date mathmatics should occur \outside this function."""return str(date.today())agent= initialize_agent(tools + [time], llm, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,handle_parsing_errors=True,verbose = True)
try:result = agent("whats the date today?") print(result)
except: print("exception on external access")

 整合所有工具

下面我们把内置工具和自定义工具整合在一起开发一个多功能agent的例子,在这个例子中我们将会整合python工具,维基百科工具,duckduckgo搜索工具,自定义工具:

# pip install duckduckgo-search
from langchain.tools import DuckDuckGoSearchRun
from langchain.utilities import WikipediaAPIWrapper
from langchain.python import PythonREPL
from langchain.agents import Tool
from langchain.agents import initialize_agent
from langchain.chat_models import ChatOpenAI
import randomllm = ChatOpenAI(temperature=0)wikipedia = WikipediaAPIWrapper()
search = DuckDuckGoSearchRun()
python_repl = PythonREPL()#自定义工具,获取随机数
def random_num(input=""):return random.randint(0,5)#定义维基百科工具
wikipedia_tool = Tool(name='wikipedia',func= wikipedia.run,description="Useful for when you need to look up a topic, country or person on wikipedia"
)#定义duckduckgo 搜索工具
duckduckgo_tool = Tool(name='DuckDuckGo Search',func= search.run,description="Useful for when you need to do a search on the internet to find information that another tool can't find. \be specific with your input."
)#定义python工具
python_tool = Tool(name = "python repl",func=python_repl.run,description="useful for when you need to use python to answer a question. You should input python code"
)#定义获取随机数工具
random_tool = Tool(name='Random number',func= random_num,description="Useful for when you need to get a random number. input should be 'random'"
)#整合所有工具
tools=[python_tool,wikipedia_tool,duckduckgo_tool,random_tool]#创建代理
zero_shot_agent = initialize_agent(agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,tools=tools,llm=llm,verbose=True,max_iterations=5,
)

下面我们查看一下代理的prompt模板:

print(zero_shot_agent.agent.llm_chain.prompt.template)

 在上面的模板中分别就4个工具的应用场景做了介绍,它告诉LLM在什么情况下应该使用什么工具,工作流程仍然是:Question->Thought->Action->Action Input->Oberservation->Thought->Final Answer,其中 Thought/Action/Action Input/Observation 可以重复N次,下面我们就用这个多工具的agent来做一下测试:

#给我一个随机数
zero_shot_agent.run("Can you give me a random number?")

#乔.拜登是哪一年出生的
zero_shot_agent.run("When was Joe Biden born?")

#17×6等于几?
zero_shot_agent.run("What is 17*6?")

#苹果公司现在的股票价格是多少?
zero_shot_agent.run('what is the current price of AAPL')

 参考资料

DuckDuckGo Search | 🦜️🔗 Langchain

Agent types | 🦜️🔗 Langchain

Agents | 🦜️🔗 Langchain

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

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

相关文章

Ajax详解

文章目录 1. 概述1.1 Ajax工作原理1.2 Ajax的作用1.3 同步异步 2. 原生Ajax3. Axios3.1 Axios的基本使用3.2 Axios快速入门3.3 请求方法的别名 1. 概述 Ajax 是 “Asynchronous JavaScript and XML”(异步 JavaScript 和 XML)的缩写。它是一种在无需重新…

Java版本企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

决赛结束,颁奖在即:2023隐私计算大会暨“星河杯”隐私计算大赛颁奖典礼震撼来袭!

7月11日-12日,首届“星河杯”隐私计算大赛4个赛题共计37支团队陆续完成决赛评审,决出的大赛获奖团队代表将受邀出席7月26日在青岛星河湾酒店举办的2023隐私计算大会暨首届“星河杯”隐私计算颁奖典礼。 2023隐私计算大会暨首届“星河杯”隐私计算大赛颁奖…

shell脚本中一个隐晦的bug

1.逻辑表达式if [ ! EXP PATTERN ]不能判断EXP结果为空的情形; 2.而逻辑表达式if [[ EXP ! PATTERN ]可以判断EXP结果为空的情形;

计算机网络 day10 DNAT问题 - 堡垒机 - WLAN

目录 DNAT策略拓扑图: 问题一:当我们访问内网的Web服务的时候,我们防火墙服务器的80端口和Web服务器的8000端口是否需要一直调用程序监控呢? DNAT的作用就是可以帮助我们进行路由转发功能 问题二:当我们在继续DNAT…

【VUE】拖动侧边栏以便自由调整左右两侧的宽度

效果 &#xff08;1&#xff09;拖动前 &#xff08;2&#xff09;拖动后 主要代码 <template><el-row class"contnet" :gutter"20">// 1. 左侧树<el-col id"left-tree" class"left-tree" :offset"0" :…

什么是 Elasticsearch 索引?

作者&#xff1a;David Brimley 索引这个术语在科技界已经被用满了。 如果你问大多数开发人员什么是索引&#xff0c;他们可能会告诉你索引通常指的是关系数据库 (RDBMS) 中与表关联的数据结构&#xff0c;它提高了数据检索操作的速度。 但什么是 Elasticsearch 索引&#xff…

利用Python与ArcGIS工具进行蒸散发ET、植被总初级生产力GPP估算

查看原文>>>基于”Python”多技术融合在蒸散发与植被总初级生产力估算中的实践应用 熟悉蒸散发ET及其组分&#xff08;植被蒸腾Ec、土壤蒸发Es、冠层截留Ei&#xff09;、植被总初级生产力GPP的概念和碳水耦合的基本原理&#xff1b;掌握利用Python与ArcGIS工具进行课…

一篇文章教会你,在IntelliJ IDEA 中,一些让你相见恨晚的技巧

1.Easy Code Easy Code我个人在写博客案例demo时用的比较多&#xff0c;它可以快速的将数据库表映射成Java中的entity、controller、service、dao、mapper等文件&#xff0c;少量编码实现快速开发。 先用database连接数据库&#xff0c;在对应表上直接右键执行EasyCode即可生成…

【PostgreSQL内核学习(三)—— 查询重写】

查询重写 查询重写系统规则视图和规则系统ASLO型规则的查询重写规则系统与触发器的区别 查询重写的处理操作定义重写规则删除重写规则对查询树进行重写 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c…

Docker 架构解析:多角度解析 Docker 引擎与容器运行时

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

HIVE SQL 根据主键去重并实现其余字段分组聚合

相同个人id下所有字段按时间顺序补位&#xff0c;取首个不为空值 --数据建表 drop table if exists db.tb_name; create table if not exists db.tb_name ( id string,name string,tele string,email string,date string ) ; insert overwrite table db.tb_name values (&qu…