今天聊点实在的。LangChain4j

张开发
2026/4/17 8:44:35 15 分钟阅读

分享文章

今天聊点实在的。LangChain4j
聊点实在的。LangChain4j 这个框架网上的资料确实不少但很多要么太教条要么直接甩你一堆官方文档链接。今天这篇不谈空话就是把自己本地搭建的完整过程掰开揉碎了说连我掉进去的那些坑都一并扒出来。一、迈出第一步之前把“地基”夯实说真的本地跑大模型比想象中简单得多。你不需要一台几十万的企业级服务器只要你手头的电脑配置不太拉跨就行。硬件到底需要啥根据我自己的经历如果你只是跑个本地 Demo不需要 GPUCPU 模式完全够用。我当初用的一台 8 核处理器、16G 内存的 MacBook Pro跑起来顺畅得很。但如果你想本地跑个大点的模型比如 7B 参数的 Llama 或者 Qwen那就得看你的 GPU 了——有个 8G 以上显存的显卡体验会舒服很多。如果你还在用 4G 显存的入门卡别灰心选个 1.5B 到 3B 的小模型照样能玩转。软件环境Java 必须是 JDK 17 或以上版本这是硬性要求因为 LangChain4j 依赖了一些 Java 17 的新特性。构建工具我选的是 Maven个人习惯Gradle 也行IDE 用的 IntelliJ IDEA基本是 Java 开发的标配。本地大模型怎么选我强烈推荐用 Ollama 来部署本地模型。Ollama 是一个专门在本地跑大模型的工具安装极其简单一条命令就能把 Llama、Mistral、Qwen 这些模型拉下来跑起来。安装 Ollama去 https://ollama.com 下载对应的安装包双击一路 Next 就行。安装完成后打开终端输入这条命令来拉取一个比较轻量的模型ollama pull qwen2.5:3b这条命令会从 Ollama 的模型仓库里下载阿里通义千问 2.5 版本参数规模 3B。这个模型对中文的支持特别好而且 3B 的规模普通电脑 CPU 跑起来也毫无压力。下载完成后可以用ollama run qwen2.5:3b先在命令行里测试一下确保模型能正常对话再开始下一步。二、Maven 依赖版本选不对后面全是坑这里我想多唠叨几句。LangChain4j 的版本迭代速度非常快而且现在主版本已经从之前的 0.x 系列全面升级到了 1.x 系列。如果你在网上搜教程看到别人用的还是0.272.0这种老版本千万别盲目跟——老版本的 API 和新版可能完全不兼容跑起来全是编译报错。根据官方文档推荐使用 BOMBill of Materials方式来统一管理版本这样各个模块的版本不会打架dependencyManagementdependenciesdependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-bom/artifactIdversion1.3.0/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependencies!-- LangChain4j 核心库 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j/artifactId/dependency!-- Ollama 集成 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-ollama/artifactId/dependency!-- 本地轻量级 Embedding 模型用于 RAG --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-embeddings-all-minilm-l6-v2/artifactId/dependency!-- 极简版 RAG 依赖开箱即用 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-easy-rag/artifactId/dependency/dependencies注意这里的langchain4j-bom版本号要和你实际使用的版本保持一致。如果你在 Maven 中央仓库查到最新的稳定版是 1.12.x就用那个版本的 BOM。另外官方文档里提到 LangChain4j 很多模块目前还是 beta 版使用时要有心理准备。三、第一个 Hello World让 Java 和大模型说上话依赖配好了写段代码跑起来试试。importdev.langchain4j.model.ollama.OllamaChatModel;importdev.langchain4j.model.chat.ChatLanguageModel;importdev.langchain4j.model.output.Response;publicclassFirstAIChat{publicstaticvoidmain(String[]args){// 配置 Ollama 模型注意模型名要和 ollama pull 时的名字一致ChatLanguageModelmodelOllamaChatModel.builder().baseUrl(http://localhost:11434)// Ollama 默认端口.modelName(qwen2.5:3b)// 你本地拉取的模型名.temperature(0.7f)// 控制回复的随机性.build();// 简单提问StringuserMessage用一句话介绍 Java 的特点;ResponseStringanswermodel.generate(userMessage);System.out.println(AI 回复answer.content());}}这段代码里temperature是一个挺有意思的参数——数值越低模型的回复越保守、越固定数值越高回复越有“想象力”但也更容易跑偏。0.7 是个比较折中的值适合日常对话。运行之前千万记得确认一件事你的 Ollama 服务必须已经启动并且qwen2.5:3b模型已经下载完毕。如果 Ollama 没跑起来这段代码会直接报连接异常这个坑我当初踩了至少三回。如果你顺利跑通了控制台应该会输出类似这样的内容AI 回复Java 是一种跨平台的面向对象编程语言以其“一次编写到处运行”的特点而闻名。看到这个输出说明你的 Java 项目已经成功和本地大模型对话上了。四、对话记忆让 AI 不再“健忘”上面那个例子每次调用generate()都是独立的AI 不记得你刚才说过什么。要让对话有上下文就需要用到 ChatMemory。LangChain4j 提供了好几种记忆实现最常用的是MessageWindowChatMemory它能记住最近的 N 条对话。importdev.langchain4j.memory.ChatMemory;importdev.langchain4j.memory.chat.MessageWindowChatMemory;importdev.langchain4j.model.ollama.OllamaChatModel;importdev.langchain4j.model.chat.ChatLanguageModel;publicclassChatWithMemory{publicstaticvoidmain(String[]args){ChatLanguageModelmodelOllamaChatModel.builder().baseUrl(http://localhost:11434).modelName(qwen2.5:3b).temperature(0.7f).build();// 创建能记住最近 10 条消息的对话记忆ChatMemorychatMemoryMessageWindowChatMemory.withMaxMessages(10);// 模拟多轮对话String[]userMessages{我叫张三,我刚才说我叫什么来着,我的名字里第一个字是什么};for(Stringmsg:userMessages){chatMemory.add(newUserMessage(msg));ResponseStringresponsemodel.generate(chatMemory.messages());System.out.println(用户msg);System.out.println(AIresponse.content());chatMemory.add(newAssistantMessage(response.content()));System.out.println(---);}}}跑完这段代码你会发现 AI 能准确记住你之前说过的名字这就是 ChatMemory 在背后起的作用。MessageWindowChatMemory.withMaxMessages(10)表示最多保留最近 10 条消息超过这个数量会自动丢弃最旧的消息。五、给 AI 配上“知识库”极简版 RAG对话记忆只是让 AI 记住你刚才说了什么但如果想让 AI 回答关于你公司内部文档、产品说明书之类的私有知识就需要 RAG检索增强生成了。简单说就是给 AI 配一个“资料库”让它在回答之前先去资料库里翻一翻。LangChain4j 有一个极简版的 RAG 实现开箱即用最适合快速验证效果。假设你在项目的src/main/resources/docs目录下放了几份技术文档比如Java编程学习路线.md、常见面试题.md之类的用下面这段代码就能让 AI 基于这些文档回答问题importdev.langchain4j.data.document.Document;importdev.langchain4j.data.document.FileSystemDocumentLoader;importdev.langchain4j.model.embedding.EmbeddingModel;importdev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;importdev.langchain4j.model.ollama.OllamaChatModel;importdev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;importdev.langchain4j.service.AiServices;importdev.langchain4j.store.embedding.EmbeddingStore;importdev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;importdev.langchain4j.rag.DefaultRetrievalAugmentor;importdev.langchain4j.rag.RetrievalAugmentor;importdev.langchain4j.model.chat.ChatLanguageModel;// 定义 AI Service 接口interfaceMyAssistant{Stringchat(StringuserMessage);}publicclassSimpleRAGDemo{publicstaticvoidmain(String[]args){// 1. 加载本地文档ListDocumentdocumentsFileSystemDocumentLoader.loadDocuments(src/main/resources/docs);// 2. 创建 Embedding 模型将文本转为向量的模型EmbeddingModelembeddingModelnewAllMiniLmL6V2EmbeddingModel();// 3. 创建内存向量存储EmbeddingStoreTextSegmentembeddingStorenewInMemoryEmbeddingStore();// 4. 将文档向量化并存入存储EmbeddingStoreIngestor.ingest(documents,embeddingStore);// 5. 创建 Chat 模型ChatLanguageModelchatModelOllamaChatModel.builder().baseUrl(http://localhost:11434).modelName(qwen2.5:3b).build();// 6. 构建带 RAG 能力的 AI ServiceMyAssistantassistantAiServices.builder(MyAssistant.class).chatModel(chatModel).contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)).build();// 7. 测试问答StringquestionJava 里如何实现多线程;Stringanswerassistant.chat(question);System.out.println(问题question);System.out.println(回答answer);}}这段代码的核心逻辑是先把你的文档向量化存起来用户提问时系统先从向量库里检索相关的内容然后把检索到的内容作为“参考资料”连同问题一起喂给大模型让模型基于这些资料来回答。这里特别想提一句AllMiniLmL6V2EmbeddingModel是个本地轻量级 Embedding 模型不需要调用任何外部 API数据完全在本地处理。如果你对数据安全有要求或者不方便联网用这个就对了。六、别踩这些坑这几条是我用 LangChain4j 过程中真实踩过的坑希望能帮你省下好几个小时的 debug 时间。坑一版本冲突。LangChain4j 还在快速迭代中部分模块目前还是 beta 版本。不同模块之间版本不一致可能会导致一些奇奇怪怪的方法找不到。解决方案用上面推荐的 BOM 方式统一版本千万不要手动分别指定各个模块的版本号。坑二官方文档不一定全。有人吐槽过 LangChain4j 的官方文档“该有的重要内容是一点都不介绍”。比如想把对话记忆持久化到数据库官方文档几乎没有相关说明需要自己翻源码。遇到这种情况去 GitHub 上搜相关的 issue 或者直接看源码可能是更高效的办法。坑三模型的 SDK 差异。有网友分享过一个亲身经历同样的代码用阿里百炼模型跑就各种报错换成 OpenAI 之后就丝般顺滑最后发现是模型 SDK 的源码 BUG。所以如果你本地跑不通别死磕一个模型换 Ollama 上另一个模型试试说不定问题就解决了。坑四Ollama 没启动就调用。这个坑我踩了好几次。代码写得再漂亮如果 Ollama 服务没跑起来或者模型没下载完调用model.generate()的时候会直接报Connection refused异常。运行前先用ollama list确认模型已下载用ollama ps确认服务在运行。坑五流式输出的用法差异。如果你想实现逐字输出的效果像 ChatGPT 那样一个字一个字蹦出来不能用普通的ChatLanguageModel需要换成StreamingChatLanguageModel并配合langchain4j-reactor依赖。这个坑在官方文档里说得不够清楚单独提一下。七、写在最后说实话LangChain4j 这个框架确实不完美。它的官方文档算不上详尽有些功能还在 beta 阶段偶尔会遇到一些意想不到的 bug。但话说回来作为一个 Java 开发者能有这样一个原生框架帮我们打通和大模型之间的“最后一公里”已经是一件很值得庆幸的事情了。我自己的经验是从最简单的一个 Hello World 开始先跑通单次对话然后慢慢引入 ChatMemory 做多轮对话再试试 RAG 给你的应用加上知识库。一步一步来每往前走一步你都会对这个框架的理解更深一点。希望这篇教程能帮你少走一些弯路。如果你在搭建过程中遇到什么问题或者有什么好玩的实践想分享欢迎留言交流——毕竟Java 圈做大模型应用的人还是少数咱们更需要互相帮衬。

更多文章