自定义MRKL代理
MRKL:Modular Reasoning, Knowledge and Language
来源:https://arxiv.org/abs/2205.00445
参考:https://medium.com/mlearning-ai/supercharging-large-language-models-with-langchain-1cac3c103b52
本文档介绍如何创建自定义的MRKL代理。
一个MRKL代理由三个部分组成:
- 工具:代理可用的工具。
- LLMChain:产生被解析的文本以确定采取哪种操作的LLMChain。
- 代理类本身:解析LLMChain的输出以确定采取哪种操作。
在本文档中,我们将通过创建自定义的LLMChain来演示如何创建自定义的MRKL代理。
自定义LLMChain
创建自定义代理的第一种方法是使用现有的Agent类,但使用自定义的LLMChain。这是创建自定义代理的最简单方法。强烈建议您使用ZeroShotAgent
,因为目前它是最通用的。
创建自定义LLMChain的大部分工作都涉及到提示。因为我们使用现有的代理类来解析输出,所以提示中指定以该格式生成文本非常重要。此外,我们目前需要一个agent_scratchpad
输入变量来记录之前的操作和观察。这几乎总是提示的最后一部分。除了这些指令之外,您可以根据需要自定义提示。
为了确保提示包含适当的指令,我们将利用该类上的一个辅助方法。ZeroShotAgent
的辅助方法接受以下参数:
- tools:代理将访问的工具列表,用于格式化提示。
- prefix:在工具列表之前放置的字符串。
- suffix:在工具列表之后放置的字符串。
- input_variables:最终提示将期望的输入变量列表。
在这个例子中,我们将让我们的代理访问Google搜索,并将其定制为以海盗的口吻回答问题。
from langchain.agents import ZeroShotAgent, Tool, AgentExecutor
from langchain import OpenAI, SerpAPIWrapper, LLMChain
search = SerpAPIWrapper()
tools = [
Tool(
name="Search",
func=search.run,
description="用于回答有关当前事件的问题时非常有用",
)
]
prefix = """尽力回答以下问题,但要以海盗的口吻回答。您可以使用以下工具:"""
suffix = """开始!在给出最终答案时,请记住以海盗的口吻说话。使用很多"Args"
问题:{input}
{agent_scratchpad}"""
prompt = ZeroShotAgent.create_prompt(
tools, prefix=prefix, suffix=suffix, input_variables=["input", "agent_scratchpad"]
)
如果我们好奇,现在我们可以查看最终提示模板,看看当所有内容都放在一起时它是什么样子的。
print(prompt.template)
尽力回答以下问题,但要以海盗的口吻回答。您可以使用以下工具:
Search: 用于回答有关当前事件的问题时非常有用
使用以下格式:
问题:您必须回答的输入问题
思考:您应该始终考虑要做什么
行动:要采取的行动,应为[Search]之一
行动输入:行动的输入
观察:行动的结果
...(这个思考/行动/行动输入/观察可以重复N次)
思考:我现在知道最终答案
最终答案:原始输入问题的最终答案
开始!在给出最终答案时,请记住以海盗的口吻说话。使用很多"Args"
问题:{input}
{agent_scratchpad}
请注意,我们可以为代理提供自定义的提示模板,即不限于create_prompt
函数生成的提示,只要它符合代理的要求。
例如,对于ZeroShotAgent
,我们需要确保它满足以下要求。应该有一个以"Action:"开头的字符串,后面跟着一个以"Action Input:"开头的字符串,两者之间应该用换行符分隔。
llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
tool_names = [tool.name for tool in tools]
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent, tools=tools, verbose=True
)
agent_executor.run("截至2023年,加拿大有多少人口?")
输出结果:
> 进入新的AgentExecutor链...
思考:我需要找出加拿大的人口
行动:Search
行动输入:加拿大2023年人口
观察:根据世界计量器对最新的联合国数据的阐述,截至2023年4月16日星期日,加拿大的当前人口为38,661,927人。
思考:我现在知道最终答案
最终答案:嗯哼,截至2023年,加拿大有38,661,927人居住!
> 完成链。
最终输出结果:
"嗯哼,截至2023年,加拿大有38,661,927人居住!"
多个输入
Agents也可以使用需要多个输入的提示进行工作。
```python
prefix = """尽力回答以下问题。您可以使用以下工具:"""
suffix = """回答时,您必须使用以下语言:{language}。
问题:{input}
{agent_scratchpad}"""
prompt = ZeroShotAgent.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
input_variables=["input", "language", "agent_scratchpad"],
)
llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)
agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent, tools=tools, verbose=True
)
agent_executor.run(
input="截至2023年,加拿大有多少人口?", language="意大利语"
)
> 进入新的AgentExecutor链...
思考:我应该寻找最近的人口估计。
行动:搜索
行动输入:加拿大人口2023年
观察:39,566,248
思考:我应该再次核实这个数字。
行动:搜索
行动输入:加拿大人口估计2023年
观察:加拿大的人口估计在2023年1月1日为39,566,248人,这是自2022年1月1日至2023年1月1日人口增长创下纪录的1,050,110人。
思考:我现在知道最终答案了。
最终答案:La popolazione del Canada è stata stimata a 39.566.248 il 1° gennaio 2023, dopo un record di crescita demografica di 1.050.110 persone dal 1° gennaio 2022 al 1° gennaio 2023.
> 完成链。
'La popolazione del Canada è stata stimata a 39.566.248 il 1° gennaio 2023, dopo un record di crescita demografica di 1.050.110 persone dal 1° gennaio 2022 al 1° gennaio 2023.'