在开发 AI Agent 应用时,我们经常遇到用户的一个请求可能涉及多个操作,比如“安排会议并发送邮件提醒”。传统的做法是在代码中硬编码调用顺序,但这样缺乏灵活性。如果用户说“先发邮件再安排会议”呢?或者“如果会议冲突,改到第二天并通知所有人”,硬编码的逻辑就会瞬间崩塌。

本文将深入探讨如何利用 Spring AI Alibaba 框架实现 监督者模式。我们将构建一个智能个人助理,让大语言模型担任“管家”角色,动态感知上下文、拆解任务并路由给专业的子Agent,实现真正的智能编排。

1.什么是监督者模式

监督者模式是一种多智能体(Multi-Agent)架构模式。其核心思想是引入一个中心化的监督者Agent,它不直接处理具体业务,而是负责:

  1. 接收意图:理解用户的复杂指令。
  2. 动态路由:根据当前状态,决定调用哪个子Agent(作为工具)。
  3. 循环决策:子Agent执行后返回结果,监督者根据结果决定是“继续下一步”还是“结束任务”。

传统硬编码工作流是显式的代码逻辑,灵活性很低,只适合流程固定、确定性高的任务;监督者模式是LLM自主决策,灵活性很高,修改提示词就能调整行为,还可以基于错误信息自主决定重试或切换,非常适合那些流程多变的场景。

在新版 Spring AI Alibaba 中,监督者模式通常通过将子Agent封装为工具来实现。

  • Supervisor Agent:持有 ReactAgent 实例,并配置 AgentTool
  • Sub-Agent:独立的 ReactAgent,拥有自己的 System Prompt 和专用工具。
  • 交互机制:监督者通过函数调用触发子Agent,子Agent执行完毕后,将结果作为工具调用的返回值返回给监督者,形成闭环。

2.构建智能个人助理

我们将实现一个场景:用户请求“下周二下午2点与设计团队开会1小时,并给他们发邮件提醒审查新模型”。这涉及日程管理邮件发送两个领域。

环境准备

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-agent-framework</artifactId>
        <version>1.1.2.2</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        <version>1.1.2.2</version>
    </dependency>
</dependencies>

定义子Agent

@Configuration
public class SupervisorConfig {

    // 1. 日程助手:专注于时间解析和日历操作
    private static final String CALENDAR_AGENT_PROMPT = """
            你是一名日程安排助手。
            职责:将自然语言形式的调度请求(如“下周二下午 2 点”)解析为 ISO 日期时间格式。
            工具:使用“get_available_time_slots”检查空闲时间,使用“create_calendar_event”创建事件。
            输出:在最终回复中一定要确认所安排的事项细节。
            """;

    // 2. 邮件助手:专注于内容撰写和发送
    private static final String EMAIL_AGENT_PROMPT = """
            你是一名专业的电子邮件助手。
            职责:根据自然语言请求撰写商务邮件。
            工具:提取收件人,设计主题和正文,使用“send_email”发送。
            输出:在最终回复中一定要确认邮件已发送及内容摘要。
            """;

    @Bean
    public ReactAgent calendarAgent(CalendarStubTools tools) {
        return ReactAgent.builder()
                .name("schedule_event")
                .description("用于安排日历事件的专家")
                .systemPrompt(CALENDAR_AGENT_PROMPT)
                .model(chatModel) // 注入 ChatModel
                .tools(tools.getTools()) // 注入具体API工具
                .inputType(String.class)
                .build();
    }

    @Bean
    public ReactAgent emailAgent(EmailStubTools tools) {
        return ReactAgent.builder()
                .name("manage_email")
                .description("用于发送电子邮件的专家")
                .systemPrompt(EMAIL_AGENT_PROMPT)
                .model(chatModel)
                .tools(tools.getTools())
                .inputType(String.class)
                .build();
    }
}

构建监督者Agent

@Bean
public ReactAgent supervisorAgent(
        @Qualifier("calendarAgent") ReactAgent calendarAgent,
        @Qualifier("emailAgent") ReactAgent emailAgent,
        MemorySaver memorySaver) {
    
    return ReactAgent.builder()
            .name("personal_assistant")
            .systemPrompt("""
                    你是一个乐于助人的个人助理管家。
                    你可以协调“日程助手”和“邮件助手”来完成用户请求。
                    
                    执行策略:
                    1. 分析用户请求,如果涉及多个步骤(如先开会后发邮件),请按顺序依次调用工具。
                    2. 如果子Agent返回信息不足(如缺少参会人),请直接向用户追问,不要编造信息。
                    3. 只有当所有子任务都完成后,才向用户输出最终结果。
                    """)
            .model(chatModel)
            .saver(memorySaver) // 必须配置 MemorySaver 以保持多轮对话上下文
            .tools(
                    // 关键点:将子Agent包装为工具,让监督者“看见”并调用它们
                    AgentTool.getFunctionToolCallback(calendarAgent),
                    AgentTool.getFunctionToolCallback(emailAgent)
            )
            .build();
}

测试验证

@Test
void testSupervisorWorkflow() {
    String complexQuery = """
            请于下周二下午 2 点安排一次与设计团队的会议,时长 1 小时,
            并给他们发送一封电子邮件以提醒他们对新的模型进行审查。
            """;
    
    // 调用监督者
    AssistantMessage response = supervisorAgent.call(new UserMessage(complexQuery));
    log.info("最终回复: {}", response.getText());
}

3.日志解析

通过日志,我们可以清晰地看到监督者是如何“思考”和“行动”的。

场景一:信息不足时的反问机制

用户输入:“安排明天上午 9 点的团队站立会议”

时间戳 日志级别 关键内容 流程解析
15:13:16 INFO User request: 安排明天上午… 步骤1:接收输入。监督者接收指令。
15:13:17 DEBUG ASSISTANT toolCalls=[schedule_event(…)] 步骤2:决策路由。监督者判断需要日程助手,生成工具调用。
15:13:20 DEBUG TOOL role=TOOL, name=schedule_event, content=“需要参会人邮箱…” 步骤3:子Agent执行。子Agent发现缺少关键参数(参会人),返回询问信息。
15:13:23 INFO Assistant: 为了帮您准确安排…需要确认参会人… 步骤4:反馈用户。监督者收到子Agent的“询问”,没有强行结束,而是将问题转达给用户。

洞察:监督者模式不仅仅是执行,还能处理异常流。子Agent的“反问”被监督者正确识别并传递给用户,实现了多轮对话的闭环。

3.2 场景二:多步骤复杂任务串联(完整流程)

阶段1:监督者接收第二个请求(含历史上下文)
行号 时间戳 日志内容 监督者模式流程对应
6 15:13:23.003 INFO - User request: 请于下周二下午 2 点安排一次与设计团队的会议,会时长 1 小时,并给他们发送一封电子邮件... 步骤1:监督者接收新用户输入(同时保留历史对话)
阶段2:第一次路由 → schedule_event
行号 时间戳 日志内容 监督者模式流程对应
7 15:13:26.305 DEBUG - ASSISTANT toolCalls=[ToolCall[name=schedule_event, arguments={"input": "下周二下午 2 点与设计团队开会,时长 1 小时"}]] 步骤2:LLM分析后,决定先调用schedule_event
8 15:13:27.085 DEBUG - Response 200 OK 子Agent执行中
9 15:13:28.919 DEBUG - TOOL role=TOOL, name=schedule_event, content="已为您安排会议:主题:与设计团队开会 时间:下周二(2024年1月16日)下午2:00-3:00" 步骤3:schedule_event执行完成,返回监督者
阶段3:第二次路由 → manage_email
行号 时间戳 日志内容 监督者模式流程对应
10 15:13:36.761 DEBUG - ASSISTANT toolCalls=[ToolCall[name=manage_email, arguments={"input": "给设计团队发送一封邮件,提醒他们对新的模型进行审查。会议定于下周二下午 2 点。"}]] 步骤2(第二次):监督者根据前序结果,决定调用manage_email
11 15:13:37.313 DEBUG - Response 200 OK 子Agent执行中
12 15:13:38.547 DEBUG - TOOL role=TOOL, name=manage_email, content="邮件已成功发送给设计团队..." 步骤3(第二次):manage_email执行完成,返回监督者
阶段4:监督者输出最终结果
行号 时间戳 日志内容 监督者模式流程对应
13 15:13:40.480 INFO - Assistant: 任务已完成:1.会议安排 2.邮件发送 步骤4:监督者判断所有任务完成,输出FINISH

我们基于 Spring AI Alibaba 的监督者模式实现了控制流与业务逻辑的解耦,利用 LLM 的推理能力处理不确定性。通过 ReactAgentAgentTool 的组合,我们仅需少量代码即可构建出具备多步规划上下文记忆异常处理能力的智能系统。这种模式特别适合企业级应用中的复杂助手场景,如IT运维自动化工单处理、智能客服工单流转等。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐