Skip to main content
异步子代理允许主管代理启动后台任务,这些任务会立即返回,因此主管代理可以在子代理并发工作的同时继续与用户交互。主管代理可以随时检查进度、发送后续指令或取消任务。 这建立在子代理的基础上,子代理是同步运行的,会阻塞主管代理直到完成。当任务耗时较长、可并行处理或需要中途调整时,请使用异步子代理。
异步子代理是 deepagents 1.9.0 中提供的预览功能。预览功能正在积极开发中,API 可能会发生变化。
异步子代理可与任何实现了代理协议的服务器通信。你可以使用 LangSmith 部署,或自托管任何兼容代理协议的服务器。每个子代理独立于主管代理运行,主管代理通过 SDK 来启动、检查、更新和取消它们。

何时使用异步子代理

配置异步子代理

将异步子代理定义为 AsyncSubAgent 规格列表,每个规格指向一个代理协议服务器:
对于基于 LangGraph 的部署,请在同一个 langgraph.json 中注册所有图,用于共部署设置:

使用异步子代理工具

AsyncSubAgentMiddleware 为主管代理提供五个工具: 主管代理的 LLM 像调用任何其他工具一样调用这些工具。中间件自动处理线程创建、运行管理和状态持久化。

理解生命周期

典型的交互遵循以下序列:
  • 启动 在服务器上创建一个新线程,以任务描述作为输入启动一个运行,并将线程 ID 作为任务 ID 返回。主管代理将此 ID 报告给用户,并且不会轮询完成情况。
  • 检查 获取当前运行状态。如果运行成功,它会检索线程状态以提取子代理的最终输出。如果仍在运行,它会向用户报告。
  • 更新 在同一线程上创建一个新的运行,使用中断多任务策略。之前的运行被中断,子代理使用完整的对话历史记录加上新指令重新启动。任务 ID 保持不变。
  • 取消 在服务器上调用 runs.cancel() 并将任务标记为 "cancelled"
  • 列出 遍历所有跟踪的任务。对于非终端任务,它会并行从服务器获取实时状态。终端状态(successerrorcancelled)从缓存返回。

理解状态管理

任务元数据存储在主管代理图上的专用状态通道(asyncTasks)中,与消息历史记录分开。这至关重要,因为深度代理在上下文窗口填满时会压缩其消息历史记录。如果任务 ID 仅存在于工具消息中,它们将在压缩过程中丢失。专用通道确保主管代理即使在多轮摘要之后,也能始终通过 list_async_tasks 回忆其任务。 每个跟踪的任务记录任务 ID、代理名称、线程 ID、运行 ID、状态和时间戳(createdAtcheckedAtupdatedAt)。

选择传输方式

ASGI 传输(共部署)

当子代理规格省略 url 字段时,LangGraph SDK 使用 ASGI 传输——SDK 调用通过进程内函数调用路由,而不是 HTTP。对于基于 LangGraph 的部署,这要求两个图都注册在同一个 langgraph.json 中。 ASGI 传输消除了网络延迟,无需额外的身份验证配置。子代理仍然作为独立线程运行,拥有自己的状态。这是推荐的默认设置。

HTTP 传输(远程)

添加 url 字段以切换到 HTTP 传输,SDK 调用通过网络发送到远程代理协议服务器:
对于 LangGraph 部署,身份验证由 LangGraph SDK 使用环境变量中的 LANGSMITH_API_KEY(或 LANGGRAPH_API_KEY)处理。自托管的代理协议服务器可能使用不同的身份验证机制。 当子代理需要独立扩展、不同的资源配置文件或由不同团队维护时,请使用 HTTP 传输。

选择部署拓扑

单一部署

单一部署意味着所有代理使用 ASGI 传输共部署在同一服务器上。对于基于 LangGraph 的部署,请在一个 langgraph.json 中注册所有图。这是推荐的起点——只需管理一个服务器,代理之间零网络延迟。

分离部署

主管代理在一个服务器上,子代理通过 HTTP 传输在另一个服务器上。当子代理需要不同的计算配置文件或独立扩展时使用。

混合部署

在混合部署中,一些子代理通过 ASGI 共部署,其他子代理通过 HTTP 远程部署:

最佳实践

为本地开发调整工作池大小

使用 langgraph dev 在本地运行时,增加工作池大小以适应并发的子代理运行。每个活跃的运行占用一个工作槽。具有 3 个并发子代理任务的主管代理需要 4 个槽(1 个主管代理 + 3 个子代理)。配置不足会导致启动排队。

编写清晰的子代理描述

主管代理使用描述来决定启动哪个子代理。描述应具体且面向操作:

使用线程 ID 进行跟踪

使用基于 LangGraph 的部署时,每个异步子代理运行都是标准的 LangGraph 运行,在 LangSmith 中完全可见。主管代理的跟踪显示 launchcheckupdatecancellist 的工具调用。每个子代理运行显示为单独的跟踪,通过线程 ID 关联。使用线程 ID(任务 ID)将主管代理编排跟踪与子代理执行跟踪关联起来。

故障排除

主管代理在启动后立即轮询

问题:主管代理在启动后立即循环调用 check,将异步执行变为阻塞。 解决方案:中间件注入系统提示规则以防止这种情况。如果轮询仍然存在,请在主管代理的系统提示中强化此行为:

主管代理报告过时的状态

问题:主管代理引用对话历史中较早的任务状态,而不是进行新的 check 调用。 解决方案:中间件提示指示模型“对话历史中的任务状态总是过时的”。如果仍然发生,请添加明确指令,在报告状态前始终调用 checklist

任务 ID 查找失败

问题:主管代理截断或重新格式化任务 ID,导致 checkcancel 失败。 解决方案:中间件提示指示模型始终使用完整的任务 ID。如果截断仍然存在,这通常是特定模型的问题——尝试不同的模型,或在系统提示中添加“始终显示完整的 task_id,切勿截断或缩写它”。

子代理启动排队而非运行

问题:启动子代理挂起或需要很长时间才能开始。 解决方案:工作池可能已耗尽。使用 --n-jobs-per-worker 增加池大小。参见调整工作池大小

参考实现

async-deep-agents 仓库包含 Python 和 TypeScript 的工作示例,可部署到 LangSmith 部署。它演示了一个主管代理,其研究员和编码员子代理作为后台任务运行。