概述
子代理模式(supervisor pattern)是一种多代理架构,其中一个中央监督者代理(supervisor agent)协调专门的工作代理(worker agents)。这种方法在任务需要不同类型的专业知识时表现出色。与其构建一个管理跨领域工具选择的单一代理,不如创建由了解整体工作流的监督者协调的专注专家。 在本教程中,您将构建一个个人助手系统,通过一个现实的工作流来演示这些好处。该系统将协调两个具有根本不同职责的专家:- 日历代理:处理日程安排、可用性检查和事件管理。
- 电子邮件代理:管理通信、起草消息和发送通知。
为什么要使用监督者?
多代理架构允许您跨工作者划分工具,每个工作者都有自己的单独提示或指令。考虑一个可以直接访问所有日历和电子邮件 API 的代理:它必须从许多类似的工具中进行选择,了解每个 API 的确切格式,并同时处理多个领域。如果性能下降,将相关工具和相关提示分成逻辑组可能会有所帮助(部分是为了管理迭代改进)。概念
我们将涵盖以下概念:设置
安装
本教程需要langchain 包:
Copy
npm install langchain
LangSmith
设置 LangSmith 以检查代理内部发生的情况。然后设置以下环境变量:Copy
export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."
组件
我们需要从 LangChain 的集成套件中选择一个聊天模型:- OpenAI
- Anthropic
- Azure
- Google Gemini
- Bedrock Converse
👉 Read the OpenAI chat model integration docs
Copy
npm install @langchain/openai
Copy
import { initChatModel } from "langchain";
process.env.OPENAI_API_KEY = "your-api-key";
const model = await initChatModel("gpt-5.2");
👉 Read the Anthropic chat model integration docs
Copy
npm install @langchain/anthropic
Copy
import { initChatModel } from "langchain";
process.env.ANTHROPIC_API_KEY = "your-api-key";
const model = await initChatModel("claude-sonnet-4-6");
👉 Read the Azure chat model integration docs
Copy
npm install @langchain/azure
Copy
import { initChatModel } from "langchain";
process.env.AZURE_OPENAI_API_KEY = "your-api-key";
process.env.AZURE_OPENAI_ENDPOINT = "your-endpoint";
process.env.OPENAI_API_VERSION = "your-api-version";
const model = await initChatModel("azure_openai:gpt-5.2");
👉 Read the Google GenAI chat model integration docs
Copy
npm install @langchain/google-genai
Copy
import { initChatModel } from "langchain";
process.env.GOOGLE_API_KEY = "your-api-key";
const model = await initChatModel("google-genai:gemini-2.5-flash-lite");
👉 Read the AWS Bedrock chat model integration docs
Copy
npm install @langchain/aws
Copy
import { initChatModel } from "langchain";
// Follow the steps here to configure your credentials:
// https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html
const model = await initChatModel("bedrock:gpt-5.2");
1. 定义工具
首先定义需要结构化输入的工具。在实际应用中,这些工具会调用实际的 API(Google Calendar、SendGrid 等)。在本教程中,您将使用存根(stubs)来演示该模式。Copy
import { tool } from "langchain";
import { z } from "zod";
const createCalendarEvent = tool(
async ({ title, startTime, endTime, attendees, location }) => {
// 存根:在实践中,这将调用 Google Calendar API、Outlook API 等。
return `Event created: ${title} from ${startTime} to ${endTime} with ${attendees.length} attendees`;
},
{
name: "create_calendar_event",
description: "Create a calendar event. Requires exact ISO datetime format.",
schema: z.object({
title: z.string(),
startTime: z.string().describe("ISO format: '2024-01-15T14:00:00'"),
endTime: z.string().describe("ISO format: '2024-01-15T15:00:00'"),
attendees: z.array(z.string()).describe("email addresses"),
location: z.string().optional(),
}),
}
);
const sendEmail = tool(
async ({ to, subject, body, cc }) => {
// 存根:在实践中,这将调用 SendGrid、Gmail API 等。
return `Email sent to ${to.join(', ')} - Subject: ${subject}`;
},
{
name: "send_email",
description: "Send an email via email API. Requires properly formatted addresses.",
schema: z.object({
to: z.array(z.string()).describe("email addresses"),
subject: z.string(),
body: z.string(),
cc: z.array(z.string()).optional(),
}),
}
);
const getAvailableTimeSlots = tool(
async ({ attendees, date, durationMinutes }) => {
// 存根:在实践中,这将查询日历 API
return ["09:00", "14:00", "16:00"];
},
{
name: "get_available_time_slots",
description: "Check calendar availability for given attendees on a specific date.",
schema: z.object({
attendees: z.array(z.string()),
date: z.string().describe("ISO format: '2024-01-15'"),
durationMinutes: z.number(),
}),
}
);
2. 创建专门的子代理
接下来,我们将创建处理每个领域的专门子代理。创建日历代理
日历代理理解自然语言的日程安排请求,并将它们转化为精确的 API 调用。它处理日期解析、可用性检查和事件创建。Copy
import { createAgent } from "langchain";
const CALENDAR_AGENT_PROMPT = `
You are a calendar scheduling assistant.
Parse natural language scheduling requests (e.g., 'next Tuesday at 2pm')
into proper ISO datetime formats.
Use get_available_time_slots to check availability when needed.
Use create_calendar_event to schedule events.
Always confirm what was scheduled in your final response.
`.trim();
const calendarAgent = createAgent({
model: llm,
tools: [createCalendarEvent, getAvailableTimeSlots],
systemPrompt: CALENDAR_AGENT_PROMPT,
});
Copy
const query = "Schedule a team meeting next Tuesday at 2pm for 1 hour";
const stream = await calendarAgent.stream({
messages: [{ role: "user", content: query }]
});
for await (const step of stream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
Copy
================================== Ai Message ==================================
Tool Calls:
get_available_time_slots (call_EIeoeIi1hE2VmwZSfHStGmXp)
Call ID: call_EIeoeIi1hE2VmwZSfHStGmXp
Args:
attendees: []
date: 2024-06-18
duration_minutes: 60
================================= Tool Message =================================
Name: get_available_time_slots
["09:00", "14:00", "16:00"]
================================== Ai Message ==================================
Tool Calls:
create_calendar_event (call_zgx3iJA66Ut0W8S3NpT93kEB)
Call ID: call_zgx3iJA66Ut0W8S3NpT93kEB
Args:
title: Team Meeting
start_time: 2024-06-18T14:00:00
end_time: 2024-06-18T15:00:00
attendees: []
================================= Tool Message =================================
Name: create_calendar_event
Event created: Team Meeting from 2024-06-18T14:00:00 to 2024-06-18T15:00:00 with 0 attendees
================================== Ai Message ==================================
The team meeting has been scheduled for next Tuesday, June 18th, at 2:00 PM and will last for 1 hour. If you need to add attendees or a location, please let me know!
create_calendar_event,并返回自然语言确认。
创建电子邮件代理
电子邮件代理处理消息撰写和发送。它专注于提取收件人信息,制作合适的主题行和正文,并管理电子邮件通信。Copy
const EMAIL_AGENT_PROMPT = `
You are an email assistant.
Compose professional emails based on natural language requests.
Extract recipient information and craft appropriate subject lines and body text.
Use send_email to send the message.
Always confirm what was sent in your final response.
`.trim();
const emailAgent = createAgent({
model: llm,
tools: [sendEmail],
systemPrompt: EMAIL_AGENT_PROMPT,
});
Copy
const query = "Send the design team a reminder about reviewing the new mockups";
const stream = await emailAgent.stream({
messages: [{ role: "user", content: query }]
});
for await (const step of stream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
Copy
================================== Ai Message ==================================
Tool Calls:
send_email (call_OMl51FziTVY6CRZvzYfjYOZr)
Call ID: call_OMl51FziTVY6CRZvzYfjYOZr
Args:
to: ['design-team@example.com']
subject: Reminder: Please Review the New Mockups
body: Hi Design Team,
This is a friendly reminder to review the new mockups at your earliest convenience. Your feedback is important to ensure that we stay on track with our project timeline.
Please let me know if you have any questions or need additional information.
Thank you!
Best regards,
================================= Tool Message =================================
Name: send_email
Email sent to design-team@example.com - Subject: Reminder: Please Review the New Mockups
================================== Ai Message ==================================
I've sent a reminder to the design team asking them to review the new mockups. If you need any further communication on this topic, just let me know!
send_email,并返回确认。每个子代理都专注于特定领域,拥有特定领域的工具和提示,使其能够出色地完成特定任务。
3. 将子代理包装为工具
现在将每个子代理包装为监督者可以调用的工具。这是创建分层系统的关键架构步骤。监督者将看到像 “schedule_event” 这样的高级工具,而不是像 “create_calendar_event” 这样的低级工具。Copy
const scheduleEvent = tool(
async ({ request }) => {
const result = await calendarAgent.invoke({
messages: [{ role: "user", content: request }]
});
const lastMessage = result.messages[result.messages.length - 1];
return lastMessage.text;
},
{
name: "schedule_event",
description: `
Schedule calendar events using natural language.
Use this when the user wants to create, modify, or check calendar appointments.
Handles date/time parsing, availability checking, and event creation.
Input: Natural language scheduling request (e.g., 'meeting with design team next Tuesday at 2pm')
`.trim(),
schema: z.object({
request: z.string().describe("Natural language scheduling request"),
}),
}
);
const manageEmail = tool(
async ({ request }) => {
const result = await emailAgent.invoke({
messages: [{ role: "user", content: request }]
});
const lastMessage = result.messages[result.messages.length - 1];
return lastMessage.text;
},
{
name: "manage_email",
description: `
Send emails using natural language.
Use this when the user wants to send notifications, reminders, or any email communication.
Handles recipient extraction, subject generation, and email composition.
Input: Natural language email request (e.g., 'send them a reminder about the meeting')
`.trim(),
schema: z.object({
request: z.string().describe("Natural language email request"),
}),
}
);
4. 创建监督者代理
现在创建协调子代理的监督者。监督者只看到高级工具,并在领域级别而不是单个 API 级别做出路由决策。Copy
const SUPERVISOR_PROMPT = `
You are a helpful personal assistant.
You can schedule calendar events and send emails.
Break down user requests into appropriate tool calls and coordinate the results.
When a request involves multiple actions, use multiple tools in sequence.
`.trim();
const supervisorAgent = createAgent({
model: llm,
tools: [scheduleEvent, manageEmail],
systemPrompt: SUPERVISOR_PROMPT,
});
5. 使用监督者
现在,使用需要跨多个领域协调的复杂请求测试您的完整系统:示例 1:简单的单一领域请求
Copy
const query = "Schedule a team standup for tomorrow at 9am";
const stream = await supervisorAgent.stream({
messages: [{ role: "user", content: query }]
});
for await (const step of stream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
Copy
================================== Ai Message ==================================
Tool Calls:
schedule_event (call_mXFJJDU8bKZadNUZPaag8Lct)
Call ID: call_mXFJJDU8bKZadNUZPaag8Lct
Args:
request: Schedule a team standup for tomorrow at 9am with Alice and Bob.
================================= Tool Message =================================
Name: schedule_event
The team standup has been scheduled for tomorrow at 9:00 AM with Alice and Bob. If you need to make any changes or add more details, just let me know!
================================== Ai Message ==================================
The team standup with Alice and Bob is scheduled for tomorrow at 9:00 AM. If you need any further arrangements or adjustments, please let me know!
schedule_event,日历代理处理日期解析和事件创建。
要完全透明地了解信息流,包括每个聊天模型调用的提示和响应,请查看上述运行的 LangSmith 跟踪。
示例 2:复杂的多领域请求
Copy
const query =
"Schedule a meeting with the design team next Tuesday at 2pm for 1 hour, " +
"and send them an email reminder about reviewing the new mockups.";
const stream = await supervisorAgent.stream({
messages: [{ role: "user", content: query }]
});
for await (const step of stream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
Copy
================================== Ai Message ==================================
Tool Calls:
schedule_event (call_YA68mqF0koZItCFPx0kGQfZi)
Call ID: call_YA68mqF0koZItCFPx0kGQfZi
Args:
request: meeting with the design team next Tuesday at 2pm for 1 hour
manage_email (call_XxqcJBvVIuKuRK794ZIzlLxx)
Call ID: call_XxqcJBvVIuKuRK794ZIzlLxx
Args:
request: send the design team an email reminder about reviewing the new mockups
================================= Tool Message =================================
Name: schedule_event
Your meeting with the design team is scheduled for next Tuesday, June 18th, from 2:00pm to 3:00pm. Let me know if you need to add more details or make any changes!
================================= Tool Message =================================
Name: manage_email
I've sent an email reminder to the design team requesting them to review the new mockups. If you need to include more information or recipients, just let me know!
================================== Ai Message ==================================
Your meeting with the design team is scheduled for next Tuesday, June 18th, from 2:00pm to 3:00pm.
I've also sent an email reminder to the design team, asking them to review the new mockups.
Let me know if you'd like to add more details to the meeting or include additional information in the email!
schedule_event,然后为提醒调用 manage_email。每个子代理完成其任务,监督者将两个结果综合成一个连贯的响应。
请参阅 LangSmith 跟踪 以查看上述运行的详细信息流,包括各个聊天模型的提示和响应。
完整的可运行示例
这是所有内容组合在一起的可运行脚本:Show 查看完整代码
Show 查看完整代码
Copy
/**
* Personal Assistant Supervisor Example
*
* This example demonstrates the tool calling pattern for multi-agent systems.
* A supervisor agent coordinates specialized sub-agents (calendar and email)
* that are wrapped as tools.
*/
import { tool, createAgent } from "langchain";
import { ChatAnthropic } from "@langchain/anthropic";
import { z } from "zod";
// ============================================================================
// Step 1: Define low-level API tools (stubbed)
// ============================================================================
const createCalendarEvent = tool(
async ({ title, startTime, endTime, attendees, location }) => {
// Stub: In practice, this would call Google Calendar API, Outlook API, etc.
return `Event created: ${title} from ${startTime} to ${endTime} with ${attendees.length} attendees`;
},
{
name: "create_calendar_event",
description: "Create a calendar event. Requires exact ISO datetime format.",
schema: z.object({
title: z.string(),
startTime: z.string().describe("ISO format: '2024-01-15T14:00:00'"),
endTime: z.string().describe("ISO format: '2024-01-15T15:00:00'"),
attendees: z.array(z.string()).describe("email addresses"),
location: z.string().optional().default(""),
}),
}
);
const sendEmail = tool(
async ({ to, subject, body, cc }) => {
// Stub: In practice, this would call SendGrid, Gmail API, etc.
return `Email sent to ${to.join(", ")} - Subject: ${subject}`;
},
{
name: "send_email",
description:
"Send an email via email API. Requires properly formatted addresses.",
schema: z.object({
to: z.array(z.string()).describe("email addresses"),
subject: z.string(),
body: z.string(),
cc: z.array(z.string()).optional().default([]),
}),
}
);
const getAvailableTimeSlots = tool(
async ({ attendees, date, durationMinutes }) => {
// Stub: In practice, this would query calendar APIs
return ["09:00", "14:00", "16:00"];
},
{
name: "get_available_time_slots",
description:
"Check calendar availability for given attendees on a specific date.",
schema: z.object({
attendees: z.array(z.string()),
date: z.string().describe("ISO format: '2024-01-15'"),
durationMinutes: z.number(),
}),
}
);
// ============================================================================
// Step 2: Create specialized sub-agents
// ============================================================================
const llm = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
});
const calendarAgent = createAgent({
model: llm,
tools: [createCalendarEvent, getAvailableTimeSlots],
systemPrompt: `
You are a calendar scheduling assistant.
Parse natural language scheduling requests (e.g., 'next Tuesday at 2pm')
into proper ISO datetime formats.
Use get_available_time_slots to check availability when needed.
Use create_calendar_event to schedule events.
Always confirm what was scheduled in your final response.
`.trim(),
});
const emailAgent = createAgent({
model: llm,
tools: [sendEmail],
systemPrompt: `
You are an email assistant.
Compose professional emails based on natural language requests.
Extract recipient information and craft appropriate subject lines and body text.
Use send_email to send the message.
Always confirm what was sent in your final response.
`.trim(),
});
// ============================================================================
// Step 3: Wrap sub-agents as tools for the supervisor
// ============================================================================
const scheduleEvent = tool(
async ({ request }) => {
const result = await calendarAgent.invoke({
messages: [{ role: "user", content: request }],
});
const lastMessage = result.messages[result.messages.length - 1];
return lastMessage.text;
},
{
name: "schedule_event",
description: `
Schedule calendar events using natural language.
Use this when the user wants to create, modify, or check calendar appointments.
Handles date/time parsing, availability checking, and event creation.
Input: Natural language scheduling request (e.g., 'meeting with design team next Tuesday at 2pm')
`.trim(),
schema: z.object({
request: z.string().describe("Natural language scheduling request"),
}),
}
);
const manageEmail = tool(
async ({ request }) => {
const result = await emailAgent.invoke({
messages: [{ role: "user", content: request }],
});
const lastMessage = result.messages[result.messages.length - 1];
return lastMessage.text;
},
{
name: "manage_email",
description: `
Send emails using natural language.
Use this when the user wants to send notifications, reminders, or any email communication.
Handles recipient extraction, subject generation, and email composition.
Input: Natural language email request (e.g., 'send them a reminder about the meeting')
`.trim(),
schema: z.object({
request: z.string().describe("Natural language email request"),
}),
}
);
// ============================================================================
// Step 4: Create the supervisor agent
// ============================================================================
const supervisorAgent = createAgent({
model: llm,
tools: [scheduleEvent, manageEmail],
systemPrompt: `
You are a helpful personal assistant.
You can schedule calendar events and send emails.
Break down user requests into appropriate tool calls and coordinate the results.
When a request involves multiple actions, use multiple tools in sequence.
`.trim(),
});
// ============================================================================
// Step 5: Use the supervisor
// ============================================================================
// Example: User request requiring both calendar and email coordination
const userRequest =
"Schedule a meeting with the design team next Tuesday at 2pm for 1 hour, " +
"and send them an email reminder about reviewing the new mockups.";
console.log("User Request:", userRequest);
console.log(`\n${"=".repeat(80)}\n`);
const stream = await supervisorAgent.stream({
messages: [{ role: "user", content: userRequest }],
});
for await (const step of stream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
理解架构
您的系统有三层。底层包含需要确切格式的刚性 API 工具。中间层包含接受自然语言、将其翻译为结构化 API 调用并返回自然语言确认的子代理。顶层包含路由到高级功能并综合结果的监督者。 这种关注点分离提供了几个好处:每一层都有明确的职责,您可以添加新领域而不影响现有领域,并且您可以独立测试和迭代每一层。6. 添加人机交互审查
对敏感操作进行人机交互审查是明智的。LangChain 包含内置中间件来审查工具调用,在本例中是由子代理调用的工具。 让我们为两个子代理添加人机交互审查:- 我们配置
create_calendar_event和send_email工具以中断,允许所有响应类型(approve、edit、reject) - 我们仅向顶层代理添加检查点。这是暂停和恢复执行所必需的。
Copy
import { createAgent, humanInTheLoopMiddleware } from "langchain";
import { MemorySaver } from "@langchain/langgraph";
const calendarAgent = createAgent({
model: llm,
tools: [createCalendarEvent, getAvailableTimeSlots],
systemPrompt: CALENDAR_AGENT_PROMPT,
middleware: [
humanInTheLoopMiddleware({
interruptOn: { create_calendar_event: true },
descriptionPrefix: "Calendar event pending approval",
}),
],
});
const emailAgent = createAgent({
model: llm,
tools: [sendEmail],
systemPrompt: EMAIL_AGENT_PROMPT,
middleware: [
humanInTheLoopMiddleware({
interruptOn: { send_email: true },
descriptionPrefix: "Outbound email pending approval",
}),
],
});
const supervisorAgent = createAgent({
model: llm,
tools: [scheduleEvent, manageEmail],
systemPrompt: SUPERVISOR_PROMPT,
checkpointer: new MemorySaver(),
});
Copy
const query =
"Schedule a meeting with the design team next Tuesday at 2pm for 1 hour, " +
"and send them an email reminder about reviewing the new mockups.";
const config = { configurable: { thread_id: "6" } };
const interrupts: any[] = [];
const stream = await supervisorAgent.stream(
{ messages: [{ role: "user", content: query }] },
config
);
for await (const step of streamA) {
for (const update of Object.values(step)) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
const interrupt = update.__interrupt__?.[0];
interrupts.push(interrupt);
console.log(`\nINTERRUPTED: ${interrupt?.id}`);
}
}
Copy
================================== Ai Message ==================================
Tool Calls:
schedule_event (call_t4Wyn32ohaShpEZKuzZbl83z)
Call ID: call_t4Wyn32ohaShpEZKuzZbl83z
Args:
request: Schedule a meeting with the design team next Tuesday at 2pm for 1 hour.
manage_email (call_JWj4vDJ5VMnvkySymhCBm4IR)
Call ID: call_JWj4vDJ5VMnvkySymhCBm4IR
Args:
request: Send an email reminder to the design team about reviewing the new mockups before our meeting next Tuesday at 2pm.
INTERRUPTED: 4f994c9721682a292af303ec1a46abb7
INTERRUPTED: 2b56f299be313ad8bc689eff02973f16
Copy
for (const interrupt of interrupts) {
for (const request of interrupt.value.actionRequests) {
console.log(`INTERRUPTED: ${interrupt.id}`);
console.log(`${request.description}\n`);
}
}
Copy
INTERRUPTED: 4f994c9721682a292af303ec1a46abb7
Calendar event pending approval
Tool: create_calendar_event
Args: {'title': 'Meeting with the Design Team', 'start_time': '2024-06-18T14:00:00', 'end_time': '2024-06-18T15:00:00', 'attendees': ['design team']}
INTERRUPTED: 2b56f299be313ad8bc689eff02973f16
Outbound email pending approval
Tool: send_email
Args: {'to': ['designteam@example.com'], 'subject': 'Reminder: Review New Mockups Before Meeting Next Tuesday at 2pm', 'body': "Hello Team,\n\nThis is a reminder to review the new mockups ahead of our meeting scheduled for next Tuesday at 2pm. Your feedback and insights will be valuable for our discussion and next steps.\n\nPlease ensure you've gone through the designs and are ready to share your thoughts during the meeting.\n\nThank you!\n\nBest regards,\n[Your Name]"}
Command 引用其中断 ID 来为每个中断指定决策。有关更多详细信息,请参阅人机交互指南。为了演示目的,这里我们将接受日历事件,但编辑外发电子邮件的主题:
Copy
import { Command } from "@langchain/langgraph";
const resume: Record<string, any> = {};
for (const interrupt of interrupts) {
const actionRequest = interrupt.value.actionRequests[0];
if (actionRequest.name === "send_email") {
// Edit email
const editedAction = { ...actionRequest };
editedAction.args.subject = "Mockups reminder";
resume[interrupt.id] = {
decisions: [{ type: "edit", editedAction }]
};
} else {
resume[interrupt.id] = { decisions: [{ type: "approve" }] };
}
}
const resumeStream = await supervisorAgent.stream(
new Command({ resume }),
config
);
for await (const step of resumeStream) {
for (const update of Object.values(step)) {
if (update && typeof update === "object" && "messages" in update) {
for (const message of update.messages) {
console.log(message.toFormattedString());
}
}
}
}
Copy
================================= Tool Message =================================
Name: schedule_event
Your meeting with the design team has been scheduled for next Tuesday, June 18th, from 2:00 pm to 3:00 pm.
================================= Tool Message =================================
Name: manage_email
Your email reminder to the design team has been sent. Here’s what was sent:
- Recipient: designteam@example.com
- Subject: Mockups reminder
- Body: A reminder to review the new mockups before the meeting next Tuesday at 2pm, with a request for feedback and readiness for discussion.
Let me know if you need any further assistance!
================================== Ai Message ==================================
- Your meeting with the design team has been scheduled for next Tuesday, June 18th, from 2:00 pm to 3:00 pm.
- An email reminder has been sent to the design team about reviewing the new mockups before the meeting.
Let me know if you need any further assistance!
7. 高级:控制信息流
默认情况下,子代理仅从监督者那里接收请求字符串。您可能希望传递额外的上下文,例如对话历史记录或用户首选项。向子代理传递额外的对话上下文
Copy
import { getCurrentTaskInput } from "@langchain/langgraph";
import { type BuiltInState, HumanMessage } from "langchain";
const scheduleEvent = tool(
async ({ request }, config) => {
// Customize context received by sub-agent
// Access full thread messages from the config
const currentMessages = getCurrentTaskInput<BuiltInState>(config).messages;
const originalUserMessage = currentMessages.find(HumanMessage.isInstance);
const prompt = `
You are assisting with the following user inquiry:
${originalUserMessage?.content || "No context available"}
You are tasked with the following sub-request:
${request}
`.trim();
const result = await calendarAgent.invoke({
messages: [{ role: "user", content: prompt }],
});
const lastMessage = result.messages[result.messages.length - 1];
return lastMessage.text;
},
{
name: "schedule_event",
description: "Schedule calendar events using natural language.",
schema: z.object({
request: z.string().describe("Natural language scheduling request"),
}),
}
);
您可以在 LangSmith 跟踪的聊天模型调用中查看子代理接收到的完整上下文。
控制监督者接收的内容
您还可以自定义流回监督者的信息:Copy
const scheduleEvent = tool(
async ({ request }) => {
const result = await calendarAgent.invoke({
messages: [{ role: "user", content: request }]
});
const lastMessage = result.messages[result.messages.length - 1];
// Option 1: Return just the confirmation message
return lastMessage.text;
// Option 2: Return structured data
// return JSON.stringify({
// status: "success",
// event_id: "evt_123",
// summary: lastMessage.text
// });
},
{
name: "schedule_event",
description: "Schedule calendar events using natural language.",
schema: z.object({
request: z.string().describe("Natural language scheduling request"),
}),
}
);
有关演示带有人机交互审查和高级信息流控制的完整监督者模式的完整工作示例,请查看 LangChain.js 示例中的
supervisor_complete.ts。8. 主要收获
监督者模式创建了抽象层,其中每一层都有明确的责任。在设计监督者系统时,从明确的领域边界开始,并为每个子代理提供专注的工具和提示。为监督者编写清晰的工具描述,在集成之前独立测试每一层,并根据您的具体需求控制信息流。何时使用监督者模式当您有多个不同的领域(日历、电子邮件、CRM、数据库),每个领域都有多个工具或复杂的逻辑,您想要集中的工作流控制,并且子代理不需要直接与用户交谈时,请使用监督者模式。对于只有几个工具的简单情况,请使用单个代理。当代理需要与用户进行对话时,请改用切换。对于代理之间的对等协作,请考虑其他多代理模式。
下一步
了解有关用于代理间对话的切换,探索上下文工程以微调信息流,阅读多代理概述以比较不同的模式,并使用 LangSmith 调试和监控您的多代理系统。通过 MCP 将这些文档连接 到 Claude、VSCode 等,以获取实时答案。

