青训营X豆包MarsCode 技术训练营第四课 | 豆包MarsCode AI刷题

73 阅读3分钟

Agent 的关键组件

在LangChain的代理中,有这样几个关键组件。

  1. 代理(Agent):这个类决定下一步执行什么操作。它由一个语言模型和一个提示(prompt)驱动。提示可能包含代理的性格(也就是给它分配角色,让它以特定方式进行响应)、任务的背景(用于给它提供更多任务类型的上下文)以及用于激发更好推理能力的提示策略(例如ReAct)。LangChain中包含很多种不同类型的代理。

  2. 工具(Tools):工具是代理调用的函数。这里有两个重要的考虑因素:一是让代理能访问到正确的工具,二是以最有帮助的方式描述这些工具。如果你没有给代理提供正确的工具,它将无法完成任务。如果你没有正确地描述工具,代理将不知道如何使用它们。LangChain提供了一系列的工具,同时你也可以定义自己的工具。

  3. 工具包(Toolkits):工具包是一组用于完成特定目标的彼此相关的工具,每个工具包中包含多个工具。比如LangChain的Office365工具包中就包含连接Outlook、读取邮件列表、发送邮件等一系列工具。当然LangChain中还有很多其他工具包供你使用。

  4. 代理执行器(AgentExecutor):代理执行器是代理的运行环境,它调用代理并执行代理选择的操作。执行器也负责处理多种复杂情况,包括处理代理选择了不存在的工具的情况、处理工具出错的情况、处理代理产生的无法解析成工具调用的输出的情况,以及在代理决策和工具调用进行观察和日志记录。

总的来说,代理就是一种用语言模型做出决策、调用工具来执行具体操作的系统。通过设定代理的性格、背景以及工具的描述,你可以定制代理的行为,使其能够根据输入的文本做出理解和推理,从而实现自动化的任务处理。而代理执行器(AgentExecutor)就是上述机制得以实现的引擎。

深挖 AgentExecutor 的运行机制

让我们先来回顾一下上一讲中的关键代码。

llm = OpenAI(temperature=0) # 大语言模型 tools = load_tools(["serpapi", "llm-math"], llm=llm) # 工具-搜索和数学运算 agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) # 代理 agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?") # 运行代理 在这段代码中,模型、工具、代理的初始化,以及代理运行的过程都极为简洁。但是,LangChain的内部封装的逻辑究竟是怎样的?我希望带着你至少弄清楚两个问题。

代理每次给大模型的具体提示是什么样子的?能够让模型给出下一步的行动指南,这个提示的秘密何在? 代理执行器是如何按照ReAct框架来调用模型,接收模型的输出,并根据这个输出来调用工具,然后又根据工具的返回结果生成新的提示的。 运行代码后我们得到下面的日志。

要回答上面的两个问题,仅仅观察LangChain输出的Log是不够的。我们需要深入到LangChain的程序内部,深挖一下AgentExcutor的运行机制。