当 Java 开发者遇上 Spring AI 2.0:从 Chat 到 Agent,一文打通 AI 全栈能力
不需要 Python,不需要学新框架。用你熟悉的 Spring Boot,3 行代码接入大模型,10 行代码构建 AI Agent。
这不是又一个"Hello World"
你可能已经见过太多 AI 演示——一个聊天框,输入问题,输出答案。然后呢?
我们要做的是完全不同的事情。
想象一下:你的 Java 微服务,不仅能聊天,还能——
- 记住每个用户的对话历史,跨会话隔离
- 从你自己的知识库中检索答案,拒绝胡说八道
- 自主决定调用天气、搜索、数据库查询等工具
- 像一个真正的 Agent 一样,拆解复杂任务、多步推理、组合工具
- 看懂图片:OCR 文字识别、图表分析、代码截图转代码
- 同时接入通义千问 + DeepSeek 双模型,按需切换
- 通过 MCP 协议把工具暴露给外部 Agent
这一切,都在一个 Spring Boot 项目里完成。
技术栈:为什么是 Spring AI 2.0?
| 组件 | 选型 | 理由 |
|---|---|---|
| 基础框架 | Spring Boot 4.x | 最新 LTS,虚拟线程原生支持 |
| AI 抽象层 | Spring AI 2.0 | Spring 官方 AI 集成,统一抽象 |
| 大模型 | 通义千问 (qwen-plus) + DeepSeek | 国产模型,OpenAI 兼容协议 |
| 向量数据库 | PostgreSQL + pgvector | 一个数据库搞定关系数据 + 向量检索 |
| 嵌入模型 | text-embedding-v3 (1024 维) | 中文语义理解优秀 |
核心理念:不造轮子,不引入新语言,用 Java 生态的方式解决 AI 问题。
第一层:基础对话——不只是"聊天机器人"
// 就这么简单,3 行代码
chatClient.prompt()
.user("你好")
.call()
.content();
但基础不等于简单。Spring AI 的 ChatClient 提供了完整的对话能力矩阵:
| 能力 | 接口 | 亮点 |
|---|---|---|
| 普通对话 | /ai/chat |
同步响应 |
| 流式输出 | /ai/chat/stream |
SSE 实时推送,打字机效果 |
| 结构化输出 | /ai/extract |
自然语言 → Java Record,自动解析 |
结构化输出是最被低估的能力。 你告诉 AI “张三今年 25 岁,是软件工程师”,它直接返回一个 PersonInfo 对象——不需要你写任何正则或解析逻辑。
chatClient.prompt(new Prompt("提取人员信息:" + message))
.call()
.entity(PersonInfo.class); // 直接返回 Java 对象
第二层:PromptTemplate——让 AI 按你的剧本演
裸聊(raw prompt)是不靠谱的。你需要模板来约束 AI 的行为。
Spring AI 的 PromptTemplate 用 {variable} 占位符实现提示词复用,就像 Thymeleaf 之于 HTML:
// 产品描述模板
String template = "请为{category}类的产品"{product}"写一段{tone}风格的描述";
// 代码解释模板
String template = "请用{level}能理解的语言解释这段{language}代码:{code}";
// 自定义模板——通用入口
String template = "请用{language}写一个{function}的示例代码";
三个真实场景,一次演示:
| 场景 | 输入 | 效果 |
|---|---|---|
| 产品描述 | product=“Spring AI 实战手册”, tone=“专业且幽默” | 生成了一本技术书的营销文案 |
| 代码解释 | code=record Point, level=“初学者” |
按初学者水平,从语法到最佳实践逐层讲解 |
| 自定义模板 | language=“Python”, function=“快速排序” | 变量替换后直接生成带注释的完整代码 |
关键点:模板不是限制 AI,而是引导 AI。 就像给一个天才实习生一份 Brief——能力不变,但产出更可控。
第三层:ChatMemory——AI 终于有记忆了
LLM 本身是无状态的。每次请求都是"失忆"的。这在生产环境中不可接受。
// 基于 JDBC 的对话记忆,持久化到 PostgreSQL
private final ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository) // JDBC 持久化
.maxMessages(20) // 滑动窗口
.build();
// 通过 Advisor 自动拦截每次对话,注入历史上下文
chatClient = builder
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.build();
实际效果:
# 第 1 轮
> "你好,我叫小明"
< "你好,小明!..."
# 第 2 轮(同一个 conversationId)
> "我叫什么名字?"
< "你叫小明 ✅"
# 第 3 轮(换一个 conversationId)
> "我叫什么名字?"
< "你还没有告诉我你的名字呢~"
- 同一会话:上下文连贯
- 不同会话:完全隔离
- 记忆持久化:重启服务不丢失
DELETE /ai/memory/{id}:一键清除
第四层:Tool Calling——让 AI 学会"动手"
这是 AI 从"聊天机器人"进化为"智能助手"的关键一步。
@Component
public class WeatherTools {
@Tool(description = "获取指定城市的当前天气信息")
public String getWeather(@ToolParam(description = "城市名称") String city) {
return switch (city) {
case "北京" -> "晴天,25°C,空气质量良好";
case "上海" -> "多云,28°C,湿度 65%";
default -> "未知城市";
};
}
}
// AI 自动决定是否调用、何时调用
chatClient.prompt()
.user("北京今天天气怎么样?")
.tools(weatherTools, timeTools, searchTools)
.call()
.content();
工作流程:
用户提问 → AI 分析意图 → 自动生成工具调用请求
→ Spring AI 执行 Java 方法 → 结果返回给 AI
→ AI 基于工具结果生成最终回答
AI 不是"被编程"去调用工具,而是自主决定何时调用哪个工具。你问天气,它调 WeatherTools;你问时间,它调 TimeTools;你问技术问题,它调 SearchTools。
第五层:ReAct Agent——AI 的"自主思考"
Tool Calling 是"被动触发",Agent 是"主动规划"。
ReAct(Reasoning + Acting)模式下,AI 会:
- 理解任务目标
- 拆解为子任务
- 选择合适的工具
- 基于中间结果调整策略
- 整合输出最终答案
// Agent 处理复杂任务
chatClient.prompt()
.system("""
你是一个强大的 AI Agent,擅长解决复杂问题。
解决步骤:理解目标 → 分解任务 → 选择工具 → 整合信息
""")
.user("我想去杭州旅游,帮我查天气,介绍景点,规划行程")
.tools(weatherTools, timeTools, searchTools)
.call()
.content();
更疯狂的是:我们构建了一个"项目演示 Agent"。
这个 Agent 拥有 11 个工具——检查服务健康、验证 Web/Dubbo/gRPC 调用、查看 Nacos 服务列表、验证配置管理……你只需要说一句"全面验证本项目",它就会自主规划执行顺序,逐个调用工具,最后输出汇总报告。
> "全面验证本项目"
Agent 内部:
1. 调用 checkEnvironment → 检查中间件状态
2. 调用 checkAllServices → 确认各模块运行
3. 调用 verifyWebCall → 验证 Web 链路
4. 调用 verifyDubboCall → 验证 Dubbo 链路
5. 调用 verifyGrpcCall → 验证 gRPC 链路
6. 调用 checkNacosServices → 查看服务注册
7. 整合所有结果 → 输出完整报告
AI 不再只是回答问题,它在"做事"。
第六层:RAG 检索增强生成——让 AI 只说你知识库里的话
LLM 最大的问题是"幻觉"——一本正经地胡说八道。RAG 用你自己的数据来约束它。
完整流程:
文档摄入 → TokenTextSplitter 自动分块
→ Embedding 模型向量化 → PgVector 存储
用户提问 → 向量相似性检索 → 找到最相关的文档片段
→ 拼接上下文到 Prompt → LLM 基于事实生成回答
// 摄入文档
Document doc = new Document(content);
List<Document> chunks = TokenTextSplitter.builder().build().split(doc);
vectorStore.add(chunks);
// RAG 查询
List<Document> docs = vectorStore.similaritySearch(
SearchRequest.builder().query(question).topK(3).build()
);
String context = docs.stream().map(Document::getText).collect(joining("\n"));
// 将 context 注入 Prompt,让 LLM 基于事实回答
实测对比(temperature 对 RAG 效果的影响):
| temperature | 效果 |
|---|---|
| 0.7 | AI 忽略检索到的文档,凭预训练知识回答,可能产生幻觉 |
| 0.2 | AI 忠实引用"参考资料",回答有据可查 |
经验:RAG 场景下 temperature 建议 0.1~0.3。 你不需要 AI 发挥创造力,你需要它忠于事实。
第七层:多模态视觉——AI 能"看"了
// 双 ChatClient 架构:纯文本用 qwen-plus,视觉用 qwen3.7-plus
@Bean
ChatClient visionChatClient(ChatClient.Builder builder) {
return builder.build(); // 预配置多模态模型
}
// 图片分析
visionChatClient.prompt()
.user(userSpec -> userSpec
.text("请描述这张图片")
.media(MediaType.IMAGE_JPEG, imageResource))
.call()
.content();
6 个视觉接口,覆盖真实业务场景:
| 接口 | 场景 |
|---|---|
| URL 图片分析 | 远程图片理解 |
| 上传图片分析 | 客户端上传 |
| OCR 文字识别 | 图片中的文字提取 |
| 图表分析 | 数据图表解读 |
| 代码截图转代码 | 看到代码截图,直接输出可运行代码 |
| 多图片对比 | 两张图同时分析差异 |
第八层:多模型管理——DashScope + DeepSeek 共存
spring:
ai:
openai: # 通义千问(OpenAI 兼容协议)
chat:
options:
model: qwen-plus
deepseek: # DeepSeek(独立提供商)
chat:
options:
model: deepseek-v4-pro
同一个模块内,两个模型提供商共存。通过 @Primary 和具名注入解决 ChatClient 歧义:
- 默认请求走通义千问
- DeepSeek 接口走独立 ChatClient
- 视觉接口自动切换多模态模型
这不是简单的"支持多个 API",而是展示 Spring AI 的模型治理能力。
第九层:MCP Server——把工具暴露给全世界
MCP(Model Context Protocol)是 AI Agent 间通信的标准协议。你的工具不再只服务于自己的 Agent,还可以被外部 Agent 发现和调用。
@Configuration
public class McpServerConfig {
@Bean
public ToolCallbackProvider mcpToolProvider(
WeatherTools weatherTools,
TimeTools timeTools,
SearchTools searchTools, ...) {
return MethodToolCallbackProvider.builder()
.toolObjects(weatherTools, timeTools, searchTools, ...)
.build();
}
}
一套 @Tool 注解,两处复用:
- 内部:Tool Calling / ReAct Agent 直接调用
- 外部:通过 MCP Server 的 SSE 端点暴露给其他 Agent
架构全景
┌─────────────────────────────────────────────────────┐
│ AI 模块 (8888) │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ 基础对话 │ │ PromptTemplate│ │ ChatMemory │ │
│ │ 流式/SSE │ │ 变量替换 │ │ JDBC 持久化 │ │
│ └──────────┘ └──────────────┘ └───────────────┘ │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │Tool Call │ │ ReAct Agent │ │ Vision │ │
│ │ @Tool │ │ 多步推理 │ │ 多模态识别 │ │
│ └──────────┘ └──────────────┘ └───────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ DeepSeek 双模型 │ │ MCP Server (SSE 暴露) │ │
│ └──────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ RAG 模块 (8889) │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ 文档摄入 │ │ 向量相似检索 │ │ 上下文增强 │ │
│ │ 自动分块 │ │ PgVector │ │ LLM 生成 │ │
│ └──────────┘ └──────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────┘
│ │
└──────── PostgreSQL ──────────┘
(关系数据 + 向量存储 + 对话记忆)
写在最后
从 3 行代码的简单对话,到自主调用 11 个工具的 ReAct Agent;从"AI 会胡说八道"到 RAG 知识约束;从无状态的记忆丢失到 JDBC 持久化的会话隔离。
这不是 PPT,不是 Demo 视频,是可以 git clone 下来直接跑的代码。
git clone https://github.com/hongxi/spring-cloud-samples
export OPENAI_API_KEY=your-key
# 启动 AI 模块
./mvnw -pl cloud-ai-sample spring-boot:run
# 启动 RAG 模块
./mvnw -pl cloud-ai-rag-sample spring-boot:run
技术栈: Spring Boot 4.x + Spring AI 2.0 + 通义千问 + DeepSeek + PostgreSQL + pgvector
覆盖能力: 对话 / 流式输出 / 结构化输出 / PromptTemplate / ChatMemory / Tool Calling / ReAct Agent / MCP Server / RAG / 多模态视觉 / 多模型管理
Spring AI 2.0 让 Java 开发者用熟悉的方式拥抱 AI。不是"也能用",而是用得优雅。
项目地址:spring-cloud-samples
作者:javahongxi | 基于 Spring Boot 4.x + Spring Cloud Alibaba 2025.1.x
更多推荐




所有评论(0)