跳到主要内容
多智能体系统将复杂的应用程序分解为多个专门的智能体,这些智能体协同工作以解决问题。多智能体架构不是依赖单个智能体来处理每个步骤,而是允许您将更小、更集中的智能体组合成一个协调的工作流程。 多智能体系统在以下情况下很有用:
  • 单个智能体拥有的工具过多,导致其在选择使用哪个工具时做出糟糕的决策。
  • 上下文或内存增长过大,单个智能体无法有效跟踪。
  • 任务需要专业化(例如,规划师、研究员、数学专家)。

多智能体模式

模式工作原理控制流示例用例
工具调用一个主管智能体将其他智能体作为工具调用。“工具”智能体不直接与用户对话——它们只是运行任务并返回结果。集中式:所有路由都通过调用智能体。任务编排、结构化工作流。
交接当前智能体决定将控制权移交给另一个智能体。活跃智能体发生变化,用户可以继续直接与新智能体交互。分散式:智能体可以改变谁是活跃的。多领域对话、专家接管。

教程:构建一个主管智能体

学习如何使用主管模式构建个人助理,其中一个中央主管智能体协调专业的工人智能体。本教程演示了
  • 为不同领域(日历和电子邮件)创建专门的子智能体
  • 将子智能体封装为工具,以实现集中编排
  • 为敏感操作添加人工审核

选择模式

问题工具调用交接
需要对工作流程进行集中控制吗?✅ 是❌ 否
希望智能体直接与用户交互吗?❌ 否✅ 是
专家之间进行复杂、类似人类的对话?❌ 有限✅ 强烈
您可以混合使用这两种模式——使用交接进行智能体切换,并让每个智能体将子智能体作为工具调用以执行专业任务。

自定义智能体上下文

多智能体设计的核心是上下文工程——决定每个智能体看到什么信息。LangChain 允许您对以下内容进行精细控制
  • 对话或状态的哪些部分被传递给每个智能体。
  • 为子智能体量身定制的专用提示。
  • 包含/排除中间推理。
  • 自定义每个智能体的输入/输出格式。
您的系统的质量严重依赖上下文工程。目标是确保每个智能体都能访问其执行任务所需的正确数据,无论它充当工具还是活跃智能体。

工具调用

工具调用中,一个智能体(“控制器”)将其他智能体视为在需要时调用的工具。控制器管理编排,而工具智能体执行特定任务并返回结果。 流程:
  1. 控制器接收输入并决定调用哪个工具(子智能体)。
  2. 工具智能体根据控制器的指令运行其任务。
  3. 工具智能体将结果返回给控制器。
  4. 控制器决定下一步或完成。
用作工具的智能体通常不期望继续与用户对话。它们的角色是执行任务并将结果返回给控制器智能体。如果您需要子智能体能够与用户对话,请改用交接

实现

下面是一个最小示例,其中主智能体通过工具定义访问单个子智能体
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]
});
在这种模式下
  1. 当主智能体决定任务与子智能体的描述匹配时,它会调用call_subagent1
  2. 子智能体独立运行并返回其结果。
  3. 主智能体接收结果并继续编排。

自定义位置

有几个点可以控制主智能体与其子智能体之间上下文的传递方式
  1. 子智能体名称"subagent1_name"):这是主智能体引用子智能体的方式。因为它会影响提示,所以请仔细选择。
  2. 子智能体描述"subagent1_description"):这是主智能体“知道”子智能体的内容。它直接决定了主智能体何时调用它。
  3. 子智能体的输入:您可以自定义此输入,以更好地塑造子智能体解释任务的方式。在上面的示例中,我们直接传递智能体生成的query
  4. 子智能体的输出:这是返回给主智能体的响应。您可以调整返回的内容,以控制主智能体如何解释结果。在上面的示例中,我们返回最终消息文本,但您可以返回额外的状态或元数据。

控制子智能体的输入

控制主智能体传递给子智能体的输入有两个主要杠杆
  • 修改提示——调整主智能体的提示或工具元数据(即,子智能体的名称和描述),以更好地指导它何时以及如何调用子智能体。
  • 上下文注入——通过调整工具调用以从智能体的状态中提取,添加不适合在静态提示中捕获的输入(例如,完整的消息历史记录、先前的结果、任务元数据)。
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")
    })
  }
);

交接

交接中,智能体可以直接将控制权相互传递。“活跃”智能体发生变化,用户与当前拥有控制权的智能体交互。 流程:
  1. 当前智能体决定它需要另一个智能体的帮助。
  2. 它将控制权(和状态)传递给下一个智能体
  3. 新智能体直接与用户交互,直到它决定再次交接或完成。

实现(即将推出)


以编程方式连接这些文档到 Claude、VSCode 等,通过 MCP 获取实时答案。
© . This site is unofficial and not affiliated with LangChain, Inc.