LangChain是一個(gè)基于大語言模型(如ChatGPT)用于構(gòu)建端到端語言模型應(yīng)用的 Python 框架。它提供了一套工具、組件和接口,可簡(jiǎn)化創(chuàng)建由大型語言模型 (LLM) 和聊天模型提供支持的應(yīng)用程序的過程。LangChain 可以輕松管理與語言模型的交互,將多個(gè)組件鏈接在一起,以便在不同的應(yīng)用程序中使用。
今天我們來學(xué)習(xí)DeepLearning.AI的在線課程:LangChain for LLM Application Development的第六門課:Agents, 所謂Agents可以理解為那些可以代替你來完成各種任務(wù)的人,即代理人(agent)。agent在執(zhí)行各種任務(wù)的時(shí)候可能會(huì)用到各種工具,那么今天我們就來討論agent及其工具的使用。
?
首先我們還是要做一些基礎(chǔ)性工作,比如設(shè)置openai的api key:
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
import warnings
warnings.filterwarnings("ignore")
Langchain的內(nèi)置工具
首先我們解釋兩個(gè)簡(jiǎn)單的Langchain的內(nèi)置工具“l(fā)lm-math”和"wikipedia",這里的llm-math工具具有做數(shù)學(xué)運(yùn)算的能力,當(dāng)我們有時(shí)候希望llm完成某些數(shù)學(xué)計(jì)算問題時(shí)就可以讓llm使用該工具來獲得準(zhǔn)確的答案,而wikipedia工具則是著名的“維基百科”的查詢工具,例如當(dāng)我們希望llm能夠準(zhǔn)確回答一些關(guān)于歷史問題時(shí),我們就可以讓llm使用該工具來查詢“維基百科”從而獲取準(zhǔn)確的答案,下面我們來創(chuàng)建一個(gè)代理(agent),并讓這個(gè)代理使用llm-math和wikipedia來完成某些特定任務(wù):
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
#創(chuàng)建llm
llm = ChatOpenAI(temperature=0)
#定義工具
tools = load_tools(["llm-math","wikipedia"], llm=llm)
#創(chuàng)建代理
agent= initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
handle_parsing_errors=True,
verbose = True)
這里對(duì)上述代碼稍加解釋,首先我們創(chuàng)建了一個(gè)openai的LLM, 接著我們創(chuàng)建了一個(gè)工具集tools,該工具集包含了"llm-math"和"wikipedia"這兩個(gè)工具,最后我們創(chuàng)建了一個(gè)代理(agent), 在創(chuàng)建代理時(shí)我們將llm 和tools作為參數(shù)傳遞給了代理,我們還設(shè)置了代理的類型為AgentType.ZERO_SHOT_REACT_DESCRIPTION,接下來我們來看一下agent的內(nèi)置prompt模板:
print(agent.agent.llm_chain.prompt.template)
?
?在該模板中LLM被告知要使用計(jì)算器工具和維基百科工具,并說明了這兩個(gè)工具的使用場(chǎng)景,然后對(duì)完成任務(wù)的工作流程進(jìn)行了介紹。
完成了創(chuàng)建代理的工作以后,我們就可以讓代理來回答一些數(shù)學(xué)或者歷史問題:
agent("300的25%是多少?")
?我們看到代理在執(zhí)行這個(gè)數(shù)學(xué)計(jì)算問題的時(shí)候有一個(gè)工作流程,這個(gè)流程主要包含下面幾個(gè)階段:
- Action: 行動(dòng)要使用的工具
- Action Input: 行動(dòng)的輸入條件
- Observation:行動(dòng)完成后的觀察到的結(jié)果
- Thought: 思考觀察到的結(jié)果是否滿足要求
- Final Answer: 最終的答案
這里需要說明的,從Action到Thought這四個(gè)階段是可以重復(fù)多次執(zhí)行的,當(dāng)Thought(思考)觀察到的結(jié)果不能滿足要求,就會(huì)開始下一輪的Action到Thought的執(zhí)行過程,直到最后思考觀察到的結(jié)果滿足要求以后才會(huì)結(jié)束Action到Thought的執(zhí)行過程,最后輸出最終答案,下面我們來詢問一個(gè)歷史相關(guān)的問題:
agent("西游記的作者是誰?請(qǐng)用中文回答我")
?這里我們看到代理認(rèn)為這是一個(gè)“人物的問題”,因此它去搜索了英文版的維基百科,最后找到了西游記的作者是吳承恩。
Python Agent
前面我們?cè)诖碇惺褂昧?llm-math","wikipedia"這兩個(gè)Langchain內(nèi)置工具,接下來我們來使用langchain的內(nèi)置python工具PythonREPLTool,在下面這個(gè)例子中我們讓agent對(duì)一組外國(guó)人姓名進(jìn)行排序,排序的順序是先last name后 first name:
#創(chuàng)建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"]
]
#對(duì)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}""")
?從上面返回的結(jié)果中,Action是 Python_REPL,在Action Input中是一段python代碼,也就是說代理通過python工具Python_REPL執(zhí)行了這段python代碼,最后得到了按last name排序的結(jié)果。
下面我們來手動(dòng)執(zhí)行一下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中的這段代碼是有效的。
查看輸出細(xì)節(jié)
下面我們來查看一下這個(gè)python agent在執(zhí)行的時(shí)候所隱藏的細(xì)節(jié),只不過我們需要打開langchain的debug功能:
import langchain
langchain.debug=True
agent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""")
langchain.debug=False
?上圖是我們截取的部分agent在執(zhí)行過程中返回的部分細(xì)節(jié)信息,這里我們注意到細(xì)節(jié)信息中存在兩個(gè)prompt, 這也就是說agent訪問了兩次LLM,我們把兩個(gè)prompt的內(nèi)容整理如下:
從上面的第一個(gè)prompt可知,我們告知LLM,它是一個(gè)執(zhí)行python代碼的代理,它可以通過使用python REPL工具來執(zhí)行python代碼,然后我們告訴LLM必須按照一套流程來完成接下來的任務(wù),這個(gè)流程是:Question->Thought->Action->Action Input->Oberservation->Thought->Final Answer,其中 Thought/Action/Action Input/Observation 可以重復(fù)N次,在prompt的最后,我們拋出了Question, 最后留下空白的Thought等待LLM來回答。
下面是第二個(gè)經(jīng)過整理的prompt內(nèi)容:
?從上面的prompt中可知第二個(gè)prompt比第一個(gè)prompt又向前邁了一步,因?yàn)榈诙€(gè)prompt中已經(jīng)有了Thought, Action 和Action Input三個(gè)步驟的內(nèi)容,接下來就需執(zhí)行Action Input中的代碼,來完成Observation和Thought這兩個(gè)步驟了。
通過上面的分析可知agent通過兩次訪問LLM后才完成了這個(gè)python編程的任務(wù)。其中第一次訪問LLM時(shí)只是告訴LLM任務(wù)的內(nèi)容是什么(也就是question)以及完成這個(gè)任務(wù)的基本流程,隨后LLM返回了完成任務(wù)所需要的python 代碼,然后調(diào)用python工具Python_REPL來執(zhí)行代碼, 第二次訪問LLM時(shí)我們已經(jīng)拿到了所需要的代碼,還剩下Observation和Thought的步驟需要完成。最后LLM返回了代碼的執(zhí)行結(jié)果,并得到了最后的Final Answer。
這里我需要說明的是整個(gè)代理的執(zhí)行過程是有點(diǎn)復(fù)雜的,我只是把里面的重點(diǎn)部分說明了一些,如果想仔細(xì)研究,那還需要自己親手跑一下代碼。
自定義工具
前面我們演示的都是Langchain的內(nèi)置工具,其實(shí)我們還可以自定義工具,比如下面我們自定義了一個(gè)獲取當(dāng)前日期的函數(shù)time, 當(dāng)我們向LLM詢問當(dāng)前日期的時(shí)候,代理都會(huì)執(zhí)行這個(gè)自定義的函數(shù):
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")
?整合所有工具
下面我們把內(nèi)置工具和自定義工具整合在一起開發(fā)一個(gè)多功能agent的例子,在這個(gè)例子中我們將會(huì)整合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 random
llm = ChatOpenAI(temperature=0)
wikipedia = WikipediaAPIWrapper()
search = DuckDuckGoSearchRun()
python_repl = PythonREPL()
#自定義工具,獲取隨機(jī)數(shù)
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"
)
#定義獲取隨機(jī)數(shù)工具
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]
#創(chuàng)建代理
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個(gè)工具的應(yīng)用場(chǎng)景做了介紹,它告訴LLM在什么情況下應(yīng)該使用什么工具,工作流程仍然是:Question->Thought->Action->Action Input->Oberservation->Thought->Final Answer,其中 Thought/Action/Action Input/Observation 可以重復(fù)N次,下面我們就用這個(gè)多工具的agent來做一下測(cè)試:
#給我一個(gè)隨機(jī)數(shù)
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?")
#蘋果公司現(xiàn)在的股票價(jià)格是多少?
zero_shot_agent.run('what is the current price of AAPL')
?參考資料
DuckDuckGo Search | ????? Langchain
Agent types | ????? Langchain文章來源:http://www.zghlxwxcb.cn/news/detail-566754.html
Agents | ????? Langchain文章來源地址http://www.zghlxwxcb.cn/news/detail-566754.html
到了這里,關(guān)于LangChain大型語言模型(LLM)應(yīng)用開發(fā)(六):Agents的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!