一名 Java 后端的 AI 转型实录(一):Day 1,让 Spring AI 说出第一句话
AI 转型系列 · 第 1 篇(共 8 篇)
系列目标:8 周,从 Spring Boot 老兵到开源 RAG 项目作者。这是第一篇,也是最"笨"的一天——搭环境、踩坑、跑通一个接口。但所有的路都从这里开始。
为什么写这个系列
我做 Java 后端多年,Spring 全家桶闭着眼写。但最近投简历、看 JD,风向变了:后端岗十有八九挂着 “有 AI 应用开发经验优先”。
与其隔着文档纸上谈兵,不如动手下水实践。但动手之前,我先梳理清楚学习边界,先明确哪些东西可以先不学,避免精力错配:
不去深耕大模型算法底座。神经网络、反向传播等底层数学原理不作为学习重点。我的目标不是转型算法工程师,而是将大模型能力集成到现有业务系统—— 这恰恰是传统 Java 后端工程师的主场优势。
真正需要重点攻克的是四块内容:
- 大模型 API + Tool Calling。不只是简单调用模型接口,核心是实现模型反向调用业务系统能力,这是区分「玩具 Demo」和「生产可用 AI 应用」的关键分水岭;
- Prompt 工程与结构化输出。随着大模型能力越来越强,传统花式 Prompt 技巧的权重正在降低。业务场景下更有价值的是保障模型输出结构化、可被代码解析,做好输出校验与异常兜底;
- 深耕 RAG(检索增强生成)。文档切分策略、重排序 (Rerank)、查询改写、效果评测体系,是本系列的主线。不能只停留在 “了解 RAG 概念”,要吃透完整链路,这也是后端工程师做 AI 应用的核心壁垒;
- Agent 编排与效果评测。把原型 Demo 打磨到可上生产环境的最后一环。
学习方法论我只坚持一条:在使用中学习。以完整项目作为主线,token 长度限制、大模型幻觉成因、向量语义检索这些原理,在调试报错、解决问题的过程中自然建立认知。拒绝 “先埋头学三个月理论再动手写代码” 的完美主义,避免只学理论缺乏实战。
整体计划是:8 周,每天下班 2 小时 + 周末 4 小时,产出一个 GitHub 开源 RAG Demo,实现能力跃迁:从只会简单调用大模型 API,到完整理解 RAG 全链路、拥有可复现的评测数据集。
本系列会完整记录每周实战过程,包含成功的经验,也记录真实翻车踩坑现场。本文就是 Day 1 的全部记录。
技术选型:尽可能零额外资金成本
作为对成本敏感的开发工程师,本次实践优先选择免费开源组件,环境清单如下:
| 组件 | 选择 | 成本 |
|---|---|---|
| JDK | Temurin 21(项目编译运行)+ JDK 25(Cursor IDE 语言服务器扩展运行) | 0 元 |
| 框架 | Spring Boot 3.5.3 + Spring AI 1.1.0 | 0 元 |
| 模型 | 本地 Ollama 运行 qwen3.8:27b | 0 元(电费除外) |
| IDE | Cursor,通过离线 vsix 方式安装扩展,规避网络市场访问问题 | 已订阅 |
| Maven 依赖源 | Maven 阿里云镜像 | 0 元 |
这里有个值得一提的细节:Spring AI Alibaba项目早已停止维护,Maven 包版本停留在 2023‑11,不再适配新版本 Spring AI。
目前 Java 生态做 AI 应用开发主流两条路线:官方 Spring AI、LangChain4j。本系列第一周优先实践 Spring AI。
搭建工程:六步流程,三次真实翻车
准备好软硬件环境后开始搭建项目。没有使用 Spring Initializr 网页生成工程,选择手写 pom.xml,完整流程分为六步:手写 pom → application‑yml 配置集成 → 编写最小业务代码 → 编译报错翻车 → 问题排查定位 → 冒烟测试验证通过,其中一半时间都在处理各类报错。
pom.xml 里面三个关键版本决策:
<!-- 决定一:Boot 3.5 是 Spring AI 1.x 的舒适区 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.3</version></parent><!-- 决定二:JDK 21 + Spring AI 1.1.0 --><properties><java.version>21</java.version><spring-ai.version>1.1.0</spring-ai.version></properties><!-- 决定三:spring-ai-bom 一揽子管版本,子依赖不用写版本号 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><!-- Ollama 集成:注意 starter 名字,1.0 之后改叫这个 --><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-ollama</artifactId></dependency></dependencies>两个非常容易踩的版本坑,给刚入门的同学提醒::
- 不要直接照搬网上旧教程的版本号:网上大量博客还在使用 M1/M2 里程碑版本,里程碑版本需要额外配置 spring‑milestones 仓库。可以用
mvn dependency:resolve命令查看 Maven 中央仓库可用版本;1.1.0 是正式 GA 发布版,不需要配置任何额外的里程碑仓库。 - Starter 坐标名称已经变更:1.0 GA 版本之后 Ollama starter 改为
spring‑ai‑starter‑model‑ollama;老的spring‑ai‑ollama‑spring‑boot‑starter属于历史旧写法,只适用于里程碑版本。
然后是 yml——整个"集成"就几行:
spring:ai:ollama:base-url:http://localhost:11434chat:options:model:qwen3.8:27b-mlx写完配置,再编写二十行左右 Java 代码,执行mvn compile,
第一次翻车来了:
找不到符号: 类 MessageChatMemoryAdvisor 位置: 程序包 org.springframework.ai.chat.memory原因是 AI 生成的示例代码引用了旧版本包路径。我用一个比较直接有效的排查手段:直接解压本地 Maven 仓库的 jar 包,查看实际类路径:
$unzip-lspring-ai-client-chat-1.1.0.jar|grepMemoryAdvisor org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.classGA 1.0 版本之后,MessageChatMemoryAdvisor被移动到org.springframework.ai.chat.client.advisor包,修改 import 导入路径后编译正常。
编译通过,启动项目调用接口
第二次翻车:接口返回 404。查看异常日志核心信息:
NonTransientAiException: HTTP 404 - {"error":"model 'qwen3.8:27b-mlx-32k' not found"}yml 配置里写了一个我本地已经删除的模型标签。执行ollama list核对本地已下载模型列表,修正配置中 model 名称,重启应用。
第三次翻车比较隐蔽:应用明明正常启动,但是服务监听端口变成莫名其妙的 4397,并不是配置文件写的 8080。
翻阅 Spring Boot 官方文档才理清根源:Spring Boot 配置源有十多个,application.yml 的优先级其实很低;操作系统环境变量优先级高于 yml 配置文件,再加上松散绑定 (Relaxed Binding) 机制,环境变量SERVER_PORT会映射为配置server.port。本机某个桌面工具通过 MacOSlaunchctl setenv设置了全局会话环境变量,Spring Boot 直接读取这个高优先级环境变量覆盖 yml 配置。
排查清除环境变量的命令三连:
env | grep SERVER # ① 终端环境里确实有它 launchctl getenv SERVER_PORT # ② 来源:launchd 全局注入 launchctl unsetenv SERVER_PORT # ③ 清掉,重启终端后永久生效📝复盘时间分配:版本选型、业务编码只占 40% 的工作量;剩下 60% 时间全部消耗在环境、配置、版本兼容的排错上。传统后端转型 AI 应用开发,调试排错能力甚至比写业务代码更重要。
小建议:可以使用 AI 生成 Spring AI 代码片段,但生成的代码务必对照官方文档校验 API、包路径。大模型训练数据会滞后,经常输出过时里程碑版本 API。
核心代码:二十行代码对接本地 27B 大模型
排除所有环境干扰后,跑通本地 Ollama 模型的核心 Controller 代码非常简洁:
@RestController@RequestMapping("/api")publicclassChatController{privatefinalChatClientchatClient;publicChatController(ChatModelchatModel){this.chatClient=ChatClient.create(chatModel);}@GetMapping("/chat")publicStringchat(@RequestParamStringq){returnchatClient.prompt().user(q).call().content();}}启动 Spring Boot,浏览器访问http://localhost:8080/api/chat?q=hello,本地运行的 27B 大模型正常返回回答。
我们没有手写 HTTP 请求、没有手动解析模型返回 JSON 报文。几行配置替代了以前自己封装一个模型对接层的三天工作。这是 Spring AI 的自动装配承诺:换供应商(Ollama → OpenAI)只改配置不改代码。
Day1 必须吃透的三个核心概念
代码量很少,但底层抽象概念要理解清楚,后续开发才不会懵。今天我逼自己分清这三兄弟:
| 概念 | 一句话理解 | 怎么记 |
|---|---|---|
| ChatModel | 大模型底层抽象接口,Ollama、OpenAI、通义千问等都有各自实现 | 设计模式策略模式里的策略接口,屏蔽不同模型服务商差异 |
| ChatClient | 门面 + 流式构建器,日常 90% 代码跟它打交道 | AI 时代的 RestTemplate,封装对话请求、参数组装、响应解析 |
| Advisor | 请求发送前、响应返回后的拦截增强组件 | 类比 SpringMVC HandlerInterceptor,可以追加记忆、日志、权限校验等逻辑 |
记住基础调用链路即可:prompt() → user() → call() → content()。下一篇会实践stream()流式返回,使用 Advisor 实现对话记忆能力。
今天踩的坑合集(按出现顺序)
- AI 生成旧版 API 代码:
MessageChatMemoryAdvisor包路径在 1.0 GA 发生迁移。AI 输出代码需要核对官方文档校验包名; - brew 安装 JDK 下载超时:官方源网络速度慢,替换为国内清华镜像可以大幅提升下载速度;
- 清华 Maven 镜像部分插件缺失:部分组件镜像不全,拉取依赖失败,换成阿里云 Maven 镜像更稳定;;
- Cursor 扩展市场网络无法访问:市场地址硬编码,无法修改;解决方案:VSCode 市场下载 vsix,离线手动安装扩展;
- redhat.java 语言服务器需要更高 JDK 版本:IDE 语言服务器运行时和项目编译 JDK 相互独立;通过配置
java.jdt.ls.java.home指定 JDK25,项目依旧使用 JDK21; - Ollama 报 model not found:yml 配置填写本地不存在 / 已经删除的模型标签,使用
ollama list核对本地模型名称。
单独看每一个坑难度都不大,但短时间连续遇到多个环境问题,很容易打击积极性。全部调试通过之后才会体会到,“环境就绪” 四个字背后工作量远超想象。
Day 1 的收获清单
- ✅ 环境:双 JDK 环境搭建(21 用于项目编译运行 / 25 用于 IDE 语言服务器),配置阿里云 Maven 镜像,Cursor 离线安装扩展;
- ✅ 工程:搭建 Spring Boot 3.5.3 + Spring AI1.1.0 完整骨架,所有 Maven 依赖坐标经过实际验证;
- ✅ 完成第一个对话接口,成功调用本地 27B 开源大模型,全程不需要调用付费大模型 API;
- ✅ 建立核心抽象认知:理解 ChatModel / ChatClient / Advisor 的职责。
写在最后
Day 1 的技术含量其实不高,真正难的是"从想学到开始学的那个决定",以及把环境磨到能跑的那份耐心。我给自己定了一条实践纪律:每天完成一个小闭环,宁可学的少一点,不要直接断更断实践。这条准则,比一份完美的学习路线图更加重要。
明天 Day 2:stream()流式输出 + 记忆 Advisor,让模型"认识"我。如果你也在转型路上,欢迎评论区交流你今天踩的坑。
本文是「Java 后端 AI 转型实录」系列第 1 篇(共 8 篇)。项目后续会开源在 GitHub(链接见主页),每周更新。