Spring AI Alibaba ——多智能体(Multi-agent)

Spring AI Alibaba ------多智能体(Multi-agent)

💡 核心结论:一句话先记住

如果说之前的 Agent 是一个"全栈打工人",既要写代码又要谈业务,最后因为工具太多、脑容量(Token)爆表而彻底疯狂;那么 Multi-agent(多智能体)架构 就是帮它开了一家公司,把复杂的任务拆解给多个"偏科"的专业精神小伙(写作者、评审员、翻译官),大家分工协作,组团忽悠大任务!


🛑 一、 为什么需要多智能体?(单打独斗的痛点)

  • 工具太多,选择困难: 给大模型塞 100 个工具,它经常"拿错扳手"。
  • 上下文太大,容易失忆: 一个人承载所有聊天记录,聊着聊着就抓不住重点。
  • 术业有专攻: 让专门搞数学的模型去算账,让搞创意的模型去写诗,效率翻倍。

Spring AI Alibaba 支持两种主流的协同模式:

  1. 工具调用模式(Tool Calling): 集中式管理。一个老板 Agent 把其他子 Agent 当成"黑盒工具"来调,子模型不跟用户直接说话,只干活交差。
  2. 交接模式(Handoffs): 去中心化管理。当前的 Agent 聊着聊着,发现超出专业范围了,直接把用户和控制权"打包转交"给另一个专家 Agent 接管。

🔑 二、 上下文工程的"四项基本原则"(参数大白话)

多智能体能不能玩得转,全看信息是怎么分发的。框架里有四个极其硬核的参数:

  • instruction:当前节点的运行指南,支持占位符 (如 {input} 用户原话,{article} 上游输出),实现跨 Agent 顺畅传小纸条!
  • returnReasoningContent(防长篇大论神器的) 设置为 false,子 Agent 的"内心思考挣扎过程"就不会传给上游,只给最终结果,极致省 Token。
  • includeContents:设置为 false 时,子 Agent 执行时会"选择性失明",不看老爹极其复杂的上下文,只专注于自己的小任务,防干扰。
  • outputKey:给自己的作业贴个标签(如 article),方便后面的 Agent 用 {article} 精准调用。

📁 三、 多智能体四大天王(全套代码抄作业区)

模式 1:顺序执行(Sequential Agent) ------ 流水线大兵

大白话: 接力棒模式。A 搞完给 B,B 搞完给 C,前者的输出是后者的输入。

💻 顺序执行代码示例:

Java 复制代码
import com.alibaba.cloud.ai.graph.agent.flow.agent.SequentialAgent;
import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.agent.ReactAgent;

// 1. 专门写作的子 Agent
ReactAgent writerAgent = ReactAgent.builder()
        .name("writer_agent")
        .model(chatModel)
        .description("专业写作Agent")
        .instruction("你是一个知名的作家,擅长写作和创作。请根据用户的提问进行回答:{input}。")
        .outputKey("article") // ⭐ 贴上作业标签
        .build();

// 2. 专门评审的子 Agent
ReactAgent reviewerAgent = ReactAgent.builder()
        .name("reviewer_agent")
        .model(chatModel)
        .description("专业评审Agent")
        .instruction("你是一个知名的评论家。对于散文类文章,请确保包含对于西湖风景的描述。待评论文章:{article}。最终只返回修改后的文章。")
        .outputKey("reviewed_article")
        .build();

// 3. 把他们拼成一条流水线
SequentialAgent blogAgent = SequentialAgent.builder()
        .name("blog_agent")
        .description("写文章并交给评论员评审的工作流")
        .subAgents(List.of(writerAgent, reviewerAgent)) // ⭐ 按顺序排队
        .build();

// 4. 召唤调用
Optional<OverAllState> result = blogAgent.invoke("帮我写一个100字左右的散文");
if (result.isPresent()) {
    OverAllState state = result.get();
    // 扒出第一个人的作业
    state.value("article").ifPresent(a -> System.out.println("原稿: " + ((AssistantMessage)a).getText()));
    // 扒出最终改好的作业
    state.value("reviewed_article").ifPresent(ra -> System.out.println("改后稿: " + ((AssistantMessage)ra).getText()));
}

💡 高级控制:不想看子 Agent 碎碎念?(控制推理内容)

Java 复制代码
ReactAgent writerAgent = ReactAgent.builder()
        .name("writer_agent")
        .model(chatModel)
        .returnReasoningContents(true) // 让我看你的思考过程
        .outputKey("article").build();

ReactAgent reviewerAgent = ReactAgent.builder()
        .name("reviewer_agent")
        .model(chatModel)
        .instruction("请对文章进行评审修正:{article}")
        .includeContents(true) // 包含上一个Agent的所有上下文
        .returnReasoningContents(true)
        .outputKey("reviewed_article").build();

模式 2:并行执行(Parallel Agent) ------ 多线齐发

大白话: 任务同时下发给多个人,大家各写各的,最后由一个"合并策略"把大家的作业融合成一份。

💻 并行执行与自定义合并示例:

Java 复制代码
import com.alibaba.cloud.ai.graph.agent.flow.agent.ParallelAgent;

// 定义三个同级别创作者
ReactAgent proseAgent = ReactAgent.builder().name("prose_agent").model(chatModel).instruction("写100字散文:{input}").outputKey("prose_result").build();
ReactAgent poemAgent = ReactAgent.builder().name("poem_agent").model(chatModel).instruction("写一首现代诗:{input}").outputKey("poem_result").build();
ReactAgent summaryAgent = ReactAgent.builder().name("summary_agent").model(chatModel).instruction("做个主题总结:{input}").outputKey("summary_result").build();

// ⭐ 自定义暴力合并策略:把所有人的结果用 "---" 拼起来
public class CustomMergeStrategy implements ParallelAgent.MergeStrategy {
    @Override
    public Map<String, Object> merge(Map<String, Object> mergedState, OverAllState state) {
        state.data().forEach((key, value) -> {
            if (key.endsWith("_result")) {
                Message message = (Message) value;
                Object existing = mergedState.get("all_results");
                mergedState.put("all_results", existing == null ? message.getText() : existing + " --- " + message.getText());
            }
        });
        return mergedState;
    }
}

// 组装并行大队
ParallelAgent parallelCreativeAgent = ParallelAgent.builder()
        .name("parallel_creative_agent")
        .subAgents(List.of(proseAgent, poemAgent, summaryAgent))
        .mergeStrategy(new CustomMergeStrategy()) // 注入合并灵魂
        .mergeOutputKey("final_merged_result")
        .build();

parallelCreativeAgent.invoke("以'西湖'为主题");

模式 3:智能路由(LlmRoutingAgent) ------ 智能前台分拨

大白话: 强依赖子 Agent 的 description(简历描述)。前台小哥(LLM)看一眼用户的诉求,查阅哪个子 Agent 的描述最匹配,就单次分发给它。

💻 智能路由与精准规则控制:

Java 复制代码
import com.alibaba.cloud.ai.graph.agent.flow.agent.LlmRoutingAgent;

// 子 Agent 的 description 是 LLM 路由的救命稻草,必须死磕写清楚!
ReactAgent codeAgent = ReactAgent.builder()
        .name("code_agent")
        .description("专门处理编程相关问题,包括Java, Python代码编写、调试和重构。")
        .instruction("你是一个高级架构师...").build();

ReactAgent businessAgent = ReactAgent.builder()
        .name("business_agent")
        .description("专门处理商业分析、财务报表和战略规划,不碰代码实现。")
        .instruction("你是一个资深商业分析师...").build();

// 如果怕 LLM 乱看分错,可以用 systemPrompt 硬核规定路由规则
final String ROUTING_RULE = "你是前台。规则:提代码找 code_agent,提钱和商业找 business_agent。只返回名字,别废话!";

LlmRoutingAgent router = LlmRoutingAgent.builder()
        .name("smart_router")
        .model(chatModel)
        .systemPrompt(ROUTING_RULE) // ⭐ 强制给路由立规矩
        .subAgents(List.of(codeAgent, businessAgent))
        .build();

// 会自动派发给 code_agent
router.invoke("帮我写一个Java连接Redis的工具类");

模式 4:监督者模式(SupervisorAgent) ------ 满级多轮项目经理

大白话: 它是 LlmRoutingAgent 的威力加强版。路由 Agent 只能分发一次就下班;而 Supervisor 能够反复横跳! 小弟干完活,必须回到 Supervisor 这里汇报,Supervisor 看一眼:整得挺好,下一个交给翻译小弟!直到全搞定,Supervisor 亲手打出 FINISH,流程结束。

💻 项目经理带队顺序嵌套案例:

Java 复制代码
import com.alibaba.cloud.ai.graph.agent.flow.agent.SupervisorAgent;

// 1. 准备先行的打工人:先写一篇基础文章
ReactAgent articleWriterAgent = ReactAgent.builder()
        .name("article_writer").model(chatModel)
        .instruction("写一篇关于春天的短文:{input}。").outputKey("article_content").build();

// 2. 准备备用的各路专家(归 Supervisor 管)
ReactAgent translatorAgent = ReactAgent.builder()
        .name("translator_agent").model(chatModel)
        .instruction("把文章翻译成英文,待译文在:{article_content}。").outputKey("translator_output").build();

ReactAgent reviewerAgent = ReactAgent.builder()
        .name("reviewer_agent").model(chatModel)
        .instruction("评审并润色文章,待审文在:{article_content}。").outputKey("reviewer_output").build();

// 3. 编写项目经理的调兵遣将指南
final String MANAGER_PROMPT = "你是总管。看一眼 {article_content},如果要英文就调 translator_agent,要改进就调 reviewer_agent,全弄完回复 FINISH。";

SupervisorAgent supervisor = SupervisorAgent.builder()
        .name("content_supervisor")
        .model(chatModel)
        .systemPrompt("你负责协调翻译和评审任务,只返回Agent名字或FINISH。")
        .instruction(MANAGER_PROMPT) // 占位符读取前序输出
        .subAgents(List.of(translatorAgent, reviewerAgent))
        .build();

// 4. 将"写作者"和"监督管理流"串联成高级复合工作流
SequentialAgent finalWorkflow = SequentialAgent.builder()
        .name("super_workflow")
        .subAgents(List.of(articleWriterAgent, supervisor)) // 先写,再由主管动态连环流转
        .build();

finalWorkflow.invoke("帮我写一篇关于春天的短文,然后翻译成英文");

🏁 四大天王对决,我该怎么选?

  • 任务一步接一步,不回头:SequentialAgent(流水线工厂)。
  • 任务各干各的,最后合体:ParallelAgent(分布式干活)。
  • 一问一答,找最懂的专家:LlmRoutingAgent(智能客服分流)。
  • 复杂长任务,需要来回审核、多步流转:SupervisorAgent(硬核总监带队)。

🎯 终极秒记口诀

单个 Agent 容易爆,多智能体来分道;

顺序执行接力棒,并行分发效率高;

路由全靠看简历,分流前台真奇妙;

最强当属监督者,反复横跳直到好!

占位符里传数据,组团打怪立功劳!