Spring AI Alibaba 使用指南
Spring AI Alibaba 1.1 正式发布!
构建 Agent 智能体应用最简单的方式,只需不到 10 行代码就可以构建您的智能体应用。
官方文档:https://java2ai.com/docs/overview
目录
- 一、简介
- 二、架构概述
- 三、快速开始
- 四、核心概念
- [五、ReactAgent 详解](#五、ReactAgent 详解)
- [六、工具调用(Function Calling)](#六、工具调用(Function Calling))
- 七、多代理编排
- 八、上下文工程
- 九、人机协同
- 十、最佳实践
- 十一、常见问题
- 十二、参考资源
一、简介
1.1 什么是 Spring AI Alibaba?
Spring AI Alibaba 是构建 Agent 智能体应用最简单的方式,基于 Spring AI 框架构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践。
1.2 核心特性
- ✅ 简单易用:只需不到 10 行代码就可以构建智能体应用
- ✅ ReAct 范式:遵循推理+行动(Reasoning + Acting)范式,用于迭代解决问题
- ✅ 多代理编排:支持顺序、并行、路由、循环等多种代理组合模式
- ✅ 丰富的模型支持:支持 DashScope、DeepSeek、智谱AI、OpenAI 等多种 LLM 提供程序
- ✅ 工具调用:支持函数调用(Function Calling)和模型上下文协议(MCP)
- ✅ 流式传输:支持代理响应的实时流式传输
- ✅ 错误处理:强大的错误恢复和重试机制
- ✅ 基于图的工作流:支持条件路由、嵌套图、并行执行和状态管理
二、架构概述
Spring AI Alibaba 项目从架构上包含如下三层:
2.1 Agent Framework(智能体框架)
核心组件 :ReactAgent
- 以 ReactAgent 设计理念为核心的 Agent 开发框架
- 使开发者能够构建具备自动上下文工程和人机交互等核心能力的 Agent
- 推荐使用
ReactAgent快速构建 Agent 应用
2.2 Graph(图工作流)
核心组件 :Graph、CompiledGraph
- 低级别的工作流和多代理协调框架
- 能够帮助开发者实现复杂的应用程序编排
- 具备丰富的预置节点和简化的图状态定义
- Graph 是 Agent Framework 的底层运行时基座
- 适用于需要超高可靠性、大量自定义逻辑、需要精确控制延迟的场景
2.3 Augmented LLM(增强 LLM)
核心组件:基于 Spring AI 框架的底层原子抽象
- 为构建大型语言模型(LLM)应用提供基础抽象
- 包括:模型(Model)、工具(Tool)、多模态组件(MCP)、消息(Message)、向量存储(Vector Store)等
2.4 设计原则
- 推荐使用 Agent Framework :使用
ReactAgent快速构建 Agent 应用 - 多代理组合 :使用
SequentialAgent、ParallelAgent、RoutingAgent、LoopAgent等基础多智能体工作流模式 - 直接使用 Graph API:适用于需要更灵活的编排、更直接的状态控制的场景
三、快速开始
3.1 添加依赖
在 pom.xml 中添加以下依赖:
xml
<properties>
<spring-ai.version>1.1.2</spring-ai.version>
<jackson.version>2.17.0</jackson.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring AI BOM -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 统一 Jackson 版本(避免版本冲突) -->
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>${jackson.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring AI Alibaba Agent Framework -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-agent-framework</artifactId>
<version>1.1.0.0-RC2</version>
<exclusions>
<!-- 排除可能冲突的 Jackson 依赖,使用统一版本 -->
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 显式引入统一版本的 Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- 选择您需要的模型 Starter(按需引入) -->
<!-- DeepSeek -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>
<!-- 智谱AI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
<!-- DashScope(阿里云通义) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>1.1.0.0-RC2</version>
</dependency>
</dependencies>
3.2 配置模型 API Key
在 application.yml 中配置:
yaml
spring:
ai:
# DeepSeek 配置
deepseek:
api-key: your-deepseek-api-key
base-url: https://api.deepseek.com/chat/completions
# 智谱AI 配置
zhipuai:
api-key: your-zhipuai-api-key
base-url: https://open.bigmodel.cn/api/paas/v4
# DashScope 配置(阿里云通义)
dashscope:
api-key: your-dashscope-api-key
3.3 创建第一个 Agent
java
package com.ygl.base;
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import com.alibaba.cloud.ai.graph.exception.GraphRunnerException;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.deepseek.api.DeepSeekApi;
public class SimpleAgentExample {
public static void main(String[] args) throws GraphRunnerException {
// 1. 创建模型实例
DeepSeekApi deepSeekApi = DeepSeekApi.builder()
.apiKey("your-api-key")
.build();
DeepSeekChatModel chatModel = DeepSeekChatModel.builder()
.deepSeekApi(deepSeekApi)
.build();
// 2. 创建 Agent
ReactAgent agent = ReactAgent.builder()
.name("simple_agent")
.model(chatModel)
.systemPrompt("You are a helpful assistant.")
.saver(new MemorySaver()) // 使用内存保存对话历史
.build();
// 3. 运行 Agent
AssistantMessage response = agent.call("你好,介绍一下你自己");
System.out.println(response.getText());
}
}
运行结果:
你好!我是一个AI助手,基于Spring AI Alibaba框架构建。我可以帮助你解答问题、提供信息、协助完成任务等。有什么我可以帮助你的吗?
四、核心概念
4.1 ReactAgent(推理-行动代理)
ReactAgent 是 Spring AI Alibaba 的核心抽象,遵循 ReAct(Reasoning + Acting)范式:
- 推理(Reasoning):分析问题,决定下一步行动
- 行动(Acting):执行工具调用或生成回答
- 观察(Observation):观察行动结果,继续推理
4.2 工具(Tool)
工具是 Agent 可以调用的函数,用于执行具体任务:
- Function Tool:Java 函数包装为工具
- HTTP Tool:HTTP API 包装为工具
- MCP Tool:模型上下文协议工具
4.3 上下文(Context)
- 对话历史:Agent 与用户的对话记录
- 工具调用历史:已执行的工具调用及其结果
- 系统提示:Agent 的角色和行为定义
4.4 检查点(Checkpoint)
用于保存和恢复 Agent 的状态:
- MemorySaver:内存保存(开发测试用)
- RedisSaver:Redis 保存(生产环境推荐)
- DatabaseSaver:数据库保存
五、ReactAgent 详解
5.1 ReactAgent.Builder API
5.1.1 完整 API 列表
java
ReactAgent.Builder builder = ReactAgent.builder();
// 必需配置
builder.name(String name) // Agent 名称(必需)
.model(ChatModel model) // LLM 模型实例(必需)
// 提示词配置
builder.systemPrompt(String systemPrompt) // 系统提示词
.instruction(String instruction) // 额外指令
// 工具配置
builder.tools(ToolCallback... tools) // 可变参数:添加工具
.tools(List<ToolCallback> tools) // 列表方式:添加工具
// 检查点配置
builder.saver(CheckpointSaver saver) // 检查点保存器
// 执行控制
builder.maxIterations(int maxIterations) // 最大迭代次数(默认 10)
.maxExecutionTime(Duration duration) // 最大执行时间
// 构建
ReactAgent agent = builder.build();
5.1.2 方法详解
name(String name)
设置 Agent 名称,用于标识和日志记录。
java
ReactAgent agent = ReactAgent.builder()
.name("weather_agent") // Agent 名称
.model(chatModel)
.build();
参数:
name:Agent 名称(String,必需)
返回 :ReactAgent.Builder
model(ChatModel model)
设置使用的 LLM 模型实例。
java
DeepSeekChatModel chatModel = DeepSeekChatModel.builder()
.deepSeekApi(deepSeekApi)
.build();
ReactAgent agent = ReactAgent.builder()
.model(chatModel) // 设置模型
.build();
参数:
model:ChatModel 实例(必需,支持 DeepSeekChatModel、DashScopeChatModel、ZhiPuAiChatModel 等)
返回 :ReactAgent.Builder
systemPrompt(String systemPrompt)
设置系统提示词,定义 Agent 的角色和行为。
java
ReactAgent agent = ReactAgent.builder()
.systemPrompt("""
You are a helpful assistant that specializes in answering questions.
Always provide accurate and detailed information.
""")
.build();
参数:
systemPrompt:系统提示词(String,可选)
返回 :ReactAgent.Builder
instruction(String instruction)
设置额外指令,用于补充系统提示词。
java
ReactAgent agent = ReactAgent.builder()
.systemPrompt("You are a helpful assistant.")
.instruction("Always be polite and concise.") // 额外指令
.build();
参数:
instruction:指令文本(String,可选)
返回 :ReactAgent.Builder
tools(ToolCallback... tools) / tools(List<ToolCallback> tools)
添加工具到 Agent,支持可变参数或列表方式。
java
// 方式1:可变参数
ReactAgent agent = ReactAgent.builder()
.tools(tool1, tool2, tool3) // 可变参数
.build();
// 方式2:列表
List<ToolCallback> tools = Arrays.asList(tool1, tool2, tool3);
ReactAgent agent = ReactAgent.builder()
.tools(tools) // 列表方式
.build();
参数:
tools:工具列表(可变参数或 List,可选)
返回 :ReactAgent.Builder
saver(CheckpointSaver saver)
设置检查点保存器,用于保存和恢复 Agent 状态。
java
// 内存保存(开发测试用)
ReactAgent agent = ReactAgent.builder()
.saver(new MemorySaver())
.build();
// Redis 保存(生产环境推荐)
RedisSaver redisSaver = RedisSaver.builder()
.redisTemplate(redisTemplate)
.build();
ReactAgent agent = ReactAgent.builder()
.saver(redisSaver)
.build();
参数:
saver:检查点保存器(CheckpointSaver,可选)
返回 :ReactAgent.Builder
支持的保存器:
MemorySaver:内存保存(开发测试用)RedisSaver:Redis 保存(生产环境推荐)DatabaseSaver:数据库保存
maxIterations(int maxIterations)
设置最大迭代次数,防止 Agent 无限循环。
java
ReactAgent agent = ReactAgent.builder()
.maxIterations(5) // 最多迭代 5 次
.build();
参数:
maxIterations:最大迭代次数(int,默认 10)
返回 :ReactAgent.Builder
maxExecutionTime(Duration duration)
设置最大执行时间,超时后自动停止。
java
ReactAgent agent = ReactAgent.builder()
.maxExecutionTime(Duration.ofMinutes(5)) // 最多执行 5 分钟
.build();
参数:
duration:最大执行时间(Duration,可选)
返回 :ReactAgent.Builder
build()
构建 ReactAgent 实例。
java
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build(); // 构建实例
返回 :ReactAgent
异常:
- 如果必需参数缺失,会抛出
IllegalArgumentException
5.2 ReactAgent 调用方法
5.2.1 call(String userMessage) - 同步调用
同步调用 Agent,返回最终响应。
java
AssistantMessage response = agent.call("用户问题");
String text = response.getText();
System.out.println(text);
方法签名:
java
public AssistantMessage call(String userMessage) throws GraphRunnerException
参数:
userMessage:用户消息(String,必需)
返回:
AssistantMessage:Agent 的响应消息
异常:
GraphRunnerException:执行失败时抛出
示例:
java
try {
AssistantMessage response = agent.call("上海天气怎么样");
System.out.println("Agent 回复:" + response.getText());
} catch (GraphRunnerException e) {
log.error("Agent 执行失败", e);
}
5.2.2 stream(String userMessage) - 流式调用
流式调用 Agent,实时返回响应片段。
java
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.messages.AssistantMessage;
Flux<AssistantMessage> responseStream = agent.stream("用户问题");
responseStream.subscribe(
message -> System.out.print(message.getText()), // 处理每个片段
error -> log.error("流式调用失败", error), // 错误处理
() -> System.out.println("\n完成") // 完成回调
);
方法签名:
java
public Flux<AssistantMessage> stream(String userMessage)
参数:
userMessage:用户消息(String,必需)
返回:
Flux<AssistantMessage>:响应消息流(Reactor 响应式流)
示例:
java
agent.stream("请详细介绍 Spring AI Alibaba")
.doOnNext(message -> System.out.print(message.getText()))
.doOnError(error -> log.error("错误", error))
.doOnComplete(() -> System.out.println("\n完成"))
.blockLast(); // 阻塞直到完成
5.2.3 call(UserMessage userMessage) - 使用消息对象
使用 UserMessage 对象调用 Agent。
java
import org.springframework.ai.chat.messages.UserMessage;
UserMessage userMessage = new UserMessage("用户问题");
AssistantMessage response = agent.call(userMessage);
方法签名:
java
public AssistantMessage call(UserMessage userMessage) throws GraphRunnerException
参数:
userMessage:用户消息对象(UserMessage,必需)
返回:
AssistantMessage:Agent 的响应消息
5.2.4 stream(UserMessage userMessage) - 流式调用(消息对象)
使用 UserMessage 对象进行流式调用。
java
UserMessage userMessage = new UserMessage("用户问题");
Flux<AssistantMessage> responseStream = agent.stream(userMessage);
方法签名:
java
public Flux<AssistantMessage> stream(UserMessage userMessage)
参数:
userMessage:用户消息对象(UserMessage,必需)
返回:
Flux<AssistantMessage>:响应消息流
5.3 配置选项总结
| 配置项 | 方法 | 类型 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|---|
| Agent 名称 | name(String) |
String | ✅ | - | Agent 标识 |
| LLM 模型 | model(ChatModel) |
ChatModel | ✅ | - | 使用的模型 |
| 系统提示词 | systemPrompt(String) |
String | ❌ | - | 定义角色 |
| 指令 | instruction(String) |
String | ❌ | - | 额外指令 |
| 工具列表 | tools(ToolCallback...) |
ToolCallback[] | ❌ | - | 可用工具 |
| 检查点保存器 | saver(CheckpointSaver) |
CheckpointSaver | ❌ | - | 状态保存 |
| 最大迭代次数 | maxIterations(int) |
int | ❌ | 10 | 防止无限循环 |
| 最大执行时间 | maxExecutionTime(Duration) |
Duration | ❌ | - | 超时控制 |
5.4 完整示例
java
public class ReactAgentExample {
public static void main(String[] args) throws GraphRunnerException {
// 创建模型
DeepSeekApi api = DeepSeekApi.builder()
.apiKey("your-api-key")
.build();
DeepSeekChatModel model = DeepSeekChatModel.builder()
.deepSeekApi(api)
.build();
// 创建 Agent
ReactAgent agent = ReactAgent.builder()
.name("helpful_agent")
.model(model)
.systemPrompt("You are a helpful assistant that provides accurate information.")
.instruction("Always be polite and concise.")
.maxIterations(5)
.saver(new MemorySaver())
.build();
// 调用 Agent
AssistantMessage response = agent.call("什么是 Spring AI Alibaba?");
System.out.println("Agent 回复:" + response.getText());
}
}
六、工具调用(Function Calling)
6.1 FunctionToolCallback.Builder API
6.1.1 完整 API 列表
java
FunctionToolCallback.Builder builder = FunctionToolCallback.builder(
String name, // 工具名称(必需)
BiFunction<T, ToolContext, R> function // 工具函数(必需)
);
// 配置
builder.description(String description) // 工具描述
.inputType(Class<T> inputType) // 输入参数类型(必需)
// 构建
ToolCallback tool = builder.build();
6.1.2 方法详解
FunctionToolCallback.builder(String name, BiFunction<T, ToolContext, R> function)
创建 FunctionToolCallback 构建器。
java
BiFunction<WeatherRequest, ToolContext, String> weatherFunction =
(request, context) -> "It's sunny in " + request.getCity();
FunctionToolCallback.Builder builder = FunctionToolCallback.builder(
"get_weather", // 工具名称
weatherFunction // 工具函数
);
参数:
name:工具名称(String,必需),用于 LLM 识别工具function:工具函数(BiFunction<T, ToolContext, R>,必需)T:输入参数类型(必须是对象类型,不能是基本类型)ToolContext:工具上下文(包含对话历史等信息)R:返回值类型(通常是 String)
返回 :FunctionToolCallback.Builder
description(String description)
设置工具描述,帮助 LLM 理解工具用途。
java
ToolCallback tool = FunctionToolCallback.builder("get_weather", weatherFunction)
.description("Get weather information for a given city") // 工具描述
.inputType(WeatherRequest.class)
.build();
参数:
description:工具描述(String,可选,但强烈推荐)
返回 :FunctionToolCallback.Builder
建议:描述要清晰明确,说明工具的用途、参数含义和返回值。
inputType(Class<T> inputType)
设置输入参数类型,必须是对象类型。
java
// ✅ 正确:使用对象类型
ToolCallback tool = FunctionToolCallback.builder("get_weather", weatherFunction)
.inputType(WeatherRequest.class) // 对象类型
.build();
// ❌ 错误:不能使用基本类型
ToolCallback tool = FunctionToolCallback.builder("get_weather", weatherFunction)
.inputType(String.class) // 错误!会抛出异常
.build();
参数:
inputType:输入参数类型(Class,必需),必须是对象类型(POJO)
返回 :FunctionToolCallback.Builder
要求:
- 参数类必须提供无参构造器
- 参数类必须提供 getter/setter 方法
- 参数类不能是基本类型(String、Integer 等)
build()
构建 ToolCallback 实例。
java
ToolCallback tool = FunctionToolCallback.builder("get_weather", weatherFunction)
.description("Get weather for a city")
.inputType(WeatherRequest.class)
.build(); // 构建实例
返回 :ToolCallback
异常:
- 如果必需参数缺失或类型不正确,会抛出
IllegalArgumentException
6.2 创建工具
6.2.1 定义参数类
重要 :函数调用的 schema 必须是 object 类型,不能直接使用 String 等基本类型。
java
/**
* 天气查询参数类
* 注意:必须提供无参构造器和 getter/setter
*/
public static class WeatherRequest {
private String city;
// 必需:无参构造器
public WeatherRequest() {
}
// 可选:有参构造器
public WeatherRequest(String city) {
this.city = city;
}
// 必需:getter 方法
public String getCity() {
return city;
}
// 必需:setter 方法
public void setCity(String city) {
this.city = city;
}
}
参数类要求:
- ✅ 提供无参构造器(必需)
- ✅ 提供 getter/setter 方法(必需)
- ✅ 使用对象类型,不能是基本类型
- ✅ 字段类型支持:String、Integer、Long、Double、Boolean、List、Map 等
6.2.2 实现工具函数
工具函数必须实现 BiFunction<T, ToolContext, R> 接口。
java
import java.util.function.BiFunction;
import org.springframework.ai.chat.model.ToolContext;
class WeatherTool implements BiFunction<WeatherRequest, ToolContext, String> {
@Override
public String apply(WeatherRequest request, ToolContext toolContext) {
// 参数验证
if (request == null || request.getCity() == null) {
return "城市名称不能为空";
}
String city = request.getCity();
// 执行工具逻辑(这里模拟天气查询)
String weather = queryWeather(city);
// 返回结果
return weather;
}
private String queryWeather(String city) {
// 实际实现:调用天气 API
return "It's always sunny in " + city + "!";
}
}
函数签名:
java
R apply(T request, ToolContext toolContext)
参数:
request:工具请求参数(类型 T,由inputType指定)toolContext:工具上下文(ToolContext),包含:- 对话历史
- 当前用户消息
- Agent 状态等
返回:
- 工具执行结果(类型 R,通常是 String)
6.2.3 注册工具
java
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.function.FunctionToolCallback;
// 创建工具实例
WeatherTool weatherToolImpl = new WeatherTool();
// 使用 WeatherRequest 作为 inputType,这样生成的 schema 类型是 "object"
ToolCallback weatherTool = FunctionToolCallback.builder("get_weather", weatherToolImpl)
.description("Get weather information for a given city. Returns current weather conditions.")
.inputType(WeatherRequest.class) // 使用对象类型,而不是 String.class
.build();
生成的 JSON Schema:
json
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
6.3 多参数工具示例
如果工具需要多个参数,在参数类中定义多个字段:
java
/**
* 计算器参数类(多参数示例)
*/
public static class CalculatorRequest {
private Double a;
private Double b;
private String operation; // "add", "subtract", "multiply", "divide"
public CalculatorRequest() {}
public Double getA() { return a; }
public void setA(Double a) { this.a = a; }
public Double getB() { return b; }
public void setB(Double b) { this.b = b; }
public String getOperation() { return operation; }
public void setOperation(String operation) { this.operation = operation; }
}
/**
* 计算器工具
*/
class CalculatorTool implements BiFunction<CalculatorRequest, ToolContext, String> {
@Override
public String apply(CalculatorRequest request, ToolContext context) {
Double a = request.getA();
Double b = request.getB();
String op = request.getOperation();
if (a == null || b == null || op == null) {
return "参数不完整";
}
double result;
switch (op) {
case "add":
result = a + b;
break;
case "subtract":
result = a - b;
break;
case "multiply":
result = a * b;
break;
case "divide":
if (b == 0) {
return "除数不能为0";
}
result = a / b;
break;
default:
return "不支持的操作:" + op;
}
return String.format("%.2f %s %.2f = %.2f", a, op, b, result);
}
}
// 注册工具
ToolCallback calculatorTool = FunctionToolCallback.builder("calculate", new CalculatorTool())
.description("Perform basic arithmetic operations (add, subtract, multiply, divide)")
.inputType(CalculatorRequest.class)
.build();
6.2 将工具添加到 Agent
java
ReactAgent agent = ReactAgent.builder()
.name("weather_agent")
.model(chatModel)
.systemPrompt("You are a helpful weather assistant.")
.tools(weatherTool) // 添加工具
.saver(new MemorySaver())
.build();
6.3 完整示例
java
public class ToolCallingExample {
// 参数类
public static class WeatherRequest {
private String city;
public WeatherRequest() {}
public WeatherRequest(String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
// 工具实现
static class WeatherTool implements BiFunction<WeatherRequest, ToolContext, String> {
@Override
public String apply(WeatherRequest request, ToolContext toolContext) {
String city = request != null && request.getCity() != null
? request.getCity()
: "unknown";
return "It's always sunny in " + city + "!";
}
}
public static void main(String[] args) throws GraphRunnerException {
// 创建模型
DeepSeekApi api = DeepSeekApi.builder()
.apiKey("your-api-key")
.build();
DeepSeekChatModel model = DeepSeekChatModel.builder()
.deepSeekApi(api)
.build();
// 创建工具
ToolCallback weatherTool = FunctionToolCallback.builder("get_weather", new WeatherTool())
.description("Get weather for a given city")
.inputType(WeatherRequest.class)
.build();
// 创建 Agent
ReactAgent agent = ReactAgent.builder()
.name("weather_agent")
.model(model)
.systemPrompt("You are a helpful weather assistant.")
.tools(weatherTool)
.saver(new MemorySaver())
.build();
// 调用 Agent(Agent 会自动调用工具)
AssistantMessage response = agent.call("上海天气怎么样");
System.out.println(response.getText());
}
}
6.4 常见错误
错误 1:使用基本类型作为 inputType
java
// ❌ 错误:schema 类型必须是 "object"
ToolCallback tool = FunctionToolCallback.builder("get_weather", new WeatherTool())
.inputType(String.class) // 错误!
.build();
错误信息:
Invalid schema for function 'get_weather': schema must be a JSON Schema of 'type: "object"', got 'type: "string"'.
解决方案:使用对象类型作为参数类。
错误 2:参数类缺少无参构造器
java
// ❌ 错误:缺少无参构造器
public static class WeatherRequest {
private String city;
// 缺少无参构造器
public WeatherRequest(String city) {
this.city = city;
}
}
解决方案:添加无参构造器。
七、多代理编排
Spring AI Alibaba 提供了多种多代理编排模式,支持复杂的任务分解和协作。
7.1 SequentialAgent(顺序代理)
按顺序执行多个 Agent,前一个 Agent 的输出作为下一个 Agent 的输入。
7.1.1 SequentialAgent.Builder API
java
SequentialAgent.Builder builder = SequentialAgent.builder();
// 必需配置
builder.name(String name) // Agent 名称(必需)
.agents(ReactAgent... agents) // 可变参数:Agent 列表
.agents(List<ReactAgent> agents) // 列表方式:Agent 列表
// 构建
SequentialAgent agent = builder.build();
7.1.2 方法详解
name(String name)
设置顺序代理的名称。
java
SequentialAgent agent = SequentialAgent.builder()
.name("sequential_agent")
.agents(agent1, agent2, agent3)
.build();
参数:
name:Agent 名称(String,必需)
返回 :SequentialAgent.Builder
agents(ReactAgent... agents) / agents(List<ReactAgent> agents)
添加要顺序执行的 Agent 列表。
java
// 方式1:可变参数
SequentialAgent agent = SequentialAgent.builder()
.name("sequential_agent")
.agents(agent1, agent2, agent3) // 按顺序执行
.build();
// 方式2:列表
List<ReactAgent> agents = Arrays.asList(agent1, agent2, agent3);
SequentialAgent agent = SequentialAgent.builder()
.name("sequential_agent")
.agents(agents)
.build();
参数:
agents:Agent 列表(可变参数或 List,必需,至少一个)
返回 :SequentialAgent.Builder
执行流程:
- 执行
agent1,获取输出 - 将
agent1的输出作为输入,执行agent2 - 将
agent2的输出作为输入,执行agent3 - 返回
agent3的输出
build()
构建 SequentialAgent 实例。
java
SequentialAgent agent = SequentialAgent.builder()
.name("sequential_agent")
.agents(agent1, agent2, agent3)
.build();
返回 :SequentialAgent
调用方式:
java
AssistantMessage response = sequentialAgent.call("用户问题");
7.1.3 完整示例
java
// 创建多个 Agent
ReactAgent researchAgent = ReactAgent.builder()
.name("research_agent")
.model(chatModel)
.systemPrompt("You are a research assistant. Analyze the question and provide research findings.")
.build();
ReactAgent summaryAgent = ReactAgent.builder()
.name("summary_agent")
.model(chatModel)
.systemPrompt("You are a summarization assistant. Summarize the research findings.")
.build();
// 创建顺序代理
SequentialAgent sequentialAgent = SequentialAgent.builder()
.name("research_and_summary_agent")
.agents(researchAgent, summaryAgent) // 先研究,后总结
.build();
// 调用
AssistantMessage response = sequentialAgent.call("什么是 Spring AI Alibaba?");
7.2 ParallelAgent(并行代理)
并行执行多个 Agent,然后合并结果。
7.2.1 ParallelAgent.Builder API
java
ParallelAgent.Builder builder = ParallelAgent.builder();
// 必需配置
builder.name(String name) // Agent 名称(必需)
.agents(ReactAgent... agents) // 可变参数:Agent 列表
.agents(List<ReactAgent> agents) // 列表方式:Agent 列表
// 可选配置
builder.mergeStrategy(MergeStrategy strategy) // 合并策略(可选)
// 构建
ParallelAgent agent = builder.build();
7.2.2 方法详解
agents(ReactAgent... agents) / agents(List<ReactAgent> agents)
添加要并行执行的 Agent 列表。
java
ParallelAgent agent = ParallelAgent.builder()
.name("parallel_agent")
.agents(agent1, agent2, agent3) // 并行执行
.build();
执行流程:
- 同时执行
agent1、agent2、agent3 - 等待所有 Agent 完成
- 合并所有结果并返回
mergeStrategy(MergeStrategy strategy)
设置结果合并策略(可选)。
java
ParallelAgent agent = ParallelAgent.builder()
.name("parallel_agent")
.agents(agent1, agent2, agent3)
.mergeStrategy(MergeStrategy.CONCATENATE) // 合并策略
.build();
支持的策略:
CONCATENATE:拼接所有结果FIRST:返回第一个结果LAST:返回最后一个结果CUSTOM:自定义合并逻辑
7.2.3 完整示例
java
// 创建多个专业 Agent
ReactAgent weatherAgent = ReactAgent.builder()
.name("weather_agent")
.model(chatModel)
.systemPrompt("You are a weather expert.")
.build();
ReactAgent newsAgent = ReactAgent.builder()
.name("news_agent")
.model(chatModel)
.systemPrompt("You are a news expert.")
.build();
// 创建并行代理
ParallelAgent parallelAgent = ParallelAgent.builder()
.name("multi_source_agent")
.agents(weatherAgent, newsAgent) // 并行查询天气和新闻
.mergeStrategy(MergeStrategy.CONCATENATE)
.build();
// 调用
AssistantMessage response = parallelAgent.call("今天北京的天气和新闻");
7.3 RoutingAgent(路由代理)
根据条件路由到不同的 Agent。
7.3.1 RoutingAgent.Builder API
java
RoutingAgent.Builder builder = RoutingAgent.builder();
// 必需配置
builder.name(String name) // Agent 名称(必需)
// 路由配置
builder.route(String condition, ReactAgent agent) // 添加路由规则
.defaultAgent(ReactAgent agent) // 设置默认 Agent
// 构建
RoutingAgent agent = builder.build();
7.3.2 方法详解
route(String condition, ReactAgent agent)
添加路由规则,当条件匹配时路由到指定的 Agent。
java
RoutingAgent agent = RoutingAgent.builder()
.name("routing_agent")
.route("weather", weatherAgent) // 包含 "weather" 时路由到 weatherAgent
.route("news", newsAgent) // 包含 "news" 时路由到 newsAgent
.defaultAgent(generalAgent) // 默认路由
.build();
参数:
condition:路由条件(String,关键词或正则表达式)agent:目标 Agent(ReactAgent)
返回 :RoutingAgent.Builder
路由逻辑:
- 检查用户消息是否包含条件关键词
- 如果匹配,路由到对应的 Agent
- 如果不匹配任何条件,使用默认 Agent
defaultAgent(ReactAgent agent)
设置默认 Agent,当没有匹配的路由规则时使用。
java
RoutingAgent agent = RoutingAgent.builder()
.name("routing_agent")
.route("weather", weatherAgent)
.defaultAgent(generalAgent) // 默认 Agent
.build();
参数:
agent:默认 Agent(ReactAgent,必需)
返回 :RoutingAgent.Builder
7.3.3 完整示例
java
// 创建专业 Agent
ReactAgent weatherAgent = ReactAgent.builder()
.name("weather_agent")
.model(chatModel)
.systemPrompt("You are a weather assistant.")
.build();
ReactAgent newsAgent = ReactAgent.builder()
.name("news_agent")
.model(chatModel)
.systemPrompt("You are a news assistant.")
.build();
ReactAgent generalAgent = ReactAgent.builder()
.name("general_agent")
.model(chatModel)
.systemPrompt("You are a general assistant.")
.build();
// 创建路由代理
RoutingAgent routingAgent = RoutingAgent.builder()
.name("smart_routing_agent")
.route("weather", weatherAgent) // 天气相关
.route("news", newsAgent) // 新闻相关
.defaultAgent(generalAgent) // 其他问题
.build();
// 调用
AssistantMessage response1 = routingAgent.call("今天天气怎么样"); // 路由到 weatherAgent
AssistantMessage response2 = routingAgent.call("有什么新闻"); // 路由到 newsAgent
AssistantMessage response3 = routingAgent.call("你好"); // 路由到 generalAgent
7.4 LoopAgent(循环代理)
循环执行 Agent 直到满足条件。
7.4.1 LoopAgent.Builder API
java
LoopAgent.Builder builder = LoopAgent.builder();
// 必需配置
builder.name(String name) // Agent 名称(必需)
.agent(ReactAgent agent) // 要循环执行的 Agent(必需)
// 循环控制
builder.maxIterations(int maxIterations) // 最大循环次数(可选)
.condition(Predicate<String> condition) // 停止条件(可选)
// 构建
LoopAgent agent = builder.build();
7.4.2 方法详解
agent(ReactAgent agent)
设置要循环执行的 Agent。
java
LoopAgent agent = LoopAgent.builder()
.name("loop_agent")
.agent(myAgent) // 要循环执行的 Agent
.build();
参数:
agent:要循环执行的 Agent(ReactAgent,必需)
返回 :LoopAgent.Builder
maxIterations(int maxIterations)
设置最大循环次数,防止无限循环。
java
LoopAgent agent = LoopAgent.builder()
.name("loop_agent")
.agent(myAgent)
.maxIterations(10) // 最多循环 10 次
.build();
参数:
maxIterations:最大循环次数(int,默认 10)
返回 :LoopAgent.Builder
condition(Predicate<String> condition)
设置停止条件,当条件满足时停止循环。
java
LoopAgent agent = LoopAgent.builder()
.name("loop_agent")
.agent(myAgent)
.condition(response -> response.contains("完成") || response.contains("done")) // 停止条件
.build();
参数:
condition:停止条件(Predicate,可选)- 返回
true时停止循环 - 返回
false时继续循环
- 返回
返回 :LoopAgent.Builder
7.4.3 完整示例
java
ReactAgent taskAgent = ReactAgent.builder()
.name("task_agent")
.model(chatModel)
.systemPrompt("You are a task executor. Execute tasks step by step.")
.build();
// 创建循环代理
LoopAgent loopAgent = LoopAgent.builder()
.name("task_loop_agent")
.agent(taskAgent)
.maxIterations(5) // 最多循环 5 次
.condition(response -> response.contains("完成") || response.contains("完成所有任务"))
.build();
// 调用
AssistantMessage response = loopAgent.call("请完成以下任务:1. 查询天气 2. 查询新闻 3. 生成报告");
7.5 多代理组合示例
可以组合使用多种代理模式:
java
// 1. 创建专业 Agent
ReactAgent researchAgent = ReactAgent.builder()
.name("research_agent")
.model(chatModel)
.systemPrompt("You are a research assistant.")
.build();
ReactAgent analysisAgent = ReactAgent.builder()
.name("analysis_agent")
.model(chatModel)
.systemPrompt("You are an analysis assistant.")
.build();
ReactAgent summaryAgent = ReactAgent.builder()
.name("summary_agent")
.model(chatModel)
.systemPrompt("You are a summarization assistant.")
.build();
// 2. 创建顺序代理(研究 -> 分析)
SequentialAgent researchAndAnalysis = SequentialAgent.builder()
.name("research_and_analysis")
.agents(researchAgent, analysisAgent)
.build();
// 3. 创建并行代理(同时执行多个研究任务)
ParallelAgent parallelResearch = ParallelAgent.builder()
.name("parallel_research")
.agents(researchAgent, researchAgent) // 可以重复使用
.build();
// 4. 创建路由代理(根据问题类型路由)
RoutingAgent mainAgent = RoutingAgent.builder()
.name("main_agent")
.route("research", researchAndAnalysis)
.route("summary", summaryAgent)
.defaultAgent(researchAgent)
.build();
八、上下文工程
8.1 系统提示(System Prompt)
8.1.1 基本用法
定义 Agent 的角色和行为:
java
ReactAgent agent = ReactAgent.builder()
.systemPrompt("""
You are a helpful assistant that specializes in answering questions about Spring AI Alibaba.
Always provide accurate and detailed information.
If you don't know something, admit it honestly.
""")
.build();
8.1.2 最佳实践
- 明确角色定义:清楚说明 Agent 的身份和职责
- 行为规范:定义 Agent 应该如何响应
- 限制条件:说明 Agent 不应该做什么
- 输出格式:如果需要特定格式,在提示词中说明
示例:
java
String systemPrompt = """
You are a professional technical assistant specializing in Spring AI Alibaba.
Your responsibilities:
- Provide accurate and detailed technical information
- Explain concepts clearly with examples
- Help users solve technical problems
Your constraints:
- Only answer questions you are confident about
- If you don't know something, admit it honestly
- Never make up information
Your response format:
- Use clear and concise language
- Provide code examples when relevant
- Structure your answers with headings when appropriate
""";
ReactAgent agent = ReactAgent.builder()
.systemPrompt(systemPrompt)
.build();
8.2 指令(Instruction)
8.2.1 基本用法
提供额外的行为指令,补充系统提示词:
java
ReactAgent agent = ReactAgent.builder()
.systemPrompt("You are a helpful assistant.")
.instruction("Always be polite and concise in your responses.") // 额外指令
.build();
8.2.2 与 System Prompt 的区别
- System Prompt :定义 Agent 的身份和核心行为
- Instruction :提供额外的行为指导,可以动态调整
使用场景:
- System Prompt:长期不变的角色定义
- Instruction:根据具体任务调整的行为指令
8.3 对话历史管理
8.3.1 MemorySaver API
内存保存器,用于开发测试,不持久化数据。
java
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
// 创建内存保存器
MemorySaver saver = new MemorySaver();
ReactAgent agent = ReactAgent.builder()
.saver(saver) // 使用内存保存
.build();
特点:
- ✅ 简单易用,无需额外配置
- ✅ 适合开发测试
- ❌ 数据不持久化,应用重启后丢失
- ❌ 不适合生产环境
8.3.2 RedisSaver API
Redis 保存器,用于生产环境,持久化对话历史。
RedisSaver.Builder API
java
RedisSaver.Builder builder = RedisSaver.builder();
// 必需配置
builder.redisTemplate(RedisTemplate<String, Object> redisTemplate) // Redis 模板(必需)
// 可选配置
builder.keyPrefix(String prefix) // Key 前缀(可选,默认 "agent:checkpoint:")
.ttl(Duration ttl) // 过期时间(可选)
// 构建
RedisSaver saver = builder.build();
方法详解
redisTemplate(RedisTemplate<String, Object> redisTemplate)
设置 Redis 模板。
java
@Autowired
private RedisTemplate<String, Object> redisTemplate;
RedisSaver saver = RedisSaver.builder()
.redisTemplate(redisTemplate) // 设置 Redis 模板
.build();
参数:
redisTemplate:Redis 模板(RedisTemplate<String, Object>,必需)
返回 :RedisSaver.Builder
keyPrefix(String prefix)
设置 Key 前缀,用于区分不同的 Agent 或应用。
java
RedisSaver saver = RedisSaver.builder()
.redisTemplate(redisTemplate)
.keyPrefix("my_app:agent:") // 自定义前缀
.build();
参数:
prefix:Key 前缀(String,可选,默认 "agent:checkpoint:")
返回 :RedisSaver.Builder
ttl(Duration ttl)
设置过期时间,自动清理过期的检查点。
java
RedisSaver saver = RedisSaver.builder()
.redisTemplate(redisTemplate)
.ttl(Duration.ofDays(7)) // 7 天后过期
.build();
参数:
ttl:过期时间(Duration,可选)
返回 :RedisSaver.Builder
完整示例
java
@Configuration
public class AgentConfig {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Bean
public RedisSaver redisSaver() {
return RedisSaver.builder()
.redisTemplate(redisTemplate)
.keyPrefix("base_agent:checkpoint:")
.ttl(Duration.ofDays(30)) // 30 天过期
.build();
}
@Bean
public ReactAgent myAgent(RedisSaver redisSaver, ChatModel chatModel) {
return ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.saver(redisSaver) // 使用 Redis 保存
.build();
}
}
8.3.3 检查点操作
检查点保存器提供以下方法:
java
// 保存检查点
saver.save(String checkpointId, Object state);
// 加载检查点
Object state = saver.load(String checkpointId);
// 删除检查点
saver.delete(String checkpointId);
// 检查检查点是否存在
boolean exists = saver.exists(String checkpointId);
注意:通常不需要直接调用这些方法,ReactAgent 会自动管理检查点。
九、人机协同
9.1 人工审批
在关键操作前请求人工审批,确保重要操作得到人工确认。
9.1.1 HumanApprovalNode API
java
import com.alibaba.cloud.ai.graph.agent.human.HumanApprovalNode;
HumanApprovalNode.Builder builder = HumanApprovalNode.builder();
// 必需配置
builder.name(String name) // 节点名称(必需)
.message(String message) // 审批提示消息(必需)
// 可选配置
builder.timeout(Duration timeout) // 超时时间(可选)
.onApproved(Runnable callback) // 审批通过回调(可选)
.onRejected(Runnable callback) // 审批拒绝回调(可选)
// 构建
HumanApprovalNode node = builder.build();
9.1.2 方法详解
name(String name)
设置节点名称。
java
HumanApprovalNode node = HumanApprovalNode.builder()
.name("approval_node")
.message("请确认是否执行此操作?")
.build();
参数:
name:节点名称(String,必需)
返回 :HumanApprovalNode.Builder
message(String message)
设置审批提示消息。
java
HumanApprovalNode node = HumanApprovalNode.builder()
.name("approval_node")
.message("""
即将执行以下操作:
- 删除用户数据
- 修改系统配置
请确认是否继续?
""")
.build();
参数:
message:审批提示消息(String,必需)
返回 :HumanApprovalNode.Builder
timeout(Duration timeout)
设置超时时间,超时后自动拒绝。
java
HumanApprovalNode node = HumanApprovalNode.builder()
.name("approval_node")
.message("请确认是否执行此操作?")
.timeout(Duration.ofMinutes(5)) // 5 分钟超时
.build();
参数:
timeout:超时时间(Duration,可选)
返回 :HumanApprovalNode.Builder
onApproved(Runnable callback)
设置审批通过时的回调。
java
HumanApprovalNode node = HumanApprovalNode.builder()
.name("approval_node")
.message("请确认是否执行此操作?")
.onApproved(() -> {
log.info("操作已审批通过");
// 执行后续操作
})
.build();
参数:
callback:回调函数(Runnable,可选)
返回 :HumanApprovalNode.Builder
onRejected(Runnable callback)
设置审批拒绝时的回调。
java
HumanApprovalNode node = HumanApprovalNode.builder()
.name("approval_node")
.message("请确认是否执行此操作?")
.onRejected(() -> {
log.info("操作已被拒绝");
// 执行清理操作
})
.build();
参数:
callback:回调函数(Runnable,可选)
返回 :HumanApprovalNode.Builder
9.2 人工反馈
收集人工反馈并用于改进 Agent 行为。
9.2.1 HumanFeedbackNode API
java
import com.alibaba.cloud.ai.graph.agent.human.HumanFeedbackNode;
HumanFeedbackNode.Builder builder = HumanFeedbackNode.builder();
// 必需配置
builder.name(String name) // 节点名称(必需)
.message(String message) // 反馈提示消息(必需)
// 可选配置
builder.timeout(Duration timeout) // 超时时间(可选)
.onFeedback(Consumer<String> callback) // 反馈回调(可选)
// 构建
HumanFeedbackNode node = builder.build();
9.2.2 方法详解
message(String message)
设置反馈提示消息。
java
HumanFeedbackNode node = HumanFeedbackNode.builder()
.name("feedback_node")
.message("请对 Agent 的回答提供反馈意见:")
.build();
参数:
message:反馈提示消息(String,必需)
返回 :HumanFeedbackNode.Builder
onFeedback(Consumer<String> callback)
设置收到反馈时的回调。
java
HumanFeedbackNode node = HumanFeedbackNode.builder()
.name("feedback_node")
.message("请提供反馈意见")
.onFeedback(feedback -> {
log.info("收到反馈:{}", feedback);
// 保存反馈用于改进 Agent
saveFeedback(feedback);
})
.build();
参数:
callback:回调函数(Consumer,可选)- 参数:用户提供的反馈文本
返回 :HumanFeedbackNode.Builder
9.3 完整示例
java
// 创建人工审批节点
HumanApprovalNode approvalNode = HumanApprovalNode.builder()
.name("delete_approval")
.message("即将删除重要数据,请确认是否继续?")
.timeout(Duration.ofMinutes(5))
.onApproved(() -> {
log.info("删除操作已审批通过");
// 执行删除操作
})
.onRejected(() -> {
log.info("删除操作已被拒绝");
// 取消删除操作
})
.build();
// 创建人工反馈节点
HumanFeedbackNode feedbackNode = HumanFeedbackNode.builder()
.name("user_feedback")
.message("请对 Agent 的回答提供反馈意见:")
.onFeedback(feedback -> {
log.info("用户反馈:{}", feedback);
// 保存反馈用于改进
feedbackService.saveFeedback(feedback);
})
.build();
十、常用 API 参考
10.1 ReactAgent API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
ReactAgent.builder() |
创建构建器 | - | ReactAgent.Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.model(ChatModel) |
设置模型 | model: ChatModel |
Builder |
✅ |
builder.systemPrompt(String) |
设置系统提示 | prompt: String |
Builder |
❌ |
builder.instruction(String) |
设置指令 | instruction: String |
Builder |
❌ |
builder.tools(ToolCallback...) |
添加工具 | tools: ToolCallback... |
Builder |
❌ |
builder.saver(CheckpointSaver) |
设置保存器 | saver: CheckpointSaver |
Builder |
❌ |
builder.maxIterations(int) |
最大迭代次数 | maxIterations: int |
Builder |
❌ |
builder.maxExecutionTime(Duration) |
最大执行时间 | duration: Duration |
Builder |
❌ |
builder.build() |
构建实例 | - | ReactAgent |
- |
agent.call(String) |
同步调用 | message: String |
AssistantMessage |
- |
agent.call(UserMessage) |
同步调用 | message: UserMessage |
AssistantMessage |
- |
agent.stream(String) |
流式调用 | message: String |
Flux<AssistantMessage> |
- |
agent.stream(UserMessage) |
流式调用 | message: UserMessage |
Flux<AssistantMessage> |
- |
10.2 FunctionToolCallback API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
FunctionToolCallback.builder(String, BiFunction) |
创建构建器 | name: String, function: BiFunction |
Builder |
- |
builder.description(String) |
设置描述 | description: String |
Builder |
❌ |
builder.inputType(Class) |
设置输入类型 | inputType: Class<T> |
Builder |
✅ |
builder.build() |
构建实例 | - | ToolCallback |
- |
重要:
inputType必须是对象类型(POJO),不能是基本类型- 参数类必须提供无参构造器和 getter/setter
10.3 SequentialAgent API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
SequentialAgent.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.agents(ReactAgent...) |
添加 Agent | agents: ReactAgent... |
Builder |
✅ |
builder.agents(List) |
添加 Agent | agents: List<ReactAgent> |
Builder |
✅ |
builder.build() |
构建实例 | - | SequentialAgent |
- |
10.4 ParallelAgent API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
ParallelAgent.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.agents(ReactAgent...) |
添加 Agent | agents: ReactAgent... |
Builder |
✅ |
builder.agents(List) |
添加 Agent | agents: List<ReactAgent> |
Builder |
✅ |
builder.mergeStrategy(MergeStrategy) |
设置合并策略 | strategy: MergeStrategy |
Builder |
❌ |
builder.build() |
构建实例 | - | ParallelAgent |
- |
10.5 RoutingAgent API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
RoutingAgent.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.route(String, ReactAgent) |
添加路由 | condition: String, agent: ReactAgent |
Builder |
❌ |
builder.defaultAgent(ReactAgent) |
设置默认 Agent | agent: ReactAgent |
Builder |
✅ |
builder.build() |
构建实例 | - | RoutingAgent |
- |
10.6 LoopAgent API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
LoopAgent.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.agent(ReactAgent) |
设置 Agent | agent: ReactAgent |
Builder |
✅ |
builder.maxIterations(int) |
最大循环次数 | maxIterations: int |
Builder |
❌ |
builder.condition(Predicate) |
停止条件 | condition: Predicate<String> |
Builder |
❌ |
builder.build() |
构建实例 | - | LoopAgent |
- |
10.7 MemorySaver API
| 方法 | 说明 | 参数 | 返回 |
|---|---|---|---|
new MemorySaver() |
创建实例 | - | MemorySaver |
saver.save(String, Object) |
保存检查点 | id: String, state: Object |
void |
saver.load(String) |
加载检查点 | id: String |
Object |
saver.delete(String) |
删除检查点 | id: String |
void |
saver.exists(String) |
检查是否存在 | id: String |
boolean |
10.8 RedisSaver API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
RedisSaver.builder() |
创建构建器 | - | Builder |
- |
builder.redisTemplate(RedisTemplate) |
设置 Redis 模板 | template: RedisTemplate |
Builder |
✅ |
builder.keyPrefix(String) |
设置 Key 前缀 | prefix: String |
Builder |
❌ |
builder.ttl(Duration) |
设置过期时间 | ttl: Duration |
Builder |
❌ |
builder.build() |
构建实例 | - | RedisSaver |
- |
10.9 HumanApprovalNode API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
HumanApprovalNode.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.message(String) |
设置提示消息 | message: String |
Builder |
✅ |
builder.timeout(Duration) |
设置超时时间 | timeout: Duration |
Builder |
❌ |
builder.onApproved(Runnable) |
审批通过回调 | callback: Runnable |
Builder |
❌ |
builder.onRejected(Runnable) |
审批拒绝回调 | callback: Runnable |
Builder |
❌ |
builder.build() |
构建实例 | - | HumanApprovalNode |
- |
10.10 HumanFeedbackNode API 总结
| 方法 | 说明 | 参数 | 返回 | 必需 |
|---|---|---|---|---|
HumanFeedbackNode.builder() |
创建构建器 | - | Builder |
- |
builder.name(String) |
设置名称 | name: String |
Builder |
✅ |
builder.message(String) |
设置提示消息 | message: String |
Builder |
✅ |
builder.timeout(Duration) |
设置超时时间 | timeout: Duration |
Builder |
❌ |
builder.onFeedback(Consumer) |
反馈回调 | callback: Consumer<String> |
Builder |
❌ |
builder.build() |
构建实例 | - | HumanFeedbackNode |
- |
十一、最佳实践
10.1 依赖管理
推荐:使用 BOM 统一管理版本,避免版本冲突。
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
10.2 Jackson 版本冲突处理
Spring AI Alibaba 可能引入不同版本的 Jackson,建议统一版本:
xml
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-agent-framework</artifactId>
<version>1.1.0.0-RC2</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 显式引入统一版本 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
10.3 工具定义规范
- 参数类必须是对象类型 :不能使用
String、Integer等基本类型 - 提供无参构造器:Spring AI 需要无参构造器来实例化参数对象
- 提供 getter/setter:用于 JSON 序列化/反序列化
- 清晰的描述:工具描述要清晰,帮助 LLM 理解工具用途
10.4 错误处理
java
try {
AssistantMessage response = agent.call("用户问题");
System.out.println(response.getText());
} catch (GraphRunnerException e) {
log.error("Agent 执行失败", e);
// 处理错误
} catch (Exception e) {
log.error("未知错误", e);
// 处理错误
}
10.5 性能优化
- 限制迭代次数 :设置合理的
maxIterations - 设置超时时间 :使用
maxExecutionTime避免长时间运行 - 使用流式响应 :对于长文本生成,使用
stream()方法 - 缓存工具结果:对于重复的工具调用,考虑缓存结果
十二、常见问题
Q1: 函数调用的 schema 类型错误
错误信息:
Invalid schema for function 'get_weather': schema must be a JSON Schema of 'type: "object"', got 'type: "string"'.
原因 :使用了基本类型(如 String.class)作为 inputType。
解决方案 :创建参数类(POJO),使用对象类型作为 inputType。
Q2: Jackson 版本冲突
错误信息:
java.lang.NoSuchMethodError: 'java.lang.Object com.fasterxml.jackson.databind.ObjectMapper.treeToValue(...)'
原因:项目中存在多个版本的 Jackson。
解决方案:统一 Jackson 版本,排除冲突的依赖。
Q3: API Key 配置问题
错误信息:
API key is required
原因:未配置或配置错误的 API Key。
解决方案 :在 application.yml 中正确配置 API Key。
Q4: Agent 执行超时
原因:Agent 迭代次数过多或执行时间过长。
解决方案:
- 设置合理的
maxIterations - 设置
maxExecutionTime - 优化工具执行效率
Q5: 工具调用失败
原因:工具函数抛出异常或返回格式不正确。
解决方案:
- 检查工具函数实现
- 确保参数类正确序列化
- 添加异常处理
十三、参考资源
12.1 官方文档
- Spring AI Alibaba 官方文档:https://java2ai.com/docs/overview
- Spring AI 官方文档:https://docs.spring.io/spring-ai/reference/index.html
12.2 示例代码
- GitHub 仓库:https://github.com/alibaba/spring-ai-alibaba
- 示例项目 :参考项目中的
src/test/java/com/ygl/base/test.java
12.3 社区支持
- GitHub Issues:https://github.com/alibaba/spring-ai-alibaba/issues
- GitHub Discussions:https://github.com/alibaba/spring-ai-alibaba/discussions
12.4 相关文档
- Spring AI 使用文档 :
md/SpringAI使用文档.md - 知识库模块开发计划 :
md/知识库模块开发计划.md
附录:完整示例代码
示例 1:简单 Agent
java
public class SimpleAgentExample {
public static void main(String[] args) throws GraphRunnerException {
DeepSeekApi api = DeepSeekApi.builder()
.apiKey("your-api-key")
.build();
DeepSeekChatModel model = DeepSeekChatModel.builder()
.deepSeekApi(api)
.build();
ReactAgent agent = ReactAgent.builder()
.name("simple_agent")
.model(model)
.systemPrompt("You are a helpful assistant.")
.saver(new MemorySaver())
.build();
AssistantMessage response = agent.call("你好");
System.out.println(response.getText());
}
}
示例 2:带工具的 Agent
java
public class ToolAgentExample {
public static class WeatherRequest {
private String city;
public WeatherRequest() {}
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
}
static class WeatherTool implements BiFunction<WeatherRequest, ToolContext, String> {
@Override
public String apply(WeatherRequest request, ToolContext context) {
return "It's sunny in " + request.getCity() + "!";
}
}
public static void main(String[] args) throws GraphRunnerException {
DeepSeekApi api = DeepSeekApi.builder().apiKey("your-api-key").build();
DeepSeekChatModel model = DeepSeekChatModel.builder().deepSeekApi(api).build();
ToolCallback tool = FunctionToolCallback.builder("get_weather", new WeatherTool())
.description("Get weather for a city")
.inputType(WeatherRequest.class)
.build();
ReactAgent agent = ReactAgent.builder()
.name("weather_agent")
.model(model)
.systemPrompt("You are a weather assistant.")
.tools(tool)
.saver(new MemorySaver())
.build();
AssistantMessage response = agent.call("上海天气怎么样");
System.out.println(response.getText());
}
}