一、AgentBuilderFactory

1、抽象定义

/**
 * agent创建工厂
 */
public interface AgentBuilderFactory {
    
    Builder builder();
}

2、具体实现

AgentBuilderFactory目前总共有三个实现类,三个实现类最后创建的都是ReactAgent

DefaultAgentBuilderFactory

/**
 * 默认创建工厂
 */
public class DefaultAgentBuilderFactory implements AgentBuilderFactory {
    
    @Override
    public Builder builder() {
        return new DefaultBuilder();
    }
}

NacosAgentPromptBuilderFactory

/**
 * NacosAgentFactory
 */
public class NacosAgentPromptBuilderFactory implements AgentBuilderFactory {

	private NacosOptions nacosOptions;

	public NacosAgentPromptBuilderFactory(NacosOptions nacosOptions) {
		this.nacosOptions = nacosOptions;
	}

	@Override
	public Builder builder() {
		return new NacosAgentPromptBuilder().nacosOptions(this.nacosOptions);
	}
}

NacosAgentBuilderFactory

/**
 * NacosAgentFactory
 */
public class NacosAgentBuilderFactory implements AgentBuilderFactory {

	private NacosOptions nacosOptions;

	public NacosAgentBuilderFactory(NacosOptions nacosOptions) {
		this.nacosOptions = nacosOptions;
	}

	@Override
	public Builder builder() {
		return new NacosReactAgentBuilder().nacosOptions(this.nacosOptions);
	}
}

NacosAgentPromptBuilderFactory和NacosAgentBuilderFactory的区别是什么?

二、Builder

1、抽象定义

public abstract class Builder {
    //...其他参数...//

    // 核心参数

    /**
	 * Agent名称
	 */
	protected String name;

    /**
	 * 系统提示词
	 */
	protected String systemPrompt;

    /**
	 * Agent使用模型
	 */
	protected ChatModel model;

    /**
	 * 模型参数
	 */
	protected ChatOptions chatOptions;

    /**
	 * 检查点保存器(不知道有什么用)
	 */
	protected BaseCheckpointSaver saver;

    /**
	 * 拦截器集合
	 * 目前拦截器主要分为三大类
	 * 1、ModelInterceptor:可以包装模型调用的模型拦截器。
	 * 2、ToolInterceptor:可以包装工具调用的工具拦截器。
	 * 3、ContextEditingInterceptor:上下文编辑拦截器,当对话超出可配置的标记阈值时,会清除较早的工具结果。
	 */
	protected List<Interceptor> interceptors;

    /**
	 * 输出key(不知道有什么用)
	 */
	protected String outputKey;

    /**
	 * 输出策略
	 */
	protected String outputSchema;
    
    /**
	 * 输出表单,自定义输出文本格式
	 */
	protected Class<?> outputType;

    //...其他方法...//
}

2、具体实现

DefaultBuilder

/**
 * ReactAgent 的默认构建器实现类
 *
 * 这个类负责构建和配置 ReactAgent 实例,整合了客户端、工具、拦截器等组件,
 * 提供了完整的 ReAct 代理构建流程。它继承自 Builder 基类,实现了具体的构建逻辑。
 */
public class DefaultBuilder extends Builder {

	/**
	 * 构建 ReactAgent 实例的核心方法
	 *
	 * 该方法执行以下主要步骤:
	 * 1. 配置客户端(ChatClient)
	 * 2. 构建 LLM 节点(AgentLlmNode)
	 * 3. 配置输出模式和类型转换
	 * 4. 处理拦截器并分类
	 * 5. 整合所有工具(包括拦截器提供的工具)
	 * 6. 构建工具节点(AgentToolNode)
	 * 7. 创建并返回完整的 ReactAgent 实例
	 *
	 * @return ReactAgent 完全配置的 ReactAgent 实例
	 * @throws GraphStateException 当图状态配置错误时抛出
	 * @throws IllegalArgumentException 当必要的参数(如 chatClient 或 model)缺失时抛出
	 */
	@Override
	public ReactAgent build() throws GraphStateException {

		// ==================== 第一步:客户端配置 ====================
		// 如果未提供 chatClient,则根据 model 创建默认的 ChatClient
		if (chatClient == null) {
			// 安全检查:必须提供 model
			if (model == null) {
				throw new IllegalArgumentException("Either chatClient or model must be provided");
			}

			// 构建 ChatClient 建造器,设置模型和可观察性注册表
			ChatClient.Builder clientBuilder = ChatClient.builder(model, this.observationRegistry == null ? ObservationRegistry.NOOP : this.observationRegistry,
					this.customObservationConvention);

			// 配置选项(如温度、最大token数等)
			if (chatOptions != null) {
				clientBuilder.defaultOptions(chatOptions);
			}

			// 配置系统提示词
			if (systemPrompt != null) {
				clientBuilder.defaultSystem(systemPrompt);
			}

			// 构建最终的 ChatClient 实例
			chatClient = clientBuilder.build();
		}

		// ==================== 第二步:LLM 节点构建 ====================
		// 创建 AgentLlmNode 建造器并设置客户端
		AgentLlmNode.Builder llmNodeBuilder = AgentLlmNode.builder().chatClient(chatClient);

		// 配置输出键(用于在响应中标识输出内容)
		if (outputKey != null && !outputKey.isEmpty()) {
			llmNodeBuilder.outputKey(outputKey);
		}

		// ==================== 第三步:输出模式配置 ====================
		// 处理输出模式配置,支持直接提供模式字符串或通过输出类型自动生成
		String outputSchema = null;
		if (StringUtils.hasLength(this.outputSchema) ) {
			// 如果直接提供了输出模式字符串,则使用它
			outputSchema = this.outputSchema;
		} else if (this.outputType != null) {
			// 如果提供了输出类型,则通过 BeanOutputConverter 自动生成模式
			FormatProvider formatProvider = new BeanOutputConverter<>(this.outputType);
			outputSchema = formatProvider.getFormat();
		}

		// 如果配置了输出模式,则设置到 LLM 节点
		if (StringUtils.hasLength(outputSchema)) {
			llmNodeBuilder.outputSchema(outputSchema);
		}

		// ==================== 第四步:拦截器处理 ====================
		// 将统一的拦截器按照类型进行分类:模型拦截器和工具拦截器
		if (CollectionUtils.isNotEmpty(interceptors)) {
			modelInterceptors = new ArrayList<>();
			toolInterceptors = new ArrayList<>();

			// 遍历所有拦截器,按类型分类
			for (Interceptor interceptor : interceptors) {
				if (interceptor instanceof ModelInterceptor) {
					modelInterceptors.add((ModelInterceptor) interceptor);
				}
				if (interceptor instanceof ToolInterceptor) {
					toolInterceptors.add((ToolInterceptor) interceptor);
				}
			}
		}

		// ==================== 第五步:工具整合 ====================
		// 收集来自不同来源的工具:
		// - regularTools: 用户直接提供的工具
		// - interceptorTools: 从拦截器中提取的工具
		List<ToolCallback> regularTools = new ArrayList<>();

		// 从用户提供的工具列表中提取常规工具
		if (CollectionUtils.isNotEmpty(tools)) {
			regularTools.addAll(tools);
		}

		// 从模型拦截器中提取工具
		List<ToolCallback> interceptorTools = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(modelInterceptors)) {
			interceptorTools = modelInterceptors.stream()
					.flatMap(interceptor -> interceptor.getTools().stream())
					.collect(Collectors.toList());
		}

		// 合并所有工具:拦截器工具 + 常规工具
		// 注意:拦截器工具在前,确保拦截器工具优先被使用
		List<ToolCallback> allTools = new ArrayList<>();
		allTools.addAll(interceptorTools);
		allTools.addAll(regularTools);

		// 将合并后的所有工具设置到 LLM 节点
		if (CollectionUtils.isNotEmpty(allTools)) {
			llmNodeBuilder.toolCallbacks(allTools);
		}

		// 构建最终的 LLM 节点
		AgentLlmNode llmNode = llmNodeBuilder.build();

		// ==================== 第六步:工具节点构建 ====================
		// 构建工具节点,支持三种配置方式(按优先级):
		// 1. 使用自定义的工具解析器(最高优先级)
		// 2. 使用合并后的所有工具列表
		// 3. 创建空工具节点(最低优先级)
		AgentToolNode toolNode = null;
		if (resolver != null) {
			// 方式1:使用自定义工具解析器
			toolNode = AgentToolNode.builder().toolCallbackResolver(resolver).build();
		}
		else if (CollectionUtils.isNotEmpty(allTools)) {
			// 方式2:使用合并后的工具列表
			toolNode = AgentToolNode.builder().toolCallbacks(allTools).build();
		}
		else {
			// 方式3:创建空工具节点
			toolNode = AgentToolNode.builder().build();
		}

		// ==================== 第七步:创建 ReactAgent 实例 ====================
		// 使用配置好的 LLM 节点、工具节点和构建配置创建最终的 ReactAgent 实例
		return new ReactAgent(llmNode, toolNode, buildConfig(), this);
	}

}

NacosAgentPromptBuilder

NacosReactAgentBuilder

三、初始化流程图

  1. 通过ReactAgent.builder()创建DefaultBuilder
  2. 设置配置属性
  3. 调用build()方法创建AgentLlmNodeAgentToolNode
  4. 通过ReactAgent构造函数创建最终的ReactAgent实例
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐