关键特性
- 集中控制:所有路由都经过主代理
- 无直接用户交互:子代理将结果返回给主代理,而不是用户(不过你可以在子代理内使用中断来允许用户交互)
- 通过工具调用子代理:子代理通过工具调用
- 并行执行:主代理可以在单次轮次中调用多个子代理
监督者 vs. 路由器:监督者代理(此模式)不同于路由器。监督者是一个完整的代理,它维护对话上下文并动态决定在多个轮次中调用哪些子代理。路由器通常是一个单一的分类步骤,它将任务分派给代理,而不维护持续的对话状态。
何时使用
当你有多个不同的领域(例如,日历、电子邮件、CRM、数据库)、子代理不需要直接与用户对话,或者你想要集中式工作流控制时,使用子代理模式。对于只有少数工具的简单情况,使用单一代理。基本实现
核心机制是将子代理包装为主代理可以调用的工具:教程:使用子代理构建个人助手
学习如何使用子代理模式构建个人助手,其中一个中央主代理(监督者)协调专门的子代理。
设计决策
在实现子代理模式时,你将做出几个关键的设计选择。此表总结了选项——每个选项在下面的章节中都有详细说明。同步 vs. 异步
子代理执行可以是同步的(阻塞)或异步的(后台)。你的选择取决于主代理是否需要结果才能继续。同步(默认)
默认情况下,子代理调用是同步的:主代理等待每个子代理完成后再继续。当主代理的下一个操作依赖于子代理的结果时,使用同步。 何时使用同步:- 主代理需要子代理的结果来构建其响应
- 任务具有顺序依赖性(例如,获取数据 → 分析 → 响应)
- 子代理失败应阻止主代理的响应
- 实现简单——只需调用并等待
- 在所有子代理完成之前,用户看不到响应
- 长时间运行的任务会冻结对话
异步
当子代理的工作是独立的——主代理不需要结果来继续与用户对话时,使用异步执行。主代理启动一个后台作业并保持响应。 何时使用异步:- 子代理工作独立于主对话流
- 用户应该能够在工作进行时继续聊天
- 你想并行运行多个独立任务
- 启动作业:启动后台任务,返回作业 ID
- 检查状态:返回当前状态(待处理、运行中、已完成、失败)
- 获取结果:检索已完成的结果
HumanMessage,例如“检查 job_123 并总结结果”。
工具模式
有两种主要方式将子代理暴露为工具:每个代理一个工具
关键思想是将子代理包装为主代理可以调用的工具:单一调度工具
另一种方法是使用一个参数化的工具来调用临时子代理以处理独立任务。与每个代理一个工具方法(每个子代理被包装为单独的工具)不同,这种方法使用基于约定的方法,只有一个task 工具:任务描述作为人类消息传递给子代理,子代理的最终消息作为工具结果返回。
当你希望跨多个团队分发代理开发、需要将复杂任务隔离到单独的上下文窗口中、需要一种可扩展的方式来添加新代理而无需修改协调器,或者偏好约定优于定制时,使用此方法。这种方法以牺牲上下文工程的灵活性为代价,换来了代理组合的简单性和强大的上下文隔离。
关键特性:
- 单一任务工具:一个参数化的工具,可以通过名称调用任何已注册的子代理
- 基于约定的调用:通过名称选择代理,任务作为人类消息传递,最终消息作为工具结果返回
- 团队分布:不同的团队可以独立开发和部署代理
- 代理发现:子代理可以通过系统提示(列出可用代理)或通过渐进式披露(通过工具按需加载代理信息)来发现
带有任务调度器的代理注册表
带有任务调度器的代理注册表
上下文工程
控制上下文如何在主代理及其子代理之间流动:
另请参阅我们关于代理上下文工程的全面指南。
子代理规范
与子代理关联的名称和描述是主代理知道调用哪些子代理的主要方式。这些是提示杠杆——请谨慎选择。- 名称:主代理如何引用子代理。保持清晰且面向行动(例如,
research_agent、code_reviewer)。 - 描述:主代理了解的子代理功能。具体说明它处理哪些任务以及何时使用它。
系统提示枚举
直接在主代理的系统提示中列出可用代理。主代理将代理列表及其描述作为其指令的一部分。 何时使用:- 你有一个小型、固定的代理集(< 10 个)
- 代理注册表很少更改
- 你想要最简单的实现
调度工具上的枚举约束
在你的调度工具的agent_name 参数上添加枚举约束。这提供了类型安全性,并使可用代理在工具模式中明确。
何时使用:
- 你有一个小型、固定的代理集(< 10 个)
- 你想要类型安全性和明确的代理名称
- 你偏好基于模式的验证,而不是基于提示的指导
基于工具的发现
提供一个单独的工具(例如,list_agents 或 search_agents),主代理可以调用它来按需发现可用代理。这支持渐进式披露并支持动态注册表。
何时使用:
- 你有很多代理(> 10 个)或不断增长的注册表
- 代理注册表频繁更改或是动态的
- 你想要减少提示大小和令牌使用量
- 不同的团队独立管理不同的代理
子代理输入
自定义子代理接收的上下文以执行其任务。通过从代理状态中提取,添加上下文,这些上下文不切实际地捕获在静态提示中——完整的消息历史、先前的结果或任务元数据。Subagent inputs example
子代理输出
自定义主代理接收到的内容,以便它能做出良好的决策。两种策略:- 提示子代理:明确指定应返回的内容。一个常见的失败模式是子代理执行工具调用或推理,但未在其最终消息中包含结果——提醒它监督者只看到最终输出。
- 在代码中格式化:在返回之前调整或丰富响应。例如,使用
Command将特定的状态键与最终文本一起传回。
Subagent outputs example
检查点和状态检查
默认情况下,子代理使用继承的检查点模式——每次调用都从新状态开始,支持中断,并且可以安全地并行运行。如果你需要一个子代理在多次调用之间维护其自己的持久对话历史,请使用checkpointer=True(延续模式)编译它。有关模式的完整比较,请参阅子图持久性。
由于子代理是在工具函数内部调用的,LangGraph 无法静态发现它们。这意味着带有 subgraphs 的 get_state 将不会返回子代理状态。如果你需要读取嵌套图状态(例如,在中断期间),请改为在自定义图中从节点函数调用子代理。有关每种模式如何影响状态可见性的详细信息,请参阅子图持久性。
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

