Agent 架构¶
许多 LLM 应用在调用 LLM 之前和 / 或之后实现特定的控制流程。例如,RAG 会检索与用户问题相关的文档,并将这些文档传递给 LLM,以使模型的回答基于提供的文档上下文。
而不是硬编码固定的控制流程,我们有时希望 LLM 系统能够自行选择控制流程来解决更复杂的问题!这就是 agent 的一个定义:agent 是一个使用 LLM 来决定应用程序控制流程的系统。 LLM 可以通过多种方式控制应用:
- LLM 可以在两个潜在路径之间进行路由
- LLM 可以决定调用哪一个工具
- LLM 可以决定生成的答案是否足够,或者是否需要进一步的工作
因此,存在许多不同类型的 agent 架构,它们为 LLM 提供了不同程度的控制。
IMG_PLACEHOLDER_1
路由器¶
路由器允许大语言模型(LLM)从指定的一组选项中选择一个步骤。这是一种代理架构,其控制能力相对有限,因为LLM通常专注于做出单个决策,并从一组预定义的选项中生成特定的输出。路由器通常采用几种不同的概念来实现这一点。
结构化输出¶
结构化输出通过为LLM提供特定的格式或模式来工作,使其响应遵循该格式或模式。这类似于工具调用,但更为通用。虽然工具调用通常涉及选择和使用预定义的函数,但结构化输出可以用于任何类型的格式化响应。实现结构化输出的常见方法包括:
- 提示工程:通过系统提示指令LLM以特定格式进行响应。
- 输出解析器:使用后处理从LLM响应中提取结构化数据。
- 工具调用:利用某些LLM内置的工具调用功能生成结构化输出。
结构化输出对于路由至关重要,因为它们确保了LLM的决策可以被系统可靠地解释和执行。了解更多关于结构化输出的指南。
工具调用代理¶
虽然路由器允许大语言模型(LLM)做出单个决策,但更复杂的代理架构在两个关键方面扩展了LLM的控制能力:
- 多步骤决策:LLM可以依次做出一系列决策,而不仅仅是单一决策。
- 工具访问:LLM可以从各种工具中选择并使用这些工具来完成任务。
ReAct 是一种流行的通用代理架构,结合了上述扩展,集成了三个核心概念。
这种架构允许代理表现出更复杂和灵活的行为,超越简单的路由,实现具有多个步骤的动态问题解决。与原始论文不同,如今的代理依赖于LLM的工具调用功能,并基于消息列表进行操作。
在LangGraph中,你可以使用预构建的代理来开始使用工具调用代理。
工具调用¶
当你希望代理与外部系统进行交互时,工具非常有用。外部系统(例如API)通常需要特定的输入模式或负载,而不是自然语言。当我们将一个API作为工具绑定时,我们让模型了解所需的输入模式。模型会根据用户的自然语言输入决定调用哪个工具,并返回符合该工具所需模式的输出。
许多LLM提供者支持工具调用,并且在LangChain中,工具调用接口很简单:你只需将任意Python function
传递给 ChatModel.bind_tools(function)
即可。
记忆¶
记忆对于代理至关重要,它使代理能够在解决问题的多个步骤中保留和利用信息。它在不同的尺度上运行:
LangGraph 提供了对记忆实现的完全控制:
State
: 用户定义的模式,指定要保留的记忆的确切结构。Checkpointer
: 在会话的不同交互中,每一步存储状态的机制。Store
: 存储用户特定或应用级别的数据跨会话的机制。
这种灵活的方法允许你根据特定代理架构的需求定制记忆系统。关于如何向图中添加记忆的实用指南,请参阅 此教程。
有效的 记忆管理 可增强代理保持上下文、从过去经验中学习并在未来做出更明智决策的能力。
规划¶
在一个工具调用 代理 中,LLM会在一个 while 循环中被反复调用。在每一步中,代理决定调用哪些工具以及这些工具的输入应为何种内容。然后执行这些工具,其输出作为观察结果反馈给 LLM。当代理认为已经收集到足够的信息来解决用户请求,并且继续调用更多工具不再值得时,while 循环终止。
自定义代理架构¶
虽然路由器和工具调用代理(如 ReAct)很常见,但自定义代理架构通常能为特定任务带来更好的性能。LangGraph 提供了多种强大的功能来构建定制化的代理系统:
人机协作(Human-in-the-loop)¶
人类的参与可以显著提高代理的可靠性,尤其是在处理敏感任务时。这可能包括:
- 批准特定操作
- 提供反馈以更新代理的状态
- 在复杂决策过程中提供指导
当完全自动化不可行或不理想时,人机协作模式尤为重要。了解更多请参阅我们的人机协作指南。
并行化¶
并行处理对于高效的多代理系统和复杂任务至关重要。LangGraph 通过其 Send API 支持并行化,实现以下功能:
- 多个状态的并发处理
- 实现类似 map-reduce 的操作
- 高效处理独立的子任务
关于实际实现,请参见我们的map-reduce 教程。
子图(Subgraphs)¶
子图在管理复杂的代理架构中至关重要,特别是在多代理系统中。它们允许:
- 为单个代理提供隔离的状态管理
- 对代理团队进行分层组织
- 控制代理与主系统之间的通信
子图通过状态模式中的重叠键与父图通信。这使得代理设计更加灵活和模块化。有关实现细节,请参考我们的子图使用指南。
反思(Reflection)¶
反思机制可以通过以下方式显著提高代理的可靠性:
- 评估任务完成情况和正确性
- 提供用于迭代改进的反馈
- 实现自我纠正和学习
尽管通常是基于 LLM 的,但反思也可以使用确定性方法。例如,在编码任务中,编译错误可以用作反馈。这种方法在这个使用 LangGraph 进行自我校正代码生成的视频中有所展示。
通过利用这些功能,LangGraph 能够创建出复杂且针对特定任务的代理架构,能够处理复杂的流程、有效协作,并持续改进其性能。