1. 串行执行

SequentialAgent 关键特性:

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

设计一个企业【合同标准化串行审核流程】,固定审核顺序(强串行,必须 1234):

  1. Agent1:合同基础内容校验(格式、缺失字段、必填项检查)
  2. Agent2:商务风险审核(付款周期、违约金、金额条款)
  3. Agent3:合规风控审核(违法条款、敏感用语、合规红线)
  4. Agent4:汇总生成审核报告(整合前三步结果,输出最终结论)

1.1 构建子智能体

依次创建四个子智能体:

        // 节点1:合同基础格式校验 Agent
        ReactAgent basicCheckAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("合同基础校验-Agent")
                .description("负责检查合同缺失字段、格式错误、甲乙双方信息完整性")
                .systemPrompt("你是行政专员,只做基础校验:检查合同是否缺少甲方、乙方、有效期、签字位置,只输出问题清单。")
                .build();

        // 节点2:商务条款风控 Agent
        ReactAgent businessRiskAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("商务条款审核-Agent")
                .description("审核付款方式、账期、违约金、报价合理性等商务风险")
                .systemPrompt("你是商务经理,专注审核付款周期、结算方式、违约赔偿条款,标记不合理商务条款。")
                .build();

        // 节点3:合规法律审核 Agent
        ReactAgent legalComplianceAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("合规法务审核-Agent")
                .description("排查违法违规、霸王条款、法律禁止性内容")
                .systemPrompt("你是法务专员,排查合同中的无效条款、霸王条款、不合规表述,给出合规修改建议。")
                .build();

        // 节点4:最终报告汇总 Agent
        ReactAgent reportSummaryAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("审核报告汇总-Agent")
                .description("整合前面所有审核结果,输出结构化审核结论:通过/整改/驳回")
                .systemPrompt("整合前面所有环节的审核结果,输出结构化报告,明确给出:审核结论、风险等级、修改建议。")
                .build();

1.2 串行编排

按照实际执行顺序构建子智能体集合,执行链路(完全串行):

  1. 基础校验 Agent → 识别:乙方缺失、无有效期、信息不全
  2. 商务风控 Agent → 识别:账期模糊、无违约约束、金额不明确
  3. 合规法务 Agent → 识别:单方霸王条款、合同无效风险
  4. 汇总 Agent → 输出完整审核报告 + 风险等级:驳回,需全面整改

构建 SequentialAgent 传入列表:

        // 关键:List 顺序 = 实际执行顺序,强串行
        List<Agent> subAgents = List.of(
                basicCheckAgent,
                businessRiskAgent,
                legalComplianceAgent,
                reportSummaryAgent
        );

        // 传入子智能体列表 构建 SequentialAgent
        return SequentialAgent.builder()
                .name("企业合同串行审核工作流")
                .description("基于顺序智能体,完成合同四步标准化审核")
                .subAgents(subAgents)
                .build();

1.3 单元测试

模拟一份简易商务合同,进行对话:

甲方:XX科技  乙方:
合作有效期:无固定期限
付款条款:项目完工后随意付款,无违约处罚
服务费用:暂定,后期口头协商
双方权责:甲方拥有无条件单方解约权,乙方不得提出任何异议

首先进入第一个:

在这里插入图片描述
依次进入第二个:

在这里插入图片描述

进入第三个时的消息列表:

  1. 当前子智能体的系统提示词
  2. 用户输入消息
  3. 第一个智能体返回的消息
  4. 第二个智能体返回的消息

在这里插入图片描述

1.4 指令占位符

在上面的案例中,我们没有使用不用占位符,框架只是把完整的消息列表(messages)丢给大模型,本质是多轮对话历史,依赖大模型自主解析历史,极易跑偏。在实际开发中,我们应该将使用占位符将内容嵌入到指令中,确保精准执行任务,零误解。

核心区别:

维度 仅传递消息列表(不使用占位符) 占位符嵌入指令(使用 {xx}
本质 多轮对话历史 单轮结构化任务指令
大模型理解 自主解析历史,极易跑偏 明确输入 + 任务,100% 精准
数据传递 非结构化、无固定参数 结构化、outputKey=固定参数
适用场景 闲聊、对话、记忆历史 工作流 / Agent 串行、业务任务
串行业务效果 流程隐式依赖上下文,易失效、结果不可控 强绑定上下游数据,流程通畅、执行稳定

优化,使用 outputKey 定义当前子智能体的输出键,下游智能体通过【占位符】填充结果到指令中:

        // 节点1:合同基础格式校验 Agent
        ReactAgent basicCheckAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("contract_basic_check")
                .description("校验合同必填字段、格式完整性、甲乙双方主体信息")
                // 结构化输出KEY,供下游Agent精准调用
                .outputKey("basic_check_result")
                // 保留推理过程,便于日志追踪+上下文传递
                .returnReasoningContents(true)
                // 强指令约束:输出格式固定,无冗余内容
                .instruction("""
                        你是企业行政审核专员,仅执行【合同基础格式校验】任务:
                        1. 检查:甲方信息、乙方信息、合同有效期、签章位置、合同标的是否完整
                        2. 仅输出【缺失/错误】清单,无问题则输出【基础校验通过】
                        3. 禁止输出无关内容,格式简洁规范
                        """)
                .build();

        // 节点2:商务条款风控 Agent
        ReactAgent businessRiskAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("contract_business_check")
                .description("审核付款、账期、违约金、报价等商务条款风险")
                .outputKey("business_check_result")
                .returnReasoningContents(true)
                // 占位符显式引用上游校验结果,杜绝上下文误解
                .instruction("""
                        你是企业商务经理,基于基础校验结果执行【商务条款审核】:
                        上游基础校验结果:{basic_check_result}
                        审核范围:付款方式、结算周期、违约金、报价合理性、权责对等性
                        输出要求:标记风险条款 + 风险等级 + 修改建议,无风险则输出【商务审核通过】
                        """)
                .build();
        // 节点3:合规法律审核 Agent
        ReactAgent legalComplianceAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("contract_legal_check")
                .description("法务合规审核,排查违法、霸王、无效条款")
                .outputKey("legal_check_result")
                .returnReasoningContents(true)
                .includeContents(true)
                .instruction("""
                        你是企业专职法务,基于前序审核结果执行【合规性审核】:
                        基础校验结果:{basic_check_result}
                        商务审核结果:{business_check_result}
                        审核范围:无效条款、霸王条款、违法违规表述、法律风险点
                        输出要求:列出违规条款 + 法律风险 + 强制修改建议,无风险则输出【合规审核通过】
                        """)
                .build();

        // 节点4:最终报告汇总 Agent
        ReactAgent reportSummaryAgent = ReactAgent.builder()
                .model(dashscopeChatModel)
                .name("contract_report_summary")
                .description("整合全流程审核结果,生成最终合同审核报告")
                // 最终输出KEY,业务层直接获取
                .outputKey("final_audit_report")
                .returnReasoningContents(true)
                // 结构化指令,强制输出企业标准格式
                .instruction("""
                        你是合同审核汇总专员,整合全部审核结果,生成【最终审核报告】:
                        基础校验:{basic_check_result}
                        商务校验:{business_check_result}
                        合规校验:{legal_check_result}
                        必须输出固定结构:
                        1. 审核结论:通过/整改/驳回
                        2. 风险等级:低/中/高
                        3. 问题汇总:精简罗列所有问题
                        4. 处理意见:明确修改要求
                        """)
                .build();

可以看到,输入内容被填充到了指令中:

在这里插入图片描述

在这里插入图片描述

1.5 完整执行状态

获取完整执行状态:

        Optional<OverAllState> result = sequentialAgent.invoke("帮我写一个100字左右的散文");

        if (result.isPresent()) {
            // 消息历史将包含所有工具调用和推理过程
            List<Message> messages = (List<Message>) result.get().value("messages").orElse(List.of());
            System.out.println("消息数量: " + messages.size()); // 包含所有中间步骤
        }

可以看到每个子智能体的输出内容:

在这里插入图片描述

messages 消息列表,如果是显示 AssistantMessage 的话,将会输出每个子智能体的响应内容:

在这里插入图片描述

2. 并行执行

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

核心流程:

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

设计一个【主题写作智能体】:

  1. 根据用户输入【主题】
  2. 同时执行:写散文、写现代诗、主题总结
  3. 合并结果,返回给用户

2.1 构建子智能体

        // 创建多个专业化Agent
        ReactAgent proseWriterAgent = ReactAgent.builder()
                .name("prose_writer_agent")
                .model(dashscopeChatModel)
                .description("专门写散文的AI助手")
                .instruction("你是一个知名的散文作家,擅长写优美的散文。" +
                        "用户会给你一个主题:{input},你只需要创作一篇100字左右的散文。")
                .outputKey("prose_result")
                .build();

        ReactAgent poemWriterAgent = ReactAgent.builder()
                .name("poem_writer_agent")
                .model(dashscopeChatModel)
                .description("专门写现代诗的AI助手")
                .instruction("你是一个知名的现代诗人,擅长写现代诗。" +
                        "用户会给你的主题是:{input},你只需要创作一首现代诗。")
                .outputKey("poem_result")
                .build();

        ReactAgent summaryAgent = ReactAgent.builder()
                .name("summary_agent")
                .model(dashscopeChatModel)
                .description("专门做内容总结的AI助手")
                .instruction("你是一个专业的内容分析师,擅长对主题进行总结和提炼。" +
                        "用户会给你一个主题:{input},你只需要对这个主题进行简要总结。")
                .outputKey("summary_result")
                .build();

2.2 合并策略

MergeStrategy 「并行结果合并」策略接口,定义如何执行结果的合并规则能力:

/**
 * 用于合并并行执行结果的策略接口
 */
public interface MergeStrategy {

    /**
     * 合并所有并行子代理的执行结果
     * @param subAgentResults 子代理输出键与其对应执行结果的映射集合
     * @param overallState 包含所有上下文信息的全局状态对象
     * @return 合并后的最终结果
     */
    Object merge(Map<String, Object> subAgentResults, OverAllState overallState);

}

默认提供了三种合并策略:

策略类 输出结果 适用场景
ConcatenationMergeStrategy 拼接字符串 文本汇总、日志输出、最终展示
ListMergeStrategy 不可变 List 遍历结果、二次处理、数据聚合
DefaultMergeStrategy 新 HashMap 保留键值映射、框架默认兜底

可以实现自定义的合并策略来控制如何组合多个 Agent 的输出,示例,分批计算结果然后输出累加值:

// 求和合并策略实现
public class SumMergeStrategy implements MergeStrategy {
    @Override
    public Object merge(Map<String, Object> subAgentResults, OverAllState overallState) {
        int total = 0;
        // 遍历所有子代理结果,累加数值
        for (Object result : subAgentResults.values()) {
            if (result instanceof Integer) {
                total += (Integer) result;
            }
        }
        return total;
    }
}

2.3 串行编排

并行中无需考虑子智能体的位置,全部传入即可,这里使用默认的合并策略:

        // 创建并行Agent
        ParallelAgent parallelAgent = ParallelAgent.builder()
                .name("parallel_creative_agent")
                .description("并行执行多个创作任务,包括写散文、写诗和做总结")
                .mergeOutputKey("merged_results")
                .subAgents(List.of(proseWriterAgent, poemWriterAgent, summaryAgent))
                .mergeStrategy(new ParallelAgent.DefaultMergeStrategy())
                .build();

2.4 查看完整执行状态

查看完整执行状态:

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

注意messages 消息列表中只有输入消息,输出需要从 merged_results 中获取:

在这里插入图片描述

3. 构建流程(SequentialAgent)

在这里插入图片描述

3.1 构建入口

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

/**
 * 【模板方法】构建具体的 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 构造函数:

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

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

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

	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 构造函数中都是调用的父类的构造进行初始化:

	protected SequentialAgent(SequentialAgentBuilder builder) {
		super(builder.name, builder.description, builder.compileConfig, builder.subAgents, builder.stateSerializer, builder.executor, builder.hooks);
	}
	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):

/**
 * 重写父类方法:初始化状态图(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);
}

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

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

3.4 图构建器

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

/**
 * 流图构建器(统一调度器)
 * 所有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. 单例全局唯一,统一管理所有策略

/**
 * 【流图构建策略注册中心】
 * 负责所有 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

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

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. 最后一个节点连接到出口节点,结束流程
	/**
	 * 【核心】构建顺序图的核心逻辑
	 */
	@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);
	}

最终图可视化如下:

在这里插入图片描述

Logo

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

更多推荐