ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Spring AI Alibaba停更背后,Java开发者做AI的三条真实路线与实操方案

Spring AI Alibaba停更背后,Java开发者做AI的三条真实路线与实操方案

先说一个判断:Spring AI Alibaba停更这件事,本身是个信号,但不是"Java 完蛋"的信号,而是"Java 生态里靠某云厂商单点绑定的路子走不通了"的信号。如果你正盯着这个项目犹豫要不要学 Java AI、要不要转型,那这篇文章就是给你写的。我会把这个停更事件拆开讲清楚、把 Java 做 AI 的三条真实路线捋一遍,再给你一套可以直接抄的实操方案,最后把我自己踩过的坑和排查思路全部摊开。看完你会发现,Java 不是没有希望,而是它的希望换了一种形态,需要你用新的方式去接住。

1. 先说结论:Java 没凉,只是舒适区没了

Spring AI Alibaba 宣布停更后,社区里一片哀嚎,我身边也有同事在问:"是不是 Java 在 AI 时代彻底没戏了?要不要赶紧转 Python?"我的回答一直是:别急着转行,先搞清楚它为什么停更,以及 Java 在整个 AI 链路里真正扮演的角色。

先说事实层面。Spring AI Alibaba 只是某云厂商基于官方 Spring AI 做的一套集成组件,它的作用是让 Java 开发者更方便地调用该云厂商的大模型服务。停更这个动作本身,影响的只是这一条集成路径的更新节奏,影响不了 Java 语言本身,更影响不了 Spring 这个全世界装机量最大的后端框架。真正底层的东西——JVM、Spring Boot、整个 Java 服务端生态——一直都在正常演进,而且活得很好。

再说生态层面。Java 在 AI 领域的位置被严重低估了。大模型落地上线之后,最赚钱、最核心的部分其实是后端的服务治理、数据管道、业务编排和稳定性保障,而这些恰恰是 Java 的主场。你去看看各家公司跑 LLM 应用的线上架构,流量入口是 Nginx,业务逻辑是 Java 或 Go 的服务,数据管道基本被大数据全家桶覆盖,这些全是 JVM 系的天下。Python 在模型训练和实验阶段有绝对优势,但到了生产环境,Java 依然是扛把子的角色。

最后说认知层面。Java 开发者真正的问题是:过去十年写 CRUD 写得太舒服了,AI 一来发现原来那套"配个数据库、写几个接口"的经验不够用了。这不是 Java 的错,是技能栈需要升级。你需要补的不是 Python,而是 AI 应用的底层逻辑——怎么调用模型、怎么设计 Prompt、怎么做检索增强、怎么评估效果。这些能力用 Java 一样能学、一样能落地。

所以我把这篇文章定位成一次"拆解+实操",既不贩卖焦虑,也不盲目吹捧,只讲清楚停更背后的逻辑、可替代的方案、以及我现在生产环境里真正在用的技术栈。

2. Spring AI Alibaba 停更,到底是怎么回事

2.1 停更是"放弃治疗"还是"战略撤退"

很多人一看到"停更"两个字就慌了,觉得项目死了、技术路线错了。其实开源项目的停更有好几种,性质完全不同。一种是项目彻底没人维护、文档失效、连 issue 都没人回,这种是真死了;另一种是官方把资源抽走、不再发新版本,但代码还能用、社区还有人在 fork 维护,这种更像"战略撤退"。

Spring AI Alibaba 属于后者。它停更的根本原因,我认为有三层。

第一层是定位尴尬。它本质上是一个桥接组件,桥的一端是 Spring AI 官方框架,另一端是云厂商自己的模型服务。桥接组件的价值取决于桥的两端是否稳定,而 Spring AI 官方迭代速度极快,API 经常调整,云厂商的模型服务也三天两头出新能力,桥接组件得不停追版本,维护成本高、收益却不明显。

第二层是官方框架逐渐成熟。Spring AI 官方项目本身就支持通过配置 Base URL 接入各种兼容 OpenAI 协议的服务,某云厂商的模型恰好也兼容这个协议。既然官方已经能干这件事,厂商自己再维护一套定制组件就有点重复造轮子了。

第三层是投入产出比。云厂商把资源投到这种开源组件上,回报远不如投到自己的云产品支持上。停更一个附带性质的集成组件,对业务没有本质影响,还能省下维护成本,从商业角度是完全可以理解的决策。

2.2 对 Java 开发者的真实冲击面

停更带来的冲击不是"没得用了",而是"你原来依赖的那条现成路子断了"。

以前用 Spring AI Alibaba,你只需要按文档引入依赖、配置好密钥,就能用 Java 调该云厂商的模型服务,它把鉴权、接口适配、流式响应这些都封装好了。现在停更了,你面临的问题不是"不能用 Java 调大模型了",而是"以前无脑抄配置就能用的路径没了,你得自己搞懂底层协议"。

这个转变其实是个好事。它逼着你去理解大模型 API 的本质:无非就是一个 HTTP 接口,PUT 一段 JSON 过去,再拿一段 JSON 回来,流式的话就是 SSE 长连接。你把这个底层逻辑弄明白了,别说换框架,就算明天冒出一个新的 Java AI 框架,你也能半天之内上手。

我对这件事的判断是:Spring AI Alibaba 停更,恰恰说明 Java AI 生态进入了更理性的阶段。早期靠厂商送温暖、送封装的时期结束了,现在拼的是对 AI 应用本身的深度理解。

3. Java 做 AI 的三条真实路线,别再纠结转不转行

很多刚入坑的人一上来就问:"Java 做 AI 是不是必须用某个特定框架?"其实不是。Java 做 AI 有清晰的层次划分,你可以根据自己的项目阶段和能力水平,选不同的路。

3.1 路线一:API 调用层,门槛最低但基本功

这条路线最简单:直接在 Java 里用 HttpClient 发送请求给大模型的 HTTP API,自己处理请求参数和响应结果。

HttpClient client = HttpClient.newHttpClient(); String payload = """ { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "用一句话解释什么是向量数据库"} ] } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com/v1/chat/completions")) .header("Content-Type", "application/json") .header("Authorization", "Bearer " + System.getenv("LLM_API_KEY")) .POST(HttpRequest.BodyPublishers.ofString(payload)) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body());

这段代码不用引入任何 AI 框架,JDK 自带的 HttpClient 就够了。它适合什么场景?适合你只想快速验证一个想法、或者项目里只需要一两个 AI 功能、不想为引入框架增加学习成本的时候。

但它的缺陷也很明显:没有封装重试、没有处理流式输出、没有 Prompt 模板管理、没有上下文记忆。一旦你的项目开始频繁调用模型、需要处理长对话和流式响应,手写 HttpClient 会把你拖垮。所以这条路线我定义为"入门理解层",适合用来搞懂大模型 API 的本质,但不适合作为生产环境的主力方案。

3.2 路线二:框架集成层,目前的主流选择

如果你已经过了"调通一个 API"的阶段,接下来就要考虑框架了。Java 生态里目前值得研究的框架有两个:一个是 Spring 官方的 Spring AI,一个是 LangChain4j。

这两个框架做的事情很像:屏蔽底层 HTTP 调用细节,提供统一的 ChatClient 接口,内置 Prompt 模板、消息历史管理、结构化输出、向量检索等高频能力。你只需要配置好模型服务的地址和密钥,就能像写业务代码一样写 AI 功能。

我现在的生产项目用的是 Spring AI 官方框架,后面会专门写一节实操。这里先说明一点:框架层解决的问题不是"能不能调通大模型",而是"怎么把大模型稳定地集成到你的业务系统里"。你的业务需要鉴权、限流、日志、链路追踪,这些能力 Spring AI 都能和 Spring Boot 无缝衔接,这是手写 HttpClient 做不到的。

3.3 路线三:本地模型推理,面向数据敏感场景

第三条路线比较硬核:把模型部署在本地或内网,Java 直接调用本地推理服务。适用场景很明确——数据不能出内网、或者你需要极低的响应延迟。

实现方式一般有两种。一种是用 Ollama 这类本地推理工具跑模型,它本身提供了 HTTP API,Java 可以通过 HTTP 调用。另一种是用 llama.cpp 的 Java 绑定通过 JNI 直接加载量化模型做推理,这种方式更底层,对性能要求高的场景会用到。

本地推理的典型配置是:一台带 GPU 的内网服务器,跑一个 7B 或 13B 的量化模型,Java 服务通过内网 API 调用,单次推理耗时控制在几百毫秒到一两秒。我做过一个内部文档问答的模拟项目,就是 Ollama + Spring Boot 的组合,核心代码量非常少,主要的复杂度全在提示词设计和向量检索部分,而不是模型调用本身。

这个路线对 Java 开发者很友好,因为你不需要碰 Python,不需要学 PyTorch,只需要把模型当成一个部署在本地的黑盒服务,用 HTTPS 一样的方式去调用就行了。这也是我觉得 Java 在 AI 时代最大的一张底牌——你不需要自己训模型,你只需要用好模型,而"用好"这件事,Java 完全搞得定。

4. 替代方案横向对比:官方 Spring AI 和 LangChain4j 怎么选

4.1 官方 Spring AI:正统血脉,和 Spring Boot 生态无缝咬合

先说官方 Spring AI。它的优势首先是"正规军":由 Spring 官方团队维护,和 Spring Boot、Spring Cloud 的版本兼容性有保障。你用 Spring AI 时,依赖注入、配置管理、自动装配这些机制和普通 Spring Boot 项目完全一致,几乎没有额外学习成本。

它内置的能力很实用:ChatClient 接口支持同步和流式调用;PromptTemplate 让你把提示词模板化,方便复用和维护;针对不同的向量数据库有对应的实现类,你可以用一套代码切换底层存储。对于已经是 Spring Boot 的用户来说,上手成本几乎为零。

我自己用的过程中体会比较深的一点是:Spring AI 的 API 设计很克制。它不会把 LangChain 里那一堆花哨的概念搬过来,而是尽可能用 Spring 开发者熟悉的方式来表达 AI 操作。聊天就是 ChatClient,提示词就是 PromptTemplate,向量存储就是 VectorStore。这种设计风格对从传统 Java 转过来的开发者非常友好。

4.2 LangChain4j:Python 生态的 Java 移植版,灵活但是学习成本高

LangChain4j 则走了另一条路:它更像是把 Python 生态里 LangChain 的设计哲学移植到 Java 上。它提供了 AiServices 这样一个基于接口代理的编程模型,你可以定义 Java 接口,框架自动把方法和模型调用绑定起来。

简单举例,LangChain4j 里的代码长这样:

ChatLanguageModel model = OpenAiChatModel.builder() .apiKey(System.getenv("LLM_API_KEY")) .modelName("qwen-plus") .build(); String answer = model.generate("给出一段酒店退订的道歉话术"); System.out.println(answer);

这个代码风格非常直白,模型就是一个对象,调用就是一个方法。它还内置了 ChatMemory 接口,管理多轮对话历史比 Spring AI 更顺手。如果你喜欢 Python 里 LangChain 的那种"把 AI 能力当积木搭"的感觉,LangChain4j 会让你很舒服。

它的缺点也很明显:一个是概念多,从 AiServices 到 Chain、MessageWindow、ToolSpecification,上手曲线比 Spring AI 陡;另一个是它和 Spring Boot 的整合没有官方框架那么原生,虽然也有 Spring Boot 的 starter,但很多高级特性还需要你手工接线。

4.3 选型建议

对比维度官方 Spring AILangChain4j
与 Spring Boot 集成原生无缝,自动装配成熟有 starter,但高级功能需手工装配
学习曲线平缓,符合 Java 开发直觉陡峭,概念多接近 Python 生态
模型支持主要面向兼容 OpenAI 协议的服务覆盖面更广,多模型适配更灵活
多轮对话管理需自己维护消息列表内置 ChatMemory 接口,开箱即用
社区活跃度Spring 官方主导,迭代稳定社区驱动,功能更新快,但变化也快
适合场景已经有 Spring Boot 底座,需要稳定生产集成重对话、重灵活组装、追求 Python 式体验

我的选型判断很直接:如果你的项目本来就跑在 Spring Boot 上,团队也是传统 Java 背景,优先选官方 Spring AI。如果你的项目核心就是复杂对话机器人、需要大量工具调用和灵活的记忆管理,LangChain4j 会让你开发效率更高。两条路都能走通,最忌讳的是今天听人说 A 好就学 A,明天看到 B 火又去学 B,最后哪个都没学透。

5. 实操:用官方 Spring AI 十分钟接上大模型对话

理论讲完,上点硬货。这一节我用一个"内部知识库问答"的模拟项目来演示,目标是用官方 Spring AI 在最短时间内实现一个能对话的 REST 接口。这套流程我在本地跑过很多遍,照着做基本不会卡壳。

5.1 环境准备

你需要准备的东西:

  • JDK 17 及以上版本
  • Spring Boot 3.2 及以上版本
  • 一个兼容 OpenAI 协议的大模型 API 服务(国内的主流大模型服务商都支持这个协议,也可以是本地部署的 Ollama)
  • 连数据库与否不重要,先跑通对话再考虑知识库

创建项目时,通过 Spring Initializr 新建工程,依赖选择 Web 即可,Spring AI 的 starter 后面手动加,这样更容易控制版本。

5.2 核心依赖与配置

在 pom.xml 里加入 Spring AI 的依赖:

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-openai</artifactId> <version>1.0.0-M6</version> </dependency>

注意 Spring AI 的版本迭代很快,早期是 M 系列版本,后来逐步走向稳定。你的依赖版本要以官方发布的最新稳定版为准,这里给出的是我本地验证过可运行的一个版本。

然后在 application.yml 里配置模型服务的地址和密钥:

spring: application: name: ai-demo ai: openai: api-key: ${LLM_API_KEY} base-url: ${LLM_BASE_URL:https://api.example.com/v1} chat: options: model: qwen-plus temperature: 0.7

这里有两个关键字段要说清楚:base-url是模型服务的地址,兼容 OpenAI 协议的服务一般都在/v1路径下;api-key记得从环境变量读取,别硬编码在配置文件里,否则一不小心提交到仓库就泄露了。temperature控制随机性,做知识库问答我一般调到 0.2 左右,更稳定,不容易胡说八道。

5.3 写一个最简的对话接口

新增一个 Controller,注入 Spring AI 的 ChatClient:

@RestController @RequestMapping("/api/chat") public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @PostMapping public Result chat(@RequestBody ChatRequest request) { String answer = chatClient.program(request.message()) .call() .content(); return Result.success(answer); } }

启动项目后,向/api/chat发一个 POST 请求就能完成对话。

这个接口的最简版只要三个要素:依赖、配置、一个 Controller。整个过程大概十分钟就能跑通。很多没接触过的人会觉得"这也太简单了吧,是不是少了什么",其实真相就是这样,大模型 API 本质就是一个网络调用,框架帮你把复杂部分封装掉了,剩下的就是业务逻辑。

5.4 加一个最简单的知识库:向量检索

只做对话没什么含金量,真正有价值的应用是让模型基于你自己的文档回答问题。这一步的关键是 RAG——先把你自己的文档向量化存起来,用户提问时先做相似度检索,找到最相关的文本片段,连同问题一起交给大模型加工。业界管这个流程叫"检索增强生成"。

我用的方案是 PostgreSQL 的向量扩展配合 Spring AI 的向量存储抽象。先建一张表存文档块和向量:

CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE document_segments ( id BIGSERIAL PRIMARY KEY, content TEXT, embedding VECTOR(1536) );

注意向量维度要和你的模型服务配套。如果模型输出 1536 维向量,字段就设成VECTOR(1536),不一致会导致写入时报错。

业务代码里,把文档切段、向量化、存入数据库:

@Bean public VectorStore vectorStore(JdbcTemplate jdbcTemplate) { return new PgVectorStore(jdbcTemplate, 1536); }

然后用 Spring AI 提供的接口做检索。这里不展开写全部代码,因为不同版本 API 细节有差异,但核心思路是固定的:文档进来,切块,向量化,写入 VectorStore;提问进来,向量化,相似度检索,取 TopK 片段,拼接 Prompt,交给模型生成最终答案。这套流程理解了,框架版本再怎么升级你都能很快跟上。

5.5 生产化要点,这几点必须做

代码跑通之后,进入生产前我有三个强烈建议。

第一个是加上流式输出。直接返回完整字符串会让用户等很久,体验很差。Spring AI 的流式调用很简单,把.call().content()换成.stream().content(),返回类型变成 Flux,前端用 SSE 方式接收即可。

第二个是做好超时和重试。大模型服务不稳定是常态,必须配置细粒度的超时控制,重试策略要克制,避免服务端已经处理完请求、客户端又在重试造成的重复计费。

第三个是 Prompt 注入防护。不要直接把用户输入拼进系统提示词,要有基本的输入校验和注入拦截思维。这个领域的安全问题和传统的 SQL 注入非常像,只是形式变成了提示词注入,一定要当成正经的安全问题来处理。

6. 常见问题速查表:这些坑我替你踩过了

围绕 Java 接入大模型这条链路,我把自己遇到过的典型问题整理成一张速查表,方便你遇到问题时直接对照排查。

现象可能原因解决方案
请求返回 401 UnauthorizedAPI Key 错误或已过期检查环境变量是否传入,确认 key 前后无空格和换行符
请求返回 404 Not Foundbase-url 路径配错确认地址是否包含/v1路径,不同服务商路径规则不同
请求成功但回答乱码模型请求和响应编码不一致统一用 UTF-8,检查 HttpClient 是否设置正确的 Content-Type
流式输出总是中断网络代理或网关对 SSE 有缓冲确认服务端响应头包含Cache-Control: no-cache,前端用 EventSource 接收
向量写入时报维度错误配置的 VECTOR 维度与模型输出不一致用服务商文档确认向量维度,修改表结构后重建索引
对话总是丢上下文没有把历史消息传给模型手动维护 message 列表,把历史走一轮传给 ChatClient
中文效果明显差于英文Prompt 太口语化,模型理解偏了把 Prompt 写得更结构化,增加示例,降低 temperature

除了表格里的问题,再分享两个我踩得最深的坑。

第一个是流式响应被网关吃掉。我一开始用 Spring AI 做流式对话,本地测试一切正常,部署到测试环境后前端一直收不到增量内容,排查很久发现是中间网关对响应做了缓冲,非要等整个请求结束才把内容推给前端。解决办法是在网关层放行 SSE 相关配置,确保响应头里设置Cache-Control: no-cache,升级到支持流式透传的版本。

第二个是模型返回代码块时 JSON 解析失败。当你让模型输出结构化 JSON 时,模型偶尔会在 JSON 里包一层 Markdown 代码块标记,直接JSON.parse就会报错。我的处理办法是在解析前先做一次预处理,把json ...的包装去掉,同时更新系统提示词,再加一层"只输出纯 JSON,不要使用 Markdown 格式"的强约束。即便如此还是要做好容错,因为模型不可控,输出格式这层永远不要信任模型,永远要写兜底逻辑。

关于重试再强调一点:超时重试的逻辑必须在业务层做,不能依赖框架默认行为。我遇到过模型服务偶发 503,框架默认重试三次,结果服务端其实已经处理了请求,客户端重试导致同一笔业务成本翻倍。后来我在业务层做了幂等控制,用请求 ID 做去重,才彻底避免重复扣费问题。

7. 个人体会:Java 开发者的 AI 时代不是末日,是换挡

写到最后,我想说一点个人层面的体会。

Spring AI Alibaba 停更那几天,我观察到一个很有趣的现象:社区里最焦虑的往往不是写代码的人,而是平时主要靠"抄配置、背文档"来工作的开发者。因为停更意味着他们熟悉的那份现成文档过期了,新的技术栈需要他们重新建立理解。

而我身边真正能打的高水平 Java 工程师,反应普遍很平静。他们不关心某个组件是不是停更,因为他们本来就不依赖单个组件活着。他们的能力在更底层的地方:理解 HTTP 协议、理解数据建模、理解并发和性能、理解业务逻辑的拆解。这些东西不会因为某个项目停更而贬值,反而会因为 AI 应用的复杂化而更值钱。

Java 在 AI 时代的机会,不在于成为训练模型的工具,而在于成为承载模型能力的底座。模型负责理解和生成,Java 负责把这些能力变成一个又一个可信、稳定、可运维的业务服务。这件事 Python 能干,但 Java 生态在工程化、稳定性、团队技能储备上的优势是实打实的。

如果你现在刚入门,我的建议是先走第三条路线里的 Ollama 本地部署方案,搞一台哪怕只有 CPU 的机器,装个 7B 模型,用 Spring Boot 写一个最简对话接口,然后逐步加上流式、向量检索、多轮对话。把这条路完整走一遍,你对"Java 能不能做 AI"这个问题就不会再有疑问了。

最后再分享一个小技巧:当你不知道某个 Java AI 框架该怎么用时,别急着去搜博客,先去看它的官方示例代码,再直接读它的源码。框架会升级,版本会变化,但核心设计思路是稳定的。把读源码当成一种习惯,你会发现所谓的"框架停更焦虑"根本不值得焦虑——代码就在那里,真本事在自己脑子里。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进