Spring AI Alibaba 停更了的消息这几天在 Java 圈子里讨论得不算少。我身边几个做后端的朋友第一反应都是同一个问题Java 还有希望吗我的回答也很直接先别急着把手里用得顺手的锤子扔掉得先看清眼前那颗钉子到底是什么形状。先说结论某个适配层项目停更和 Java 这门语言在 AI 时代有没有未来中间至少隔着一整个技术生态的距离。真正要紧的不是盯着一个仓库的提交记录叹气而是想清楚 Java 开发者手里那套积累了十几年的工程能力到底在 AI 应用里能变成什么实实在在的东西。这篇文章我不打算讲太多虚的。会先从 Spring AI Alibaba 的定位说起再聊 Java 在 AI 生态里的真实位置最后给几条可以直接上手的路线和一个完整跑通的案例。如果你是做 Java 后端、最近因为这条消息有点慌的这篇文章应该能帮你把心放到肚子里。1. 先弄清停的是哪座桥别把整条河都当成没路走1.1 Spring AI Alibaba 在技术栈里的真实定位很多人把 Spring AI Alibaba 理解成了Java 做 AI 的唯一入口这个误解是焦虑的源头。实际上它更像是 Spring AI 生态里的一座桥一端连着 Spring AI 这套 Java 侧的 AI 抽象框架另一端连着某个云厂商的模型服务。有了它你在配置里写几行参数就能让 Spring Boot 应用直接调用云端的大模型接口省去自己封装 HTTP 请求、鉴权、消息格式转换这些重复工作。但要注意这座桥解决的是方便的问题不是能不能的问题。哪怕这座桥不存在你依然可以用 Spring AI 主项目对接模型服务甚至完全不用任何框架直接拿 Java 的 HttpClient 去调用模型接口。打个比方Spring AI Alibaba 停更相当于一条商业街里某个品牌奶茶店关门了你不能因此认为整个奶茶行业完了更不能认为自己以后只能喝白开水。从技术结构上看Spring AI Alibaba 属于适配层。它的主要工作是跟随上游 Spring AI 的变化同步调整配置属性和自动装配逻辑。这种项目有一个天然痛点只要上游版本一更新它就得跟着改维护成本高、收益却不太明显。一旦项目方觉得投入产出不划算停更往往是大概率事件。1.2 适配层项目停更背后的原因不外乎这几类我翻过不少类似的适配项目停更原因基本逃不出三类一是上游迭代太快跟不上。Spring AI 本身正处于快速演进期版本号涨得快API 说变就变。适配项目如果团队规模小很难做到同步更新。时间一长版本落后太多再想追就难了。二是厂商阶段性的资源调整。开源项目往往依赖公司内部的资源和战略方向。如果项目方把人力调去别的方向或者觉得这个适配层不再需要单独维护停更就是自然结果。这不代表 Java 生态出问题只代表某个具体团队的业务优先级变了。三是官方能力已经覆盖。有时上游主项目直接内置了同类能力适配层就没有存在必要了。这在开源世界里是好事说明生态是在整合不是在萎缩。想验证一个项目是不是真的停更不用听传言直接看三点GitHub 上的最近提交时间、Issue 的响应情况、以及有没有新版本发布。我当前看到的是Spring AI Alibaba 近期确实长时间没有活跃更新但 Spring AI 主项目本身仍然在正常迭代。两者是完全不同层面的东西。1.3 停更的直接影响谁该慌谁不用慌为了让你判断得更准确我把受影响人群分成三类用表格直接看清楚人群实际影响我的建议已经在生产环境用了 Spring AI Alibaba功能已经固定只要不过度追求新特性风险可控暂时不用动评估后续有没有必要迁移到标准 Spring AI 接口正准备启动新项目不建议再选它作为集成层避免刚起步就背上维护包袱直接改用 Spring AI 主项目或下面要说的其他路线还没开始用 Java 做 AI 的开发者几乎没有影响正好跳过这段历史包袱从当前稳定的生态直接起步说到底技术选型里真正值钱的不是某座桥而是你过桥之后能不能把事情做成。Java 的能力沉淀在桥的对岸不在桥本身。2. Java 做 AI 真的没戏吗先把基本盘看清楚2.1 AI 应用的真正战场不在训练在集成聊到 AI很多人先想到 Python、PyTorch、训练大模型。这些确实是 AI 前端科技最密集的地方但它们是属于少数团队的战场。绝大多数公司做 AI 项目做的不是从零训练一个模型而是把现成的大模型能力接进自己的产品客服机器人、文档分析、代码辅助、智能审核、流程自动化。这些东西的本质是集成是把模型变成业务系统里一个可靠的服务。而集成恰恰是 Java 最有话语权的地方。一个典型的 Java 后端工程师日常干的活就是对接数据库、调用第三方接口、处理消息队列、保证事务一致性、做好权限控制。这些能力在做 AI 应用时一个都不少反而因为大模型带入了很多不可控因素对工程化的要求更高了。你可以把大模型想象成一个能力很强但经常情绪不稳定的新同事Java 后端的工作就是给他配好流程、设好边界、管好上下文让他稳定地输出结果。训练一个能写诗的大模型是模型团队的事。但在自己的业务系统里稳定地调用这个模型把它的回答接进工单系统、加上权限校验、记录审计日志这一整套活儿Java 工程师闭着眼都能干。2.2 企业级落地的硬约束恰恰站在 Java 这边企业级 AI 应用有几个绕不开的硬约束合规审计、系统对接、稳定性保障、事务一致性、监控告警。这些东西不是加分项是一票否决项。做个智能客服回答对了问题只是开始。你得知道这个回答是哪个模型给的、当时的提示词是什么、上下文中包含哪些业务数据、用户最终看到了什么。这一整套可追溯链路Java 生态里的日志框架、链路追踪、审计组件基本是现成的。换成一个临时起意的 Python 脚本这些能力要从零搭而且要搭好不容易。再说系统对接。很多公司的核心业务跑在 Java 技术栈里Spring Boot 就是事实上的标准。AI 能力要进生产就得跟现有系统做同一个容器、同一套注册中心、同一个监控大盘。Java 版本的 AI 应用可以顺滑地融进这套基础设施Python 服务还得单独维护一套部署和监控链路。我见过不少团队最后把 Python 推理服务外面再套一层 Java 网关本质上还是为了接入这个体系。所以说Java 不是被 AI 抛弃了恰恰是因为 AI 要落地到企业业务里Java 的工程能力反而变成了刚需。大模型负责聪明Java 负责靠谱这两件事在现实项目里是分工合作关系。2.3 别只盯一个仓库Java AI 生态比你想的活跃经常有人问我Java 做 AI 是不是只有 Spring AI 一条路真不是。我简单列几个方向Spring AI 主项目Spring 官方主导的 AI 应用框架提供 ChatClient、Prompt Template、VectorStore、Function Calling 等抽象模型服务商适配还在持续扩展中。LangChain4j专门为 Java 设计的 LLM 应用框架思路参考 LangChain但 API 完全是 Java 风格中文文档也维护得不错。DJL 和 ONNX Runtime Java API适合在 Java 进程里直接跑本地推理模型用于隐私场景、离线场景或低延迟场景。直接调用模型服务商的标准 REST 接口连框架都不用一个 HttpClient 就能干活。从社区活跃度看这些项目里有不少还在持续发版本。说Java 生态在 AI 时代彻底没戏更像是情绪化表达而不是对技术现状的客观判断。3. 真要在 Java 里搞 AI这几条路线我都替你趟过3.1 路线一继续守好 Spring AI 主项目Spring AI 主项目是 Spring 官方团队在维护的定位是给 Java 开发者提供一套统一的 AI 应用开发抽象。它已经走出了早期做个聊天 Demo的阶段开始覆盖对话、提示词模板、向量检索、函数调用、多轮记忆这些真实项目里绕不开的能力。我用它接本地模型的时候最小配置是这样的以本地 Ollama 服务为例换成其他模型服务商只需调整对应的 starter 依赖和配置前缀spring.ai.ollama.base-urlhttp://localhost:11434 spring.ai.ollama.chat.modelqwen2.5:7b spring.ai.ollama.embedding.modelnomic-embed-text然后直接注入 ChatClient 就能用RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/chat) public String chat(RequestParam(defaultValue 你好) String message) { return chatClient.prompt() .system(你是一个乐于助人的中文助手。) .user(message) .call() .content(); } }如果你选这条路核心收益是保持 Spring 生态的统一编程体验事务、配置、监控这些基础设施都是现成的。核心成本是需要花时间熟悉 Spring AI 自己的抽象概念而且它本身 API 还在演进升级版本时要留意兼容性。3.2 路线二用 LangChain4j 这类更纯粹的 Java AI 库LangChain4j 从一开始就是按 LLM 应用的思路设计的对链式调用、消息记忆、AI Service 这类抽象支持得很直接。如果你的项目不是一个典型的 Spring MVC 应用或者你想少一点 Spring AI 的魔法、多一点自己掌控的参数LangChain4j 会更顺手。var model OpenAiChatModel.builder() .baseUrl(System.getenv(LLM_BASE_URL)) .apiKey(System.getenv(LLM_API_KEY)) .modelName(qwen2.5:7b) .build(); String answer model.chat(用一句话解释什么是RAG); System.out.println(answer);注意代码里的接线方式是示例具体版本的方法签名略有差异以你依赖的版本为准。但整体上LangChain4j 对 Java 开发者的心智负担比较小尤其适合喜欢显式组装每一步流程的人。3.3 路线三直接裸调模型接口清爽又可控如果项目里只是偶尔调用一次模型比如做一个内部小工具那我建议别上框架。Java 自带的 HttpClient 足够完成整个调用好处是没有额外依赖、逻辑一目了然、出了问题时排查路径最短。HttpClient client HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); String json { model: qwen2.5:7b, messages: [ {role: user, content: 用一句话解释RAG} ], temperature: 0.7 } ; HttpRequest request HttpRequest.newBuilder() .uri(URI.create(http://localhost:11434/v1/chat/completions)) .header(Content-Type, application/json) .header(Authorization, Bearer System.getenv(LLM_API_KEY)) .POST(HttpRequest.BodyPublishers.ofString(json)) .timeout(Duration.ofSeconds(60)) .build(); HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body());我把调用地址写成了本地兼容端点正式接入时换成实际服务的地址即可。用裸调的方式你会更清楚每次请求到底往外面发了什么、返回了什么。我有一个感受裸调几次之后再回去用框架你会对框架帮你做的那些事情有完全不同的理解。3.4 路线四本地推理留给 DJL 和 ONNX Runtime还有一类场景数据不能出内网、或者需要极低延迟响应这时候就得在 Java 进程内直接跑模型推理。DJL 让 Java 开发者能加载 PyTorch、TensorFlow、ONNX 格式的模型ONNX Runtime 的 Java API 也相当成熟加载模型后可以直接跑推理不依赖外部推理服务。这类方案的代价是你需要处理模型本身的体积、显存占用、输入输出的张量转换等一堆底层细节上手门槛比调用 API 高不少。但从架构角度看它把 AI 能力变成了一个纯 Java 组件部署形态跟在项目里嵌一个缓存组件差不多。如果只是想快速出活优先走前三条路线。如果业务对数据安全、延迟有硬指标再考虑本地推理。这个顺序能帮你少走很多弯路。4. 手把手实操用 Java 跑通一个文档问答RAG应用前面讲的是路线这一段我给一个完整的落地案例。RAG检索增强生成是目前 Java 后端最容易切入、也最能体现工程价值的 AI 场景先把自己的文档切块存进向量库用户提问时先检索相关片段再把片段和问题一起交给模型生成回答。这样答案能锚定在你的文档内容上大幅减少幻觉。4.1 场景设定与准备工作我用的是一个模拟项目 X内部售后文档问答系统用户问退款流程是什么系统应该基于已有的售后手册回答而不是模型凭空编一个流程。准备清单JDK 17Maven 项目Spring Boot 3.x 项目PostgreSQL 数据库启用 pgvector 扩展本地模型服务或远程模型服务需要一个支持 Chat 和 Embedding 的接口为了演示方便下面的代码以 Spring AI 主项目为基础。4.2 依赖与配置在 pom.xml 里引入 Spring AI 的 Ollama starter用本地模型演示和 pgvector starter作为向量存储dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-ollama/artifactId version1.0.0/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-pgvector/artifactId version1.0.0/version /dependency配置里指定模型和数据库连接spring.ai.ollama.base-urlhttp://localhost:11434 spring.ai.ollama.chat.modelqwen2.5:7b spring.ai.ollama.embedding.modelnomic-embed-text spring.datasource.urljdbc:postgresql://localhost:5432/rag_demo spring.datasource.usernamepostgres spring.datasource.passwordpostgresSpring AI 的自动装配会帮你创建 ChatModel、EmbeddingModel 和 VectorStore 这些 Bean接下来的代码里直接注入就行。4.3 文档加载、切分与向量化把 docs 目录下的 Markdown 售后文档读进来切分成小块向量化之后存入向量库。这是 RAG 的入库阶段也是决定检索质量的第一步。Service public class DocumentIndexService { private final VectorStore vectorStore; public DocumentIndexService(VectorStore vectorStore) { this.vectorStore vectorStore; } public void indexDocuments(String path) { ListDocument docs new ArrayList(); File dir new File(path); for (File file : dir.listFiles((d, name) - name.endsWith(.md))) { Document doc new Document(file.toURI().toString(), new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8)); docs.add(doc); } // 切分每块约 500 字块与块之间保留 100 字重叠 TextSplitter splitter new TokenTextSplitter(500, 100); ListDocument chunks splitter.apply(docs); vectorStore.add(chunks); } }切分参数不是拍脑袋定的。块太小检索到的内容缺乏上下文模型很难给出完整答案块太大检索粒度太粗可能有大量无关内容混进来既浪费 token 也稀释注意力。我在实际项目里一般从 400 到 600 开始试再根据问答效果调整。调用一次indexDocuments(./docs)文档就进向量库了。这一步可以在应用启动时执行也可以做成管理接口手动触发。4.4 检索问答接口把相关文档片段喂给模型用户提问时先做相似度检索找出向量库里最相关的几块文档拼进提示词再让模型基于这些材料回答。RestController public class QaController { private final VectorStore vectorStore; private final ChatClient chatClient; public QaController(VectorStore vectorStore, ChatClient chatClient) { this.vectorStore vectorStore; this.chatClient chatClient; } GetMapping(/qa) public String ask(RequestParam String question) { ListDocument matches vectorStore.similaritySearch( SearchRequest.query(question).withTopK(3)); String context matches.stream() .map(Document::getText) .collect(Collectors.joining(\n---\n)); return chatClient.prompt() .system(你是售后文档助手只能基于提供的文档内容回答。 如果文档中找不到答案直接说不知道。) .user(相关文档\n context \n\n问题 question) .call() .content(); } }到这里一个最简的 Java RAG 应用已经通了。调用/qa?question退款流程是什么系统会先检索到售后手册里关于退款的段落再让模型根据这些段落组织回答。4.5 调优的三个旋钮跑通只是开始效果好不好要看三个旋钮怎么调。第一个是检索数量 topK。K 太小可能漏掉关键内容K 太大无关内容会干扰模型。先用 3 到 5 起步观察回答里有没有出现不相关内容再决定增减。第二个是切分尺寸。500 字是一般起点。如果文档本身是按章节组织的可以优先按标题切分保持语义完整如果文档是长段落再考虑按 token 切分避免切断核心表述。第三个是提示词模板。不要只把检索结果和问题简单拼在一起最好明确告诉模型只能基于文档回答不要推理文档之外的内容如果文档信息不足就承认不知道。加不加这两句话回答质量差距非常明显。5. 避坑清单这些坑我是用时间换来的5.1 网络超时默认超时一定会坑你一次模型接口的响应时间通常比普通 REST 接口长得多动辄十几秒、几十秒。Java HTTP 客户端默认连接超时很容易触发实际开发里要显式设置连接超时和请求超时。更隐蔽的是就算你设置了 60 秒超时遇到长文本生成依然可能被中断。解法是能流式就不等全量能用异步就用异步。Spring AI 里流式调用写着很简单FluxString stream chatClient.prompt() .user(讲一个关于程序员的故事) .stream() .content();前端通过 SSE 接收一边生成一边展示体验好也不容易撞上超时墙。5.2 上下文管理别把整个聊天记录全塞进去多轮对话是最容易出问题的场景。很多新手直接把所有历史消息拼进请求结果聊几轮后 token 数爆掉模型开始无视你最新的指示或者直接报错。正确的做法是只保留最近几轮的消息并且把过长的历史做摘要。Spring AI 提供 ChatMemory 抽象LangChain4j 也有对应的消息窗口实现。自己实现的话最简单的方式是维护一个最近十轮的滑动窗口超出部分压缩成一段摘要再拼进消息列表。5.3 API Key 安全正经项目别把 Key 写进代码本地 Demo 怎么都行一旦项目要上线API Key 必须走环境变量或配置中心绝对不能硬编码进代码或者提交进 Git 仓库。更稳妥的做法是经过一个网关服务统一代理模型调用由网关集中管控限流、审计和成本业务侧拿不到真正的 Key。这样既能防泄露也方便做配额管理。5.4 结构化输出别让模型自由发挥业务系统里经常需要模型输出固定格式的数据比如从用户反馈里提取客户名、产品名、情绪倾向。如果让模型自由输出你会发现它今天给你 JSON明天给你 Markdown后天带上一堆废话。解法有两个一是用 Spring AI 的实体映射让模型直接返回 Java 对象例如.call().entity(MyRecord.class)二是用 Function Calling 方式把提取结构化信息当成一个工具调用让模型自己决定用哪个参数去调用。5.5 检索质量差先别急着换大模型RAG 项目效果差十有八九是检索阶段出了问题而不是模型能力不够。先检查切分是否合理再检查检索 score 是否符合预期然后再看拼进提示词的内容是否和张冠李戴。我见过不少团队花大力气换更强的大模型结果问题出在向量库数据没清理检索结果全是过期文档。基础工作做扎实比迷信模型能力重要得多。写在最后的一点感受Spring AI Alibaba 停更这事我个人的看法是它提醒我们选型的时候不要把整个生态的安危押在一个适配项目上。真正值钱的是你对 AI 应用本身的理解——怎么检索、怎么设计提示词、怎么管好上下文、怎么保证输出可靠。这些能力在任何一个框架里都是通用的不会因为某个仓库停止更新就贬值。Java 在 AI 时代的希望不在一座桥上而在业务集成的主战场上。模型提供能力Java 提供秩序。只要企业还在用 Java 写业务系统Java 开发者做 AI 就有天然的入场券。把手里那套工程能力真正用到 AI 项目里你会发现路比你想象的宽得多。