单 Agent 的天花板

你写了一个 Agent,注册了 7-8 个工具:查订单、查用户、查产品、生成 Excel、发邮件、生成报告、发送通知……

Prompt 写了几百字描述每个工具的用途。LLM 跑起来。

第一次跑:基本能用。
第三次跑:LLM 选了”知识库搜索”而不是”SQL 查询”,因为”查数据”两个工具都沾边。
第十次跑:你开始写”必须先用 SQL 工具,否则不通过”的硬约束,Prompt 越来越长。
第三十次跑:Prompt 已经 1000+ token 了,LLM 还是偶尔选错。

这就是单 Agent 的天花板:工具一多,准确性断崖式下降。

多 Agent 是解法。Spring AI Alibaba 的 Graph 框架提供了 4 种核心模式:顺序、并行、路由、监督。这篇文章讲清楚每种怎么用、什么时候用。

准备:公共 ChatModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ChatModelFactory {
public static ChatModel getChatModel() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AliQwen_API"))
.build();

return DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.defaultOptions(DashScopeChatOptions.builder()
.model("qwen-plus")
.temperature(0.5)
.maxToken(1000)
.build())
.build();
}
}

模式 1:顺序执行(SequentialAgent)

适用场景:流水线式任务,每一步依赖前一步的结果。

典型用例

  • 先写文章 → 再翻译
  • 先查数据 → 再生成图表 → 再发邮件
  • 先识别意图 → 再调用具体工具 → 再格式化输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class SequentialAgentTest {
public static void main(String[] args) throws GraphRunnerException {
ChatModel chatModel = ChatModelFactory.getChatModel();

// Agent 1:写作者
ReactAgent writerAgent = ReactAgent.builder()
.name("writer_agent")
.model(chatModel)
.description("专业写作 Agent")
.instruction("你是一个作家。请根据用户提问写一段话:{input}")
.outputKey("article") // 输出存到 state['article']
.build();

// Agent 2:翻译官
ReactAgent translateAgent = ReactAgent.builder()
.name("translate_agent")
.model(chatModel)
.description("专业翻译 Agent")
.instruction("""
你是翻译官。请翻译以下文章:
{article}
只返回翻译结果。
""")
.outputKey("reviewed_article")
.build();

// 顺序编排
SequentialAgent blogAgent = SequentialAgent.builder()
.name("blog_agent")
.description("写文章并翻译")
.subAgents(List.of(writerAgent, translateAgent))
.build();

// 执行
Optional<OverAllState> result = blogAgent.invoke("写一个 100 字的散文");

result.ifPresent(state -> {
state.value("article").ifPresent(a ->
System.out.println("原文: " + ((AssistantMessage) a).getText())
);
state.value("reviewed_article").ifPresent(t ->
System.out.println("译文: " + ((AssistantMessage) t).getText())
);
});
}
}

关键设计

  • outputKey("article") 把 Agent 1 的输出存到 state
  • Agent 2 的 instruction 用 {article} 占位符引用
  • 系统自动做字符串替换

模式 2:并行执行(ParallelAgent)

适用场景:多个独立任务可以同时跑,结果合并。

典型用例

  • 同时让 3 个 Agent 写不同风格的散文,取最好的
  • 同时让”优点分析 Agent”和”缺点分析 Agent”评估同一篇产品
  • 同时从多个数据源采集数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class ParallelAgentTest {
public static void main(String[] args) throws GraphRunnerException {
ChatModel chatModel = ChatModelFactory.getChatModel();

// 三个不同风格的作家,并行写
ReactAgent proseAgent = ReactAgent.builder()
.name("prose_writer")
.model(chatModel)
.description("散文作家")
.instruction("写一段散文:{input}")
.outputKey("prose_result")
.build();

ReactAgent poetryAgent = ReactAgent.builder()
.name("poetry_writer")
.model(chatModel)
.description("诗歌作家")
.instruction("写一首诗:{input}")
.outputKey("poetry_result")
.build();

ReactAgent novelAgent = ReactAgent.builder()
.name("novel_writer")
.model(chatModel)
.description("小说作家")
.instruction("写一段小说:{input}")
.outputKey("novel_result")
.build();

// 并行执行
ParallelAgent parallelAgent = ParallelAgent.builder()
.name("multi_style_writer")
.description("并行让 3 个作家同时写")
.subAgents(List.of(proseAgent, poetryAgent, novelAgent))
.build();

Optional<OverAllState> result = parallelAgent.invoke("秋天");

result.ifPresent(state -> {
// 三个结果都在 state 里
state.value("prose_result").ifPresent(System.out::println);
state.value("poetry_result").ifPresent(System.out::println);
state.value("novel_result").ifPresent(System.out::println);
});
}
}

关键设计

  • 三个 Agent 同时启动,节省总时间(如果单 Agent 3 秒,并行后还是 3 秒)
  • 每个 Agent 写自己的 outputKey,结果不冲突
  • 你需要后续的”汇总 Agent”决定用哪个结果

模式 3:路由(RoutingAgent)

适用场景:根据输入动态选择执行路径。

典型用例

  • 用户问”查订单”→ 路由到 OrderAgent
  • 用户问”推荐产品”→ 路由到 RecommendAgent
  • 用户问”投诉”→ 路由到 CustomerServiceAgent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class RoutingAgentTest {
public static void main(String[] args) throws GraphRunnerException {
ChatModel chatModel = ChatModelFactory.getChatModel();

// 不同的子 Agent
ReactAgent orderAgent = ReactAgent.builder()
.name("order_agent")
.model(chatModel)
.description("处理订单相关问题:查订单、修改订单、取消订单")
.instruction("你是订单助手。用户说:{input}")
.build();

ReactAgent productAgent = ReactAgent.builder()
.name("product_agent")
.model(chatModel)
.description("处理产品问题:推荐、参数、对比")
.instruction("你是产品助手。用户说:{input}")
.build();

ReactAgent serviceAgent = ReactAgent.builder()
.name("service_agent")
.model(chatModel)
.description("处理售后问题:投诉、退换货、客服")
.instruction("你是售后助手。用户说:{input}")
.build();

// 路由编排
RoutingAgent routingAgent = RoutingAgent.builder()
.name("customer_service_router")
.description("根据用户意图路由到对应专家")
.subAgents(List.of(orderAgent, productAgent, serviceAgent))
.build();

// 路由 Agent 会根据用户输入选择其中一个 sub-agent 执行
routingAgent.invoke("我想查一下我的订单 #12345 的状态");
}
}

关键设计

  • 路由 Agent 内部有个”调度 LLM”,它根据用户输入和每个子 Agent 的 description 决定走哪条路
  • 子 Agent 的 description 必须清晰区分,否则路由错误
  • 适合”意图分类”清晰的场景(3-10 个明确分支)

  • 如果子 Agent 描述重叠(比如”订单”和”产品”经常一起出现),路由会乱
  • 解决:description 写”互斥”的描述,”订单 = 已有订单的查改退”,”产品 = 浏览、推荐、对比”

模式 4:监督者(SupervisorAgent)

适用场景:复杂任务,需要”总指挥”动态协调多个子 Agent。

典型用例

  • 用户一句话里有多步操作:”帮我查上个月销售最高的产品,导出成 Excel,发给老板”
  • 任务流程不确定,需要根据上一步结果决定下一步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class SupervisorAgentTest {
public static void main(String[] args) throws GraphRunnerException {
ChatModel chatModel = ChatModelFactory.getChatModel();

// 4 个专业子 Agent
ReactAgent knowledgeAgent = ReactAgent.builder()
.name("knowledge_agent")
.model(chatModel)
.description("知识库查询。处理关于文档、政策、流程的查询")
.instruction("基于知识库回答:{input}")
.build();

ReactAgent dataQueryAgent = ReactAgent.builder()
.name("data_query_agent")
.model(chatModel)
.description("数据库查询。处理关于销售、用户、订单数据的查询")
.instruction("执行 SQL 查询:{input}")
.build();

ReactAgent exportAgent = ReactAgent.builder()
.name("export_agent")
.model(chatModel)
.description("数据导出。处理 Excel、PDF、CSV 导出请求")
.instruction("导出数据:{input}")
.build();

ReactAgent analysisAgent = ReactAgent.builder()
.name("analysis_agent")
.model(chatModel)
.description("数据分析。处理趋势分析、对比、洞察请求")
.instruction("分析数据:{input}")
.build();

// Supervisor
SupervisorAgent supervisor = SupervisorAgent.builder()
.name("business_assistant")
.description("总指挥。协调 knowledge、data_query、export、analysis 4 个子 Agent")
.subAgents(List.of(knowledgeAgent, dataQueryAgent, exportAgent, analysisAgent))
.maxIterations(10) // 防止死循环
.build();

// 复杂任务:先查数据,再导出,再发邮件
Optional<OverAllState> result = supervisor.invoke("""
帮我查上个月销售额最高的 5 个产品,
然后导出成 Excel,
最后发邮件给 boss@company.com
""");

// Supervisor 会自动拆解:
// 1. data_query_agent 查销售数据
// 2. export_agent 导出 Excel
// 3. (需要的话) 调邮件 Agent
}
}

关键设计

  • Supervisor 内部有个”调度 LLM”循环,根据上一步结果决定下一步调用谁
  • maxIterations(10) 防止陷入死循环
  • 适合”任务流程不确定”的复杂场景

Supervisor vs Routing 的区别

  • Routing:入口一次性路由,选定一个 Agent 后任务结束
  • Supervisor:持续协调,可以根据中间结果决定后续步骤

实战选型决策

场景特征 用哪种
流程固定、每步依赖上一步 Sequential
多步独立、可同时跑 Parallel
入口分流、单一意图 Routing
任务复杂、流程动态 Supervisor
流程固定 + 中间有并行 Sequential + Parallel 嵌套
入口分流 + 后续协调 Routing → Supervisor 嵌套

一个完整的业务系统设计

场景:智能客服系统

架构

1
2
3
4
5
6
7
8
9
10
11
12
13
Supervisor(业务总指挥)

├─ Routing Agent(意图路由)
│ │
│ ├─ 售前 Agent(产品咨询)
│ ├─ 售中 Agent(订单相关)
│ └─ 售后 Agent(投诉、退换货)

└─ Parallel Agent(多源信息收集)

├─ 知识库查询 Agent
├─ 用户历史订单 Agent
└─ 产品库存 Agent

执行流程

  1. 用户:”我想退掉上周买的手机”
  2. Supervisor 决定走”售后 Agent”(Routing)
  3. 售后 Agent 启动后,并行调用 3 个数据源(Parallel)
  4. 拿到结果后生成回复
  5. Supervisor 决定是否需要后续(如”是否生成退货工单”)

这套架构在 Spring AI Alibaba Graph 里都能实现

意味着什么?

多 Agent 不是”花式玩法”,是解决单 Agent 工具过多导致决策不准的标准答案。

  • 工具 < 5 个:单 Agent 就够
  • 工具 5-20 个:考虑 Routing(按意图分组)
  • 工具 20+ 个:必须多 Agent(按领域拆分)
  • 任务流程固定:Sequential
  • 任务流程动态:Supervisor

Java 后端做 AI Agent 的最大优势:可以直接用 Spring 生态的成熟模式。Spring AI Alibaba 的 4 大模式就是从 Java 企业开发经验里抽象出来的——Sequential 对应 pipeline,Parallel 对应 fan-out,Routing 对应 dispatcher,Supervisor 对应 orchestrator。

数据密集型 AI 后端的工程师,**多 Agent 编排能力是 2026 年必须掌握的”基本架构”**。比 LangChain、LangGraph 在 Python 生态里更工程化。

关联阅读