代理架构¶
许多LLM应用在LLM调用之前和/或之后实现特定的控制流程步骤。例如,RAG会检索与用户问题相关的文档,并将这些文档传递给LLM,以便将模型的响应基于提供的文档上下文。
我们有时不希望硬编码固定的控制流程,而是希望LLM系统能够选择自己的控制流程来解决更复杂的问题!这就是代理的一个定义:代理是使用LLM决定应用程序控制流程的系统。 LLM可以通过多种方式控制应用程序:
- LLM可以在两个潜在路径之间进行路由
- LLM可以决定调用众多工具中的哪一个
- LLM可以判断生成的答案是否足够,或者是否需要更多工作
因此,存在许多不同类型的代理架构,它们赋予LLM不同程度的控制权。
路由器¶
路由器允许LLM从指定的选项集中选择单个步骤。这是一种表现出相对有限控制级别的代理架构,因为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 提供了多个强大功能,用于构建定制化的代理系统:
人机协作¶
人类参与可以显著提高代理的可靠性,特别是对于敏感任务。这可能涉及:
- 批准特定操作
- 提供反馈以更新代理的状态
- 在复杂的决策过程中提供指导
当完全自动化不可行或不可取时,人机协作模式至关重要。在我们的人机协作指南中了解更多信息。
并行化¶
并行处理对于高效的多代理系统和复杂任务至关重要。LangGraph 通过其Send API 支持并行化,实现:
- 多个状态的并发处理
- 类似 map-reduce 操作的实现
- 独立子任务的高效处理
有关实际实现,请参阅我们的map-reduce 教程
子图¶
子图对于管理复杂的代理架构至关重要,特别是在多代理系统中。它们允许:
- 单个代理的隔离状态管理
- 代理团队的层次化组织
- 代理与主系统之间的受控通信
子图通过状态模式中的重叠键与父图通信。这实现了灵活的模块化代理设计。有关实现细节,请参阅我们的子图操作指南。
反思¶
反思机制可以通过以下方式显著提高代理的可靠性:
- 评估任务完成度和正确性
- 提供反馈以实现迭代改进
- 实现自我修正和学习
虽然反思通常基于 LLM,但也可以使用确定性方法。例如,在编码任务中,编译错误可以作为反馈。这种方法在这个使用 LangGraph 进行自我修正代码生成的视频中得到了演示。
通过利用这些功能,LangGraph 能够创建复杂的、特定任务的代理架构,这些架构可以处理复杂的工作流程、有效协作并持续改进其性能。