上个月,我在公司里负责搭建一个企业内部知识库问答系统。需求听起来很简单——用户提问,AI 去查阅文档并给出答案。但实际操作起来,却踩了不少坑。
第一版采用了纯 API 调用的方式,为了实现问题路由和逻辑判断,写了一大堆 if-else,代码变得冗长且难以维护。第二版,我转向了 LangChain4j,虽然 Agent 能跑起来了,但在处理多智能体协同和流程编排时,简直是一场噩梦。工具调用、记忆管理、人机协作……每一个功能都几乎需要从零开始搭建。
一个看似简单的“查文档+执行操作”的智能体,我前后花了整整五天时间,代码量超过了 2000 行。
直到我发现了 Spring AI Alibaba。
实现同样的功能,核心代码不到10行,一个功能完整的 Agent 就成功运行起来了。多智能体编排?框架内置支持。记忆管理?一行配置搞定。人工审批?一个 Hook 就能轻松接入。
今天这篇文章,我将结合自己的实践,从架构到实战,从单智能体到多智能体协同,为你彻底解析这个框架。
一、先看定位:Spring AI Alibaba 是什么?
一句话概括:这是阿里巴巴基于 Spring AI 打造的 Java Agent 开发框架,旨在帮助 Java 开发者快速构建企业级 AI 智能体应用。
它与 Spring AI 的层次关系可以这样理解:
┌──────────────────────────────────────────┐
│ Spring AI Alibaba(Agent 开发框架) │
│ ├── ReactAgent 核心 │
│ ├── Agent Skills 技能体系 │
│ ├── Multi-Agent 多智能体编排 │
│ └── Context Engineering 上下文工程 │
├──────────────────────────────────────────┤
│ Spring AI(基础框架) │
│ ├── ChatModel 抽象 │
│ ├── Tool Calling │
│ ├── MCP 协议支持 │
│ └── RAG & Vector Store │
├──────────────────────────────────────────┤
│ Spring Boot 3.5.x(运行时基座) │
└──────────────────────────────────────────┘
关键信息速览:
| 维度 |
说明 |
| 最新版本 |
1.1.2.0(2026年2月发布,生产环境推荐) |
| 核心能力 |
ReactAgent + Graph + Multi-Agent |
| 模型支持 |
通义千问(DashScope)、OpenAI 等 |
| 代码量 |
不到10行启动一个Agent |
| 企业特性 |
Human-in-the-Loop、记忆管理、成本控制 |
与 LangChain4j 对比,最核心的区别在于:Spring AI Alibaba 将 Agent 的编排逻辑深度集成到了框架层。开发者无需手动编写 ReAct 循环、管理状态机或拼接复杂的消息历史,框架已经为你封装好了这些复杂性。
二、实战开始:10行代码启动你的第一个 Agent
1. Maven 依赖配置
首先,在项目中引入必要的依赖。建议使用 BOM 进行版本统一管理。
<dependencyManagement>
<dependencies>
<!-- BOM 统一版本管理 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>1.1.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Agent 框架核心 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-agent-framework</artifactId>
</dependency>
<!-- 通义千问模型支持 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
</dependencies>
2. 配置文件
在 application.yml 中配置模型连接信息,建议将 API Key 设置为环境变量。
spring:
ai:
dashscope:
api-key: ${AI_DASHSCOPE_API_KEY}
chat:
options:
model: qwen-plus
3. 创建 Agent(核心代码)
下面就是见证“10行代码”魔法的时刻。通过定义一个 Spring Bean,即可创建一个具备 ReAct 推理能力的智能体。
@Bean
public ReactAgent myFirstAgent(ChatModel chatModel) {
return ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.instruction("你是一个有帮助的AI助手")
.build();
}
是的,就这些。 一个功能完整的 Agent 已经就绪。
调用方式也非常简单直观:
@Autowired
private ReactAgent myFirstAgent;
public String chat(String userMessage) {
return myFirstAgent.call(userMessage);
}
- ✅ 无需手动编写 ReAct 循环
- ✅ 无需手动拼接和管理消息历史
- ✅ 无需自己维护工具调用链
框架已经为你处理了所有底层复杂性。
三、赋予 Agent “动手”能力:工具调用
一个只能聊天的 Agent 价值有限,真正的智能体需要能够“执行任务”。Spring AI Alibaba 提供了多种灵活的工具定义方式。
1. 函数式定义(推荐)
这是最直接的一种方式,通过实现 BiFunction 接口来定义工具。
// 定义搜索工具
public class SearchTool implements BiFunction<String, ToolContext, String> {
@Override
public String apply(@ToolParam(description = "搜索关键词") String query,
ToolContext ctx) {
// 实际业务逻辑:调用搜索API
return searchService.search(query);
}
}
// 注册工具
@Bean
public ToolCallback searchTool() {
return FunctionToolCallback.builder("search", new SearchTool())
.description("搜索内部知识库,获取相关信息")
.inputType(String.class)
.build();
}
2. 将工具绑定到 Agent
创建 Agent 时,将定义好的工具传入即可。
@Bean
public ReactAgent smartAgent(ChatModel chatModel,
ToolCallback searchTool,
ToolCallback dbQueryTool) {
return ReactAgent.builder()
.name("smart_agent")
.model(chatModel)
.instruction("""
你是一个企业知识库助手。
当用户提问时,先用search工具搜索知识库,
如果需要数据,再用db_query工具查询数据库。
""")
.tools(searchTool, dbQueryTool)
.build();
}
此后,Agent 会根据用户的输入和自身指令,自主决策调用哪个工具、传递什么参数。这正是 ReAct(推理-行动)范式的核心体现。
3. 工具调用流程示例
用户提问:“上个月销售额是多少?”
│
▼
Agent 思考:需要查询数据库
│
▼
调用 db_query(“SELECT SUM(amount) FROM sales WHERE month=‘last’”)
│
▼
获取结果:¥1,234,567
│
▼
Agent 回复:“上个月的总销售额为123万4千567元。”
四、Agent 的记忆:实现连续对话
没有记忆的 Agent 就像金鱼,每次对话都从零开始。Spring AI Alibaba 提供了优雅且强大的记忆管理方案。
1. 开启会话记忆
仅需一行代码,即可为 Agent 添加记忆能力。
ReactAgent agent = ReactAgent.builder()
.name("chat_agent")
.model(chatModel)
.saver(new MemorySaver()) // 一行代码,开启记忆
.build();
// 使用 threadId 来维护独立的对话上下文
RunnableConfig config = RunnableConfig.builder()
.threadId("user_123")
.build();
agent.call(“我叫张三,我是Java开发”, config);
agent.call(“我叫什么名字?”, config);
// Agent 回答:“你叫张三,你是一名Java开发”
2. 生产环境使用 Redis 持久化
对于分布式生产环境,可以将内存存储替换为 Redis,实现记忆的持久化和跨实例共享。
// 内存版 → 生产替换为 Redis
ReactAgent agent = ReactAgent.builder()
.saver(new RedisSaver(redisTemplate)) // 分布式持久化
.build();
3. 消息自动压缩(控制成本与上下文长度)
随着对话轮次增加,上下文会越来越长,导致 Token 消耗剧增。框架提供了自动总结压缩的 Hook。
SummarizationHook summarizationHook = SummarizationHook.builder()
.model(chatModel) // 可使用更经济的模型进行总结
.maxTokensBeforeSummary(4000) // 触发总结的Token阈值
.messagesToKeep(20) // 总结后保留的最新消息数量
.build();
ReactAgent agent = ReactAgent.builder()
.hooks(summarizationHook)
.saver(new MemorySaver())
.build();
- ✅ 消息长度超过阈值后自动触发总结
- ✅ 只保留指定数量的最近消息,防止上下文窗口溢出
- ✅ 总结过程可使用成本更低的模型,有效控制费用
五、生产级功能:人工审批与安全护栏
这是 Spring AI Alibaba 最具吸引力的部分之一——开箱即用的企业级特性,为智能体应用保驾护航。
1. Human-in-the-Loop(人工审批)
对于删除数据、执行敏感 SQL 等高危操作,可以配置必须经过人工确认后才能执行。
// 1. 配置审批Hook
HumanInTheLoopHook humanReviewHook = HumanInTheLoopHook.builder()
.approvalOn(“execute_sql”,
ToolConfig.builder()
.description(“SQL执行需要人工审批”)
.build())
.build();
ReactAgent agent = ReactAgent.builder()
.hooks(humanReviewHook)
.saver(new MemorySaver())
.tools(executeSqlTool)
.build();
// 2. Agent 执行到该工具时会自动中断,等待人工确认
RunnableConfig config = RunnableConfig.builder()
.threadId(“user_123”)
.build();
Optional<NodeOutput> result = agent.invokeAndGetOutput(“删除过期数据”, config);
// 返回 InterruptionMetadata → 可通知前端弹出确认对话框
// 3. 人工确认后,携带元数据恢复执行
RunnableConfig resumeConfig = RunnableConfig.builder()
.threadId(“user_123”)
.addMetadata(RunnableConfig.HUMAN_FEEDBACK_METADATA_KEY, approvalMetadata)
.build();
Optional<NodeOutput> finalResult = agent.invokeAndGetOutput(“”, resumeConfig);
2. 安全护栏(Guardrail)
通过自定义拦截器,实现对输入和输出的双向安全检查,过滤敏感内容。
public class GuardrailInterceptor extends ModelInterceptor {
private static final List<String> BLOCKED = List.of(“密码”, “token”, “密钥”);
@Override
public ModelResponse interceptModel(ModelRequest request,
ModelCallHandler handler) {
// 前置检查:输入过滤
if (containsSensitive(request.getMessages())) {
return ModelResponse.of(new AssistantMessage(“检测到敏感内容,已拦截”));
}
// 正常调用模型
ModelResponse response = handler.call(request);
// 后置清洗:输出过滤
return sanitizeIfNeeded(response);
}
}
3. 模型调用限制
防止 Agent 陷入无限推理循环,限制其单次任务中调用大模型的最高次数。
// 限制 Agent 单次调用最多使用模型 10 次
ModelCallLimitHook limitHook = ModelCallLimitHook.builder()
.maxCalls(10)
.build();
ReactAgent agent = ReactAgent.builder()
.hooks(limitHook)
.build();
六、多 Agent 协同:从单兵作战到团队协作
1.1.2.0 版本 的一个重要更新是增强了多智能体协作能力,提供了6种主要模式,覆盖绝大多数企业应用场景。
将一个智能体作为另一个智能体的工具来调用,实现能力的嵌套和复用。
// 子Agent:写作专家
ReactAgent writerAgent = ReactAgent.builder()
.name(“writer_agent”)
.model(chatModel)
.description(“擅长写作,可以写文章”)
.build();
// 主Agent:博客管理Agent,将写作Agent当作一个工具使用
ReactAgent blogAgent = ReactAgent.builder()
.name(“blog_agent”)
.model(chatModel)
.instruction(“使用写作工具来完成用户的文章创作请求”)
.tools(AgentTool.getFunctionToolCallback(writerAgent))
.build();
blogAgent.invoke(“帮我写一篇关于西湖的散文”);
2. LLM 智能路由
根据用户问题的领域,自动将其路由到最合适的专家智能体进行处理。
// 创建两个专家Agent
ReactAgent writerAgent = ReactAgent.builder()
.name(“writer_agent”)
.description(“擅长创作各类文章,包括散文、诗歌等文学作品”)
.outputKey(“writer_output”)
.build();
ReactAgent codeAgent = ReactAgent.builder()
.name(“code_agent”)
.description(“专门处理编程相关问题”)
.outputKey(“code_output”)
.build();
// 路由Agent负责智能分发任务
LlmRoutingAgent routingAgent = LlmRoutingAgent.builder()
.name(“content_routing_agent”)
.model(chatModel)
.subAgents(List.of(writerAgent, codeAgent))
.build();
routingAgent.invoke(“帮我写一篇关于春天的散文”); // → 自动路由到 writerAgent
routingAgent.invoke(“帮我写一个Java排序算法”); // → 自动路由到 codeAgent
1.1.2.0 新增特性:路由 Agent 现在支持一次选择多个子 Agent 并行执行,极大提升了处理复杂任务的效率。
3. 六大多 Agent 协作模式速查
| 模式 |
核心特点 |
典型场景 |
| Supervisor(主管) |
主Agent协调子Agent,支持并行执行 |
同时查询邮件和数据库 |
| Handoffs(交接) |
多轮对话间状态持久化,动态切换Agent |
客服流程:收集信息 → 执行退款操作 |
| Skills(技能) |
能力按需披露,由Prompt驱动 |
单Agent根据需求动态扩展多种能力 |
| Routing(路由) |
按问题领域拆解并分派给不同Agent |
多领域知识库并行问答 |
| Sequential/Parallel(管道) |
前序节点输出作为后续节点输入 |
RAG 处理管道、固定业务流程 |
| Custom Workflow |
自定义图结构,混合编排以上模式 |
上述标准模式无法满足的复杂场景 |
对于希望深入探讨 Java 和 人工智能 结合的开发者,理解这些协作模式至关重要。
七、1.1.2.0 新特性:Agent Skills 技能体系
这个特性非常巧妙——Agent 的能力可以动态按需加载,而不是在初始化时就将所有工具描述塞进系统提示词(System Prompt)中。
核心机制:渐进式披露
初始状态:Agent 只知道技能列表(技能名 + 简要描述)
│
▼ 用户提问了一个需要PDF提取的问题
Agent 判断:需要调用 ‘pdf_extract’ 技能
│
▼ 自动调用 read_skill(“pdf_extract”)
动态加载完整的 SKILL.md 文件内容及关联的工具
│
▼ 使用 pdf_extract 技能下的工具处理用户请求
│
▼ 返回处理结果
带来的好处是显而易见的:
- ❌ 传统方式:将所有工具的详细描述都写入 System Prompt → 导致 Token 消耗巨大,成本高且可能超出模型上下文限制。
- ✅ Skills 方式:仅动态加载当前任务所需的技能描述 → 可节省 70% 以上的 Token 消耗,更加经济高效。
技能目录结构
技能以目录形式组织,每个技能是一个独立的文件夹。
skills/
├── pdf_extract/
│ ├── SKILL.md # 技能描述文件(必需)
│ ├── references/ # 该技能相关的参考资料
│ └── scripts/ # 可执行脚本或工具类
├── data_query/
│ ├── SKILL.md
│ └── examples/
└── code_review/
├── SKILL.md
└── references/
SKILL.md 文件规范
这是一个技能的核心描述文件,采用 Markdown 格式,包含元数据和详细说明。
---
name: pdf_extract
description: 从PDF文件中提取文本和表格数据
---
# PDF 提取技能
## 功能说明
支持从PDF文件中提取文本内容、表格数据和图片信息。
## 可用资源
- references/pdf_parser.py:PDF解析脚本
- scripts/batch_extract.sh:批量提取脚本
代码集成示例
// 1. 注册技能目录
SkillRegistry registry = new FileSystemSkillRegistry(“/path/to/skills”);
// 2. 构建技能钩子,将技能与具体工具关联
SkillsAgentHook skillsHook = SkillsAgentHook.builder()
.skillRegistry(registry)
.groupedTools(Map.of(
“pdf_extract”, List.of(pdfTool),
“data_query”, List.of(dbTool)
))
.build();
// 3. 将技能钩子注入Agent
ReactAgent agent = ReactAgent.builder()
.hooks(skillsHook)
.build();
八、开发过程中的常见“坑”与解决方案
坑1:DashScope API Key 未正确配置
现象:应用启动时报错 ApiKey is null。
解决方案:确保 API Key 已通过配置文件或环境变量设置。
# 方式1:在 application.yml 中配置(不推荐用于生产)
# spring.ai.dashscope.api-key=sk-xxxxx
# 方式2:使用环境变量(推荐,更安全)
export AI_DASHSCOPE_API_KEY=sk-xxxxx
坑2:工具定义时描述(description)过于简略或缺失
现象:Agent 几乎不调用工具,倾向于自己“编造”答案。
原因:FunctionToolCallback 的 description 字段是大语言模型(LLM)判断是否以及何时调用该工具的主要依据。描述不清,模型就无法理解工具用途。
// ❌ 错误:描述过于模糊
FunctionToolCallback.builder(“search”, new SearchTool())
.description(“搜索”) // 模型困惑:搜索什么?什么时候用?
.build();
// ✅ 正确:描述清晰明确
FunctionToolCallback.builder(“search”, new SearchTool())
.description(“搜索企业内部知识库,当用户询问公司政策、流程、产品信息时使用此工具”)
.build();
坑3:配置了 Hook 但未配置 Saver,导致功能失效
现象:配置了 HumanInTheLoopHook 或 SummarizationHook,但在多轮对话中不生效。
原因:这些 Hook 依赖对话状态的持久化(Saver)来记录中断点或历史消息。必须同时配置 Saver。
// ❌ 错误:只配置了 Hook,没有配置 Saver
ReactAgent agent = ReactAgent.builder()
.hooks(summarizationHook) // 不会生效!
.build();
// ✅ 正确:Hook 和 Saver 需配对使用
ReactAgent agent = ReactAgent.builder()
.hooks(summarizationHook)
.saver(new MemorySaver()) // 必须配置!
.build();
坑4:多 Agent 并行执行时,结果顺序混乱
现象:并行执行多个子 Agent 任务,最终聚合结果的顺序与预期不符。
解决方案:在 1.1.2.0 版本中,可以利用 AllOf 和 AnyOf 聚合策略来控制流程。
// AllOf:等待所有并行分支都完成后,再聚合结果继续执行。
// AnyOf:任一分支完成后即可聚合结果继续执行。
StateGraph workflow = new StateGraph(“my_workflow”, keyStrategyFactory);
workflow.addParallelEdge(
List.of(“research”, “analysis”, “writing”), // 三个并行执行的节点
AggregationStrategy.ALL_OF, // 等待全部完成
“merge_node” // 结果聚合节点
);
九、方案对比与总结
| 维度 |
纯API调用 |
LangChain4j |
Spring AI Alibaba |
| 启动代码量 |
~500行 |
~200行 |
<10行 |
| 多Agent编排 |
需手动实现路由逻辑 |
需手动构建Chain |
内置6种协作模式 |
| 记忆管理 |
需自行实现 |
需额外配置 |
一行配置即可 |
| 人工审批 |
不支持 |
不支持 |
内置Hook支持 |
| 上下文管理 |
需手动裁剪 |
需手动裁剪 |
支持自动压缩 |
| Spring生态集成 |
无 |
需适配 |
原生深度集成 |
| 学习曲线 |
⭐⭐ |
⭐⭐⭐⭐ |
⭐⭐ |
| 生产就绪度 |
⭐⭐ |
⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
十、Java 开发者学习路径建议
如果你是一名 Java 开发者,希望快速掌握 AI Agent 开发,我建议遵循以下路径:
1️⃣ Spring AI 基础(1-2天)
└── 掌握 ChatModel、Tool Calling、RAG 核心概念
2️⃣ Spring AI Alibaba 入门(1天)
└── 学会创建 ReactAgent、绑定工具、配置记忆
3️⃣ 进阶:上下文与管控(2天)
└── 掌握 Hook/Interceptor、Human-in-the-Loop、安全护栏
4️⃣ 高级:多智能体编排(2-3天)
└── 实践 Supervisor、Routing、Graph 工作流等模式
5️⃣ 实战:Agent Skills(1-2天)
└── 理解技能定义、渐进式披露、工具分组管理
写在最后
进入2026年,Java 生态下的 AI Agent 开发早已不再是“手搓轮子”的蛮荒时代。Spring AI Alibaba 做对了一件至关重要的事:将智能体编排、记忆管理、上下文工程等底层复杂性,全部封装到了框架层面。
作为开发者,我们的核心工作得以聚焦于两件事:
- 定义清晰、可靠的业务工具(Tools)。
- 编写高质量的指引(Prompt)。
剩下的繁重工作,就交给框架来处理吧。如果你正在或计划进行 Java AI Agent 相关的开发,强烈建议尝试一下 Spring AI Alibaba,它或许能让你避开我走过的那些弯路,更高效地构建智能、可靠的企业级应用。
希望这篇从实践出发的总结对你有帮助。如果你想与更多开发者交流类似的技术实践,可以关注 云栈社区 的相关讨论。