多智能体系统 将复杂应用程序分解为多个协同工作以解决问题的专门智能体。
多智能体架构允许您将较小的、专注的智能体组合成协调的工作流程,而不是依赖单个智能体来处理每个步骤。
多智能体系统在以下情况下很有用:
单个智能体有太多工具,并且在选择使用哪个工具方面做出糟糕的决策。
上下文或记忆对于一个智能体来说太大而无法有效跟踪。
任务需要专业化 (例如,规划者、研究者、数学专家)。
多智能体模式
模式 工作原理 控制流 示例用例 工具调用 监督者 智能体将其他智能体作为工具 调用。“工具”智能体不直接与用户交谈 — 它们只是运行其任务并返回结果。集中式:所有路由都通过调用智能体。 任务编排、结构化工作流程。 交接 当前智能体决定转移控制 到另一个智能体。活动智能体改变,用户可以继续直接与新智能体交互。 分散式:智能体可以更改谁处于活动状态。 多领域对话、专家接管。
教程:构建监督者智能体 学习如何使用监督者模式构建个人助理,其中中央监督者智能体协调专门的工作者智能体。
本教程演示:
为不同领域(日历和电子邮件)创建专门的子智能体
将子智能体包装为工具以实现集中编排
为敏感操作添加人在回路审查
选择模式
问题 工具调用 交接 需要对工作流程进行集中控制? ✅ 是 ❌ 否 希望智能体直接与用户交互? ❌ 否 ✅ 是 专家之间的复杂的、类似人类的对话? ❌ 有限 ✅ 强
您可以混合使用两种模式 — 使用交接 进行智能体切换,并让每个智能体将子智能体作为工具调用 以执行专门任务。
自定义智能体上下文
多智能体设计的核心是上下文工程 - 决定每个智能体看到什么信息。LangChain 为您提供精细控制:
将对话或状态的哪些部分传递给每个智能体。
为子智能体量身定制的专门提示。
包含/排除中间推理。
为每个智能体自定义输入/输出格式。
您的系统质量严重依赖 上下文工程。目标是确保每个智能体都可以访问执行其任务所需的正确数据,无论它是作为工具还是作为活动智能体。
工具调用
在工具调用 中,一个智能体(“控制器 ”)将其他智能体视为需要时调用的工具 。控制器管理编排,而工具智能体执行特定任务并返回结果。
流程:
控制器 接收输入并决定调用哪个工具(子智能体)。
工具智能体 根据控制器的指令运行其任务。
工具智能体 将结果返回给控制器。
控制器 决定下一步或完成。
Agents used as tools are generally not expected to continue conversation with the user.
Their role is to perform a task and return results to the controller agent.
If you need subagents to be able to converse with the user, use handoffs instead.
下面是一个最小示例,其中主智能体通过工具定义获得对单个子智能体的访问权限:
import { createAgent , tool } from "langchain" ;
import * as z from "zod" ;
const subagent1 = createAgent ({ ... });
const callSubagent1 = tool (
async ({ query }) => {
const result = await subagent1 . invoke ({
messages: [{ role: "user" , content: query }]
});
return result . messages . at ( - 1 )?. text ;
},
{
name: "subagent1_name" ,
description: "subagent1_description" ,
schema: z . object ({
query: z . string (). describe ( "The query to to send to subagent1." ),
}),
}
);
const agent = createAgent ({
model ,
tools: [ callSubagent1 ]
});
In this pattern:
The main agent invokes call_subagent1 when it decides the task matches the subagent’s description.
The subagent runs independently and returns its result.
The main agent receives the result and continues orchestration.
自定义位置
有几个点可以控制上下文在主智能体及其子智能体之间传递的方式:
子智能体名称 ("subagent1_name"):这是主智能体引用子智能体的方式。由于它影响提示,请仔细选择。
子智能体描述 ("subagent1_description"):这是主智能体对子智能体的”了解”。它直接影响主智能体决定何时调用它。
子智能体的输入 :您可以自定义此输入,以更好地塑造子智能体如何解释任务。在上面的示例中,我们直接传递智能体生成的 query。
子智能体的输出 :这是传递回主智能体的响应 。您可以调整返回的内容以控制主智能体如何解释结果。在上面的示例中,我们返回最终消息文本,但您可以返回其他状态或元数据。
控制子智能体的输入
有两个主要杠杆可以控制主智能体传递给子智能体的输入:
修改提示 – 调整主智能体的提示或工具元数据(即子智能体的名称和描述),以更好地指导何时以及如何调用子智能体。
上下文注入 – 通过调整工具调用从智能体状态中提取,添加在静态提示中无法实际捕获的输入(例如,完整消息历史、先前结果、任务元数据)。
import { createAgent , tool , AgentState , ToolMessage } from "langchain" ;
import { Command } from "@langchain/langgraph" ;
import * as z from "zod" ;
// Example of passing the full conversation history to the sub agent via the state.
const callSubagent1 = tool (
async ({ query }) => {
const state = getCurrentTaskInput < AgentState >();
// Apply any logic needed to transform the messages into a suitable input
const subAgentInput = someLogic ( query , state . messages );
const result = await subagent1 . invoke ({
messages: subAgentInput ,
// You could also pass other state keys here as needed.
// Make sure to define these in both the main and subagent's
// state schemas.
exampleStateKey: state . exampleStateKey
});
return result . messages . at ( - 1 )?. content ;
},
{
name: "subagent1_name" ,
description: "subagent1_description" ,
}
);
控制子智能体的输出
塑造主智能体从子智能体接收内容的两种常见策略:
修改提示 – 优化子智能体的提示,以精确指定应返回的内容。
当输出不完整、过于冗长或缺少关键细节时很有用。
一个常见的失败模式是子智能体执行工具调用或推理,但未在其最终消息中包含结果 。提醒它控制器(和用户)只能看到最终输出,因此所有相关信息必须包含在那里。
自定义输出格式 – 在将子智能体的响应返回给主智能体之前,在代码中调整或丰富它。
示例:除了最终文本之外,还将特定状态键传递回主智能体。
这需要将结果包装在 Command (或等效结构)中,以便您可以将自定义状态与子智能体的响应合并。
import { tool , ToolMessage } from "langchain" ;
import { Command } from "@langchain/langgraph" ;
import * as z from "zod" ;
const callSubagent1 = tool (
async ({ query }, config ) => {
const result = await subagent1 . invoke ({
messages: [{ role: "user" , content: query }]
});
// Return a Command to update multiple state keys
return new Command ({
update: {
// Pass back additional state from the subagent
exampleStateKey: result . exampleStateKey ,
messages: [
new ToolMessage ({
content: result . messages . at ( - 1 )?. text ,
tool_call_id: config . toolCall ?. id !
})
]
}
});
},
{
name: "subagent1_name" ,
description: "subagent1_description" ,
schema: z . object ({
query: z . string (). describe ( "The query to send to subagent1" )
})
}
);
在交接 中,智能体可以直接将控制权传递给彼此。“活动”智能体会发生变化,用户与当前拥有控制权的智能体交互。
流程:
当前智能体 决定需要另一个智能体的帮助。
它将控制权(和状态)传递给下一个智能体 。
新智能体 直接与用户交互,直到它决定再次交接或完成。
实现(即将推出)