Spring AI Alibaba 1.x 系列【39】四大多智能体(Multi-agent)架构

文章目录

  • [1. 多智能体 Multi-Agent](#1. 多智能体 Multi-Agent)
    • [1.1 概述](#1.1 概述)
    • [1.2 两大多智能体模式](#1.2 两大多智能体模式)
      • [1.2.1 Tool Calling 工具调用模式](#1.2.1 Tool Calling 工具调用模式)
      • [1.2.2 Handoffs 智能体交接模式](#1.2.2 Handoffs 智能体交接模式)
  • [2. FlowAgent 抽象类](#2. FlowAgent 抽象类)
    • [2.1 顺序执行智能体(SequentialAgent)](#2.1 顺序执行智能体(SequentialAgent))
    • [2.2 并行执行智能体(Parallel Agent)](#2.2 并行执行智能体(Parallel Agent))
    • [2.3 循环智能体(LoopAgent)](#2.3 循环智能体(LoopAgent))
    • [2.4 路由执行智能体(LlmRoutingAgent )](#2.4 路由执行智能体(LlmRoutingAgent ))
  • [3. 构建流程](#3. 构建流程)
    • [3.1 构建入口](#3.1 构建入口)
    • [3.2 构造函数](#3.2 构造函数)
    • [3.3 初始化状态图](#3.3 初始化状态图)
    • [3.4 图构建器](#3.4 图构建器)
      • [3.4.1 FlowGraphBuildingStrategyRegistry](#3.4.1 FlowGraphBuildingStrategyRegistry)
      • [3.4.2 SequentialGraphBuildingStrategy](#3.4.2 SequentialGraphBuildingStrategy)
    • [3.5 构建完成](#3.5 构建完成)

1. 多智能体 Multi-Agent

1.1 概述

多智能体Multi-agent)将复杂的应用程序分解为多个协同工作的专业化 Agent

与依赖单个 Agent承载全量任务、全量工具、全量逻辑不同,Multi-agent 架构可以将更小、职责单一、高度专注的轻量化 Agent,组合为可编排、可协作、可路由的标准化工作流。

Agent 架构核心痛点:

  • 单个Agent 挂载大量工具,工具选择决策混乱、大模型幻觉严重
  • 全局上下文、对话记忆持续膨胀,Token 开销大、推理性能低
  • 业务职责臃肿耦合,难以维护、迭代、横向扩展
  • 无法实现工具隔离、权限隔离、场景化资源管控

多智能体适用场景:

  • Agent 工具过多,模型无法精准决策
  • 上下文/历史记忆体量过大,单 Agent 难以高效处理
  • 任务需要专业化分工 (规划 Agent 、检索 Agent、审核 Agent、计算 Agent
  • 跨领域业务协作、多角色专家接力处理、复杂长链路流程

1.2 两大多智能体模式

框架原生提供两种主流多智能体协作模式,覆盖流程编排拟人化对话两类场景。

两大模式核心对比:

对比维度 工具调用(Agent Tool) 交接模式(Handoffs)
控制模式 集中式(Supervisor 统一调度) 去中心化(Agent 自主移交)
用户交互 子Agent不直接对话,仅返回结果 交接后新Agent直接与用户交互
对话能力 有限,适合固定任务流水线 极强,支持跨领域连续对话
流程约束 强固化、可编排、易管控 弱约束、动态灵活、自适应流转
上下文优化 支持分层裁剪、工具隔离 依赖 returnReasoningContent 做上下文瘦身
典型组件 SupervisorAgent、Flow顺序/并行编排 会话级Agent、领域专属Agent

最佳实践:混合使用两种模式

  1. 大领域切换使用「Handoffs 交接」;
  2. 单个领域内部复杂子任务,使用「Tool CallingAgent 调用」;
  3. 结合 outputKey / includeContents 实现安全、高效的跨节点数据流转。

1.2.1 Tool Calling 工具调用模式

工作原理

  • Supervisor 总管 Agent 将其他子 Agent 封装为工具进行调用;
  • Agent 仅执行专属任务、产出结果,不直接对接用户

控制流

  • 集中式管控:所有路由、调度、任务分发统一由 Supervisor 控制。

适用场景

  • 固定结构化工作流、后台自动化任务、子任务拆解编排、权限集中管控。

1.2.2 Handoffs 智能体交接模式

工作原理

  • 当前活跃 Agent 自主判断业务边界,主动将会话控制权+全局状态 移交至目标专业 Agent
  • 交接完成后,活动 Agent 自动切换 ,用户直接与新 Agent 持续交互。

控制流

  • 去中心化协作:每个 Agent 具备自主决策能力,可主动切换会话处理方,无统一总管调度。

适用场景

  • 跨领域自然对话、专家角色接力、开放式问答流转、人工介入接管。

标准执行流程

  1. 当前 Agent 判断自身能力边界,判定需要其他专业 Agent 协助
  2. 完整传递会话控制权 + 全局State状态 + 上下文 至目标 Agent
  3. Agent 成为活动节点,直接响应用户对话
  4. 循环往复:新 Agent 可继续交接、或任务完成结束流程

2. FlowAgent 抽象类

FlowAgent 是所有多智能体智能体的顶层父类

  • 统一封装子智能体管理、状态图初始化、钩子挂载、配置构建能力
  • 衔接多智能体协作与 StateGraph 底层图执行引擎

默认已经实现的子类:

四大智能体对比:

特性 顺序智能体 SequentialAgent 并行智能体 ParallelAgent 循环智能体 LoopAgent 路由智能体 LlmRoutingAgent
执行逻辑 线性依次执行 并发执行 重复执行1个子智能体 LLM决策,路由到1个子智能体
子智能体数量 无限制 2~10个 仅1个 多个(候选池)
核心价值 分步流程 提升效率 重试/遍历 智能决策、统一入口
动态工具场景 分阶段切换工具 多工具并行 循环调用工具 按路由场景加载工具
定位 流程执行 性能优化 迭代重试 工作流大脑

2.1 顺序执行智能体(SequentialAgent)

FlowAgent 的具体子类,专门用于线性按顺序执行子智能体的工作流场景,将所有子智能体按照【添加的先后顺序】线性、依次执行(无分支、无循环)。

在顺序执行模式中,多个 Agent 按预定义的顺序依次执行:

  • Agent A 处理初始输入
  • Agent A 的输出传递给 Agent B
  • Agent B 处理并传递给 Agent C
  • 最后一个 Agent 返回最终结果

关键特性:

  • 按顺序执行:Agent 按照 subAgents 列表中定义的顺序执行
  • 状态传递:每个 Agent 的输出通过 outputKey 存储在状态中,可被后续 Agent 访问
  • 消息历史:默认情况下,所有 Agent 共享消息历史
  • 推理内容控制:使用 returnReasoningContents 控制是否在消息历史中包含中间推理

源码如下:

java 复制代码
public class SequentialAgent extends FlowAgent {

	/**
	 * 构造方法
	 * 通过建造者模式接收配置参数,委托给父类 FlowAgent 初始化
	 * @param builder 顺序智能体建造器
	 */
	protected SequentialAgent(SequentialAgentBuilder builder) {
		super(builder.name, builder.description, builder.compileConfig, builder.subAgents,
				builder.stateSerializer, builder.executor, builder.hooks);
	}

	/**
	 * 静态建造器入口
	 * 提供类型安全的链式调用方式创建 SequentialAgent 实例
	 */
	public static SequentialAgentBuilder builder() {
		return new SequentialAgentBuilder();
	}

	/**
	 * 重写父类抽象方法:构建【顺序类型】的状态图
	 * 核心逻辑:调用 FlowGraphBuilder,指定 SEQUENTIAL(顺序)类型生成工作流图
	 * @param config 流图配置(包含子智能体、钩子、序列化器等)
	 * @return 构建完成的顺序执行状态图
	 * @throws GraphStateException 图构建异常
	 */
	@Override
	protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
		return FlowGraphBuilder.buildGraph(FlowAgentEnum.SEQUENTIAL.getType(), config);
	}

	/**
	 * 【顺序智能体建造器】
	 * 继承通用 FlowAgentBuilder,实现类型安全的对象创建
	 * 遵循建造者设计模式,简化复杂对象的初始化
	 */
	public static class SequentialAgentBuilder extends FlowAgentBuilder<SequentialAgent, SequentialAgentBuilder> {

		/**
		 * 返回当前建造器实例(用于链式调用)
		 */
		@Override
		protected SequentialAgentBuilder self() {
			return this;
		}

		/**
		 * 参数校验
		 * 继承父类基础校验,可扩展顺序智能体专属校验规则
		 */
		@Override
		protected void validate() {
			super.validate();
			// 如需扩展顺序执行的专属校验逻辑,可在此处添加
		}

		/**
		 * 执行构建:创建 SequentialAgent 实例
		 */
		@Override
		public SequentialAgent doBuild() {
			validate();
			return new SequentialAgent(this);
		}

	}
}

极简使用示例:

java 复制代码
// 1. 创建多个子智能体(每个绑定不同动态工具)
Agent orderAgent = ...; // 订单查询智能体
Agent refundAgent = ...; // 退款处理智能体

// 2. 链式创建顺序执行智能体
SequentialAgent agent = SequentialAgent.builder()
        .name("客服流程智能体")
        .description("按顺序执行:查询→退款")
        .subAgents(List.of(orderAgent, refundAgent)) // 顺序执行
        .hooks(List.of(new ToolAuditHook())) // 工具审计钩子
        .build();

// 3. 启动执行
agent.run();

2.2 并行执行智能体(Parallel Agent)

在并行执行模式中,多个 Agent 同时处理相同的输入。它们的结果被收集并合并。

流程:

  • 输入同时发送给所有 Agent
  • 所有 Agent 并行处理
  • 结果被合并成单一输出

源码如下:

java 复制代码
/**
 * 【并行执行智能体】
 * 并发执行多个子智能体,并自动合并所有子智能体的执行结果。
 *
 * <p>
 * 实现 【分发-并行-聚合】(Fan-Out/Gather) 设计模式:
 * </p>
 * <ul>
 * <li><strong>分发</strong>:将输入数据同时分发给所有子智能体</li>
 * <li><strong>并行</strong>:所有子智能体并发执行(非顺序阻塞)</li>
 * <li><strong>聚合</strong>:收集所有子智能体的结果,按策略合并</li>
 * </ul>
 *
 * <p>
 * 基于底层 ParallelNode 实现真正的并发执行,支持自定义结果合并策略。
 * </p>
 */
public class ParallelAgent extends FlowAgent {

	private static final Logger logger = LoggerFactory.getLogger(ParallelAgent.class);

	/** 结果合并策略 */
	private final MergeStrategy mergeStrategy;

	/** 合并结果的输出Key */
	private String mergeOutputKey;

	/** 最大并发数(控制子智能体的并发执行数量) */
	private final Integer maxConcurrency;

	/**
	 * 构造方法:通过建造器初始化参数
	 */
	protected ParallelAgent(ParallelAgentBuilder builder) {
		super(builder.name, builder.description, builder.compileConfig, builder.subAgents,
				builder.stateSerializer, builder.executor, builder.hooks);
		// 未指定合并策略则使用默认
		this.mergeStrategy = builder.mergeStrategy != null ? builder.mergeStrategy : new DefaultMergeStrategy();
		this.maxConcurrency = builder.maxConcurrency;
		this.mergeOutputKey = builder.mergeOutputKey;
	}

	/**
	 * 建造器入口:链式创建 ParallelAgent 实例
	 */
	public static ParallelAgentBuilder builder() {
		return new ParallelAgentBuilder();
	}

	/**
	 * 重写:构建【并行类型】的状态图
	 * 向配置中注入并行专属参数(合并策略、最大并发数)
	 */
	@Override
	protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
		config.customProperty("mergeStrategy", this.mergeStrategy);
		config.customProperty("maxConcurrency", this.maxConcurrency);

		return FlowGraphBuilder.buildGraph(FlowAgentEnum.PARALLEL.getType(), config);
	}

	// ========== Getter 方法 ==========
	public MergeStrategy mergeStrategy() {
		return mergeStrategy;
	}

	public String mergeOutputKey() {
		return mergeOutputKey;
	}

	public Integer maxConcurrency() {
		return maxConcurrency;
	}

	/**
	 * 重写:构建非流式配置,将最大并发数注入元数据
	 * 供 ParallelNode 运行时读取并发限制
	 */
	@Override
	protected RunnableConfig buildNonStreamConfig(RunnableConfig config) {
		RunnableConfig baseConfig = super.buildNonStreamConfig(config);

		if (this.maxConcurrency != null) {
			return RunnableConfig.builder(baseConfig)
					.addMetadata(ParallelNode.formatMaxConcurrencyKey(ParallelNode.formatNodeId(this.name())), this.maxConcurrency)
					.build();
		}
		return baseConfig;
	}

	/**
	 * 重写:构建流式配置,逻辑同上
	 */
	@Override
	protected RunnableConfig buildStreamConfig(RunnableConfig config) {
		RunnableConfig baseConfig = super.buildStreamConfig(config);

		if (this.maxConcurrency != null) {
			return RunnableConfig.builder(baseConfig)
					.addMetadata(ParallelNode.formatMaxConcurrencyKey(ParallelNode.formatNodeId(this.name())), this.maxConcurrency)
					.build();
		}
		return baseConfig;
	}

	/**
	 * 【结果合并策略接口】
	 * 定义并行子智能体结果的合并规则,支持自定义扩展
	 */
	public interface MergeStrategy {
		/**
		 * 合并并行执行结果
		 * @param subAgentResults 子智能体结果(Key=智能体标识,Value=执行结果)
		 * @param overallState 全局状态上下文
		 * @return 合并后的最终结果
		 */
		Object merge(Map<String, Object> subAgentResults, OverAllState overallState);
	}

	/**
	 * 并行智能体建造器
	 * 继承通用 FlowAgentBuilder,提供并行专属配置(并发数、合并策略)
	 */
	public static class ParallelAgentBuilder extends FlowAgentBuilder<ParallelAgent, ParallelAgentBuilder> {

		private MergeStrategy mergeStrategy;
		private Integer maxConcurrency;
		private String mergeOutputKey;

		/** 设置结果合并策略 */
		public ParallelAgentBuilder mergeStrategy(MergeStrategy mergeStrategy) {
			this.mergeStrategy = mergeStrategy;
			return this;
		}

		/** 设置合并结果的输出Key */
		public ParallelAgentBuilder mergeOutputKey(String mergeOutputKey) {
			this.mergeOutputKey = mergeOutputKey;
			return this;
		}

		/**
		 * 重写:设置子智能体
		 * 强制校验:子智能体必须是 BaseAgent 类型
		 */
		@Override
		public ParallelAgentBuilder subAgents(List<Agent> subAgents) {
			if (subAgents == null || subAgents.isEmpty()) {
				throw new IllegalArgumentException("必须指定子智能体列表");
			}
			if (subAgents.stream().anyMatch(agent -> !(agent instanceof BaseAgent))) {
				throw new IllegalArgumentException("子智能体必须是 BaseAgent 类型");
			}
			return super.subAgents(subAgents);
		}

		/** 设置最大并发数 */
		public ParallelAgentBuilder maxConcurrency(Integer maxConcurrency) {
			this.maxConcurrency = maxConcurrency;
			return this;
		}

		@Override
		protected ParallelAgentBuilder self() {
			return this;
		}

		/**
		 * 核心校验:并行智能体强校验规则
		 */
		@Override
		protected void validate() {
			// 1. 校验名称必填
			if (name == null || name.trim().isEmpty()) {
				throw new IllegalArgumentException("必须指定智能体名称");
			}

			// 2. 至少2个子智能体,最多10个(性能限制)
			if (subAgents == null || subAgents.size() < 2) {
				throw new IllegalArgumentException("并行智能体至少需要2个子智能体,当前:"
						+ (subAgents != null ? subAgents.size() : 0));
			}
			if (subAgents.size() > 10) {
				throw new IllegalArgumentException("并行智能体最多支持10个子智能体,当前:" + subAgents.size());
			}

			// 3. 校验子智能体输出Key唯一(避免合并冲突)
			validateUniqueOutputKeys();

			// 4. 校验输入输出Key兼容性
			validateInputKeyCompatibility();

			// 5. 校验并发数合法性
			if (maxConcurrency != null && maxConcurrency < 1) {
				throw new IllegalArgumentException("最大并发数必须≥1,当前:" + maxConcurrency);
			}
		}

		/** 校验所有子智能体的 outputKey 唯一 */
		private void validateUniqueOutputKeys() {
			Set<String> outputKeys = new HashSet<>();
			Set<String> duplicateKeys = new HashSet<>();

			for (Agent subAgent : subAgents) {
				if (subAgent instanceof ReactAgent agent) {
					String key = agent.getOutputKey();
					if (key != null && !outputKeys.add(key)) {
						duplicateKeys.add(key);
					}
				}
			}

			if (!duplicateKeys.isEmpty()) {
				throw new IllegalArgumentException("子智能体输出Key重复:" + duplicateKeys + ",必须唯一");
			}
		}

		/** 校验子智能体输入输出兼容性 */
		private void validateInputKeyCompatibility() {
			for (Agent subAgent : subAgents) {
				if (!(subAgent instanceof ReactAgent)) continue;
				String key = ((ReactAgent) subAgent).getOutputKey();
				if (key == null) {
					logger.warn("子智能体 {} 未配置 outputKey,可能导致数据流转异常", subAgent.name());
				}
			}
		}

		/** 构建并行智能体实例 */
		@Override
		public ParallelAgent doBuild() {
			validate();
			return new ParallelAgent(this);
		}
	}

	// ==================== 内置默认合并策略 ====================
	/** 默认合并策略:将结果封装为 Map */
	public static class DefaultMergeStrategy implements MergeStrategy {
		@Override
		public Object merge(Map<String, Object> subAgentResults, OverAllState overallState) {
			return new HashMap<>(subAgentResults);
		}
	}

	/** 列表合并策略:将结果转为 List */
	public static class ListMergeStrategy implements MergeStrategy {
		@Override
		public Object merge(Map<String, Object> subAgentResults, OverAllState overallState) {
			return subAgentResults.values().stream().toList();
		}
	}

	/** 字符串拼接策略:合并文本结果 */
	public static class ConcatenationMergeStrategy implements MergeStrategy {
		private final String separator;

		public ConcatenationMergeStrategy() {
			this("\n");
		}

		public ConcatenationMergeStrategy(String separator) {
			this.separator = separator;
		}

		@Override
		public Object merge(Map<String, Object> subAgentResults, OverAllState overallState) {
			return subAgentResults.values()
					.stream()
					.map(Object::toString)
					.reduce("", (a, b) -> a.isEmpty() ? b : a + separator + b);
		}
	}

}

2.3 循环智能体(LoopAgent)

循环执行智能体,继承自 FlowAgent,核心能力是按指定策略循环执行单个子智能体,支持固定次数、条件判断、JSON 数组遍历等多种循环模式。

支持多种循环模式,用于重复执行单个子智能体:

  • COUNT(次数循环):执行固定次数的循环
  • CONDITION(条件循环) :根据条件判断是否继续循环,满足条件时终止循环,结构类似 do-while
  • JSON_ARRAY(数组遍历):解析 JSON 数组,遍历数组内每个元素并执行子智能体
  • 自定义策略 :可实现 LoopStrategy 接口,自行拓展自定义循环逻辑

核心约束LoopAgent 有且仅能配置一个子智能体,该子智能体将在每一轮循环中重复执行。

使用示例:

java 复制代码
LoopAgent loopAgent = LoopAgent.builder()
    .name("example-loop-agent")
    .description("循环智能体示例")
    .loopStrategy(LoopMode.condition(messagePredicate))
    .subAgent(subAgent)
    .build();

源码如下:

java 复制代码
public class LoopAgent extends FlowAgent {

    /** 循环策略对象 */
    private final LoopStrategy loopStrategy;

    /** 配置常量:循环策略的Key */
    public static final String LOOP_STRATEGY = "loopStrategy";

    /**
     * 构造方法:通过建造器初始化参数
     */
    private LoopAgent(LoopAgentBuilder builder) {
        super(builder.name, builder.description, builder.compileConfig, builder.subAgents,
                builder.stateSerializer, builder.executor, builder.hooks);
        this.loopStrategy = builder.loopStrategy;
    }

    /**
     * 重写父类方法:构建【循环类型】的状态图
     * 将循环策略注入配置,交由 FlowGraphBuilder 构建循环工作流
     */
    @Override
    protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
        config.customProperty(LOOP_STRATEGY, loopStrategy);
        return FlowGraphBuilder.buildGraph(FlowAgentEnum.LOOP.getType(), config);
    }

    /**
     * 建造器入口:链式创建 LoopAgent 实例
     */
    public static LoopAgentBuilder builder() {
        return new LoopAgentBuilder();
    }

    /**
     * 【循环智能体建造器】
     * 重写通用建造器,强制约束:仅支持单个子智能体、必须配置循环策略
     */
    public static class LoopAgentBuilder extends FlowAgentBuilder<LoopAgent, LoopAgentBuilder> {

        /** 循环策略(必填) */
        private LoopStrategy loopStrategy = null;

        /**
         * 返回当前建造器实例,支持链式调用
         */
        @Override
        protected LoopAgentBuilder self() {
            return this;
        }

        /**
         * 设置【单个】子智能体(LoopAgent 唯一支持的子智能体配置方式)
         * @param subAgent 循环中重复执行的子智能体
         */
        public LoopAgentBuilder subAgent(Agent subAgent)
        {
            this.subAgents = List.of(subAgent);
            return self();
        }

        /**
         * 重写:禁用批量设置子智能体
         * 强制约束:LoopAgent 只能有一个子智能体,禁止调用此方法
         */
        @Override
        public LoopAgentBuilder subAgents(List<Agent> subAgents) {
            throw new UnsupportedOperationException("LoopAgent 必须且只能有一个子智能体,请使用 subAgent() 方法。");
        }

        /**
         * 设置循环策略(必填)
         */
        public LoopAgentBuilder loopStrategy(LoopStrategy loopStrategy) {
            this.loopStrategy = loopStrategy;
            return self();
        }

        /**
         * 参数校验:强制校验循环策略不能为空
         */
        @Override
        protected void validate() {
            super.validate();
            if (this.loopStrategy == null) {
                throw new IllegalArgumentException("LoopAgent 必须配置循环策略 loopStrategy。");
            }
        }

        /**
         * 构建 LoopAgent 实例
         */
        @Override
        public LoopAgent doBuild() {
            validate();
            return new LoopAgent(this);
        }
    }
}

2.4 路由执行智能体(LlmRoutingAgent )

利用大模型的理解能力,自动决策、智能路由到最合适的子智能体执行。

核心功能

  1. 基于大模型(ChatModel)理解用户意图
  2. 自动从子智能体列表中,路由到最匹配的子智能体执行
  3. 支持兜底智能体,路由失败时自动降级
  4. 支持自定义系统提示词、路由指令,灵活控制路由逻辑

适用场景:多场景智能体统一入口、意图识别、动态分支决策

核心属性:

java 复制代码
public class LlmRoutingAgent extends FlowAgent {

	/** 大模型实例(用于做路由决策,必填) */
	private final ChatModel chatModel;

	/** 兜底智能体名称(路由决策失败/无匹配时,执行该智能体) */
	private final String fallbackAgent;

	/** 路由系统提示词(定义路由智能体的角色、规则) */
	private final String systemPrompt;

	/** 路由指令(具体的路由执行指令) */
	private final String instruction;

其他源码内容:

java 复制代码
public class LlmRoutingAgent extends FlowAgent {

	/**
	 * 构造方法:通过建造器初始化所有配置
	 */
	protected LlmRoutingAgent(LlmRoutingAgentBuilder builder) {
		super(builder.name, builder.description, builder.compileConfig, builder.subAgents,
				builder.stateSerializer, builder.executor, builder.hooks);
		this.chatModel = builder.chatModel;
		this.fallbackAgent = builder.fallbackAgent;
		this.systemPrompt = builder.systemPrompt;
		this.instruction = builder.instruction;
	}

	/**
	 * 静态建造器入口:链式创建 LlmRoutingAgent 实例
	 */
	public static LlmRoutingAgentBuilder builder() {
		return new LlmRoutingAgentBuilder();
	}

	// ========== Getter 方法 ==========
	public String getFallbackAgent() {
		return fallbackAgent;
	}

	public String getSystemPrompt() {
		return systemPrompt;
	}

	public String getInstruction() {
		return instruction;
	}

	/**
	 * 重写父类抽象方法:构建【路由类型】的状态图
	 * 注入大模型实例,交由 FlowGraphBuilder 构建路由工作流
	 */
	@Override
	protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
		// 向图配置中注入大模型(路由决策核心依赖)
		config.setChatModel(this.chatModel);
		// 构建路由类型的状态图
		return FlowGraphBuilder.buildGraph(FlowAgentEnum.ROUTING.getType(), config);
	}

	/**
	 * 【LLM路由智能体建造器】
	 * 继承通用 FlowAgentBuilder,扩展大模型路由专属配置
	 * 强制校验:必须指定 ChatModel
	 */
	public static class LlmRoutingAgentBuilder extends FlowAgentBuilder<LlmRoutingAgent, LlmRoutingAgentBuilder> {

		/** 大模型(必填,路由决策核心) */
		private ChatModel chatModel;

		/** 兜底智能体(可选) */
		private String fallbackAgent;

		/** 系统提示词(可选) */
		private String systemPrompt;

		/** 路由指令(可选) */
		private String instruction;

		/**
		 * 设置路由决策使用的大模型(必填)
		 * @param chatModel Spring AI 大模型实例
		 * @return 建造器实例
		 */
		public LlmRoutingAgentBuilder model(ChatModel chatModel) {
			this.chatModel = chatModel;
			return this;
		}

		/**
		 * 设置兜底智能体(路由无匹配时执行)
		 */
		public LlmRoutingAgentBuilder fallbackAgent(String fallbackAgent) {
			this.fallbackAgent = fallbackAgent;
			return this;
		}

		/**
		 * 设置路由系统提示词
		 */
		public LlmRoutingAgentBuilder systemPrompt(String systemPrompt) {
			this.systemPrompt = systemPrompt;
			return this;
		}

		/**
		 * 设置路由执行指令
		 */
		public LlmRoutingAgentBuilder instruction(String instruction) {
			this.instruction = instruction;
			return this;
		}

		/**
		 * 返回当前建造器实例,支持链式调用
		 */
		@Override
		protected LlmRoutingAgentBuilder self() {
			return this;
		}

		/**
		 * 核心校验:路由智能体必须配置 ChatModel
		 */
		@Override
		protected void validate() {
			super.validate();
			if (chatModel == null) {
				throw new IllegalArgumentException("LLM路由智能体必须指定 ChatModel 大模型实例");
			}
		}

		/**
		 * 构建最终的 LlmRoutingAgent 实例
		 */
		@Override
		public LlmRoutingAgent doBuild() {
			validate();
			return new LlmRoutingAgent(this);
		}

	}

极简使用示例:

java 复制代码
// 1. 注入大模型
@Autowired
private ChatModel chatModel;

// 2. 创建多个带独立动态工具的子智能体
Agent customerServiceAgent = createAgentWithTool("客服智能体", "orderQuery,refund");
Agent opsAgent = createAgentWithTool("运维智能体", "logQuery,monitor");
Agent officeAgent = createAgentWithTool("办公智能体", "summary,parse");

// 3. 构建 LLM 路由智能体
LlmRoutingAgent routingAgent = LlmRoutingAgent.builder()
        .name("企业统一智能体入口")
        .description("根据用户问题,智能路由到对应场景智能体")
        .model(chatModel) // 必选:大模型
        .fallbackAgent("customerServiceAgent") // 兜底:客服智能体
        .systemPrompt("你是智能路由助手,根据用户问题选择对应智能体")
        .subAgents(List.of(customerServiceAgent, opsAgent, officeAgent)) // 路由候选池
        .build();

// 4. 执行:自动路由 + 调用对应工具
routingAgent.run(userMessage);

3. 构建流程

3.1 构建入口

所有 FlowAgent 建造器的 build() 方法,调用的都是抽象父类 FlowAgentBuilder,再调用子类实现的 doBuild() 创建具体智能体:

java 复制代码
/**
 * 【模板方法】构建具体的 FlowAgent 实例
 * @return 构建完成的 FlowAgent 实例
 * @throws GraphStateException 智能体创建失败时抛出异常
 */
public T build() {
    // ====================== 公共逻辑:统一处理状态持久化配置 ======================
    // 如果配置了状态持久化器(saver,用于智能体状态保存/恢复)
    if (this.saver != null) {
        // 场景1:若编译配置(CompileConfig)为空,创建新的编译配置,并注册持久化器
        if (this.compileConfig == null) {
            this.compileConfig = CompileConfig.builder()
                    .saverConfig(SaverConfig.builder()
                            .register(saver) // 注册状态持久化器
                            .build())
                    .build();
        }
        // 场景2:若编译配置已存在,基于原有配置,覆盖/注入持久化配置
        else {
            this.compileConfig = CompileConfig.builder(compileConfig)
                    .saverConfig(SaverConfig.builder()
                            .register(saver)
                            .build())
                    .build();
        }
    }

    // ====================== 调用子类实现:创建具体智能体实例 ======================
    return doBuild();
}

doBuild() 会先进行校验,再调用 SequentialAgent 构造函数:

java 复制代码
/**
 * 重写:抽象构建方法
 * 完成校验后,创建并返回 SequentialAgent 具体实例
 * @return 构建完成的顺序执行智能体
 */
@Override
public SequentialAgent doBuild() {
    // 执行参数校验(确保所有配置合法)
    validate();
    // 通过构造方法创建 SequentialAgent,传入当前建造器的所有配置
    return new SequentialAgent(this);
}

/**
 * 重写:参数校验方法
 * 先执行父类通用校验,再扩展顺序智能体专属校验(可扩展)
 */
@Override
protected void validate() {
    // 1. 执行父类 FlowAgentBuilder 的基础校验(必填项:名称、子智能体非空等)
    super.validate();
    // 2. 扩展点:此处可添加 SequentialAgent 专属的参数校验规则(当前无额外校验)
}

校验智能体名称 name 非空,智能体列表 subAgents 非空

java 复制代码
	protected void validate() {
		if (name == null || name.trim().isEmpty()) {
			throw new IllegalArgumentException("Name must be provided");
		}
		if (subAgents == null || subAgents.isEmpty()) {
			throw new IllegalArgumentException("At least one sub-agent must be provided for flow");
		}
	}

3.2 构造函数

SequentialAgent 构造函数中都是调用的父类的构造进行初始化:

java 复制代码
	protected SequentialAgent(SequentialAgentBuilder builder) {
		super(builder.name, builder.description, builder.compileConfig, builder.subAgents, builder.stateSerializer, builder.executor, builder.hooks);
	}
java 复制代码
	protected FlowAgent(String name, String description, CompileConfig compileConfig, List<Agent> subAgents,
						StateSerializer stateSerializer, Executor executor, List<Hook> hooks) {
		super(name, description);
		this.compileConfig = compileConfig;
		this.subAgents = subAgents;
		this.stateSerializer = stateSerializer;
		this.executor = executor;
		this.hooks = hooks;
	}

	protected Agent(String name, String description) {
		this.name = name;
		this.description = description;
	}

3.3 初始化状态图

图在第一次执行时,会调用 FlowAgent #initGraph() 进行初始化,统一为所有子类(顺序 / 并行 / 循环 / 路由智能体)初始化状态图(StateGraph):

java 复制代码
/**
 * 重写父类方法:初始化状态图(StateGraph)
 * 所有 FlowAgent 子类(顺序/并行/循环/路由)统一复用此模板方法
 * @return 构建完成的状态图对象
 * @throws GraphStateException 状态图构建失败时抛出异常
 */
@Override
protected StateGraph initGraph() throws GraphStateException {
    // ====================== 1. 构建流图基础配置 ======================
    // 使用 FlowGraphBuilder 构建工作流配置,封装智能体核心属性
    FlowGraphBuilder.FlowGraphConfig config = FlowGraphBuilder.FlowGraphConfig.builder()
            .name(this.name())               // 设置智能体名称
            .rootAgent(this)                 // 设置当前智能体为【根智能体】(工作流入口)
            .subAgents(this.subAgents());    // 设置子智能体列表

    // ====================== 2. 注入可选配置 ======================
    // 如果配置了状态序列化器(用于状态持久化/断点续跑),则注入配置
    if (this.stateSerializer != null) {
        config.stateSerializer(this.stateSerializer);
    }

    // 如果配置了钩子函数(日志/裁剪/权限/工具扩展),则注入配置
    if (this.hooks != null && !this.hooks.isEmpty()) {
        config.hooks(this.hooks);
    }

    // ====================== 3. 子类实现具体图构建逻辑 ======================
    // 调用抽象方法 buildSpecificGraph,由子类实现【顺序/并行/循环/路由】的具体图构建
    return buildSpecificGraph(config);
}

接着进入到子类中的具体构建【顺序执行】类型的状态图方法:

java 复制代码
/**
 * 重写父类抽象方法:构建【顺序执行】类型的状态图
 * @param config 流图通用配置(名称、子智能体、钩子、序列化器等)
 * @return 构建完成的顺序执行状态图
 * @throws GraphStateException 图构建失败异常
 */
@Override
protected StateGraph buildSpecificGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
    // 调用统一的流图构建器,传入【顺序类型】和通用配置,生成StateGraph
    return FlowGraphBuilder.buildGraph(FlowAgentEnum.SEQUENTIAL.getType(), config);
}

3.4 图构建器

使用策略模式 ,从【策略注册器】中,根据类型创建对应的图构建策略,再调用具体策略,执行图构建逻辑:

java 复制代码
/**
 * 流图构建器(统一调度器)
 * 所有FlowAgent的状态图构建,最终都会走到这个静态方法
 */
public class FlowGraphBuilder {

	/**
	 * 通用图构建方法:根据策略类型,分发到对应的具体构建逻辑
	 * @param strategyType 策略类型(对应FlowAgentEnum:SEQUENTIAL/PARALLEL/LOOP/ROUTING)
	 * @param config 图构建的所有配置参数
	 * @return 最终构建完成的StateGraph(状态图)
	 * @throws GraphStateException 图构建失败抛出异常
	 */
	public static StateGraph buildGraph(String strategyType, FlowGraphConfig config) throws GraphStateException {
		// 1. 从【策略注册器】中,根据类型创建对应的图构建策略
		FlowGraphBuildingStrategy strategy = FlowGraphBuildingStrategyRegistry.getInstance().createStrategy(strategyType);

		// 2. 执行策略专属的配置校验
		strategy.validateConfig(config);

		// 3. 调用具体策略,执行图构建逻辑
		return strategy.buildGraph(config);
	}
}

3.4.1 FlowGraphBuildingStrategyRegistry

【流图构建策略注册中心】负责所有 FlowGraphBuildingStrategy(图构建策略)的注册、查询、创建。

核心能力:

  1. 动态注册新的图构建策略,无需修改框架核心代码(符合开闭原则)
  2. 线程安全设计,支持多线程环境下的策略注册与获取
  3. 单例全局唯一,统一管理所有策略
java 复制代码
/**
 * 【流图构建策略注册中心】
 * 负责所有 FlowGraphBuildingStrategy(图构建策略)的注册、查询、创建
 *
 * 核心能力:
 * 1. 动态注册新的图构建策略,无需修改框架核心代码(符合开闭原则)
 * 2. 线程安全设计,支持多线程环境下的策略注册与获取
 * 3. 单例全局唯一,统一管理所有策略
 *
 * 所有 FlowAgent(顺序/并行/循环/路由)的图构建策略,都由此类管理
 */
public class FlowGraphBuildingStrategyRegistry {

	/** 单例实例:全局唯一的注册中心对象 */
	private static final FlowGraphBuildingStrategyRegistry INSTANCE = new FlowGraphBuildingStrategyRegistry();

	/**
	 * 策略工厂容器:线程安全的 ConcurrentHashMap
	 * Key:策略类型(如 sequential/parallel/loop/routing)
	 * Value:策略工厂(Supplier 函数式接口,用于创建策略实例)
	 */
	private final Map<String, Supplier<FlowGraphBuildingStrategy>> strategyFactories = new ConcurrentHashMap<>();

	/**
	 * 私有构造方法:禁止外部实例化,保证单例
	 * 构造时自动注册框架内置的默认策略
	 */
	private FlowGraphBuildingStrategyRegistry() {
		registerDefaultStrategies();
	}

	/**
	 * 获取单例实例:全局唯一入口
	 */
	public static FlowGraphBuildingStrategyRegistry getInstance() {
		return INSTANCE;
	}

	/**
	 * 注册策略实例:每次获取返回同一个对象(单例策略)
	 * @param strategy 具体的图构建策略
	 */
	public void registerStrategy(FlowGraphBuildingStrategy strategy) {
		if (strategy == null) {
			throw new IllegalArgumentException("策略实例不能为空");
		}

		String type = strategy.getStrategyType();
		if (type == null || type.trim().isEmpty()) {
			throw new IllegalArgumentException("策略类型不能为空");
		}

		if (strategyFactories.containsKey(type)) {
			throw new IllegalArgumentException("策略类型 '" + type + "' 已注册,不可重复注册");
		}

		// 存入工厂:固定返回当前策略实例
		strategyFactories.put(type, () -> strategy);
	}

	/**
	 * 注册策略工厂:每次获取创建新实例(原型策略)
	 * 适用于每次构建都需要新策略对象的场景
	 * @param type 策略类型
	 * @param factory 策略工厂(创建新实例)
	 */
	public void registerStrategy(String type, Supplier<FlowGraphBuildingStrategy> factory) {
		if (type == null || type.trim().isEmpty()) {
			throw new IllegalArgumentException("策略类型不能为空");
		}
		if (factory == null) {
			throw new IllegalArgumentException("策略工厂不能为空");
		}
		if (strategyFactories.containsKey(type)) {
			throw new IllegalArgumentException("策略类型 '" + type + "' 已注册");
		}
		strategyFactories.put(type, factory);
	}

	/**
	 * 创建策略实例:调用工厂生成新的策略对象
	 * 内置策略:每次返回新实例
	 * 手动注册实例:每次返回同一实例
	 */
	public FlowGraphBuildingStrategy createStrategy(String type) {
		if (type == null || type.trim().isEmpty()) {
			throw new IllegalArgumentException("策略类型不能为空");
		}

		Supplier<FlowGraphBuildingStrategy> factory = strategyFactories.get(type);
		if (factory == null) {
			throw new IllegalArgumentException("未找到策略类型: " + type);
		}

		// 执行工厂方法,创建/获取策略实例
		return factory.get();
	}

	/**
	 * 获取策略实例(别名方法,底层调用 createStrategy)
	 */
	public FlowGraphBuildingStrategy getStrategy(String type) {
		return createStrategy(type);
	}

	/**
	 * 判断指定类型的策略是否已注册
	 */
	public boolean hasStrategy(String type) {
		return type != null && strategyFactories.containsKey(type);
	}

	/**
	 * 获取所有已注册的策略类型
	 */
	public Set<String> getRegisteredTypes() {
		return Set.copyOf(strategyFactories.keySet());
	}

	/**
	 * 注销指定策略(主要用于测试)
	 */
	public Supplier<FlowGraphBuildingStrategy> unregisterStrategy(String type) {
		return strategyFactories.remove(type);
	}

	/**
	 * 清空所有策略(主要用于测试)
	 */
	public void clear() {
		strategyFactories.clear();
	}

	/**
	 * 注册框架【内置默认策略】
	 * 所有官方 FlowAgent 对应的图构建策略,都在这里初始化
	 * 采用 工厂方法::new 模式,每次创建新实例
	 */
	private void registerDefaultStrategies() {
		registerStrategy(FlowAgentEnum.SEQUENTIAL.getType(), SequentialGraphBuildingStrategy::new);
		registerStrategy(FlowAgentEnum.ROUTING.getType(), RoutingGraphBuildingStrategy::new);
		registerStrategy(FlowAgentEnum.PARALLEL.getType(), ParallelGraphBuildingStrategy::new);
		registerStrategy(FlowAgentEnum.CONDITIONAL.getType(), ConditionalGraphBuildingStrategy::new);
		registerStrategy(FlowAgentEnum.LOOP.getType(), LoopGraphBuildingStrategy::new);
	}
}

注册中心初始化时,自动注册 5 种官方策略

  1. SEQUENTIALSequentialGraphBuildingStrategy(顺序)
  2. ROUTINGRoutingGraphBuildingStrategy(路由)
  3. PARALLELParallelGraphBuildingStrategy(并行)
  4. LOOPLoopGraphBuildingStrategy(循环)
  5. CONDITIONALConditionalGraphBuildingStrategy(条件分支)

3.4.2 SequentialGraphBuildingStrategy

【顺序执行图构建策略】实现线性顺序执行流程,子智能体按添加顺序串联,前一个执行完成 → 后一个执行。

java 复制代码
public class SequentialGraphBuildingStrategy extends AbstractFlowGraphBuildingStrategy {

	/**
	 * 【核心】构建顺序图的核心逻辑
	 */
	@Override
	protected void buildCoreGraph(FlowGraphBuilder.FlowGraphConfig config)
			throws GraphStateException {
		// 1. 专属校验:至少1个子智能体
		validateSequentialConfig(config);

		// 2. 定义顺序流程入口:根智能体名称
		String sequentialStartNode = getRootAgent().name();

		// 3. 添加【透明节点】作为流程入口(无业务逻辑,仅做流转)
		this.graph.addNode(sequentialStartNode, node_async(new TransparentNode()));

		// 4. 连接前置钩子(如果有)到入口节点
		if (!this.beforeModelHooks.isEmpty()) {
			connectBeforeModelHookEdges(this.graph, sequentialStartNode, this.beforeModelHooks);
		}

		// 5. 🌟 核心:线性串联所有子智能体
		Agent currentAgent = getRootAgent();
		for (Agent subAgent : config.getSubAgents()) {
			// 添加子智能体节点
			FlowGraphBuildingStrategy.addSubAgentNode(subAgent, this.graph);
			// 建立边:前一个节点 → 当前子节点
			this.graph.addEdge(currentAgent.name(), subAgent.name());
			// 移动指针,继续串联
			currentAgent = subAgent;
		}

		// 6. 连接后置钩子(如果有)
		String finalNode;
		if (!this.afterModelHooks.isEmpty()) {
			finalNode = connectAfterModelHookEdges(this.graph, currentAgent.name(), this.afterModelHooks);
		} else {
			finalNode = currentAgent.name();
		}

		// 7. 最后一个节点连接到出口节点,结束流程
		this.graph.addEdge(finalNode, this.exitNode);
	}

	/**
	 * 重写:空实现(顺序策略已在核心方法中处理钩子,避免重复连接)
	 */
	@Override
	protected void connectBeforeModelHooks() throws GraphStateException {
	}

	/**
	 * 重写:空实现(顺序策略已在核心方法中处理钩子,避免重复连接)
	 */
	@Override
	protected void connectAfterModelHooks() throws GraphStateException {
	}

	/**
	 * 返回策略类型:sequential
	 */
	@Override
	public String getStrategyType() {
		return FlowAgentEnum.SEQUENTIAL.getType();
	}

	/**
	 * 扩展校验:父类通用校验 + 顺序专属校验
	 */
	@Override
	public void validateConfig(FlowGraphBuilder.FlowGraphConfig config) {
		super.validateConfig(config);
		validateSequentialConfig(config);
	}

	/**
	 * 顺序流程专属校验规则
	 */
	private void validateSequentialConfig(FlowGraphBuilder.FlowGraphConfig config) {
		// 必须至少有一个子智能体
		if (config.getSubAgents() == null || config.getSubAgents().isEmpty()) {
			throw new IllegalArgumentException("顺序流程至少需要一个子智能体");
		}
		// 根节点必须是 FlowAgent
		if (!(config.getRootAgent() instanceof FlowAgent)) {
			throw new IllegalArgumentException("顺序流程的根节点必须是 FlowAgent");
		}
	}

}

3.5 构建完成

所有智能体都是通过对应的 GraphBuildingStrategy 策略类进行构建,SequentialGraphBuildingStrategy 中的核心流程:

  1. 专属校验:至少1个子智能体
  2. 定义顺序流程入口:根智能体名称
  3. 添加【透明节点】作为流程入口(无业务逻辑,仅做流转)
  4. 连接前置钩子(如果有)到入口节点
  5. 🌟 核心:线性串联所有子智能体
  6. 连接后置钩子(如果有)
  7. 最后一个节点连接到出口节点,结束流程
java 复制代码
	/**
	 * 【核心】构建顺序图的核心逻辑
	 */
	@Override
	protected void buildCoreGraph(FlowGraphBuilder.FlowGraphConfig config)
			throws GraphStateException {
		// 1. 专属校验:至少1个子智能体
		validateSequentialConfig(config);

		// 2. 定义顺序流程入口:根智能体名称
		String sequentialStartNode = getRootAgent().name();

		// 3. 添加【透明节点】作为流程入口(无业务逻辑,仅做流转)
		this.graph.addNode(sequentialStartNode, node_async(new TransparentNode()));

		// 4. 连接前置钩子(如果有)到入口节点
		if (!this.beforeModelHooks.isEmpty()) {
			connectBeforeModelHookEdges(this.graph, sequentialStartNode, this.beforeModelHooks);
		}

		// 5. 🌟 核心:线性串联所有子智能体
		Agent currentAgent = getRootAgent();
		for (Agent subAgent : config.getSubAgents()) {
			// 添加子智能体节点
			FlowGraphBuildingStrategy.addSubAgentNode(subAgent, this.graph);
			// 建立边:前一个节点 → 当前子节点
			this.graph.addEdge(currentAgent.name(), subAgent.name());
			// 移动指针,继续串联
			currentAgent = subAgent;
		}

		// 6. 连接后置钩子(如果有)
		String finalNode;
		if (!this.afterModelHooks.isEmpty()) {
			finalNode = connectAfterModelHookEdges(this.graph, currentAgent.name(), this.afterModelHooks);
		} else {
			finalNode = currentAgent.name();
		}

		// 7. 最后一个节点连接到出口节点,结束流程
		this.graph.addEdge(finalNode, this.exitNode);
	}

最终图可视化如下:

相关推荐
Xingxing?!1 小时前
Java 后端分层架构详解
java·架构·状态模式
搞科研的小刘选手1 小时前
【机器人方向研讨会】第五届控制工程与机器人技术国际研讨会(ISCER 2026)
人工智能·机器学习·机器人·自动化·人机交互·无人机·控制工程
knight_9___1 小时前
RAG面试篇6
人工智能·python·机器学习·agent·rag
阿杰学AI1 小时前
AI核心知识138—大语言模型之 数据墙危机(简洁且通俗易懂版)
人工智能·机器学习·ai·语言模型·合成数据·数据墙危机·data wall
我的世界洛天依2 小时前
洛天依讲编程:调音教学・高级班网易云音乐工作室专篇|声线绘制 + 音频转 MIDI 实操
人工智能
_Evan_Yao2 小时前
对话的边界:HTTP 的克制,SSE 的流淌,WebSocket 的自由
java·后端·websocket·网络协议·http
陶陶然Yay2 小时前
神经网络常见层Numpy封装参考(6):卷积层
人工智能·神经网络·numpy
Raink老师2 小时前
【AI面试临阵磨枪】OpenClaw Skill 如何嵌入 Harness 约束:参数校验、超时、权限、熔断?
人工智能·ai 面试
危桥带雨2 小时前
FLASH代码部分
java·后端·spring