Java开发者AI入门:Spring AI与LangChain4j实战指南
1. 从写业务代码到跑通第一个AI功能中间隔着什么如果你是一个写了三五年 Java 的开发者最近大概率会有一种隐隐的焦虑身边做算法的同事在聊 RAG、Agent、向量库而你每天还在跟 MyBatis 的映射文件和 Spring 的事务传播行为打交道。想入门 AI打开教程一看全是 PythonPyTorch、Transformers、LangChain光是环境配置就能劝退一半人。于是很多人卡在第一步我到底要不要转 Python我的结论很直接绝大多数 Java 开发者入门 AI不需要转 Python也不需要从零训练模型。你要做的是把 AI 能力当成一个新的外部依赖接进现有的 Spring 体系里就像当年你接 Redis、接 MQ 一样。真正需要你花时间理解的是提示词怎么组织、上下文怎么管理、工具怎么调用、结果怎么校验这几件事而不是反向传播怎么求导。这篇内容就是给这类人写的有 Java 基础、熟悉 Spring Boot、想在自己的项目里落地 AI 功能但不知道从哪下手、用什么库、踩哪些坑。我会把整条路线拆成可执行的阶段重点讲清楚Spring AI 和 LangChain4j 这两个主流框架怎么选、工具链怎么搭、第一个能跑的功能怎么写以及那些文档里不会写、只有实际跑过才知道的经验。全程不涉及任何需要特殊网络环境的内容所有依赖都走公开的 Maven 仓库。先说清楚一个前提AI 应用开发和传统后端开发最大的区别在于你的下游服务是不确定的。数据库查询返回什么就是什么但大模型的输出每次都可能不一样。这个不确定性会渗透到你整个架构设计里——重试策略、结果解析、降级方案、成本控制全都跟传统 CRUD 不一样。想明白这一点后面的很多设计选择就顺理成章了。2. 先搞清楚 Java 在 AI 应用里的真实定位2.1 你不是在训练模型你是在编排模型很多新手一上来就想搞明白 Transformer 架构、注意力机制结果啃了两周论文代码一行没写。这是典型的路线错误。Java 开发者在 AI 应用层的角色本质上是编排者把大模型、向量数据库、业务系统、外部工具串成一条能完成任务的链路。打个比方大模型就像一个知识渊博但记性不太好、还偶尔会胡说八道的顾问。你的工作不是把他脑子重新造一遍而是给他准备好参考资料RAG、告诉他这次任务的具体要求提示词工程、给他配几个能查数据能调接口的助手Function Calling / Tool、最后检查他给的答案靠不靠谱输出校验。这套活儿用 Java 干完全没问题而且因为 Java 的工程化能力强做企业级落地反而更有优势。2.2 哪些场景适合 Java 团队先切入不是所有 AI 功能都值得做。根据我见过的落地案例Java 团队最容易出成果的方向有这么几类场景类型典型例子技术要点落地难度智能问答基于内部文档的知识库问答RAG、向量检索中内容生成自动写周报、生成商品描述提示词模板、结构化输出低信息抽取从合同/简历里抽字段结构化输出、JSON Schema低智能助手能查订单能改状态的客服Tool Calling、多轮对话高代码辅助内部代码规范检查、单测生成长上下文、代码理解中建议从信息抽取或内容生成入手因为这两个场景对准确性要求相对可控出错了人工兜底成本低能让你快速跑通全链路、建立信心。等这套流程熟了再上 RAG 和 Agent。2.3 一个容易被忽略的现实成本和质量是要权衡的新手最容易犯的错是拿最强的模型去干最简单的活。我见过一个项目用顶级模型给每条用户评论做情感分类正面/负面/中性一天几万条账单直接爆炸。实际上这种任务用一个小模型甚至本地跑个小模型就够了。所以从第一天起你就要在架构里留出模型可切换的抽象层。这也是为什么我强烈建议用 Spring AI 或 LangChain4j 这类框架而不是直接裸调 HTTP 接口——它们把模型抽象成了统一的接口换模型基本只改配置。这个设计决策会在你后期优化成本时救你的命。3. Spring AI 和 LangChain4j 到底怎么选这是被问得最多的问题没有之一。网上很多对比文章列一堆特性表格看完还是不知道选哪个。我换个角度从你的项目现状来给判断依据。3.1 Spring AI如果你已经是 Spring 重度用户Spring AI 最大的优势就是和 Spring 生态无缝。你的ChatClient可以像RestTemplate一样注入配置写在application.yml里和现有的Service、Configuration风格完全一致。团队里只要会 Spring Boot上手几乎没有学习成本。它的核心抽象是ChatClient和ChatModel调用长这样RestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder .defaultSystem(你是一个专业的客服助手回答要简洁准确。) .build(); } GetMapping(/chat) public String chat(RequestParam String message) { return chatClient.prompt() .user(message) .call() .content(); } }看到没这就是标准的 Spring 风格。如果你团队里有人对 AI 完全没概念让他看这段代码也能大概明白在干嘛。Spring AI 的短板在于它的高级特性比如复杂的 Agent 编排、多步推理链相对 LangChain4j 来说还在快速演进中版本迭代比较快API 偶尔会有变动。用的时候要留意版本兼容。3.2 LangChain4j如果你需要更细的编排控制LangChain4j 是 LangChain 理念在 Java 上的实现它的抽象层次更丰富ChatLanguageModel、EmbeddingModel、EmbeddingStore、AiServices、RetrievalAugmentor等等。如果你要做 RAG、要做带记忆的多轮对话、要做工具调用链LangChain4j 提供的现成组件更多。它最有意思的是AiServices这个声明式接口你可以定义一个 Java 接口框架自动帮你实现interface Assistant { SystemMessage(你是一个只回答技术问题的助手其他问题礼貌拒绝。) String chat(UserMessage String userMessage); } Assistant assistant AiServices.builder(Assistant.class) .chatLanguageModel(model) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); String answer assistant.chat(Spring 的事务传播行为有哪些);这种接口即 Agent的写法对 Java 开发者来说非常自然比手写一堆 prompt 拼接清爽得多。3.3 我的实际选择建议说个实在的判断标准项目以 CRUD 为主只想加个 AI 功能选 Spring AI。集成成本最低和现有代码风格统一。要做 RAG 知识库、多轮对话、工具调用选 LangChain4j。组件更全编排更灵活。两个都想用其实可以共存它们底层都是调 HTTP 接口不冲突。但别在一个功能里混用容易乱。还有一个现实因素看你团队的技术栈惯性。如果团队连 Spring Cloud 都用得很溜Spring AI 的接受度会高很多如果团队本来就喜欢用各种独立组件拼装LangChain4j 更对味。提示无论选哪个都建议先用一个独立的小项目跑通别一上来就往核心业务里塞。AI 功能的调试成本和传统功能完全不是一个量级。4. 工具链搭建从零到跑通第一个调用4.1 环境准备里最容易忽略的三件事搭环境这一步看着简单但坑不少。我列几个实际踩过的第一JDK 版本。Spring AI 目前主流版本要求 JDK 17 及以上LangChain4j 也建议 17。如果你还在用 JDK 8先升级别想着凑合。这不是框架挑剔是因为它们大量用了 record、sealed class、虚拟线程这些新特性。第二构建工具的依赖管理。Spring AI 的版本管理建议用 BOMBill of Materials避免各个子模块版本对不上dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagementLangChain4j 同理它也有自己的 BOM。千万别手动一个个指定版本号模块之间的版本依赖很微妙用 BOM 能省掉大量排查时间。第三API Key 的管理。这是安全红线。绝对不要把 Key 硬编码在代码里也不要在测试代码里明文写。用环境变量或者配置中心spring: ai: openai: api-key: ${AI_API_KEY} base-url: ${AI_BASE_URL}然后在启动脚本或 IDE 的运行配置里注入环境变量。团队协作时把.env文件加进.gitignore提供一个.env.example模板给同事参考。4.2 第一个能跑的功能结构化信息抽取我建议第一个练手项目做信息抽取因为它最能体现 AI 应用的核心模式又不需要复杂的编排。比如从一段用户反馈里抽出产品名称、问题类型、紧急程度、联系方式。用 Spring AI 的BeanOutputConverter可以直接把模型输出映射成 Java 对象public record FeedbackInfo( String productName, String issueType, String urgency, String contact ) {} GetMapping(/extract) public FeedbackInfo extract(RequestParam String text) { BeanOutputConverterFeedbackInfo converter new BeanOutputConverter(FeedbackInfo.class); String prompt 从下面的用户反馈中抽取信息严格按照要求的 JSON 格式输出。 反馈内容%s %s .formatted(text, converter.getFormat()); String result chatClient.prompt().user(prompt).call().content(); return converter.convert(result); }这里有个关键点converter.getFormat()会自动生成 JSON Schema 描述塞进提示词告诉模型该输出什么结构。这比你自己手写请输出 JSON包含以下字段……要可靠得多因为 Schema 是机器生成的格式更规范。4.3 跑通之后立刻要做的三件事很多人跑通第一个 Demo 就以为入门了其实真正的工程化才刚开始。跑通后立刻做这三件事加超时和重试。大模型接口的响应时间波动很大快的时候一两秒慢的时候几十秒。必须设置合理的超时并且对可重试的错误比如限流、网络抖动做退避重试。Spring AI 支持通过RetryTemplate配置LangChain4j 也有类似机制。加日志和可观测性。把每次调用的输入、输出、耗时、token 消耗都记下来。这不是为了调试是为了成本核算和质量分析。你会需要知道哪个功能最费钱、哪类问题模型答得最差。加降级方案。模型服务挂了怎么办限流了怎么办必须有兜底逻辑比如返回缓存结果、走规则引擎、或者给用户一个友好的提示。AI 功能不能成为系统的单点故障。5. RAG 落地让模型回答你的私有知识5.1 RAG 的本质是开卷考试RAG检索增强生成这个词听着高大上本质特别朴素模型不知道你公司内部的事那就在提问之前先把相关资料找出来塞给它。就像开卷考试允许你带小抄进场。整个流程分两步离线索引和在线检索。离线阶段把你的文档切块、向量化、存进向量库在线阶段把用户问题也向量化去库里找最相似的几块拼进提示词一起发给模型。用 LangChain4j 做一套最小可用的 RAG核心代码大概是这样// 离线文档入库 EmbeddingModel embeddingModel OpenAiEmbeddingModel.builder() .apiKey(System.getenv(AI_API_KEY)) .build(); EmbeddingStoreTextSegment store new InMemoryEmbeddingStore(); DocumentSplitter splitter DocumentSplitters.recursive(500, 50); ListTextSegment segments splitter.split(Document.from(你的文档内容)); ListEmbedding embeddings embeddingModel.embedAll(segments).content(); store.addAll(embeddings, segments); // 在线检索 生成 ContentRetriever retriever EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .maxResults(5) .minScore(0.7) .build(); RetrievalAugmentor augmentor DefaultRetrievalAugmentor.builder() .contentRetriever(retriever) .build();5.2 切块策略RAG 效果好坏的第一决定因素我见过太多 RAG 项目效果差问题根本不在模型而在切块。文档切得不好检索出来的内容驴唇不对马嘴模型再强也救不回来。几个实战经验块大小别一刀切。500 字符是个常见起点但不是万能。技术文档、法律条款这种信息密度高的块可以小一点300-400叙述性的内容可以大一点800-1000。关键是保证一个块内的内容是语义完整的别把一句话从中间劈开。一定要有重叠。相邻块之间留 10%-20% 的重叠防止关键信息正好卡在边界上被切断。上面代码里的50就是重叠字符数。按结构切优于按长度切。如果文档有明确的标题层级、段落结构优先按结构切。Markdown 文档按##切代码按函数切效果通常比纯按字符数切好很多。5.3 检索质量调优从能查到到查得准基础 RAG 跑通后你会发现检索质量不稳定。这时候有几个调优方向调整相似度阈值。minScore设太低会召回一堆无关内容干扰模型设太高又可能什么都查不到。建议从 0.7 开始根据实际效果微调。这个值跟你的 embedding 模型有关换模型要重新调。混合检索。纯向量检索对关键词不敏感比如用户搜错误码 5001向量检索可能找不准。加上关键词检索BM25做混合效果会明显提升。LangChain4j 支持组合多个 retriever。重排序Rerank。先粗召回 20 条再用一个重排序模型精排出最相关的 5 条。这一步能显著提升精度代价是多一次模型调用。对质量要求高的场景值得加。注意RAG 不是银弹。如果检索出来的内容本身就是错的或者过时的模型只会把错误信息包装得更像真的。所以知识库的维护和更新机制比技术选型更重要。6. 那些文档不会告诉你的坑6.1 提示词不是越长越好新手容易陷入一个误区把提示词写得越长越详细模型表现就越好。实际上过长的提示词会稀释关键信息模型可能抓不住重点。而且提示词越长token 消耗越大成本越高。我的经验是核心指令放开头和结尾因为模型对这两个位置的注意力最强。中间放参考资料。指令要具体、可执行避免尽量适当这种模糊词。比如别说回答要简洁要说回答控制在 100 字以内。6.2 结构化输出会失败必须做容错即使你用了 JSON Schema模型偶尔还是会输出格式不对的内容——多一个逗号、少一个引号、或者干脆输出一段解释文字。所以解析的时候必须 try-catch失败了要么重试要么降级。try { return converter.convert(result); } catch (Exception e) { log.warn(结构化输出解析失败原始内容{}, result); // 降级返回默认值或触发重试 return FeedbackInfo.empty(); }别指望模型 100% 听话这是概率系统不是确定性系统。6.3 上下文窗口是硬约束要主动管理多轮对话场景下历史消息会越积越多最终超出模型的上下文窗口。你必须主动管理要么只保留最近 N 轮要么对历史做摘要压缩。LangChain4j 的MessageWindowChatMemory就是干这个的设置maxMessages后它会自动丢弃最老的消息。但要注意简单丢弃可能导致上下文断裂更好的做法是对早期对话做摘要保留关键信息。6.4 流式输出能极大改善体验大模型生成完整回答可能要十几秒用户干等着体验很差。用流式输出SSE让文字一个字一个字蹦出来感知延迟会低很多。Spring AI 和 LangChain4j 都支持流式Spring AI 配合Flux返回即可GetMapping(value /chat/stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString chatStream(RequestParam String message) { return chatClient.prompt().user(message).stream().content(); }这个改动很小但对用户体验的提升是质变的。建议所有面向用户的对话功能都上流式。7. 从能跑到能用工程化的几个关键决策7.1 模型抽象层要提前留好前面提过一定要在架构里留出模型可切换的抽象。Spring AI 的ChatModel接口、LangChain4j 的ChatLanguageModel接口都是干这个的。你的业务代码只依赖接口具体用哪个模型通过配置决定。这样做的好处在你想换模型、想加多模型路由、想做 A/B 测试的时候会体现得淋漓尽致。我见过一个项目因为把模型调用写死在业务代码里后来想换个更便宜的模型改了几十个文件。7.2 成本控制要从第一天做起AI 功能的成本是持续的、随用量线性增长的不像服务器是一次性投入。几个控制手段按场景选模型简单任务用小模型复杂任务才用大模型。缓存高频请求相同或相似的问题直接返回缓存结果。限制输入长度对用户输入做长度限制避免有人恶意塞超长文本。监控 token 消耗把每次调用的 token 数记下来做用量看板。7.3 测试策略要调整传统单元测试那套给定输入断言输出的方法对 AI 功能基本失效因为输出不确定。你需要换一套思路断言结构而非内容验证输出是合法 JSON、包含必需字段而不是断言具体文字。用评分而非相等对生成质量用另一个模型打分或者用关键词覆盖率等指标。建立回归集收集一批典型输入和期望输出特征每次改动后跑一遍看有没有明显退化。这套测试体系搭起来费劲但一旦有了你改提示词、换模型的时候心里就有底了。8. 我个人的学习路线建议说了这么多技术细节最后聊聊路线。如果你现在完全零基础我建议按这个顺序走每一步都动手写代码别只看不练第一阶段1-2 周跑通最简单的对话调用理解提示词、token、上下文窗口这几个概念。用 Spring AI 或 LangChain4j 都行重点是建立AI 调用就是个特殊的外部接口这个认知。第二阶段2-3 周做结构化输出和信息抽取。这一步会让你理解提示词工程的实际价值以及为什么要做输出校验。第三阶段3-4 周搭一套最小 RAG。重点体会切块策略和检索质量的关系这是 RAG 的核心。第四阶段持续做工具调用和多步编排。这是 Agent 的基础也是最难的部分建议等前三阶段都熟了再碰。整个过程不需要你去看深度学习论文也不需要学 Python。你需要的是工程思维 对不确定性的容忍度。Java 开发者在这两点上其实有天然优势因为企业级开发本来就是在和各种不确定性打交道。我自己的体会是入门 AI 最大的障碍不是技术难度而是心理上的陌生感。一旦你跑通第一个功能发现它其实就是个 HTTP 调用加一堆字符串处理那种神秘感就消失了。剩下的就是不断实践、踩坑、总结。这个领域变化很快但底层的工程方法论是稳定的把方法论吃透工具怎么变都不慌。