如何用 Spring AI + Ollama 構建生成式 AI 應用
一、故事背景:Java 老炮兒與 AI 新秀的較量
上周,產品經理拍著桌子說:"三天內必須上線智能客服!要能回答訂單查詢、退換貨政策,還要會講冷笑話!" 我盯著需求文檔陷入沉思:傳統規則引擎就像老黃牛,拉不動這么重的活;調用 OpenAI 又怕數據泄露——這不是讓 Java 程序員在鋼絲上跳霹靂舞嗎?
這時候,實習生小王推了推眼鏡:"試試 Spring AI + Ollama 唄!本地部署大模型,既能裝逼又安全!" 這場景讓我想起《黑客帝國》里 Neo 看到數據流的瞬間——當我們還在用 if-else 寫邏輯時,年輕人已經掏出了矩陣級解決方案。
二、技術選型:為什么是這對 CP?
1. Spring AI:Java 界的 AI 翻譯官
- 零門檻上車:@Autowired 注入 LLM 客戶端,比寫 MyBatis 還簡單
- 企業級 buff:支持模型版本控制、請求限流、審計日志,CTO 看了都說穩
- 生態融合:和 Spring Boot 天生一對,老項目改造就像換火花塞
2. Ollama:本地部署的 AI 變形金剛
- 數據安全屋:所有計算本地完成,數據不出服務器半步
- 模型百寶箱:LLaMA2、Mistral、CodeLlama 應有盡有
- 性能黑科技:基于 Metal Performance Shaders 加速,MacBook Pro 秒變煉丹爐
小王神補刀:"這就像你家樓下開了個私人影院,想看啥片自己選,還不怕被鄰居偷聽。"
三、實戰開發:從 Hello World 到智能客服
第一步:環境搭建(10 分鐘搞定)
# 安裝 Ollama(Mac 專屬福利)
brew install ollama
# 啟動服務(像啟動 Tomcat 一樣簡單)
ollama serve
# 拉取中文模型(注意別手抖寫成 pull request)
ollama pull mistral:7b-v0.1
小插曲:小王把 pull
敲成 push
,結果把本地模型推到公共倉庫,嚇得他連夜改密碼——這波操作像極了把私人日記發朋友圈。
第二步:Spring AI 集成
<!-- 添加依賴,比追女朋友還直接 -->
<dependency>
<groupId>com.ai.ollama</groupId>
<artifactId>ollama-spring-boot-starter</artifactId>
<version>0.2.1</version>
</dependency>
配置文件設置模型參數:
ollama:
endpoint: http://localhost:11434
model: mistral:7b-v0.1
temperature: 0.8 # 0.1 是鋼鐵直男,1.0 是話癆文藝青年
max_tokens: 256 # 回答長度控制,比領導講話還精煉
第三步:核心業務邏輯
@Service
public class ChatService {
private final OllamaClient ollamaClient;
public ChatService(OllamaClient ollamaClient) {
this.ollamaClient = ollamaClient;
}
public String generateResponse(String query) {
// 給 AI 穿上客服制服
String prompt = """
你是專業電商客服豆包,回答要簡潔。用戶問:%s
""".formatted(query);
// 調用模型生成回答,像調用 Dubbo 接口一樣絲滑
return ollamaClient.generate(OllamaRequest.builder()
.model("mistral:7b-v0.1")
.prompt(prompt)
.build())
.stream()
.map(OllamaResponse::getContent)
.collect(Collectors.joining());
}
}
隱藏彩蛋:當用戶問"你是誰"時,AI 會回答:"我是您的專屬豆包,由 Spring AI 和 Ollama 聯合驅動,比您的前任更可靠。"
四、性能優化:讓 AI 跑得比老板的 KPI 還快
1. 緩存加速(給 AI 配小本本)
private final Map<String, String> cache = new ConcurrentHashMap<>();
public String generateResponse(String query) {
if (cache.containsKey(query)) return cache.get(query);
String response = ollamaClient.generate(...);
cache.put(query, response);
return response;
}
注意:涉及隱私的問題不能緩存,比如用戶的銀行卡密碼——AI 也得守規矩。
2. 異步處理(多線程拯救世界)
@Async("chatExecutor")
public CompletableFuture<String> generateResponseAsync(String query) {
return CompletableFuture.supplyAsync(() ->
ollamaClient.generate(...).stream().collect(Collectors.joining())
);
}
線程池配置建議:核心線程數=CPU 核心數,最大線程數=核心數×2,隊列大小=核心數×10——比火鍋配菜搭配還講究。
3. 流式響應(實時看 AI 打字)
@GetMapping("/stream")
public Flux<String> streamResponse(@RequestParam String query) {
return ollamaClient.generateStream(OllamaRequest.builder()
.prompt(query)
.build())
.map(OllamaResponse::getContent);
}
效果:用戶能看到"豆包正在思考中…",就像看主播直播寫代碼,體驗感拉滿。
五、進階玩法:解鎖 AI 的隱藏技能
1. 多模態交互(AI 識圖功能)
public String handleImageQuery(MultipartFile image) throws IOException {
String imageText = ocrService.recognize(image.getBytes());
return chatService.generateResponse(imageText);
}
應用場景:用戶發產品圖問"這是什么型號",AI 直接返回購買鏈接——比導購員還機靈。
2. 上下文管理(記住聊天歷史)
private final Map<String, List<Message>> historyMap = new ConcurrentHashMap<>();
public String generateResponse(String userId, String message) {
List<Message> history = historyMap.computeIfAbsent(userId, k -> new ArrayList<>());
history.add(new Message("user", message));
String prompt = buildPromptWithHistory(history);
String response = ollamaClient.generate(prompt);
history.add(new Message("assistant", response));
return response;
}
效果:用戶說"昨天推薦的手機",AI 能接著之前的話題聊——比人類還記性好。
3. 自定義插件(給 AI 安裝 APP)
@Bean
public OllamaPlugin calculatorPlugin() {
return new OllamaPlugin("calculator")
.addFunction("calculate", this::calculate)
.addSchema(CalculatorSchema.class);
}
private Double calculate(CalculatorRequest req) {
return req.getA() + req.getB();
}
用戶問"100 加 50 等于多少",AI 直接調用插件計算,比程序員用 Excel 還快。
六、避坑指南:AI 開發的十大禁忌
- 模型越大越好:用 70B 模型回答"今天天氣如何",就像用牛刀殺雞
- 忽略 prompt 工程:直接把用戶問題丟給 AI,結果生成火星文
- 數據裸奔:把身份證號傳給云端模型,等于把金庫鑰匙交給陌生人
- 性能預估錯誤:用 8GB 內存跑 70B 模型,結果服務器直接 OOM
- 沒有監控報警:AI 返回"我要統治人類"才發現模型中毒
- 缺乏回退機制:模型故障時讓用戶干等,比春運搶票還絕望
- 倫理失守:生成虛假醫療建議,可能吃官司
- 版本混亂:不同環境用不同模型版本,導致回答人格分裂
- 技術黑話:返回"根據余弦相似度計算…",用戶直接黑人問號臉
- 沒有測試用例:直接上線生產,結果用戶問"怎么退貨",AI 開始寫詩
血淚教訓:小王把 temperature 設為 1.5,AI 直接開始創作七言絕句,用戶投訴“
客服是文藝青年”——這波操作像極了讓數學老師教語文。
七、行業洞察:生成式 AI 的未來在哪里?
1. 企業級應用爆發
- 代碼生成:自動補全、單元測試生成,程序員可能失業?
- 數據分析:自動生成 SQL 查詢,BI 工程師瑟瑟發抖
- 文檔處理:合同條款自動解析,法務部要換人?
2. 硬件軍備競賽
- 蘋果 M3 Max 芯片跑 30B 模型無壓力
- 國產昇騰芯片性能逼近英偉達 A100
- 量子計算研究取得突破,傳統 GPU 瑟瑟發抖
3. 監管政策收緊
- GDPR 要求 AI 生成內容必須標注
- 中國《生成式人工智能服務管理暫行辦法》正式實施
- 歐盟 AI Act 將模型分為四個風險等級