Java开发者AI入门路线图:Spring AI与LangChain4j实战RAG
1. Java 开发者切入 AI 的真实路径拆解1.1 为什么 Java 开发者做 AI 总觉得“隔了一层”我做了十多年 Java 后端从 SSH 时代一路写到 Spring Boot 微服务中间也带过不少团队。这两年身边问得最多的问题就是“我想转 AI但我是写 Java 的是不是得先学 Python”这个问题背后其实藏着一个很深的误解——很多人把“AI 开发”等同于“训练大模型”于是觉得必须进 Python 生态必须懂 PyTorch必须会调参。但真实的企业场景里90% 的 Java 开发者要做的 AI 工作根本不是训练模型而是把大模型能力集成进现有业务系统。这个定位非常关键。你去看现在招聘市场上挂着“AI 应用开发”的岗位真正要求你从零训模型的少之又少绝大多数要求的是会调用大模型 API、会做 RAG 知识库、会写 Agent 编排逻辑、能把 AI 能力嵌到 Spring Boot 服务里。这些活儿Java 开发者不但能干而且因为有工程化底子干得往往比纯算法背景的人更稳。所以路线图的第一件事不是去补 Python而是认清自己的生态位你是 AI 能力的集成者和工程化落地者不是模型训练者。那为什么还是觉得隔了一层我总结下来有三个具体的卡点。第一是概念断层Java 世界里讲的是 Bean、IoC、事务、连接池AI 世界里讲的是 Token、Embedding、向量、Prompt两套词汇体系对不上看文档像看天书。第二是工具链陌生Python 那边 LangChain 生态已经很成熟Java 这边虽然有了 Spring AI 和 LangChain4j但很多人不知道它们能干什么、该怎么选。第三是缺乏可复制的项目模板网上教程要么是 Python 的要么是纯概念讲解很少有“一个 Spring Boot 项目怎么从零接上大模型并跑通 RAG”的完整实操。这篇内容就是冲着这三个卡点来的。我会把 Java 开发者入门 AI 的路线图拆成可执行的阶段把 Spring AI、LangChain4j、RAG 这些核心工具链讲清楚并且给出能直接抄作业的实操方案。不管你是刚工作一两年的 Java 新手还是写了七八年 CRUD 想转型的老兵都能从里面找到自己能上手的那一步。核心关键词就几个Java、AI、Spring AI、LangChain4j、RAG这几个词会贯穿全文因为它们就是 Java 开发者进入 AI 领域的四块基石。1.2 一张适合 Java 人的 AI 学习路线图我不喜欢那种“先学数学、再学机器学习、再学深度学习”的学院派路线那套东西对在职开发者来说周期太长、回报太慢学到一半人就放弃了。对 Java 开发者我更推荐自顶向下、以用带学的路线先从“能跑起来一个 AI 功能”开始再逐步往下补原理。具体分四个阶段。第一阶段打通调用链路1-2 周。目标是让一个 Spring Boot 项目能成功调用大模型并返回结果。这个阶段你不需要懂 Transformer只需要搞明白三件事怎么拿到模型服务的访问凭证、怎么发一个 HTTP 请求把 Prompt 传过去、怎么解析返回的 JSON。用 Spring AI 的话这些都被封装成了一行代码的事。这个阶段的核心产出是一个能对话的接口比如/chat?msg你好返回模型回复。第二阶段掌握 Prompt 工程与结构化输出2-3 周。光会对话没用业务要的是结构化数据。这个阶段要学的是怎么设计 Prompt 让模型稳定输出 JSON、怎么用 Spring AI 的BeanOutputConverter把模型输出直接映射成 Java 对象、怎么处理模型不听话输出格式错乱的情况。这一步是 Java 开发者最能发挥优势的地方因为你有强类型思维知道怎么用契约约束不确定性。第三阶段上手 RAG 知识库3-4 周。这是目前企业落地最广的 AI 场景。核心是把企业私有文档PDF、Word、数据库记录切块、向量化、存进向量库用户提问时先检索相关片段再喂给模型。LangChain4j 和 Spring AI 都提供了完整的 RAG 组件。这个阶段要搞懂 Embedding 模型、向量数据库、文本切分策略、检索召回率这几个关键点。第四阶段Agent 与工作流编排持续。当单次问答满足不了需求时就要让模型能调用工具、能多步推理。这就是 Agent 的范畴涉及 Function Calling、ReAct 模式、多 Agent 协作。LangChain4j 的 AiServices 和 Spring AI 的 Tool Calling 都能支撑。这个阶段没有终点因为 Agent 的玩法还在快速演进。这四个阶段走下来大概两到三个月你就能独立负责一个企业级 AI 应用模块了。注意全程不需要你写一行 Python。下面我把每个阶段的关键工具和实操细节展开讲。2. 工具链选型Spring AI 还是 LangChain4j2.1 两个框架的定位差异与选型逻辑Java 生态里做 AI 集成绕不开两个名字Spring AI和LangChain4j。很多人一上来就纠结选哪个其实这个问题问错了方向。正确的问法是“我的项目是什么形态哪个框架更贴合”我两个都用过也都在生产环境跑过说说我的判断。Spring AI 的定位是Spring 生态的原生 AI 抽象层。它的设计哲学和 Spring Data、Spring Cache 一脉相承用统一的接口屏蔽底层差异让你换模型提供商像换数据库一样简单。它的优势在于和 Spring Boot 的无缝集成——自动配置、依赖注入、Actuator 监控全都是你熟悉的那套。如果你的项目本身就是 Spring Boot 微服务团队又不想引入太多新概念Spring AI 是阻力最小的选择。它目前对 OpenAI 协议兼容的模型支持最好国内的通义千问、智谱等也都有对应的 starter。LangChain4j 的定位是对标 Python LangChain 的 Java 实现功能覆盖面更广、更“重”。它不只是模型调用还包括了完整的 RAG 流水线、Agent 编排、记忆管理、工具调用、多模态支持。它的 API 设计更贴近 AI 应用的思维方式比如AiServices可以把一个 Java 接口直接变成 AI 驱动的实现类这种声明式写法在复杂场景下非常省事。缺点是它的抽象层次多学习曲线比 Spring AI 陡一些而且和 Spring 的集成虽然也有 starter但不如 Spring AI 那么“原生”。我的选型建议很直接新项目、Spring Boot 为主、需求以对话和简单 RAG 为主选 Spring AI需求复杂、要做多步 Agent、要精细控制 RAG 每个环节、或者团队已经在用 LangChain 的思路选 LangChain4j。两者并不互斥我甚至见过一个项目里 Spring AI 负责对外接口、LangChain4j 负责内部 RAG 流水线的混搭用法。下面这张表是我整理的对比方便你快速决策。对比维度Spring AILangChain4j设计定位Spring 原生 AI 抽象对标 LangChain 的全功能框架与 Spring Boot 集成极佳自动配置开箱即用良好有 starter 但需手动配置更多模型调用抽象ChatClient 统一接口ChatLanguageModel 多实现RAG 支持有组件较基础完整流水线切分/检索/重排齐全Agent 能力Tool Calling 为主AiServices、多 Agent 编排更强学习曲线平缓Spring 开发者上手快中等偏陡概念较多适合场景微服务集成、对话、简单 RAG复杂 RAG、Agent、精细控制提示不要因为“LangChain4j 功能多”就无脑选它。功能多意味着抽象多、调试链路长。我见过团队为了一个简单的问答功能引入 LangChain4j结果被它的多层抽象绕晕最后换回 Spring AI 半天就搞定了。选型的第一原则是匹配需求不是堆功能。2.2 环境准备与依赖引入的实操细节不管选哪个框架环境准备这一步都差不多。我以 Spring AI 为例把从零到跑通的步骤写清楚LangChain4j 的差异我会单独标注。首先是 JDK 版本。Spring AI 目前要求JDK 17 及以上这是硬性门槛因为用到了 record、sealed class 等特性。如果你还在 JDK 8第一步就是升级别想着绕过。Maven 用 3.8Gradle 用 7.5。这些基础环境我不多啰嗦重点说依赖。Spring AI 的依赖引入有个坑它不在 Maven 中央仓库的主坐标下而是有自己的 BOM。正确做法是先引入 BOM 管理版本再引入具体 starter。以 OpenAI 兼容协议为例pom.xml里这样写dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency /dependencies然后在application.yml里配置模型服务的地址和凭证spring: ai: openai: base-url: https://你的模型服务地址/v1 api-key: ${AI_API_KEY} chat: options: model: gpt-4o-mini temperature: 0.7这里有几个实操要点。第一api-key千万别硬编码在配置文件里用环境变量注入这是安全底线。第二base-url要确认是否带/v1后缀不同服务商要求不一样配错了会报 404。第三temperature控制输出的随机性做知识问答建议调到 0.2 以下做创意生成可以调到 0.8 以上。LangChain4j 的依赖引入方式不同它是按功能模块拆分的dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai-spring-boot-starter/artifactId version0.35.0/version /dependency配置项类似但 LangChain4j 的模型配置更细比如可以单独配置超时、重试、日志级别。我建议初期把日志级别调到 DEBUG能看到完整的请求和响应排查问题方便很多。注意引入依赖后如果启动报NoClassDefFoundError八成是版本冲突。Spring AI 和 LangChain4j 都依赖一些 HTTP 客户端和 JSON 库如果项目里已经有旧版本会打架。用mvn dependency:tree查一下把冲突的排除掉。3. 从对话到 RAG核心能力逐个击破3.1 第一个 AI 接口让 Spring Boot 开口说话环境搭好后第一件事是写一个能对话的接口。Spring AI 的写法极其简洁注入ChatClient就行RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } GetMapping(/chat) public String chat(RequestParam String msg) { return chatClient.prompt() .user(msg) .call() .content(); } }就这么几行一个 AI 对话接口就跑起来了。ChatClient是 Spring AI 的核心入口prompt()开始构建请求user()设置用户消息call()同步调用content()取文本结果。如果你要流式输出打字机效果把call()换成stream()返回FluxString即可配合 SSE 就能实现前端逐字显示。LangChain4j 的等价写法是注入ChatLanguageModelRestController public class ChatController { private final ChatLanguageModel model; public ChatController(ChatLanguageModel model) { this.model model; } GetMapping(/chat) public String chat(RequestParam String msg) { return model.generate(msg); } }看起来更简单但 LangChain4j 的威力在后面。它有个AiServices机制可以把一个 Java 接口直接变成 AI 实现interface Assistant { String chat(String message); } Assistant assistant AiServices.create(Assistant.class, model); String reply assistant.chat(你好);这种声明式写法在复杂场景下非常优雅你定义接口框架帮你生成实现底层自动处理 Prompt 模板、记忆、工具调用。这是 LangChain4j 相比 Spring AI 的一个明显优势。这个阶段我踩过的坑是中文乱码。有些模型服务返回的编码不是 UTF-8Spring 默认按 ISO-8859-1 解析中文就成乱码了。解决办法是在配置里强制指定编码或者在ChatClient构建时设置。另外超时设置也很关键大模型响应慢默认超时经常不够建议把读超时设到 60 秒以上。3.2 Prompt 工程让模型稳定输出结构化数据会对话只是起点业务系统要的是结构化数据。比如你让模型从一段文本里提取订单信息希望它返回 JSON但模型经常给你加一堆“好的以下是提取结果”这样的废话导致 JSON 解析失败。这就是 Prompt 工程要解决的问题。Spring AI 提供了BeanOutputConverter能把模型输出直接映射成 Java 对象。用法是先定义 recordpublic record OrderInfo(String orderNo, String customer, BigDecimal amount) {}然后构建 Prompt 时带上转换器BeanOutputConverterOrderInfo converter new BeanOutputConverter(OrderInfo.class); String result chatClient.prompt() .user(u - u.text(从以下文本提取订单信息{text}) .param(text, rawText)) .options(ChatOptions.builder() .responseFormat(converter.getFormat()) .build()) .call() .content(); OrderInfo order converter.convert(result);converter.getFormat()会自动生成一段 JSON Schema 描述塞进 Prompt告诉模型“你必须按这个格式输出”。实测下来加了 Schema 约束后格式正确率能从 60% 提到 95% 以上。但还有 5% 的漏网之鱼所以生产环境一定要加兜底解析先尝试直接解析失败后用正则提取 JSON 片段再解析再失败就重试一次。LangChain4j 的做法更彻底它直接支持方法返回类型自动映射interface OrderExtractor { UserMessage(从以下文本提取订单信息{{text}}) OrderInfo extract(V(text) String text); }框架会自动处理格式约束和解析连BeanOutputConverter都不用写。这是 LangChain4j 在结构化输出上的优势。实操心得Prompt 里一定要给示例Few-shot。我做过对比同样一个抽取任务只给 Schema 的准确率是 88%加一个输入输出示例后能到 96%。示例不用多一个就够但必须覆盖边界情况比如金额为负、字段缺失的场景。3.3 RAG 知识库企业私有数据接入的核心方案RAG 是 Java 开发者做 AI 落地最值钱的一块。它的核心逻辑是用户提问时先从企业私有知识库里检索出最相关的片段把这些片段作为上下文一起喂给模型模型基于这些片段回答。这样既解决了模型不知道企业私有数据的问题又避免了微调的高成本。一个完整的 RAG 流水线分两个阶段离线索引和在线检索。离线索引是把文档切块、向量化、存库在线检索是把用户问题向量化、在库里找最相似的块、拼进 Prompt。我用 LangChain4j 演示因为它的 RAG 组件最完整。离线索引的代码大致是这样// 1. 加载文档 Document document FileSystemDocumentLoader.loadDocument( Paths.get(/data/knowledge/产品手册.pdf), new ApachePdfBoxDocumentParser()); // 2. 切分 DocumentSplitter splitter DocumentSplitters.recursive(500, 50); ListTextSegment segments splitter.split(document); // 3. 向量化 EmbeddingModel embeddingModel new OpenAiEmbeddingModel(...); EmbeddingStoreTextSegment store new InMemoryEmbeddingStore(); EmbeddingStoreIngestor ingestor EmbeddingStoreIngestor.builder() .documentSplitter(splitter) .embeddingModel(embeddingModel) .embeddingStore(store) .build(); ingestor.ingest(document);在线检索和问答ContentRetriever retriever EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .maxResults(5) .minScore(0.7) .build(); Assistant assistant AiServices.builder(Assistant.class) .chatLanguageModel(model) .contentRetriever(retriever) .build(); String answer assistant.chat(产品保修期是多久);这里有几个参数直接决定 RAG 效果我逐个说。切分大小recursive(500, 50)里的 500指的是每块最大字符数太小会丢上下文太大会稀释相关性中文场景我建议 300-500 字。重叠长度50是相邻块的重叠部分防止关键信息被切断一般设切分大小的 10%-20%。maxResults是检索返回的块数太少信息不全太多会超出模型上下文窗口5 个是常用起点。minScore是相似度阈值低于这个分数的块直接丢弃防止无关内容干扰0.7 是个经验值具体要按你的 Embedding 模型调。注意RAG 最常见的失败不是模型不行而是切分策略不对。我见过把整份 PDF 按固定长度硬切的结果一个表格被切成两半检索出来全是残缺信息。正确做法是按语义切分优先在段落、标题、列表边界切。LangChain4j 的recursive切分器会尝试按段落、句子、字符逐级降级切分比硬切好很多。3.4 向量数据库选型从内存到生产级RAG 的检索性能很大程度取决于向量数据库。开发阶段用内存版就够了但生产环境必须上专业的。我按使用场景给个选型建议。向量库部署方式适合场景我的评价InMemoryEmbeddingStore进程内开发测试、小数据量零配置重启即丢别上生产Redis Stack独立服务已有 Redis 基础设施复用现有运维性价比高PostgreSQL pgvector独立服务已有 PG、数据量中等SQL 和向量统一管理很省心Milvus独立集群亿级向量、高并发功能强但运维重小团队慎选Elasticsearch独立集群已有 ES、要混合检索全文向量混合检索是亮点我的经验是中小项目优先选 PostgreSQL pgvector 或 Redis Stack。原因很简单你大概率已经有其中一个了不用引入新的运维负担。pgvector 的 SQL 写法对 Java 开发者极其友好一个ORDER BY embedding ?就能做相似度检索配合 Spring Data JPA 用起来毫无违和感。Milvus 这种专业向量库除非你的向量规模真的到了千万级以上否则是杀鸡用牛刀。4. 实操避坑与常见问题排查4.1 RAG 效果差的五个典型原因RAG 搭起来容易效果好难。我调过好几个 RAG 项目总结下来效果差基本逃不出这五个原因按出现频率排序。第一切分粒度不对。这是头号杀手。切太大检索出来的块包含太多无关信息模型被干扰切太小上下文不完整模型答非所问。判断方法很简单随便抽几个检索结果看看如果块里一半内容是无关的就是切大了如果块里句子都不完整就是切小了。第二Embedding 模型选错。中文场景一定要用支持中文的 Embedding 模型。有些团队图省事用了英文模型结果中文语义相似度算得一塌糊涂。国内的通义千问 Embedding、智谱 Embedding 在中文上表现都不错选之前先拿几十条真实问题测一下召回率。第三检索策略单一。纯向量检索对“关键词精确匹配”的场景很弱比如用户问“型号 X200 的保修政策”向量检索可能召回一堆讲保修但不涉及 X200 的块。解决办法是混合检索向量检索 关键词检索BM25两路结果融合重排。LangChain4j 支持组合多个ContentRetrieverES 也原生支持混合检索。第四没有重排。初步检索回来的块是按向量相似度排序的但向量相似不等于语义相关。加一个 Rerank 模型重排模型对候选块重新打分能显著提升精度。这一步成本不高但效果提升明显我强烈建议加上。第五Prompt 没约束。检索回来的上下文直接塞给模型模型可能忽略上下文自己编。Prompt 里必须明确写“只根据以下资料回答资料中没有的信息就说不知道”。这句话能大幅降低幻觉率。4.2 常见问题速查表下面这张表是我在实际项目中遇到的高频问题整理出来方便你对照排查。现象可能原因排查与解决启动报依赖冲突版本不兼容mvn dependency:tree查冲突排除旧版本调用返回 401凭证错误或过期检查 api-key 环境变量是否注入成功调用返回 404base-url 路径错误确认是否带 /v1不同服务商要求不同中文乱码编码未指定强制 UTF-8检查 HTTP 客户端配置响应超时默认超时太短读超时调到 60s 以上考虑流式输出结构化输出解析失败模型加了废话加 Schema 约束 正则兜底 重试RAG 答非所问切分或检索问题检查切分粒度、minScore、加 Rerank检索召回率低Embedding 不匹配换中文 Embedding 模型测召回率内存溢出向量全量加载换外部向量库分批处理文档并发下响应慢模型服务限流加本地缓存、请求队列、降级策略4.3 几个只有踩过才知道的实操心得说几个文档里不会写、但实际项目里特别重要的点。关于成本控制。大模型调用是按 Token 计费的RAG 场景下每次请求都要把检索到的上下文塞进去Token 消耗是纯对话的好几倍。我的做法是对高频问题做结果缓存相同问题直接返回缓存答案对检索块做去重和压缩把重复内容合并对简单问题走小模型复杂问题才走大模型。这三招下来成本能降一半以上。关于流式输出。用户等 10 秒才看到完整回答体验很差。用 SSE 做流式输出模型吐一个字前端显示一个字感知延迟大幅降低。Spring AI 的stream()和 LangChain4j 的StreamingChatLanguageModel都支持。注意流式场景下错误处理更麻烦要在流结束的回调里统一处理异常。关于 Prompt 版本管理。Prompt 是 AI 应用的“代码”但很多人把它硬编码在 Java 里改一次要重新部署。我的做法是把 Prompt 抽到配置文件或数据库里支持热更新并且给每个 Prompt 打版本号方便 A/B 测试和回滚。这个习惯在 Prompt 调优阶段能省大量时间。关于测试。AI 应用的测试和传统应用完全不同输出是不确定的没法用assertEquals。我的做法是对结构化输出测字段完整性对问答测关键信息是否命中对 RAG 测召回率。建一个几十条的评测集每次改 Prompt 或换模型都跑一遍看指标有没有退化。这个评测集是 AI 应用的质量生命线越早建越好。5. 进阶方向Agent 与工作流编排5.1 从单次问答到多步推理当你的 RAG 跑通后会发现有些问题不是一次检索能解决的。比如用户问“帮我对比一下 A 产品和 B 产品的保修政策差异”这需要先分别检索两个产品的信息再对比。这种多步任务就是 Agent 的用武之地。Agent 的核心是让模型能调用工具。你定义一组工具查数据库、调 API、算数模型根据用户问题决定调哪个、传什么参数拿到结果后继续推理直到给出最终答案。Spring AI 的 Tool Calling 和 LangChain4j 的Tool注解都能实现。LangChain4j 的写法很直观public class OrderTools { Tool(根据订单号查询订单状态) public String queryOrderStatus(String orderNo) { // 实际查库逻辑 return 已发货; } } Assistant assistant AiServices.builder(Assistant.class) .chatLanguageModel(model) .tools(new OrderTools()) .build(); String answer assistant.chat(订单 12345 到哪了);模型会自动识别出需要调用queryOrderStatus提取订单号参数执行后把结果融入回答。这种能力让 AI 应用从“问答机器人”升级成“能办事的助手”。5.2 Agentic RAG让检索也智能起来传统 RAG 是“一问一检索”但复杂问题需要多轮检索、甚至需要判断“这个问题要不要检索”。Agentic RAG 就是把 Agent 的思路引入 RAG让模型自己决定检索策略。具体来说Agentic RAG 会做几件事查询改写把用户口语化的问题改写成适合检索的形式、检索决策判断是否需要检索简单问题直接答、多轮检索一次检索不够就换个角度再检、结果验证检查检索结果是否真的回答了问题不够就再检。LangChain4j 的AiServices配合自定义的ContentRetriever和RetrievalAugmentor可以实现这些。这块目前还在快速演进我的建议是先把基础 RAG 做扎实再考虑 Agentic。基础 RAG 的切分、检索、重排没调好上 Agentic 只会让问题更复杂、更难排查。我见过团队基础 RAG 召回率才 60% 就急着上 Agentic结果调了两周还不如老老实实优化切分策略。5.3 给 Java 开发者的长期建议最后说点掏心窝的话。Java 开发者做 AI最大的优势不是算法而是工程化能力。模型会迭代、框架会更新但把不确定的 AI 能力封装成稳定的服务、做好降级和监控、保证高并发下的可用性这些是 Java 开发者的看家本领也是 AI 应用从 Demo 走向生产的关键。我的建议是别追新概念把 RAG 和 Agent 这两个场景吃透就够了。市面上新框架、新名词层出不穷但企业真正愿意付费的还是“能基于私有知识准确回答”和“能自动完成多步任务”这两件事。把这两件事做到 90 分比追十个新概念到 60 分有价值得多。另外保持动手。AI 这东西看一百篇教程不如自己跑通一个项目。从今天开始拿一个你熟悉的业务场景用 Spring AI 或 LangChain4j 做一个最小可用的 AI 功能哪怕只是把公司 FAQ 做成问答机器人。跑通之后你会发现那些看起来高深的概念其实都是可以拆解、可以上手的工程问题。我自己就是这么一步步走过来的从第一次调通接口的兴奋到被 RAG 召回率折磨再到把 Agent 跑进生产每一步都是踩坑踩出来的。你也一样可以。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →