1. 从写业务代码到调模型:Java 开发者切入 AI 的真实路径
写了五六年 Spring Boot,CRUD 写得飞起,微服务拆分、消息队列、分布式事务都能搞定,结果一看招聘市场,AI 工程师的岗位薪资翻了一倍不止。更让人焦虑的是,打开技术社区,满屏都是 Python 的教程、LangChain 的示例、PyTorch 的文档,好像 Java 开发者天生就跟 AI 无缘。我身边不少做 Java 的朋友都在问同一个问题:我到底要不要转 Python?转了之后之前积累的工程能力是不是全废了?
这个问题的答案其实很明确:不需要转 Python,Java 开发者有自己切入 AI 的完整路径。而且从工程落地的角度看,Java 开发者在构建企业级 AI 应用时反而有独特的优势——你懂事务、懂并发、懂服务治理、懂可观测性,这些东西在把 AI 能力集成到真实业务系统时,比会写几行 PyTorch 重要得多。
我自己是从 2023 年底开始系统性地把 AI 能力往 Java 技术栈里搬的,踩了不少坑,也摸索出了一条相对清晰的路线。这篇文章就是把这套路线图完整地拆开讲——从需要补哪些 AI 基础概念,到 Spring AI 和 LangChain4j 这两个核心框架怎么选、怎么用,再到 RAG 知识库的搭建、Agent 的开发、以及最终怎么把 AI 能力集成到 Spring Boot 项目里。适合有 Java 基础、想往 AI 方向靠但不知道从哪下手的开发者,也适合已经在做 AI 集成但想系统梳理一下技术栈的工程师。
先说一个核心判断:Java 开发者的 AI 入门,重点不在训练模型,而在应用集成。你不需要去搞模型微调、分布式训练这些事,那是算法团队的工作。你需要掌握的是怎么调用大模型 API、怎么构建 RAG 检索增强生成链路、怎么用 Agent 编排复杂任务、怎么把这些能力封装成稳定的服务。这个定位想清楚了,后面的学习路径就清晰了。
2. 动手之前先想清楚:Java AI 开发到底在做什么
2.1 大模型应用开发的三层分工
在聊具体技术之前,有必要先把大模型应用开发的分工讲清楚。整个领域大致可以分成三层:
第一层是模型层,负责预训练、微调、推理优化,主要用 Python 和 PyTorch/JAX 这些工具,参与者是算法工程师和研究员。这一层跟绝大多数 Java 开发者没关系。
第二层是应用层,负责把大模型能力接入业务系统,包括 Prompt 工程、RAG 检索增强、Agent 任务编排、Function Calling 工具调用等。这一层是 Java 开发者的主战场,核心框架就是 Spring AI 和 LangChain4j。
第三层是基础设施层,负责模型部署、向量数据库、推理服务网关等,Java 开发者也可以参与,比如用 Spring Boot 封装模型推理服务、做多模型路由网关等。
大部分 Java 开发者应该把精力放在第二层和第三层。我见过不少人一上来就去啃 Transformer 原理、注意力机制公式,啃了两个月发现还是不知道怎么把 AI 接进项目里,这就是方向搞错了。先会用,再理解原理,这个顺序对工程背景的人更友好。
2.2 Java 做 AI 集成的独特优势
为什么我说 Java 开发者在 AI 应用层有优势?因为真实的企业级 AI 应用,难点从来不是调通模型 API,而是:
- 稳定性:模型 API 会超时、会限流、会返回格式错误,你需要重试、熔断、降级,这些是 Java 微服务的强项
- 数据一致性:RAG 场景下,向量库和业务库的数据要同步,文档更新后向量要重建,这涉及分布式事务和最终一致性,Java 开发者天天在处理
- 可观测性:AI 链路的耗时、Token 消耗、检索命中率都需要监控,Micrometer + Prometheus 这套东西 Java 生态最成熟
- 并发与资源管理:大模型调用是 IO 密集型操作,线程池怎么配、连接怎么复用、背压怎么处理,这些都是 Java 开发者的日常
所以不要觉得自己在 AI 时代落伍了。你缺的只是 AI 领域的那几个核心概念和框架用法,工程能力反而是你的护城河。
2.3 需要补的 AI 基础概念清单
不用学太多,下面这几个概念搞懂了就能开始干活:
| 概念 | 一句话解释 | 在 Java AI 开发中的作用 |
|---|---|---|
| Token | 模型处理文本的最小单位,约等于 0.75 个英文单词或 1-2 个汉字 | 计费依据、上下文长度限制的判断标准 |
| Embedding | 把文本转成高维向量,语义相近的文本向量距离近 | RAG 检索的基础,向量数据库存储的就是它 |
| Prompt | 发给模型的指令文本 | 决定模型输出质量的关键,需要反复调试 |
| RAG | 检索增强生成,先从知识库检索相关内容再让模型回答 | 解决模型幻觉和私有知识问题的主流方案 |
| Agent | 能自主规划、调用工具、多步推理的 AI 程序 | 处理复杂任务,比如自动查数据库、调 API |
| Function Calling | 模型根据用户意图决定调用哪个函数 | Agent 的基础能力,让模型能操作外部系统 |
| 向量数据库 | 专门存储和检索向量的数据库 | RAG 的核心组件,常用有 Milvus、PgVector、Redis |
这些概念不需要深究数学原理,知道它们是什么、解决什么问题、怎么在代码里用就行。我建议的学习方式是:边写代码边查概念,遇到不懂的再回去补,比系统性地啃教材效率高得多。
3. 框架选型:Spring AI 和 LangChain4j 到底怎么选
3.1 两个框架的定位差异
Java 生态里做 AI 集成,目前主流就是 Spring AI 和 LangChain4j 两个框架。很多人纠结选哪个,我的建议是先搞清楚它们的定位差异:
Spring AI是 Spring 官方团队推出的项目,设计哲学跟 Spring 一脉相承——约定优于配置、依赖注入、自动装配。如果你已经在用 Spring Boot,集成 Spring AI 几乎是零成本,加个 starter 依赖,配一下 API Key 就能用。它的优势是跟 Spring 生态无缝集成,事务、安全、监控这些都能直接复用。
LangChain4j是社区驱动的项目,灵感来自 Python 的 LangChain,功能更丰富、更灵活。它的优势在于 AI 特有的抽象做得更细,比如 ChatMemory、DocumentSplitter、EmbeddingStore、AiServices 这些,覆盖的场景更全。特别是 Agent 和 RAG 方面,LangChain4j 的 API 设计更成熟。
我自己的做法是:简单集成用 Spring AI,复杂 AI 链路用 LangChain4j。两个框架并不冲突,可以在同一个项目里共存。
3.2 核心 API 对比
拿最基础的对话功能举例,两个框架的写法差异很明显。
Spring AI 的写法:
@RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/chat") public String chat(@RequestParam String message) { return chatClient.prompt() .user(message) .call() .content(); } }LangChain4j 的写法:
interface Assistant { String chat(String message); } Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(model) .build(); String answer = assistant.chat("你好");Spring AI 更符合 Spring 开发者的直觉,LangChain4j 的 AiServices 则更像在定义一个远程服务接口,声明式风格更强。
3.3 选型决策表
| 维度 | Spring AI | LangChain4j |
|---|---|---|
| 官方支持 | Spring 官方 | 社区驱动 |
| Spring Boot 集成 | 原生无缝 | 需要手动配置 |
| RAG 支持 | 基础功能齐全 | 更丰富,支持多种检索策略 |
| Agent 支持 | 较新,功能在完善 | 成熟,支持工具调用和编排 |
| 学习曲线 | 低,Spring 开发者友好 | 中等,概念较多 |
| 版本稳定性 | 1.0 已 GA | 迭代快,API 偶有变动 |
| 适用场景 | 企业级集成、快速落地 | 复杂 AI 链路、实验性项目 |
我的实际经验是:新项目如果只是做对话、简单 RAG,直接上 Spring AI;如果要做多轮 Agent、复杂检索策略、多模型路由,LangChain4j 更合适。另外要注意版本,Spring AI 1.0 之后 API 稳定了很多,LangChain4j 建议锁定版本号,避免升级踩坑。
3.4 模型接入的现实考量
不管用哪个框架,模型接入都是绕不开的。目前主流选择有几类:
- 云端 API:OpenAI、Claude、通义千问、DeepSeek 等,接入简单,按 Token 计费
- 本地部署:通过 Ollama 跑 Llama、Qwen 等开源模型,数据不出内网,适合敏感场景
- 混合模式:简单任务走本地小模型,复杂任务走云端大模型,平衡成本和效果
Spring AI 和 LangChain4j 都支持这些接入方式。我建议开发阶段用云端 API 快速验证,生产环境根据数据敏感度和成本预算决定。本地部署的话,Ollama 是最省事的方案,一条命令就能跑起来,Java 侧通过 HTTP 接口调用即可。
4. RAG 知识库:从文档到可检索的向量库
4.1 RAG 到底解决了什么问题
大模型有两个硬伤:一是知识截止,训练数据之后的事情它不知道;二是幻觉,不知道的事情它会编。RAG 就是来解决这两个问题的——先从你的私有知识库里检索相关内容,把检索结果作为上下文塞进 Prompt,让模型基于这些内容回答。
举个实际场景:你公司有一堆产品文档、FAQ、历史工单,想让 AI 客服能准确回答用户问题。直接问大模型,它不知道你公司的产品细节,只能瞎编。用 RAG,先把用户问题转成向量,去向量库里检索最相关的文档片段,再把片段和问题一起发给模型,模型就能基于真实文档回答了。
RAG 的核心流程是:文档加载 → 文本切分 → 向量化 → 存储 → 检索 → 增强生成。每一步都有讲究,下面逐个拆。
4.2 文档切分的策略选择
文本切分看着简单,实际上对检索效果影响巨大。切得太碎,语义不完整;切得太大,检索精度下降。常见的策略有:
- 固定长度切分:按字符数或 Token 数切,简单粗暴,适合格式统一的文档
- 递归切分:按段落、句子、字符逐级切分,尽量保持语义完整,LangChain4j 的
DocumentSplitters.recursive()就是这种 - 语义切分:用模型判断语义边界,效果最好但成本高
- 结构化切分:针对 Markdown、HTML、代码等有结构的文档,按标题层级切
我的经验是:大部分场景用递归切分就够了,chunk size 设 500-800 Token,overlap 设 50-100 Token。overlap 的作用是防止关键信息刚好被切在边界上导致丢失。如果是技术文档,按标题层级切效果更好,因为每个章节本身就是语义完整的单元。
DocumentSplitter splitter = DocumentSplitters.recursive(800, 100); List<TextSegment> segments = splitter.split(document);4.3 向量化与存储的实操细节
切分完之后要转成向量。Embedding 模型的选择很关键,它直接决定检索质量。常见的有 OpenAI 的 text-embedding-3-small、BGE 系列、通义千问的 embedding 模型等。选型时关注两个指标:向量维度和检索准确率。维度越高表达能力越强,但存储和计算成本也越高。
向量数据库的选择:
| 数据库 | 特点 | 适用场景 |
|---|---|---|
| PgVector | PostgreSQL 扩展,跟业务库共用 | 已有 PG,数据量中等 |
| Milvus | 专业向量库,性能强 | 大规模向量检索 |
| Redis | 内存存储,速度快 | 实时性要求高,数据量可控 |
| Chroma | 轻量级,易上手 | 开发和原型阶段 |
| Elasticsearch | 支持混合检索 | 已有 ES,需要全文+向量混合 |
我一般推荐PgVector,因为大部分 Java 项目本来就有 PostgreSQL,加个扩展就能用,省去维护独立向量库的成本。数据量上千万级别再考虑 Milvus。
4.4 检索策略:从朴素检索到混合检索
最简单的检索就是向量相似度搜索,取 Top-K 个最相似的片段。但实际用下来,纯向量检索有几个问题:对关键词不敏感、对专有名词效果差、容易召回语义相近但实际不相关的内容。
改进方案有几种:
- 混合检索:向量检索 + 关键词检索(BM25),结果融合。对专有名词和精确匹配场景效果好很多
- 重排序:先召回较多候选(比如 20 个),再用重排序模型精排取 Top-5。能显著提升精度
- 查询改写:用户问题往往口语化,先用模型改写成更适合检索的形式
- 多路召回:从不同角度生成多个查询,分别检索后合并
LangChain4j 对这些策略支持比较完善,Spring AI 的基础检索够用但高级策略需要自己实现。我实测下来,混合检索 + 重排序的组合能把检索命中率从 60% 左右提升到 85% 以上,值得投入。
4.5 一个完整的 RAG 代码骨架
用 LangChain4j 搭一个最小可用的 RAG:
// 1. 加载文档 Document document = FileSystemDocumentLoader.loadDocument( Paths.get("/docs/product-manual.md")); // 2. 切分 DocumentSplitter splitter = DocumentSplitters.recursive(800, 100); List<TextSegment> segments = splitter.split(document); // 3. 向量化并存储 EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel(); EmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>(); EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() .embeddingModel(embeddingModel) .embeddingStore(store) .build(); ingestor.ingest(segments); // 4. 构建检索增强的对话服务 ContentRetriever retriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .maxResults(5) .minScore(0.7) .build(); Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatModel) .contentRetriever(retriever) .build(); // 5. 提问 String answer = assistant.chat("产品支持哪些支付方式?");这段代码跑通之后,你就有了一个能基于私有文档回答问题的 AI 服务。生产环境把 InMemoryEmbeddingStore 换成 PgVector 或 Milvus,加上文档更新时的增量索引逻辑即可。
5. Agent 开发:让 AI 能调用你的 Java 方法
5.1 Agent 和普通对话的本质区别
普通对话是"你问我答",Agent 是"你给目标,它自己规划步骤并执行"。区别在于 Agent 能调用工具(Function Calling)、能做多步推理、能根据中间结果调整策略。
举个例子:用户问"帮我查一下上个月销售额最高的产品,然后看看它的库存够不够"。普通对话模型只能瞎编,Agent 可以:第一步调用销售查询接口拿到数据,第二步调用库存查询接口,第三步综合两个结果给出回答。这就是 Agent 的价值。
5.2 Function Calling 的实现方式
LangChain4j 里定义工具非常简单,用注解就行:
public class SalesTools { @Tool("查询指定月份的销售额最高的产品") public String topProduct(@P("月份,格式 yyyy-MM") String month) { // 实际查询数据库 return "产品A,销售额 120 万"; } @Tool("查询指定产品的库存数量") public int stock(@P("产品名称") String productName) { // 实际查询库存系统 return 350; } } Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatModel) .tools(new SalesTools()) .build();模型会根据用户问题自动决定调用哪个工具、传什么参数。你只需要把业务方法用@Tool注解暴露出去,剩下的交给框架。
5.3 Agent 编排的常见模式
实际项目里 Agent 的编排模式主要有几种:
- ReAct 模式:推理-行动循环,模型先思考需要做什么,调用工具,观察结果,再思考下一步。适合探索性任务
- Plan-and-Execute:先制定完整计划,再逐步执行。适合步骤明确的复杂任务
- 多 Agent 协作:多个 Agent 各司其职,比如一个负责检索、一个负责计算、一个负责汇总
LangChain4j 对 ReAct 模式支持最好,其他模式需要自己组合。我的建议是先从单 Agent + 几个工具开始,跑通了再考虑复杂编排。很多场景其实单 Agent 就够了,多 Agent 反而增加调试难度。
5.4 Agent 开发中最容易踩的坑
说几个我实际踩过的坑:
工具描述写得太模糊。模型靠工具描述来决定调不调用、怎么调用。描述写"查询数据"模型根本不知道查什么数据,要写"根据产品名称查询当前库存数量,返回整数"。
工具返回值太大。如果工具返回几千字的文本,会迅速消耗上下文窗口,还会干扰模型判断。工具返回值要精简,只返回关键信息。
没有设置最大迭代次数。Agent 可能陷入循环,反复调用同一个工具。一定要设置最大步数限制,比如 10 步,超过就强制结束。
错误处理不完善。工具调用失败时,要把错误信息返回给模型,让它决定是重试还是换方案,而不是直接抛异常中断整个流程。
6. 把 AI 能力集成进 Spring Boot 项目
6.1 集成架构的设计思路
AI 能力集成到现有 Spring Boot 项目,核心原则是解耦。不要把 AI 调用逻辑散落在各个 Service 里,而是封装成独立的模块,通过接口对外暴露。这样模型切换、Prompt 调整、降级策略都不会影响业务代码。
我通常的架构是:
- ai-core 模块:封装模型客户端、Prompt 模板、RAG 检索、Agent 编排
- ai-api 模块:定义对外的 AI 服务接口
- 业务模块:通过接口调用 AI 能力,不关心底层实现
这样业务代码里只有aiService.answer(question)这样的调用,底层用 Spring AI 还是 LangChain4j、用哪个模型,业务方完全无感。
6.2 配置管理与多环境适配
AI 相关的配置项比较多:API Key、模型名称、超时时间、重试次数、向量库连接等。建议用@ConfigurationProperties统一管理:
@ConfigurationProperties(prefix = "app.ai") @Data public class AiProperties { private String provider; private String apiKey; private String model; private Duration timeout = Duration.ofSeconds(30); private int maxRetries = 3; private RagConfig rag = new RagConfig(); }不同环境用不同的配置文件,开发环境可以用本地 Ollama,生产环境用云端 API。API Key 绝对不能硬编码,走配置中心或环境变量。
6.3 稳定性保障:重试、熔断、降级
模型 API 的不稳定性远超普通 HTTP 服务,必须做好防护:
重试:网络抖动、限流导致的失败可以重试,但要注意幂等性。用 Spring Retry 或 Resilience4j 配置指数退避。
熔断:连续失败达到阈值就熔断,避免雪崩。Resilience4j 的 CircuitBreaker 很好用。
降级:模型不可用时返回兜底答案,比如"当前 AI 服务繁忙,请稍后再试"或走规则引擎。
超时控制:大模型响应可能很慢,必须设置合理超时。流式输出场景要单独处理。
@Bean public ChatClient chatClient(ChatClient.Builder builder, AiProperties props) { return builder .defaultOptions(ChatOptions.builder() .model(props.getModel()) .timeout(props.getTimeout()) .build()) .build(); }6.4 可观测性:监控什么指标
AI 服务的监控跟普通服务不太一样,除了常规的 QPS、延迟、错误率,还要关注:
- Token 消耗:按模型、按接口统计,直接关系到成本
- 检索命中率:RAG 场景下,检索到的内容是否真的被用上了
- 首 Token 延迟:流式输出场景下用户体验的关键指标
- Prompt 长度分布:异常长的 Prompt 可能意味着上下文管理有问题
这些指标通过 Micrometer 埋点,Prometheus 采集,Grafana 展示。我一般会做一个 AI 服务专属的 Dashboard,把上面这些指标都放上去。
6.5 成本控制的几个实用手段
Token 就是钱,成本控制是绕不开的。几个有效的手段:
- 缓存:相同或相似的问题直接返回缓存结果,用语义缓存效果更好
- 模型分级:简单问题用小模型,复杂问题才用大模型
- Prompt 精简:去掉冗余的指令和示例,能省不少 Token
- 上下文裁剪:多轮对话时只保留最近几轮,或者做摘要压缩
- 流式输出:虽然不省 Token,但能提升用户体验,让用户感觉更快
我实测下来,加上语义缓存和模型分级之后,整体成本能降 40% 左右。
7. 学习路线与资源推荐
7.1 分阶段的学习路径
根据我带团队的经验,Java 开发者入门 AI 可以分三个阶段:
第一阶段(1-2 周):搞懂核心概念,跑通第一个 Demo。用 Spring AI 或 LangChain4j 接一个云端模型,实现一个简单的对话接口。这个阶段的目标是建立信心,知道 AI 集成没那么神秘。
第二阶段(3-4 周):深入 RAG。搭一个本地知识库,把公司文档灌进去,实现基于文档的问答。这个阶段会遇到切分策略、检索精度、幻觉处理等实际问题,是成长最快的阶段。
第三阶段(1-2 个月):Agent 和工程化。实现 Function Calling,让 AI 能调用业务接口;把 AI 能力封装成稳定的服务,加上重试、熔断、监控、成本控制。这个阶段完成后,你就具备了独立负责 AI 应用开发的能力。
7.2 值得投入的学习资源
- Spring AI 官方文档:虽然还比较新,但示例代码质量高,跟着敲一遍就能上手
- LangChain4j 官方文档和 Examples 仓库:RAG 和 Agent 的示例很全,直接抄改就能用
- Ollama 官方文档:本地跑模型的最简方案,零基础也能搞定
- 各大模型厂商的 API 文档:了解不同模型的参数和限制,对选型有帮助
不建议一上来就看论文和数学推导,那是第二阶段之后的事情。先把应用跑起来,有了体感再深入原理。
7.3 几个容易走弯路的地方
最后说几个我见过很多人踩的坑:
盲目追求最新模型。新模型不一定适合你的场景,而且 API 可能不稳定。生产环境选成熟稳定的版本。
忽视 Prompt 工程。很多人觉得 Prompt 就是随便写写,实际上同样的模型,Prompt 优化前后效果差距巨大。花时间打磨 Prompt 是值得的。
不做评估就上线。AI 应用的效果很难用传统测试覆盖,需要建立评估集,定期跑回归测试。没有评估就没有优化方向。
低估数据质量的重要性。RAG 的效果上限取决于知识库的质量。文档格式混乱、内容过时、重复冗余,再好的检索策略也救不回来。
忽略安全合规。用户输入可能包含敏感信息,模型输出可能不合规,这些都需要在架构层面考虑过滤和审核机制。
我自己从 Java 后端转到 AI 应用开发,最大的体会是:工程能力是底座,AI 能力是增量。你不需要推翻过去积累的一切,只需要在原有的技术栈上叠加 AI 这一层。Spring AI 和 LangChain4j 这两个框架,本质上就是把 AI 能力包装成了 Java 开发者熟悉的形式——依赖注入、接口抽象、配置管理。用你已有的工程思维去理解它们,上手会比想象中快得多。真正需要花时间的是对 AI 应用特有问题的理解:检索质量怎么评估、Prompt 怎么迭代、Agent 怎么调试、成本怎么控制。这些东西没有捷径,只能在项目里一个个踩过来。