Spring AI 实战入门案例
(2026年初 · 零基础到能跑完整小应用的路径)
目标:用最短时间让你能自己跑通一个包含以下功能的 Spring AI 小应用:
- 普通聊天
- 流式输出(打字机效果)
- 带记忆的对话
- 简单 RAG(知识库问答)
- 结构化输出(JSON → Java 对象)
推荐起点技术栈(2026年1月最友好组合)
Spring Boot 3.3.x / 3.4.x
Spring AI 1.0.x ~ 1.1.x (稳定版已发布很久)
模型选择 DeepSeek-V3 / DeepSeek-R1(硅基流动中转)或 Ollama 本地
向量存储 内存(SimpleVectorStore)→ 先体验,后面可换 PGVector/Redis/Chroma
极简起步项目(5分钟能跑起来)
- 使用 start.spring.io 创建项目
- Dependencies:Spring Web + Spring AI OpenAI Starter(后面改配置即可兼容 DeepSeek)
- Java 21(推荐)/ 17
- application.yml 最简配置(硅基流动 + DeepSeek-R1 示例)
spring:
ai:
openai:
base-url: https://api.siliconflow.cn/v1 # 硅基流动(性价比最高)
api-key: sk-你的硅基流动key(新用户送很多免费token)
chat:
options:
model: deepseek-ai/DeepSeek-R1 # 强推理
# model: deepseek-ai/DeepSeek-V3 # 更万能/快
temperature: 0.7
max-tokens: 4096
综合入门案例 – 单文件 Controller(复制粘贴就能跑)
@RestController
@RequestMapping("/ai/easy")
@RequiredArgsConstructor
public class EasyAiController {
private final ChatClient chatClient;
private final EmbeddingModel embeddingModel; // 用于 RAG
// 内存向量存储(最简单,启动即有)
private final VectorStore vectorStore = new SimpleVectorStore(embeddingModel);
// 启动时自动加载一点知识(模拟知识库)
@PostConstruct
public void loadSomeKnowledge() {
var docs = List.of(
"Spring AI 是 Spring 官方出品的大模型集成框架,目标让 Java 开发者用最熟悉的方式玩 AI。",
"ChatClient 是核心高层抽象,像 RestClient 一样好用。",
"目前最受欢迎的国内模型组合:DeepSeek-R1(推理强)+ DeepSeek-V3(综合最强)。",
"2025年下半年 Spring AI 正式 1.0,2026年已经非常稳定成熟。"
);
vectorStore.add(docs.stream()
.map(content -> new Document(content, Map.of("type", "spring-ai-intro")))
.toList());
}
// 1. 最基础聊天
@GetMapping("/chat")
public String chat(@RequestParam String q) {
return chatClient.prompt()
.user(q)
.call()
.content();
}
// 2. 流式输出(前端打字机神器)
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> stream(@RequestParam String q) {
return chatClient.prompt()
.user(q)
.stream()
.content();
}
// 3. 带记忆 + 系统角色(最实用写法)
private final ChatMemory memory = new MessageWindowChatMemory(8); // 保留最近8轮
@GetMapping("/memory")
public String memoryChat(
@RequestParam String session, // 区分不同会话
@RequestParam String q) {
return chatClient.prompt()
.system("""
你是一个说话很幽默、爱用表情、非常接地气的「资深Java老鸟」
尽量用 markdown 排版,喜欢用生活化比喻
""")
.user(q)
.advisors(MessageChatMemoryAdvisor.builder()
.chatMemory(memory)
.sessionId(session) // 重要:按会话隔离记忆
.build())
.call()
.content();
}
// 4. 简单 RAG(基于上面加载的知识库)
@GetMapping("/rag")
public String rag(@RequestParam String question) {
// 检索最相似的3段知识
var results = vectorStore.similaritySearch(
SearchRequest.query(question).withTopK(3));
String context = results.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n---\n\n"));
return chatClient.prompt()
.system("你现在是基于以下文档知识回答问题的专家助手:\n\n" + context +
"\n\n只用给出的信息回答,不要编造。如果不知道就说不知道。")
.user(question)
.call()
.content();
}
// 5. 结构化输出(最推荐的生产用法之一)
public record JokeResponse(
String setup,
String punchline,
String emoji,
Integer difficulty // 1~10
) {}
@GetMapping("/joke")
public JokeResponse structuredJoke(@RequestParam(defaultValue = "程序员") String theme) {
var converter = new BeanOutputConverter<>(JokeResponse.class);
String jsonSchema = converter.jsonSchema;
String prompt = """
请讲一个关于「%s」的笑话。
必须严格按照以下 JSON Schema 输出,不要多一个字:
%s
""".formatted(theme, jsonSchema);
String json = chatClient.prompt(prompt).call().content();
return converter.convert(json);
}
}
快速进阶方向建议(按实用度排序)
| 顺序 | 功能 | 大概难度 | 建议练习项目 | 预计耗时 |
|---|---|---|---|---|
| 1 | Function Calling | ★★☆ | 写一个「查天气+查汇率+生成周报」的工具助手 | 4~8h |
| 2 | 更好的 RAG | ★★★ | 用 PGVector/Redis + 上传 pdf/docx 问答 | 8~15h |
| 3 | Agent / ReAct | ★★★★ | 写一个「程序员小助手」能自己思考调用工具 | 15~30h+ |
| 4 | 多模态(图片理解) | ★★★☆ | 接入通义千问/智谱GLM-4V 做图片描述/OCR | 6~12h |
| 5 | 语音输入输出 | ★★★★ | Whisper + TTS 语音聊天机器人 | 20h+ |
最快上手口诀(2026版):
先跑通 ChatClient + 流式 + 记忆 → 再加 简单 RAG → 再学 结构化输出 → 再玩 Function Calling → 最后冲 Agent
需要我帮你把上面某个功能再展开成更详细的完整小项目(带依赖、配置、测试页面)吗?
直接说你最想先做哪一块~ 😄