Spring AI Alibaba 源码学习

Spring AI Alibaba 源码学习 05:Agent Framework 工作原理与使用

从 Graph Runtime 转向 Agent Framework,了解 ReAct、编排方式及 Hook、Interceptor 和 Tool 的用法。

前四讲已经介绍 Graph 的定义、执行、状态与 Store。本讲转向 Agent Framework:先看 Agent 如何创建和执行 Graph,再认识 ReAct 循环以及 Hook、Interceptor、Tool 等扩展入口。

概述

Spring AI Alibaba Agent Framework 建立在 Graph Runtime 之上,面向 Java 开发者提供基于 ReAct(Reasoning + Acting)的 Agent 开发能力。它支持构建、编排和部署 AI Agent,也提供多 Agent 编排和上下文工程等功能。

整体架构

Agent Framework 采用分层架构设计:

  1. Agent 基类层:Agent 提供所有 Agent 的通用能力。

  2. BaseAgent 抽象层:BaseAgent 提供输入输出管理和节点转换能力。

  3. 具体实现层:

    • ReactAgent:实现 ReAct 模式的单 Agent。
    • FlowAgent 系列:实现多 Agent 编排(Sequential、Parallel、Loop、Routing)。
    • A2aRemoteAgent:实现 Agent-to-Agent 远程调用。
  4. 扩展机制层:

    • Hook:在 Agent 执行的关键点插入自定义逻辑。
    • Interceptor:拦截和修改模型调用、工具调用。
    • Tool:扩展 Agent 的能力。

工作原理

ReAct 模式

ReactAgent 实现了经典的 ReAct(Reasoning + Acting)模式:

  1. Reasoning(推理):LLM节点分析当前状态,决定下一步行动;
  2. Acting(行动):根据决策执行工具调用;
  3. Observing(观察):收集工具执行结果,更新状态;
  4. 循环:重复上述过程,直到达到终止条件;

Graph 执行流程

Agent Framework 基于 Graph Runtime 执行:

public abstract class Agent {

	/** The agent's name. Must be a unique identifier within the graph. */
	protected String name;

	/**
	 * One line description about the agent's capability. The system can use this for
	 * decision-making when delegating control to different agents.
	 */
	protected String description;

	protected CompileConfig compileConfig;

	protected volatile CompiledGraph compiledGraph;

	protected volatile StateGraph graph;

	/**
	 * Protected constructor for initializing all base agent properties.
	 * @param name the unique name of the agent
	 * @param description the description of the agent's capability
	 */
	protected Agent(String name, String description) throws GraphStateException {
		this.name = name;
		this.description = description;
	}

	/**
	 * Default protected constructor for subclasses that need to initialize properties
	 * differently.
	 */
	protected Agent() {
		// Allow subclasses to initialize properties through other means
	}

	/**
	 * Gets the agent's unique name.
	 * @return the unique name of the agent.
	 */
	public String name() {
		return name;
	}

	/**
	 * Gets the one-line description of the agent's capability.
	 * @return the description of the agent.
	 */
	public String description() {
		return description;
	}

	public StateGraph getGraph() {
		if (this.graph == null) {
			try {
				this.graph = initGraph();
			}
			catch (GraphStateException e) {
				throw new RuntimeException(e);
			}
		}
		return this.graph;
	}

	public synchronized CompiledGraph getAndCompileGraph() {
		if (compiledGraph != null) {
			return compiledGraph;
		}

		StateGraph graph = getGraph();
		try {
			if (this.compileConfig == null) {
				this.compiledGraph = graph.compile();
			}
			else {
				this.compiledGraph = graph.compile(this.compileConfig);
			}
		} catch (GraphStateException e) {
			throw new RuntimeException(e);
		}
		return this.compiledGraph;
	}

执行流程:

  1. 初始化Graph:调用initGraph()创建状态图;
  2. 编译Graph:将状态图编译为可执行的CompiledGraph;
  3. 执行Graph:通过invoke()或stream()方法执行;
  4. 状态管理:使用OverAllState在节点间传递数据;

使用示例

ReactAgent 基本使用

// 1. 创建 ReactAgent Builder
ReactAgent agent = ReactAgent.builder()
    .name("assistant")
    .description("A helpful assistant")
    .instruction("You are a helpful assistant.")
    .chatModel(chatModel)  // 设置 LLM 模型
    .tools(tools)          // 设置工具列表
    .maxIterations(10)     // 设置最大迭代次数
    .build();

// 2. 同步调用
AssistantMessage response = agent.call("What's the weather today?");

// 3. 流式调用
Flux<NodeOutput> stream = agent.stream("Tell me a story");
stream.subscribe(output -> {
    // 处理流式输出
});

FlowAgent 使用示例

// 1. 创建 SequentialAgent(顺序执行)
SequentialAgent sequentialAgent = SequentialAgent.builder()
    .name("sequential")
    .agents(agent1, agent2, agent3)
    .build();

// 2. 创建 ParallelAgent(并行执行)
ParallelAgent parallelAgent = ParallelAgent.builder()
    .name("parallel")
    .agents(agent1, agent2, agent3)
    .build();

// 3. 创建 LoopAgent(循环执行)
LoopAgent loopAgent = LoopAgent.builder()
    .name("loop")
    .agent(agent)
    .loopStrategy(new CountLoopStrategy(5))
    .build();

// 4. 创建 RoutingAgent(路由选择)
LlmRoutingAgent routingAgent = LlmRoutingAgent.builder()
    .name("routing")
    .agents(agent1, agent2, agent3)
    .chatModel(chatModel)
    .build();

Hook 使用示例

// 创建 HumanInTheLoop Hook
HumanInTheLoopHook hook = HumanInTheLoopHook.builder()
    .name("human-feedback")
    .interactionHandler(new ConsoleInteractionHandler())
    .build();

// 添加到 ReactAgent
ReactAgent agent = ReactAgent.builder()
    .name("assistant")
    .chatModel(chatModel)
    .tools(tools)
    .hooks(hook)  // 添加 Hook
    .build();

Interceptor 使用示例

// 创建 Model Fallback Interceptor
ModelFallbackInterceptor fallbackInterceptor = ModelFallbackInterceptor.builder()
    .primaryModel(primaryModel)
    .fallbackModel(fallbackModel)
    .build();

// 创建 Tool Retry Interceptor
ToolRetryInterceptor retryInterceptor = ToolRetryInterceptor.builder()
    .maxRetries(3)
    .build();

// 添加到 ReactAgent
ReactAgent agent = ReactAgent.builder()
    .name("assistant")
    .chatModel(chatModel)
    .tools(tools)
    .modelInterceptors(fallbackInterceptor)  // 添加 Model Interceptor
    .toolInterceptors(retryInterceptor)     // 添加 Tool Interceptor
    .build();

Tool 扩展示例

// 1. 实现自定义 Tool
@Bean
public Function<String, String> weatherTool() {
    return (location) -> {
        // 调用天气 API
        return "Sunny, 25°C";
    };
}

// 2. 注册为 Spring AI Tool
@Bean
public Tool weatherToolBean() {
    return Tool.builder()
        .name("get_weather")
        .description("Get weather for a location")
        .function("weatherTool")
        .build();
}

// 3. 在 ReactAgent 中使用
ReactAgent agent = ReactAgent.builder()
    .name("assistant")
    .chatModel(chatModel)
    .tools(weatherToolBean)  // 使用自定义工具
    .build();

核心特性

1. Context Engineering(上下文工程)

Agent Framework 自动管理对话上下文:

  • 自动维护消息历史
  • 支持多轮对话
  • 智能上下文压缩

2. Human In The Loop

通过HumanInTheLoopHook 实现:

  • 在执行关键步骤前暂停
  • 等待人工确认或输入
  • 支持继续或中断执行

3. Multi-Agent Orchestration(多 Agent 编排)

支持多种编排模式:

  • Sequential:顺序执行多个 Agent
  • Parallel:并行执行多个 Agent
  • Loop:循环执行 Agent
  • Routing:根据条件路由到不同 Agent

4. A2A(Agent-to-Agent)

支持 Agent 之间的远程调用:

  • 通过 A2aRemoteAgent 实现
  • 支持分布式 Agent 部署
  • 支持 Agent 发现和注册

最佳实践

1. Agent 设计原则

  • 单一职责:每个 Agent 专注于特定任务
  • 清晰描述:提供准确的 description 帮助路由选择
  • 合理迭代:设置合适的 maxIterations 避免无限循环

2. Tool 设计建议

  • 工具粒度:保持工具功能单一、明确
  • 错误处理:工具应妥善处理异常情况
  • 文档完善:提供清晰的工具描述和参数说明

3. Hook 使用场景

  • HumanInTheLoopHook:需要人工审核的场景
  • PIIDetectionHook:敏感信息检测和处理
  • ModelCallLimitHook:控制模型调用成本

4. Interceptor 使用场景

  • ModelFallbackInterceptor:提高系统可用性
  • ToolRetryInterceptor:提高工具调用成功率
  • ContextEditingInterceptor:动态调整上下文

注意事项

  1. 状态管理:理解OverAllState的键策略,避免状态覆盖;
  2. 异步执行:使用stream()方法实现流式响应;
  3. 错误处理:合理处理GraphRunnerException和工具调用异常;
  4. 性能优化:合理设置maxIterations和工具超时时间;
  5. 资源清理:及时释放Graph和CompiledGraph资源;

总结

本讲从 Graph Runtime 看到了 Agent Framework 的几类入口。原材料对框架特点的概括如下:

  • 易用性:简洁的 Builder API,快速上手
  • 灵活性:支持多种 Agent 类型和编排模式
  • 可扩展性:通过 Hook、Interceptor、Tool 机制轻松扩展
  • 生产就绪(原材料评价):原文据错误处理和状态管理作出这一评价,本讲未进行生产环境验证。