看到这个标题点进来的,估计都是这两天在技术群里听到风声的Java开发者。说实话,“Spring AI Alibaba已停更”这个说法刚传开的时候,我心里也咯噔了一下,毕竟去年大家还在讨论怎么用Spring AI统一接入各家大模型,结果官方适配层说躺平就躺平,难免让人怀疑Java在AI时代是不是真的要被拍在沙滩上。
但冷静下来,把项目仓库翻了一遍,又动手写了几个Demo之后,我的判断反而更坚定了:Spring AI Alibaba停更这件事,并不代表Java没戏,反而说明AI应用开发正在从“谁接得快”走向“谁控得住”的阶段。这篇文章就围绕这个大家最近都在刷的话题展开,先把停更的背景和真实影响说清楚,再分析Java剩下的可行路线,最后给一套我自己跑通的本地RAG实操方案,以及几个折腾过程中踩过的坑。不管你是刚入门的Java新人,还是正在评估技术路线的老手,这篇文章应该能帮你省掉不少试错的功夫。
1. 停更到底是怎么一回事
1.1 先说清楚它是什么
Spring AI Alibaba是阿里在Spring AI基础上做的一个适配层,主要作用是让Java开发者能通过Spring Boot的自动配置,快速接入通义千问的DashScope服务,同时兼容Nacos服务发现等阿里生态组件。用一句话概括:它是Spring AI和国内大模型之间的一座桥。
先纠正一个常见的误会:Spring AI Alibaba停更,不等于Spring AI死了。Spring AI是Spring官方主推的AI集成框架,是活蹦乱跳的,新版本持续在发,现在还支持了更多模型供应商和工具调用能力。而Spring AI Alibaba只是Spring AI生态里的一个“方言适配包”,它的更新节奏受阿里战略调整影响很大,维护变慢甚至停止,并不能推导出“Spring AI这套东西不行了”的结论。
我在网上翻了很多帖子,发现很多开发者把这两个概念混在一起,然后得出“Java被AI抛弃”的结论,这是典型的归因错误。你在落地某个Java项目时,真正依赖的是Spring AI的核心抽象,而不是某个厂商的适配插件。适配插件停更,换个入口照样能接大模型。
1.2 停更背后的三个原因
结合仓库的提交历史、Issues反馈和社区讨论来把事实拆开看,所谓“停更”并不是突然暴毙,而是长期维护力度下降的结果。我推测主要有三个原因,后两个属于我基于行业惯例的合理推断:
- 模型供应商的API变更太快,适配层维护成本太高。接通义、通义Spark(原文:通义系列)这类国内大模型,接口动不动就调整,而且各家还经常有认证、流式、工具调用上的私有协议。Spring AI Alibaba作为第二层适配,要跟着两层上游变,维护成本和收益不成正比。
- 阿里自己的重心在往DashScope SDK上转移。如果只针对阿里云生态,官方更希望你直接用DashScope SDK或者百炼的控制台,因为这样能更好地把用户锁定在自己的云产品链路里。在一个第三方开源中间件上投入太多,对他们自己的产品矩阵不是最优解。
- Spring AI官方已经把多供应商抽象做起来了。一旦Spring AI原生支持了OpenAI格式的通义接口,阿里这边也就没必要再单独维护一个适配包了。说得直白点,原来需要中间商赚差价,现在官方直联了,中间商自然退出。
明白这三点之后,你就不会被一个项目的“停更”带偏节奏。做技术选型不能只看某个组件活没活,要看整个链路里还有没有替代路径。
2. Java在AI生态里为什么还有救
2.1 位置变了:从模型训练到应用工程化
很多焦虑的Java开发者都有一个惯性思维:AI等于Python,Python等于AI,所以Java没戏。这是把“训练模型”和“构建AI应用”两件事搞混了。训练大模型、搞算法实验确实是Python的天下,但绝大多数企业要的不是一个模型,而是一个能集成进业务系统的智能服务。这块恰恰是Java的主场。
你想,一个正经的AI应用,尤其是2B场景里的,它需要什么?需要和高并发的用户体系打通,需要处理事务,需要对接已有的订单、库存、风控系统,需要稳定的连接池和事务管理。这些能力Java已经打磨了二十多年,Spring Boot那一套微服务基建在金融、制造、政企等行业里依然是绝对主力。AI只是给系统加了一个“会说话的大脑”,而这个大脑要装进现有的躯壳里,工程化、稳定性、可维护性才是关键。
与其说Java没有希望,不如说Java的机会已经从“从零搭模型”变成了“让模型在企业系统里稳定生产”。这个切换更隐蔽,但需求更真实。我调研过不少公司在落地AI功能时的技术栈,最后做业务集成的,用Java的比例相当可观。
2.2 Spring AI的维护状态和官方抽象为什么更重要
Spring AI官方项目的活跃度不用怀疑,它每版适配的主流模型列表都在变长,除了OpenAI、Ollama之外,还覆盖了大量新的向量库和工具调用方案。Spring AI的本质价值在于抽象:它把“和大模型对话”做成了一套标准接口,屏蔽掉底层各家模型的差异,让你可以在开发阶段换个模型不用改业务代码。
举个例子,今天你用Ollama跑本地开源小模型,明天想切换到云上的大模型,只要把配置改一下,消息结构、提示词模板、输出映射这些代码可以原样保留。这种可替换性的价值,在对接不确定的模型生态时是非常大的资产。Spring AI Alibaba的停更,某种意义上恰恰证明了Spring AI的核心竞争力——当官方足够强大,第三方的适配层就变得多余了。
简单来说,只要Spring官方还在更新Spring AI,Java在AI应用工程的底座上就没有输。你要关注的不是某个厂商适配包死没死,而是官方推荐的标准接口还能不能继续用、社区积累够不够厚。
3. 停更之后,Java开发者还有哪些路可走
3.1 路径一:直接用Spring AI官方库
这是目前最推荐的主流路线,也是绕开Spring AI Alibaba依赖之后的首选。Spring AI官方通过统一的RestClient风格API支持多种大模型接入,只要目标模型提供兼容OpenAI的接口,就能比较轻松地接入。大多数国产模型服务其实都提供了OpenAI兼容模式,这意味着你可以几乎无改动地完成迁移。
使用上,在pom.xml里引入spring-ai-starter-model-openai,然后指定base-url为你的模型服务地址。如果是本地用Ollama,则引入spring-ai-starter-model-ollama,直接把服务跑在http://localhost:11434。这种模式的好处是代码里只依赖Spring AI标准接口,不依赖任何厂商私有SDK,切换成本最低。我自己实际跑下来的感受是,这套API设计得挺顺手的,尤其是ChatClient的流式接口和工具调用,写起来确实有当年用JdbcTemplate那种清爽感。
需要提醒一点,Spring AI不同版本之间API演进比较快,以官方文档为准,不要盲目复制博客里的旧代码。如果看到网上示例用的还是0.8.x的Snapshot版本,建议直接升级到1.x的最新正式版,兼容性更好。
3.2 路径二:官方SDK加大模型网关
如果你的业务深度绑定某家云厂商,需要用到他们的专属模型、多租户配额或者企业级审计能力,那直接用厂商官方SDK是最省心的。比如阿里云DashScope、百炼SDK,它们各自提供了完整的会话、Agent和模型管理能力。加上一个统一的大模型网关(比如OneAPI或NewAPI这类开源聚合层),你还能把多家的OpenAI风格接口收拢成一套,企业内部的调用权限、密钥管理和成本统计都能集中处理。
这种方案的好处是离厂商最近,新模型、新功能往往第一时间能用;代价是代码里会掺入不少厂商私有类,将来想换供应商时,需要修改的地方比Spring AI方案多一些。因此它适合“绑定一家云就够”的项目,不适合“我要在多家模型之间反复横跳”的场景。
我自己的习惯是:中小型项目优先Spring AI官方统一接口,集团型项目、对云上账单敏感的项目才考虑SDK加网关的组合。两条路不冲突,甚至可以在一个项目里共存,比如Spring AI只负责对话和RAG,厂商SDK只负责调用特殊模型能力。
3.3 路径三:LangChain4j作为备选
如果你之前用惯了Python的LangChain,又希望用Java写同样的编排逻辑,LangChain4j是一个相当活跃的替代方案。它在社区热度、示例数量和模型支持广度上都不错,而且对Spring Boot集成支持得很细。它和Spring AI是竞争关系,但各有侧重:Spring AI偏工程化、跟Spring生态无缝结合;LangChain4j更贴近LangChain的思维模式,适合已经熟悉LangChain概念的人。
选LangChain4j还有一个现实原因:它的更新频率比Spring AI还高,版本迭代很快,很多模型接入例子甚至比官方文档更贴近实际使用。但它也是一把双刃剑,API变化快意味着升级麻烦,基础知识可能要跟着重构。因此我更建议把LangChain4j定位成“方案B”,当Spring AI在某些特殊场景(比如某种向量库的适配)还有缺口时,用来应急替代,而不是一上来就全盘切换。
4. 实操:用Spring AI加Ollama跑通一个完整的本地RAG问答
标题里既然提到了“希望”,多说不如演示。下面这套是我在本地环境完整跑过的方案,用Spring AI官方库接Ollama的本地模型,再配合轻量语义检索,实现一个本地知识库问答。全程不需要注册云服务,也不需要高昂的API费用,笔记本就能跑。
4.1 环境准备
先列一下我用的硬件和软件版本,供参考:
| 项目 | 版本 |
|---|---|
| 操作系统 | 某Linux发行版双系统,8核CPU,16G内存 |
| JDK | 某OpenJDK 17发行版,推荐17或21 |
| Spring Boot | 3.4.5及以上,需与之匹配的Spring AI |
| Spring AI | 1.1.0-M1(或最新的GA版本) |
| Ollama | 0.11.x |
| 本地模型 | qwen2.5:7b(对话),nomic-embed-text(向量) |
| 数据库 | H2内存库配合向量插件 |
JDK版本别用8,Spring AI 1.x对JDK版本有底线要求。我个人推荐直接上JDK21,虚拟线程在流式调用场景下体验很不错。Ollama安装很简单,几条命令就能装好,它主要用来拉取和管理本地模型。安装完成后先拉取模型,这一步在国内网络环境下可能会慢一些,需要一些耐心。
# 安装完成后,分别拉取对话模型和向量模型 ollama pull qwen2.5:7b ollama pull nomic-embed-text拉完后可以用ollama list确认模型都在,然后启动服务ollama serve,默认跑在 11434 端口。
4.2 搭建Spring Boot项目并配置依赖
我习惯用某在线代码生成平台生成基础工程,选Java 17、Spring Boot 3.4.x,然后手动在pom.xml里加上Spring AI的依赖管理。注意,Spring AI的依赖不只在中央仓库,需要把里程碑仓库地址配到pom里,不然会提示找不到包。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.5</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.1.0-M1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>核心依赖是这几个:spring-ai-starter-model-ollama、spring-ai-starter-vector-store-pgvector或h2向量扩展,以及spring-boot-starter-web。如果你只是想先跑通对话,不接知识库,只需要第一个依赖就够了。我这次把RAG也带上,所以多加了向量库相关的依赖。
<dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-ollama</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-pdf-document-reader</artifactId> <exclusions> <exclusion> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-vector-store-h2</artifactId> </dependency> </dependencies>关于h2向量扩展,我建议先关注兼容性。如果你用1.1.0-M1版本,H2扩展是能用且自带PGlite模拟的,配置相对简单;如果用的是更早版本,可能要自行引入H2的向量依赖。总之,以Maven实际拉下来的依赖为准。配置方面,application.yml这样写:
spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen2.5:7b temperature: 0.7 embedding: options: model: nomic-embed-text4.3 实现一个最简单的RAG问答
RAG的核心思路:先从本地文档里检索出和用户问题最相关的片段,再把片段塞进提示词模板,让大模型在限定范围内作答。这样做的好处是减少大模型胡编乱造,让答案基于你提供的知识。我用PDF文档阅读器加载一份产品说明,然后用文本分块器切成块,再向量化存储到H2关联的向量存储里。
代码核心部分如下,这是基于常见实践的写法。分块大小我设置了500个字符,重叠50个字符,这是一个比较中庸的参数。太大会让信息混在一起降低检索精度,太小又会让上下文碎片化,模型理解不完整。
@Component public class DocumentIngestionRunner implements ApplicationRunner { private final VectorStore vectorStore; private final EmbeddingModel embeddingModel; public DocumentIngestionRunner(VectorStore vectorStore, EmbeddingModel embeddingModel) { this.vectorStore = vectorStore; this.embeddingModel = embeddingModel; } @Override public void run(ApplicationArguments args) throws Exception { // 读取PDF文档 var reader = new PagePdfDocumentReader("file:docs/manual.pdf"); var documents = reader.get(); // 切块 var tokenizer = new TokenTextSplitter(500, 100, 5, 1000, true); var chunks = tokenizer.apply(documents); // 写入向量库 vectorStore.add(chunks); System.out.println("文档已写入向量库,共" + chunks.size() + "个分块"); } }然后写个简单的查询接口,核心是向量检索和ChatClient组合。先用EmbeddingModel查询向量库里最相似的片段,然后把这些片段拼到提示词里,再交给ChatClient调用本地模型生成最终答案。
@Service public class RagService { private final ChatClient chatClient; private final VectorStore vectorStore; public RagService(ChatClient.Builder builder, VectorStore vectorStore) { this.chatClient = builder.build(); this.vectorStore = vectorStore; } public String ask(String question) { // 从向量库搜索上下文 var searchRequests = SearchRequest.builder() .query(question) .topK(3) .similarityThreshold(0.6) .build(); var similarDocs = vectorStore.similaritySearch(searchRequests); // 拼接上下文 StringBuilder context = new StringBuilder(); for (var doc : similarDocs) { context.append(doc.getContent()).append("\n\n"); } String promptTemplate = """ 你是一个产品客服助手,请只根据以下资料回答问题。 如果资料中没有相关信息,请直接回答:根据现有资料无法解答。 资料: %s 问题: %s """; String prompt = promptTemplate.formatted(context.toString().trim(), question); return chatClient.prompt().user(prompt).call().content(); } }4.4 运行验证与效果
启动项目,观察控制台。第一次启动会比较慢,因为要加载PDF、切块、调用本地embedding模型生成向量。本地7B模型在CPU上跑,单次推理可能需要几秒到十几秒,这属于正常的性能表现。如果用的是带独立显卡的机器,体验会好很多,响应时间能压缩到一两秒。
请求接口GET /api/rag?question=这个产品支持哪些登陆方式,返回结果应该是从资料里找到的准确回答。我拿几份不同资料试过,总体回答质量稳定,关键信息基本不会编。唯一的缺点是本地小模型在复杂推理题上不够聪明,但RAG场景本来就不是让它秀智商,而是让它做“文档摘要员”,这个定位下效果已经足够用在企业内部问答了。
强力建议替换成比较大的模型,比如qwen2.5:14b或32b,只要机器内存吃得下,回答的准确度会有明显提升。小模型和中等模型在RAG场景下的差距,主要就体现在长文档归纳和引用能力的强弱上。
5. 踩坑记录与排查清单
5.1 版本和依赖冲突
我踩过的第一个坑是版本号不匹配。Spring AI每个里程碑版本对应特定范围的Spring Boot版本,拿1.0.0-M6配Spring Boot 3.3.0能跑,配3.4.0就可能启动失败。第一次遇到这个问题时,我以为是代码问题,后来看异常栈才发现是自动配置类找不到方法。处理方式很直接:严格按照官方BOM表格对齐版本。
另外要注意,Spring AI的某些模块会传递引入较早版本的第三方库,比如Jackson或Apache HttpClient。如果你的项目里还有其他组件对这些库有精确版本要求,启动时就会出现NoSuchMethodError之类的错误。排查办法是mvn dependency:tree或idea的依赖视图看冲突,然后手动exclusion或dependencyManagement指定版本。这个坑比较容易出现在老项目升级AI功能时,新项目反而干净一些。
5.2 Ollama连接失败与模型加载问题
联不上Ollama是我见过最多的问题。首先确认服务是否启动,用浏览器访问http://localhost:11434,能看到Ollama的调试页面说明服务正常。第二个常见原因是模型没提前拉取,Spring AI调用时不会自动帮你拉模型,只会报模型不存在的错。解决方案就是先命令行拉取好再启动业务程序。
另一个隐蔽问题是端口被防火墙拦截。如果在远程服务器上部署,不仅要放行11434端口,还要在Ollama配置里开启监听外部地址,默认它只监听本机回环地址。我在公司内网测试时就被这个卡过,后来临时换成本机访问绕过了,但正式部署时一定要把访问控制和认证考虑进去。
还有一次,我同时跑了两个模型导致显存/内存不足,Ollama直接崩溃,控制台报一堆OOM异常。Ollama默认每个模型加载都会占用内存,如果机器配置有限,建议一次只运行一个模型,或者通过OLLAMA_MAX_LOADED_MODELS环境变量限制加载数量。
5.3 向量维度不一致与嵌入模型选择
RAG场景里最典型的问题:你写入向量库时用的是nomic-embed-text(768维),查询时换成了另一款向量模型(例如1024维),系统就会抛出维度不一致异常,或者查出来一堆完全不相干的结果。原因是向量库里的索引结构是按写入时的维度建的,换模型等于用另一种尺子去量旧物品,自然对不上。
处理方案是固定一套embedding模型,不要混着用。如果要换模型,就得清空向量库重新构建。这个操作有一次让我折腾了很久,因为测试时为了追求“中文语义更准”,切换了向量模型,结果线上数据全部失效。从那以后我立了个规矩:embedding模型选定后写进文档手册,升级前必须做迁移演练。
相似度阈值也不要拍脑袋设。topK设得越大,塞给模型的上下文越多,但废话也多;similarityThreshold设得过高,可能导致什么都查不到。我的经验值是topK=3、threshold=0.6起步,再根据实际问答效果微调。多试几组正规测试query,看到输出效果再定,别猜。
6. 选型建议和我的个人体会
6.1 三种路径怎么选
评估项目用哪张路线,我一般问自己三个问题:项目里有多少非官方模型的诉求?团队对Spring生态的绑定有多深?公司是否有云厂商绑定政策?
如果你在做一个标准的Spring Boot业务系统,希望AI能力像数据库一样“接到一起就能跑”,那就是Spring AI官方库,没悬念,技术最正,升级路径清晰。如果公司已经深度使用某朵,并且需要账单闭环、企业级权限对接,那就放心用它的官方SDK,把Spring AI当辅助层,只在需要统一抽象的地方使用。至于LangChain4j,更适合那些已经在Python里写了一套LangChain原型的团队,需要在Java端快速平移逻辑,以及对Spring AI某些能力不满足的场景。
没有一种方案是银弹。我见过用纯厂商SDK的项目,也因为SDK版本升级被迫改了一周代码;也见过强行用Spring AI接所有私有服务的项目,最后维护成本比迁移成本还高。关键是你对项目未来两三个季度的演进心里有数,选一条能持续走的路。
6.2 我个人的一些看法
说到底,“Spring AI Alibaba停更”这件事,我在实际操作中体会到的最重要的一点是:不要把自己绑死在某个厂商的适配组件上。只要你的代码依赖的是Spring AI标准接口,就算某个适配层停了,你换一个实现、改几行配置,照样能跑。反过来,如果你满项目都是厂商私有类,那才是真正的风险。
我自己的项目现在基本不碰第三方AI适配包,统一走Spring AI官方,模型层全加一层网关兜底。日常开发也用一套自研的小封装:切换模型时只改配置文件里的base-url和model名称,连代码都不用动。这套思路用下来,省掉了很多不必要的折腾。
如果让我给刚入门的Java开发者一句建议:别被“停更”标题吓退,去看看Spring AI官方仓库的提交记录,再照着本文的demo跑一遍本地问答,你对这个生态有没有前途的判断,会比看一百篇讨论帖都清楚。Java不是没希望,是希望从“追着模型跑”变成了“稳坐中军帐”,关键是你别站错地方。