概述

监督者模式 是一种 多智能体 架构,其中中央监督代理协调专门的工作代理。当任务需要不同类型的专门知识时,这种方法表现出色。与其构建一个能跨领域管理工具选择的单一代理,不如创建专注于特定领域的专家,并由一个理解整体工作流程的监督者来协调。 在本教程中,您将构建一个个人助理系统,通过一个实际的工作流来展示这些优势。该系统将协调两个职责截然不同的专家:
  • 一个 日历代理,负责处理日程安排、可用性检查和事件管理。
  • 一个 电子邮件代理,负责管理通信、起草消息和发送通知。
我们还将融入 人工参与审核,以允许用户根据需要批准、编辑和拒绝操作(例如发送电子邮件)。
如果您正在从 langgraph-supervisor 包迁移,请参阅 从 langgraph-supervisor 迁移,其中包含迁移前后的模式,包括中断和恢复流程。

为什么使用监督者?

多智能体架构允许您在工作者之间划分 工具,每个工作者都有自己的独立提示词或指令。考虑一个能直接访问所有日历和电子邮件 API 的代理:它必须从众多相似工具中进行选择,理解每个 API 的确切格式,并同时处理多个领域。如果性能下降,将相关工具和相关提示词分离到逻辑组中可能会有所帮助(部分是为了管理迭代改进)。

概念

我们将涵盖以下概念:

设置

安装

本教程需要 langchain 包:
更多详情,请参阅我们的 安装指南。

LangSmith

设置 LangSmith 以检查代理内部发生了什么。然后设置以下环境变量:

组件

我们需要从 LangChain 的集成套件中选择一个聊天模型:
👉 阅读 OpenAI 聊天模型集成文档

1. 定义工具

首先定义需要结构化输入的工具。在实际应用中,这些工具会调用真实的 API(例如 Google Calendar、SendGrid 等)。在本教程中,您将使用桩代码来演示该模式。

2. 创建专门的子代理

接下来,我们将创建处理每个领域的专门子代理。

创建日历代理

日历代理理解自然语言的调度请求,并将其转换为精确的 API 调用。它处理日期解析、可用性检查和事件创建。
测试日历代理,看看它如何处理自然语言调度:
代理将 “明天下午2点” 解析为 ISO 格式(“2024-01-16T14:00:00”),计算结束时间,调用 create_calendar_event,并返回自然语言确认。

创建电子邮件代理

电子邮件代理处理消息的撰写和发送。它专注于提取收件人信息、制作合适的主题行和正文,并管理电子邮件通信。
使用一个自然语言请求测试电子邮件代理:
代理从非正式的请求中推断出收件人,制作了专业的主题行和正文,调用 send_email,并返回确认。每个子代理都有一个狭窄的关注点,配备了特定领域的工具和提示词,使其能够出色地完成特定任务。

3. 将子代理包装为工具

现在,将每个子代理包装成监督者可以调用的工具。这是创建分层系统的关键架构步骤。监督者将看到像 “schedule_event” 这样的高级工具,而不是像 “create_calendar_event” 这样的低级工具。
工具的描述有助于监督者决定何时使用每个工具,因此请确保它们清晰具体。我们只返回子代理的最终响应,因为监督者不需要看到中间的推理过程或工具调用。

4. 创建监督者代理

现在创建协调子代理的监督者。监督者只看到高级工具,并在域级别(而非单个 API 级别)做出路由决策。

5. 使用监督者

现在用需要跨多个领域协调的复杂请求来测试您完整的系统:

示例 1:简单的单域请求

监督者识别出这是一个日历任务,调用 schedule_event,然后日历代理处理日期解析和事件创建。
如需全面了解信息流,包括每个聊天模型调用的提示词和响应,请查看上述运行的 LangSmith 跟踪。

示例 2:复杂的多域请求

监督者识别出这需要同时执行日历和电子邮件操作,先为会议调用 schedule_event,然后为提醒调用 manage_email。每个子代理完成其任务,监督者将两个结果综合成一个连贯的响应。
监督者默认按顺序向子代理分派任务。每个工具调用在下一个开始前完成。然而,许多大型语言模型会在单个响应中发出多个工具调用(如上面的跟踪所示,schedule_event 和 manage_email 被一起调用),运行时会并行执行它们。您也可以配置显式的并行分派。详情请参阅 create_supervisor 参考文档。
请参阅 LangSmith 跟踪,以查看上述运行的详细信息流,包括各个聊天模型的提示词和响应。

完整的可运行示例

这是一个包含所有内容的可运行脚本:

理解架构

您的系统有三个层次。底层包含需要精确格式的刚性 API 工具。中间层包含接受自然语言、将其转换为结构化 API 调用,并返回自然语言确认的子代理。顶层包含路由到高级功能并综合结果的监督者。 这种关注点分离带来了几个好处:每一层都有聚焦的职责,您可以在不影响现有功能的情况下添加新领域,并且可以独立地测试和迭代每一层。

6. 添加人工参与审核

对敏感操作纳入 人工参与审核 是审慎的做法。LangChain 包含 内置中间件 来审核工具调用,在本例中是子代理调用的工具。 让我们为两个子代理都添加人工参与审核:
  • 我们将 create_calendar_event 和 send_email 工具配置为中断,允许所有 响应类型 (approve, edit, reject)
  • 我们仅在顶级代理中添加一个 检查点器。这是暂停和恢复执行所必需的。
让我们重复该查询。请注意,我们将中断事件收集到一个列表中以便下游访问:
这次我们中断了执行。让我们检查一下中断事件:
我们可以通过引用其 ID 使用 Command 来为每个中断指定决策。更多详情请参阅 人工参与审核指南。为了演示目的,这里我们将接受日历事件,但编辑出站电子邮件的主题:
运行按照我们的输入继续进行。

7. 进阶:控制信息流

默认情况下,子代理仅接收来自监督器的请求字符串。您可能希望传递额外的上下文,例如对话历史或用户偏好。

向子代理传递额外的对话上下文

这允许子代理查看完整的对话上下文,这对于解决歧义(例如“安排到明天同一时间”,这参考了之前的对话)非常有用。
您可以在 LangSmith 追踪的 聊天模型调用 中看到子代理接收的完整上下文。

控制监督器接收的内容

您还可以自定义流回监督器的信息:
重要提示: 确保子代理的提示强调其最终消息应包含所有相关信息。一个常见的失败模式是子代理执行了工具调用,但没有在最终响应中包含结果。

8. 关键要点

监督器模式创建了抽象层,其中每一层都有明确的职责。在设计监督器系统时,从明确的领域边界开始,并为每个子代理提供专注的工具和提示。为监督器编写清晰的工具描述,在集成之前独立测试每一层,并根据您的具体需求控制信息流。
何时使用监督器模式当您拥有多个不同的领域(日历、电子邮件、CRM、数据库),每个领域有多个工具或复杂的逻辑,您希望集中工作流控制,并且子代理不需要直接与用户对话时,请使用监督器模式。对于只有少数几个工具的简单情况,请使用单个代理。当代理需要与用户对话时,请使用 交接 代替。对于代理之间的点对点协作,请考虑其他多代理模式。

后续步骤

了解用于代理间对话的 交接,探索 上下文工程 以微调信息流,阅读 多代理概述 以比较不同模式,并使用 LangSmith 来调试和监控您的多代理系统。