在构建 大型语言模型 (LLM) 智能体应用时,您需要四个关键组件:智能体核心、内存模块、智能体工具和规划模块。无论您是设计问答智能体、多模态智能体还是智能体群,您都可以考虑许多实现框架 — 从开源到生产就绪。有关更多信息,请参阅 LLM 代理简介。
对于首次尝试开发 LLM 代理的用户,本文提供了以下内容:
- 开发者生态系统概述,包括可用框架和推荐的读数,以加快 LLM 代理的速度
- 用于构建首个由 LLM 提供支持的代理的初学者教程
面向代理的开发者生态系统概述
你们大多数人可能已经阅读过有关 LangChain 或 LLaMa-Index 代理的文章。以下是目前可用的一些实现框架:
那么,我推荐哪一种?答案是,“这取决于”。
单代理框架
社区构建了多个框架来推进 LLM 应用开发生态系统,为您提供了开发代理的简单路径。热门框架的一些示例包括 LangChain、LlamaIndex 和 Haystack.这些框架提供通用代理类、连接器和内存模组功能、第三方工具的访问权限,以及数据检索和提取机制。
选择哪种框架在很大程度上取决于您的工作流的细节和要求。在必须构建具有有向无环图 (DAG) (如逻辑流)或具有独特属性的复杂代理的情况下,这些框架为您自己的自定义实现提供了一个很好的提示参考点和通用架构。
多智能体框架
您可能会问:“多智能体框架有何不同?”简短回答是“世界”类。要管理多个智能体,您必须构建世界,或者说构建环境中它们彼此交互的环境、用户和环境中的工具。
这里的挑战在于,对于每个应用程序,所面对的世界都将是不同的。您需要一个定制的工具包来构建模拟环境,以及一个能够管理世界状态并具备代理通用类的工具包。您还需要一个用于管理代理之间流量的通信协议。 OSS 框架的选择取决于您所构建的应用程序类型以及所需的自定义程度。
为建筑代理推荐的阅读清单
您可以使用大量资源和材料来激发您对智能体的可能性的思考,但以下资源是涵盖智能体整体精神的良好起点:
- AutoGPT: 这个 GitHub 项目是首批真正的智能体之一,它旨在展示智能体能够提供的各种功能。查看项目中所使用的通用架构和提示技术将非常有益。
- Voyager:这个项目由 NVIDIA 研究 所提出,探索了自我提升智能体的概念,即智能体能够在没有任何外部干预的情况下学习使用新工具或构建工具。
- 智能体概念框架如OlaGPT提供了一个很好的起点,用于激发关于如何超越简单智能体的思考。这是因为简单智能体通常包含四个基本模块。
- 本文首先提出了使用结合大型语言模型、外部知识来源和离散推理的模块化神经符号架构(MRKL 系统)来执行复杂任务的核心机制。详情请参阅MRKL 系统:结合大型语言模型、外部知识来源和离散推理的模块化神经符号架构。
- 生成智能体:人类行为的交互式 Simulacra: 这是首批构建真正智能体群体的项目之一,它提供了一个多个智能体以去中心化的方式进行相互交互的解决方案。
如果您正在寻找更多阅读材料,由 LLM 提供支持的优秀智能体 列出了许多有用信息。如果您有特定的查询,请在此帖子下发表评论。
教程:构建问答代理
在本教程中,您构建了一个问答 (QA) 代理,可帮助您处理数据。
为了证明即使是一个简单的坐席也能应对复杂的挑战,您可以构建一个能够从财报电话会议中提取信息的坐席。您可以参考通话记录。图 1 展示了财报电话会议的一般结构,这将帮助您理解本教程中使用的文件。
在本文结束时,您构建的智能体将回答如下复杂的分层问题:
- 从 2024 年第一季度到 2024 年第二季度,收入增长了多少?
- 24 财年第 2 季度的关键要点是什么?
正如本系列的第 1 部分所介绍的,智能体包含四个组件:
- 工具
- 规划模块
- 显存
- 智能体核心
工具
要构建 LLM 代理,您需要以下工具:
- RAG 管道:没有 RAG,您将无法解决涉及数据对话的问题。因此,您需要的工具之一就是 RAG 工作流。为了本次讨论,我们假设 RAG 工作流对基本问题或原子问题的准确性为 100%。
- 数学工具:您还需要一个数学工具来执行各种分析。为了简化本文,我使用了 LLM 来回答数学问题,但对于生产应用程序,我推荐使用类似于 WolframAlpha 的工具。
规划模块
通过此 LLM 代理,您将能够回答以下问题:“在 2024 年第一季度到 2024 年第二季度期间,收入增长了多少?”基本上,我们将以下三个问题合二为一:
- 第一季度的收入是多少?
- 第二季度的收入是多少?
- 这两者之间有何区别?
答案是,您必须构建一个问题分解模块:
decomp_template = """GENERAL INSTRUCTIONS
You are a domain expert. Your task is to break down a complex question into simpler sub-parts.
USER QUESTION
{{user_question}}
ANSWER FORMAT
{"sub-questions":["<FILL>"]}""
如您所见,分解模块促使 LLM 将问题分解为不太复杂的部分。图 3 展示了答案。
显存
接下来,您必须构建一个内存模块,以跟踪被问到的所有问题,或者仅保留所有子问题和上述问题答案的列表。
class Ledger:
def __init__(self):
self.question_trace = []
self.answer_trace = []
您可以使用由两个列表组成的简单分类帐来执行此操作:一个用于跟踪所有问题,另一个用于跟踪所有答案。这有助于代理记住其已回答但尚未回答的问题。
评估心理模型
在构建智能体核心之前,请评估您目前拥有的核心:
- 用于搜索和执行数学计算的工具
- 一个计划者来分解这个问题
- 用于跟踪提问的内存模块。
此时,您可以将它们连接在一起,看看它是否可以用作心理模型(图 4)。
template = """GENERAL INSTRUCTIONS
Your task is to answer questions. If you cannot answer the question, request a helper or use a tool. Fill with Nil where no tool or helper is required.
AVAILABLE TOOLS
- Search Tool
- Math Tool
AVAILABLE HELPERS
- Decomposition: Breaks Complex Questions down into simpler subparts
CONTEXTUAL INFORMATION
<No previous questions asked>
QUESTION
How much did the revenue grow between Q1 of 2024 and Q2 of 2024?
ANSWER FORMAT
{"Tool_Request": "<Fill>", "Helper_Request "<Fill>"}"""
图 4 显示了收到的 LLM 答案。
您可以看到,LLM 请求使用搜索工具,这是一个合乎逻辑的步骤,因为答案很可能在语料库中。也就是说,您知道所有转录都不包含答案。在下一步(图 5)中,您提供来自 RAG 管道的输入,以确定答案不可用,因此代理随后决定将问题分解为更简单的子部分。
通过本练习,您确认逻辑的核心机制是可靠的。LLM 会根据需要选择工具和辅助工具。
现在,只需将其整齐地包装在 Python 函数中,该函数看起来类似于以下代码示例:
def agent_core(question):
answer_dict = prompt_core_llm(question, memory)
update_memory()
if answer_dict[tools]:
execute_tool()
update_memory()
if answer_dict[planner]:
questions = execute_planner()
update_memory()
if no_new_questions and no tool request:
return generate_final_answer(memory)
智能体核心
您刚刚看到了智能体核心的示例,还剩下什么?智能体核心不仅仅是将所有组件拼接在一起。您必须定义智能体执行流的机制。本质上有三个主要选择:
- 线性求解器
- 单线程递归求解器
- 多线程递归求解器
线性求解器
这就是我之前讨论过的执行类型。有一个线性解决方案链,代理可以在其中使用工具并进行一级规划。虽然这是一个简单的设置,但真正的复杂和微妙的问题通常需要分层思考。
单线程递归求解器
您还可以构建一个递归求解器,该求解器构建一个问题和答案树,直到原始问题得到解答。此树在深度优先遍历中求解。以下代码示例展示了逻辑:
def Agent_Core(Question, Context):
Action = LLM(Context + Question)
if Action == "Decomposition":
Sub Questions = LLM(Question)
Agent_Core(Sub Question, Context)
if Action == "Search Tool":
Answer = RAG_Pipeline(Question)
Context = Context + Answer
Agent_Core(Question, Context)
if Action == "Gen Final Answer”:
return LLM(Context)
if Action == "<Another Tool>":
<Execute Another Tool>
多线程递归求解器
您可以为树上的每个节点分离并行执行线程,而不是以迭代方式求解树。此方法增加了执行复杂性,但由于可以并行处理 LLM 调用,因此会产生巨大的延迟优势。
接下来该怎么做?
恭喜!您现在已经掌握了构建相当复杂的智能体的知识!下一步是根据您的问题调整前面讨论的原则。
要为 LLM 代理开发更多工具,请参阅 NVIDIA 深度学习培训中心 (DLI)。如需为您的用例构建、自定义和部署 LLM,请参阅 NVIDIA NeMo 框架。