Skip to content

使用子代理构建个人助手

概述

监督者模式 是一种多代理架构,其中中央监督者代理协调专门的工人代理。当任务需要不同类型的专业知识时,这种方法尤为出色。与其构建一个管理所有领域工具选择的单一代理,不如创建聚焦的专家代理,由理解整体工作流的监督者进行协调。

在本教程中,您将构建一个个人助手系统,通过一个真实的工作流展示这些优势。该系统将协调两个职责根本不同的专家代理:

  • 日历代理 — 处理日程安排、可用性检查和事件管理。
  • 邮件代理 — 管理通信、起草消息和发送通知。

我们还将引入人工审核机制,允许用户在必要时批准、编辑或拒绝操作(如外发邮件)。

为什么要使用监督者?

多代理架构允许您将工具分配到不同的工人代理中,每个代理拥有各自的提示词或指令。假设一个代理直接拥有所有日历和邮件 API:它必须从众多相似的工具中选择,理解每个 API 的确切格式,并同时处理多个领域。如果性能下降,将相关工具和提示词分组到逻辑单元中会有帮助(部分原因是为了便于迭代改进)。

概念

我们将涵盖以下概念:

设置

安装

本教程需要 langchain 包:

bash
pip install langchain

更多详情请参阅我们的安装指南

LangSmith

设置 LangSmith 以观察代理内部的运行情况。然后设置以下环境变量:

python
import getpass
import os

os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = getpass.getpass()

选择模型

我们需要从 LangChain 的集成套件中选择一个聊天模型:

python
from langchain.chat_models import init_chat_model

# OpenAI
model = init_chat_model("openai:gpt-5.4")

# Anthropic
model = init_chat_model("anthropic:claude-sonnet-4-6")

# Google Gemini
model = init_chat_model("google_genai:gemini-2.5-flash-lite")

您也可以直接使用特定提供者的类:

python
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-5.4")

from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-sonnet-4-6")

from langchain_google_genai import ChatGoogleGenerativeAI
model = ChatGoogleGenerativeAI(model="gemini-2.5-flash-lite")

1. 定义工具

首先定义需要结构化输入的工具。在实际应用中,这些工具会调用真实的 API(Google Calendar、SendGrid 等)。在本教程中,您将使用桩代码来演示模式。

python
from langchain.tools import tool

@tool
def create_calendar_event(
    title: str,
    start_time: str,       # ISO 格式: "2024-01-15T14:00:00"
    end_time: str,         # ISO 格式: "2024-01-15T15:00:00"
    attendees: list[str],  # 邮箱地址
    location: str = ""
) -> str:
    """创建日历事件。需要精确的 ISO 日期时间格式。"""
    # 桩代码:实践中会调用 Google Calendar API、Outlook API 等
    return f"事件已创建:{title},从 {start_time}{end_time},共 {len(attendees)} 位参与者"


@tool
def send_email(
    to: list[str],  # 邮箱地址
    subject: str,
    body: str,
    cc: list[str] = []
) -> str:
    """通过邮件 API 发送电子邮件。需要格式正确的地址。"""
    # 桩代码:实践中会调用 SendGrid、Gmail API 等
    return f"邮件已发送至 {', '.join(to)} - 主题:{subject}"


@tool
def get_available_time_slots(
    attendees: list[str],
    date: str,  # ISO 格式: "2024-01-15"
    duration_minutes: int
) -> list[str]:
    """检查指定日期参与者的日历可用性。"""
    # 桩代码:实践中会查询日历 API
    return ["09:00", "14:00", "16:00"]

2. 创建专门化的子代理

接下来,我们将创建处理每个领域的专门化子代理。

创建日历代理

日历代理理解自然语言的日程安排请求,并将其转换为精确的 API 调用。它处理日期解析、可用性检查和事件创建。

python
from langchain.agents import create_agent

CALENDAR_AGENT_PROMPT = (
    "你是一个日历日程助手。"
    "将自然语言的日程安排请求(例如'下周二下午2点')"
    "解析为正确的 ISO 日期时间格式。"
    "需要时使用 get_available_time_slots 检查可用性。"
    "如果没有合适的时间段,请停止并在回复中确认不可用。"
    "使用 create_calendar_event 来安排事件。"
    "始终在最终回复中确认安排了什么。"
)

calendar_agent = create_agent(
    model,
    tools=[create_calendar_event, get_available_time_slots],
    system_prompt=CALENDAR_AGENT_PROMPT,
)

测试日历代理如何处理自然语言日程安排:

python
query = "安排一个团队会议,下周二下午2点,时长1小时"

for step in calendar_agent.stream(
    {"messages": [{"role": "user", "content": query}]}
):
    for update in step.values():
        for message in update.get("messages", []):
            message.pretty_print()

输出:

================================== Ai Message ==================================
工具调用:
  get_available_time_slots (call_...)
  参数:
    attendees: []
    date: 2024-06-18
    duration_minutes: 60
================================= Tool Message =================================
名称: get_available_time_slots

["09:00", "14:00", "16:00"]
================================== Ai Message ==================================
工具调用:
  create_calendar_event (call_...)
  参数:
    title: 团队会议
    start_time: 2024-06-18T14:00:00
    end_time: 2024-06-18T15:00:00
    attendees: []
================================= Tool Message =================================
名称: create_calendar_event

事件已创建:团队会议,从 2024-06-18T14:00:00 到 2024-06-18T15:00:00,共 0 位参与者
================================== Ai Message ==================================

团队会议已安排在 6 月 18 日(周二)下午 2:00,持续 1 小时。如需添加参与者或地点,请告知!

代理将"下周二下午2点"解析为 ISO 格式("2024-01-16T14:00:00"),计算结束时间,调用 create_calendar_event,并返回一个自然语言的确认信息。

创建邮件代理

邮件代理处理消息撰写和发送。它专注于提取收件人信息、编写合适的主题和正文,以及管理邮件通信。

python
EMAIL_AGENT_PROMPT = (
    "你是一个邮件助手。"
    "根据自然语言请求撰写专业邮件。"
    "提取收件人信息并编写合适的主题和正文。"
    "使用 send_email 发送消息。"
    "始终在最终回复中确认发送了什么。"
)

email_agent = create_agent(
    model,
    tools=[send_email],
    system_prompt=EMAIL_AGENT_PROMPT,
)

测试邮件代理:

python
query = "给设计团队发个提醒,让他们审阅新的设计稿"

for step in email_agent.stream(
    {"messages": [{"role": "user", "content": query}]}
):
    for update in step.values():
        for message in update.get("messages", []):
            message.pretty_print()

输出:

================================== Ai Message ==================================
工具调用:
  send_email (call_...)
  参数:
    to: ['design-team@example.com']
    subject: 提醒:请审阅新的设计稿
    body: 设计团队,你们好!

这是提醒您们审阅新的设计稿。您的反馈对我们按时推进项目至关重要。

如有任何问题或需要更多信息,请告知!

谢谢!
================================= Tool Message =================================
名称: send_email

邮件已发送至 design-team@example.com - 主题:提醒:请审阅新的设计稿
================================== Ai Message ==================================

我已向设计团队发送了提醒,请他们审阅新的设计稿。如需就此议题进行进一步沟通,请告知!

代理从非正式请求中推断收件人,编写专业的主题和正文,调用 send_email,并返回确认信息。每个子代理都有狭窄的聚焦领域和领域特定的工具与提示,使其能够出色地完成特定任务。

3. 将子代理包装为工具

现在将每个子代理包装为一个供监督者调用的工具。这是创建分层系统的关键架构步骤。监督者将看到高级工具(如 schedule_event),而不是低级工具(如 create_calendar_event)。

python
from langchain.agents import SubAgent

schedule_event_agent = SubAgent(
    agent=calendar_agent,
    name="schedule_event",
    description=(
        "使用自然语言安排日历事件。"
        "当用户想要创建、修改或查看日历预约时使用。"
        "处理日期/时间解析、可用性检查和事件创建。"
    ),
)

manage_email_agent = SubAgent(
    agent=email_agent,
    name="manage_email",
    description=(
        "使用自然语言发送电子邮件。"
        "当用户想要发送通知、提醒或任何邮件通信时使用。"
        "处理收件人提取、主题生成和邮件撰写。"
    ),
)

工具描述帮助监督者决定何时使用每个工具,因此请使其清晰明确。我们只返回子代理的最终响应,因为监督者不需要看到中间推理或工具调用。

4. 创建监督者代理

现在创建协调子代理的监督者。监督者只看到高级工具,并在领域层面做出路由决策,而不是在单个 API 层面。

python
SUPERVISOR_PROMPT = (
    "你是一个有用的个人助手。"
    "你可以安排日历事件和发送电子邮件。"
    "将用户请求分解为适当的工具调用并协调结果。"
    "当请求涉及多个操作时,按顺序使用多个工具。"
)

supervisor_agent = create_agent(
    model,
    tools=[schedule_event_agent, manage_email_agent],
    system_prompt=SUPERVISOR_PROMPT,
)

测试完整的监督者流程:

python
query = "下周三下午3点安排一个团队会议,然后给团队发邮件提醒他们"

for step in supervisor_agent.stream(
    {"messages": [{"role": "user", "content": query}]}
):
    for update in step.values():
        for message in update.get("messages", []):
            message.pretty_print()

监督者会将请求分解为两个步骤:首先调用日历子代理安排事件,然后调用邮件子代理发送提醒。每个子代理独立处理其领域内的具体细节,而监督者只需关注高级协调。

5. 添加人工审核

在真实场景中,您可能希望在发送邮件前让用户审阅。LangChain 支持通过添加审核步骤来实现人工审核

python
from langchain.agents.middleware import HumanInTheLoopMiddleware

# 为邮件子代理添加人工审核
manage_email_agent_with_review = SubAgent(
    agent=email_agent,
    name="manage_email",
    description="发送邮件。收件人提取、主题生成和邮件撰写。",
    middlewares=[HumanInTheLoopMiddleware(
        approve_callback=lambda msg: print(f"\n=== 等待审批 ===\n{msg}\n================")
    )],
)

概念回顾

在本教程中,您学到了:

  • 监督者模式 — 中央代理协调专门的子代理
  • create_agent — 创建具有特定工具和系统提示的代理
  • SubAgent — 将子代理包装为供监督者调用的工具
  • 多提供商模型选择 — 使用 init_chat_model 或特定类选择 OpenAI、Anthropic、Gemini 等
  • 人工审核 — 通过在子代理中添加中间件允许用户批准/拒绝操作

下一步

本站为非官方中文学习站点,不代表 LangChain 官方。部分内容参考官方文档并重新整理为中文学习笔记。