基础部分总结(3/3) | 豆包MarsCode AI刷题

112 阅读4分钟

5. Agents

大模型在输出答案时,如果没有足够的数据,就会胡言乱语。代理就是对大模型的数据进行补充。可以根据用户的输入自主判断、自行调用工具、自行决定下一步行动。

1)ReAct框架

**ZERO_SHOT_REACT_DESCRIPTION:**最常用的代理类型,自动形成了一个完善的思考与行动链条。

通过设置AgentTypeZERO_SHOT_REACT_DESCRIPTION,使用该框架进行推理。

from langchain_community.agent_toolkits.load_tools import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType

#初始化大模型(llm)

# 设置工具
tools = load_tools(["**工具名**"], llm=llm)

# 初始化Agent
agent = initialize_agent(
		tools, 
		llm, 
		agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 
		verbose=True)

# 运行Agent
agent.run("**问题**")

2)Structured Tool Chat(结构化工具对话)

**STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION:**调用包含一系列复杂工具的“结构化工具箱”,组合调用其中的多个工具,完成批次相关的任务集合。

相比ZERO_SHOT_REACT_DESCRIPTION,这个方法可以执行更多、更复杂的操作。

以PlayWright为例,PlayWrightBrowserToolkit为 PlayWright 浏览器提供了一系列交互的工具,可以在同步或异步模式下操作。构化工具代理可以组合调用工具包中的多个工具,在回答问题的过程中判断需要用到哪些工具,根据调用工具得到的结果回答问题或者调用其他工具。

  • 创建tools,明确需要用到的代理工具:SerpAPI,同时明确异步浏览的策略
from langchain_community.agent_toolkits.playwright.toolkit import PlayWrightBrowserToolkit
from langchain_community.tools.playwright.utils import create_async_playwright_browser

async_browser = create_async_playwright_browser()
toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=async_browser)
tools = toolkit.get_tools()
  • 创建代理工具,AgentType为.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
from langchain.agents import initialize_agent, AgentType

agent_chain = initialize_agent(
    tools,
    llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,    #代理类型(结构化工具对话)
    verbose=True,
)
#异步定义函数,调用代理链执行任务,并打印响应。
async def main():
    response = await agent_chain.arun("##需要问的问题##")
    print(response)

arun是异步版本的run方法,用于执行代理链。

3)Self-Ask with Search(自问自答结合搜索)

利用 “Follow-up Question(追问)”加“Intermediate Answer(中间答案)”的技巧,辅助大模型寻找事实性问题的过渡性答案,从而引出最终答案。

适合解决多跳问题,从信息源中获取中间信息,根据中建信息获取下一步信息,循环该步骤得到最终答案。

以SerpAPI为例,在回答问题的过程中,会先回答“使用玫瑰作为国花的国家”,再回答“这个国家的首都”

  • 创建tools,明确需要用到的代理工具:SerpAPI
from langchain_community.utilities import SerpAPIWrapper

search = SerpAPIWrapper()
tools = [
    Tool(
        name="Intermediate Answer",
        func=search.run,
        description="useful for when you need to ask with search",
    )
]
  • 创建代理工具,AgentTypeSELF_ASK_WITH_SEARCH
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
self_ask_with_search = initialize_agent(
    tools,
    llm, 
    agent=AgentType.SELF_ASK_WITH_SEARCH, 
    verbose=True
)
self_ask_with_search.run("使用玫瑰作为国花的国家的首都是哪里?")

4)Plan and execute(计划与执行)

先计划,再执行,一个Planner,有一个Executor,可以使用不同的模型。

以SerpAPI为例,分别创建Planner和Executor,再进行组合。

  • 先创建tools,明确需要用到的代理工具:SerpAPI以及LLMMath。
from langchain.agents import Tool
from langchain.chains import LLMMathChain
from langchain_community.utilities import SerpAPIWrapper
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="useful for when you need to answer questions about current events",
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math",
    ),
]
  • 创建planner,需要一个大模型model1,这个大模型制定实现问题所需要的步骤,以及如何使用代理工具。
from langchain_experimental.plan_and_execute import load_chat_planner,
planner=load_chat_planner(model1)
  • 创建Executor,需要一个大模型model2,可以跟model1相同。因为Executor对问题进行检索,所以需要用到tools里面的代理工具,检索相关信息。
from langchain_experimental.plan_and_execute import load_agent_executor
executor = load_agent_executor(model2, tools, verbose=True)
  • 使用PlanAndExecute将二者组合,获得一个代理
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
agent.run("在纽约,100美元能买几束玫瑰?")

6. Toolkits

6.1. 如何加载工具

1)方法一:

from langchain.agents import load_tools
tool_names = [...]
tools = load_tools(tool_names)

2)方法二:

某些工具(例如链、代理)可能需要 LLM 来初始化它们。

from langchain.agents import load_tools
tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm)

6.2. langchain支持的工具及工具箱

1)支持的工具

image.png

2)支持的工具箱

image.png

6.3. 案例:arXiv助手

  • 初始化模型和工具
from langchain.agents import load_tools
llm = ChatOpenAI(temperature=0.0)
tools = load_tools(
    ["arxiv"],
)
  • 初始化链
from langchain.agents import initialize_agent, AgentType
agent_chain = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
)
  • 运行链

agent_chain.run("介绍一下2005.14165这篇论文的创新点?")

总结

基础部分的内容难度并不大,但是却非常重用。通过对基础部分的总结,将重点部分凝练出来,有助于个人理解langchain如何实现各种功能,同时在使用langchain部署开发项目的时候,可以直接copy模板替换内容,降低写代码难度。目前对这部分的理解尚处在学习、模仿阶段,未来在实际使用中才能真正融会贯通。