概述
监督者模式是一种多智能体架构,其中中央监督者智能体协调专业化的工作智能体。当任务需要不同类型的专业知识时,这种方法尤为有效。与其构建一个需跨领域管理工具选择的单一智能体,不如创建由理解整体工作流程的监督者所协调的专业工作智能体。
在本教程中,您将构建一个个人助手系统,通过真实工作流程展示这些优势。该系统将协调两名职责截然不同的专业工作智能体:
- 日历智能体:负责处理日程安排、可用性检查与事件管理。
- 邮件智能体:负责管理通信、起草消息并发送通知。
我们还将引入人在回路审查机制,允许用户根据需要批准、编辑或拒绝特定操作(例如外发邮件)。
为何使用监督者?
多智能体架构允许您将工具分配至各个工作智能体,每个智能体拥有独立的提示词或指令。试想一个直接访问所有日历与邮件 API 的智能体:它需从众多相似工具中做出选择,理解每项 API 的确切格式,并同时处理多个领域。若性能下降,将相关工具及其关联提示词划分为逻辑组可能更为有利(部分原因在于便于管理迭代改进)。
1. 定义工具
首先定义需要结构化输入的工具。在实际应用中,这些工具会调用真实的 API(例如 Google Calendar、SendGrid 等)。在本教程中,您将使用存根(stubs)来演示该模式。
2. 创建专业化子智能体
接下来,我们将创建处理各个领域的专业化子智能体。
创建日历智能体
日历智能体理解自然语言日程请求,并将其转化为精确的 API 调用。它负责处理日期解析、可用性检查和事件创建。
创建邮件智能体
邮件智能体负责消息撰写和发送。它专注于提取收件人信息、构思合适的主题行和正文内容,以及管理邮件通信。
该智能体从非正式请求中推断收件人,构思专业的主题行和正文,调用 send_email,并返回确认信息。每个子智能体都专注于特定领域,配备领域特定的工具和提示词,使其能够出色地完成特定任务。
3. 将子智能体封装为工具
现在将每个子智能体封装为监督者可调用的工具。这是创建分层系统的关键架构步骤。监督者将看到高级工具(如 schedule_event),而非低级工具(如 create_calendar_event)。
工具描述有助于监督者决定何时使用每个工具,因此请确保它们清晰具体。我们仅返回子智能体的最终响应,因为监督者无需查看中间推理或工具调用。
4. 创建监督者智能体
现在创建协调子智能体的监督者。监督者仅看到高级工具,并在领域级别而非单个 API 级别做出路由决策。
5. 使用监督者
现在使用需要跨多个领域协调的复杂请求来测试您的完整系统:
因为langchain安装的包特别大,所以这里换成非常mini的xsai来展示,需要langchain版本去上面原文看就好了。因为发件需要邮件地址,所以我多加了一个模拟获取公司人员的子智能体
ts
/**
* 个人助理主管示例 (xsai 版本)
*
* 本示例演示了多智能体系统中的工具调用模式。
* 一个主管智能体协调专门的子智能体(日历和邮件),这些子智能体被封装为工具。
*/
import { generateText } from "@xsai/generate-text";
import { tool } from "@xsai/tool";
import { env } from "node:process";
import * as z from "zod";
// ============================================================================
// 步骤 1:定义底层 API 工具(模拟实现)
// ============================================================================
const createCalendarEvent = await tool({
name: "create_calendar_event",
description: "创建日历事件。需要使用精确的 ISO 日期时间格式。",
parameters: z.object({
title: z.string().describe("事件标题"),
startTime: z.string().describe("ISO 格式:'2024-01-15T14:00:00'"),
endTime: z.string().describe("ISO 格式:'2024-01-15T15:00:00'"),
attendees: z.array(z.string()).describe("参会者邮箱地址列表"),
location: z.string().optional().default(""),
}),
execute: async ({ title, startTime, endTime, attendees, location }) => {
console.log("[createCalendarEvent] input:", {
title,
startTime,
endTime,
attendees,
location,
});
// 模拟:实际应用中会调用 Google Calendar API、Outlook API 等
return `事件已创建:${title},时间从 ${startTime} 到 ${endTime},共 ${attendees.length} 位参会者`;
},
});
const sendEmail = await tool({
name: "send_email",
description: "通过邮件 API 发送邮件。需要使用格式正确的邮箱地址。",
parameters: z.object({
to: z.array(z.string()).describe("收件人邮箱地址列表"),
subject: z.string().describe("邮件主题"),
body: z.string().describe("邮件正文"),
cc: z.array(z.string()).optional().default([]).describe("抄送邮箱地址列表"),
}),
execute: async ({ to, subject, body, cc }) => {
console.log("[sendEmail] input:", { to, subject, body, cc });
// 模拟:实际应用中会调用 SendGrid、Gmail API 等
return `邮件已发送至 ${to.join(", ")} - 主题:${subject}`;
},
});
const getAvailableTimeSlots = await tool({
name: "get_available_time_slots",
description: "检查指定日期内给定参会者的日历可用时间段。",
parameters: z.object({
attendees: z.array(z.string()).describe("参会者邮箱地址列表"),
date: z.string().describe("ISO 格式:'2024-01-15'"),
durationMinutes: z.number().describe("会议时长(分钟)"),
}),
execute: async ({ attendees, date, durationMinutes }) => {
console.log("[getAvailableTimeSlots] input:", {
attendees,
date,
durationMinutes,
});
// 模拟:实际应用中会查询日历 API
// xsai 工具返回值会被自动序列化,数组建议显式转为字符串
return JSON.stringify(["09:00", "14:00", "16:00"]);
},
});
const getTeamMembers = await tool({
name: "get_team_members",
description: "获取指定公司团队的人员联系信息,包括姓名、手机号和邮箱。",
parameters: z.object({
teamName: z
.enum(["设计团队", "研发团队", "产品团队", "运营团队"])
.describe("团队名称"),
}),
execute: async ({ teamName }) => {
console.log("[getTeamMembers] input:", { teamName });
// 模拟团队人员数据库
const teamDatabase: Record<
string,
Array<{ name: string; phone: string; email: string }>
> = {
设计团队: [
{ name: "张三", phone: "138-0013-8001", email: "zhangsan@company.com" },
{
name: "王美设计",
phone: "138-0013-8002",
email: "wangmei@company.com",
},
{
name: "陈创意",
phone: "138-0013-8003",
email: "chencreative@company.com",
},
],
研发团队: [
{ name: "李四", phone: "139-0014-9001", email: "lisi@company.com" },
{
name: "赵代码",
phone: "139-0014-9002",
email: "zhaocode@company.com",
},
{
name: "孙算法",
phone: "139-0014-9003",
email: "sunalgo@company.com",
},
],
产品团队: [
{ name: "周产品", phone: "137-0012-7001", email: "zhoupm@company.com" },
{ name: "吴需求", phone: "137-0012-7002", email: "wureq@company.com" },
],
运营团队: [
{
name: "郑运营",
phone: "136-0011-6001",
email: "zhengops@company.com",
},
{
name: "冯增长",
phone: "136-0011-6002",
email: "fenggrowth@company.com",
},
],
};
const members = teamDatabase[teamName] || [];
if (members.length === 0) {
return `未找到团队「${teamName}」的人员信息`;
}
// 格式化返回结果,便于 LLM 理解
const formatted = members
.map((m) => `${m.name} | 手机: ${m.phone} | 邮箱: ${m.email}`)
.join("\n");
return `【${teamName}】成员列表:\n${formatted}`;
},
});
// ============================================================================
// 步骤 2:创建专门的子智能体(手动实现 agent 循环)
// ============================================================================
const llmConfig = {
apiKey: env.OPENAI_API_KEY!,
baseURL: env.OPENAI_BASE_URL!,
model: "DeepSeek-V3.2", // xsai 兼容 OpenAI 格式的模型
};
/**
* 日历子智能体 - 处理调度相关请求
*/
async function calendarAgent(request: string): Promise<string> {
const systemPrompt = `
你是一个日历调度助手。
将自然语言的调度请求(例如:"下周二下午 2 点")解析为正确的 ISO 日期时间格式。
必要时使用 get_available_time_slots 检查可用性。
如果没有合适的时间段,请停止并在回复中确认可用性不足。
使用 create_calendar_event 创建事件。
始终在最终回复中确认已安排的内容。
`.trim();
console.log("[calendarAgent] input:", request);
const { text } = await generateText({
...llmConfig,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: request },
],
tools: [createCalendarEvent, getAvailableTimeSlots],
maxSteps: 3,
});
console.log("[calendarAgent] output:", text);
return text!;
}
/**
* 邮件子智能体 - 处理邮件相关请求
*/
async function emailAgent(request: string): Promise<string> {
const systemPrompt = `
你是一个邮件助手。
根据自然语言请求撰写专业邮件。
提取收件人信息并撰写合适的主题行和正文内容。
使用 send_email 发送邮件。
始终在最终回复中确认已发送的内容。
`.trim();
console.log("[emailAgent] input:", request);
const { text } = await generateText({
...llmConfig,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: request },
],
tools: [sendEmail],
maxSteps: 3,
});
console.log("[emailAgent] output:", text);
return text!;
}
/**
* 团队信息子智能体 - 处理人员查询相关请求
*/
async function teamInfoAgent(request: string): Promise<string> {
const systemPrompt = `
你是一个公司通讯录助手。
帮助用户查询各个团队的人员联系信息。
- 识别用户请求中的团队名称(如"设计团队"、"研发团队"等)
- 使用 get_team_members 工具获取人员列表
- 将结果以清晰友好的格式返回给用户
- 如果团队不存在,礼貌告知并建议可用团队选项
`.trim();
console.log("[teamInfoAgent] input:", request);
const { text } = await generateText({
...llmConfig,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: request },
],
tools: [getTeamMembers],
maxSteps: 3,
});
console.log("[teamInfoAgent] output:", text);
return text!;
}
// ============================================================================
// 步骤 3:将子智能体封装为主管智能体可调用的工具
// ============================================================================
const scheduleEvent = await tool({
name: "schedule_event",
description: `
使用自然语言调度日历事件。
当用户想要创建、修改或查看日历预约时使用此工具。
处理日期/时间解析、可用性检查和事件创建。
输入:自然语言调度请求(例如:"下周二下午 2 点与设计团队开会")
`.trim(),
parameters: z.object({
request: z.string().describe("自然语言调度请求"),
}),
execute: async ({ request }) => {
// 调用日历子智能体处理请求
return await calendarAgent(request);
},
});
const manageEmail = await tool({
name: "manage_email",
description: `
使用自然语言发送邮件。
当用户想要发送通知、提醒或任何邮件通信时使用此工具。
处理收件人提取、主题生成和邮件撰写。
输入:自然语言邮件请求(例如:"给他们发一封关于会议的提醒")
`.trim(),
parameters: z.object({
request: z.string().describe("自然语言邮件请求"),
}),
execute: async ({ request }) => {
// 调用邮件子智能体处理请求
return await emailAgent(request);
},
});
const queryTeamMembers = await tool({
name: "query_team_members",
description: `
查询公司团队的人员联系信息。
当用户想要获取某个团队的成员姓名、电话或邮箱时使用此工具。
支持团队:设计团队、研发团队、产品团队、运营团队
输入:自然语言查询请求(例如:"设计团队有哪些人?" 或 "研发李四的邮箱是多少")
`.trim(),
parameters: z.object({
request: z.string().describe("自然语言人员查询请求"),
}),
execute: async ({ request }) => {
// 调用团队信息子智能体处理请求
return await teamInfoAgent(request);
},
});
// ============================================================================
// 步骤 4:创建主管智能体
// ============================================================================
/**
* 主管智能体 - 协调日历和邮件子智能体
*/
async function supervisorAgent(userRequest: string): Promise<string> {
const systemPrompt = `
你是一个贴心的个人助理。
你可以:
1. 调度日历事件(创建会议、检查可用时间)
2. 发送邮件通知和提醒
3. 查询公司团队人员联系信息
将用户请求分解为适当的工具调用并协调结果。
当请求涉及多个操作时,按顺序使用多个工具。
如果用户询问某团队人员并要联系他们,可组合使用 query_team_members + manage_email/schedule_event。
`.trim();
const { text } = await generateText({
...llmConfig,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: userRequest },
],
maxSteps: 20,
tools: [scheduleEvent, manageEmail, queryTeamMembers],
});
return text!;
}
// ============================================================================
// 步骤 5:使用主管智能体
// ============================================================================
async function main() {
// 示例:需要同时协调日历和邮件的用户请求
const userRequest =
"安排下周二下午 2 点与设计团队进行 1 小时的会议," +
"并给他们发送一封邮件提醒,关于审阅新的设计稿。";
console.log("用户请求:", userRequest);
console.log(`\n${"=".repeat(80)}\n`);
try {
const result = await supervisorAgent(userRequest);
console.log("主管智能体回复:\n", result);
} catch (error) {
console.error("执行出错:", error);
}
}
// 执行入口
main();
一个简单的MultiAgent就完成辣!!!