LangChain4j常见问题包括:1.依赖冲突导致ClassNotFoundException,需用dependency:tree检查并锁死okhttp、jackson版本;2.OpenAI Key不生效因未显式调用apiKey();3.流式响应卡住需用OkHttpClient+超时控制;4.启动慢或OOM因EmbeddingModel过早加载,应延迟初始化并调大MaxDirectMemorySize。

LangChain4j 依赖冲突导致 ClassNotFoundException
LangChain4j 本身不绑定具体 LLM 实现,但你选的模型适配器(比如 langchain4j-open-ai 或 langchain4j-anthropic)会拉入大量第三方 SDK,和项目里已有的 okhttp、slf4j、jackson 版本极易打架。常见现象是启动时报 ClassNotFoundException: okhttp3.OkHttpClient 或 NoClassDefFoundError: com.fasterxml.jackson.databind.JsonNode。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
mvn dependency:tree -Dincludes=okhttp检查实际加载的okhttp版本,LangChain4j 官方推荐 4.12.x,低于 4.10 或高于 4.13 都可能出问题 - 在
pom.xml中强制指定关键依赖版本,例如用<dependencyManagement>锁死com.squareup.okhttp3:okhttp和com.fasterxml.jackson.core:jackson-databind - 避免同时引入
langchain4j-open-ai和langchain4j-vertex-ai—— 它们各自带的 gRPC/HTTP 客户端栈不同,叠加后类加载顺序不可控
OpenAI API Key 不生效或 401 错误
不是 Key 写错,而是 LangChain4j 默认走系统环境变量 OPENAI_API_KEY,不读取 Spring Boot 的 application.yml 里的配置项。如果你用 @Value("${openai.api-key}") 注入再传给 OpenAiChatModel.builder(),但没显式调用 .apiKey(...),Key 就根本不会进请求头。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 确认
OpenAiChatModel构造时是否显式调用了.apiKey(...)—— 它不会自动从 Spring Environment 读取 - 别依赖
System.setProperty("OPENAI_API_KEY", "..."),JVM 属性在多线程环境下不可靠,且会被某些测试框架重置 - 如果用 Spring Boot,把 Key 存进
application.yml后,用@ConfigurationProperties绑定到一个 POJO,再注入到 Builder 中,比硬编码更安全
流式响应(Streaming)卡住或乱序
LangChain4j 的 stream() 方法底层依赖 OpenAI 的 SSE(Server-Sent Events),但 JDK 自带的 HttpClient 对 chunked 编码 + 多行 event/data 字段解析不够鲁棒,尤其遇到网络抖动或模型返回空行时,容易 hang 在 onNext() 回调前,或者把多个 token 拼成一个字符串。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 不要直接用
chatModel.stream(prompt)返回的StreamResponse做 UI 渲染,先包装一层:检查response.content()是否非空,且response.finishReason()为STOP才认为结束 - 加超时控制:用
CompletableFuture.orTimeout(30, TimeUnit.SECONDS)包裹 stream 调用,避免前端无限等待 - 生产环境务必换掉默认 HTTP 客户端:用
OkHttpClient替代 JDK HttpClient,它对 SSE 支持更稳定,需在构建OpenAiChatModel时传入.httpClient(...)
Spring Boot 启动慢或 OOM
LangChain4j 默认启用 EmbeddingModel(比如 all-MiniLM-L6-v2)做本地向量检索时,会加载几百 MB 的 ONNX 模型或 HuggingFace tokenizer,而 Spring Boot 的 @PostConstruct 或 InitializingBean 会在主上下文初始化阶段就触发加载 —— 这会导致启动时间飙升,甚至堆外内存溢出(OutOfMemoryError: Direct buffer memory)。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 把 EmbeddingModel 初始化逻辑移到单独的
@LazyBean 或按需加载方法中,别让它参与主上下文启动流程 - 显式设置 JVM 参数:
-XX:MaxDirectMemorySize=512m,否则 Netty/ONNX runtime 默认只分 128MB,不够用 - 确认没在
@Bean方法里重复 new 多个OpenAiChatModel实例 —— 它不是无状态工具类,每个实例都持有独立的 HTTP 连接池和缓存
真正麻烦的是嵌入模型和大语言模型的生命周期混在一起管理,很多人以为“配好就能跑”,结果发现启动要一分半,第一次 query 卡三秒,第二次又快起来——其实是 embedding cache 没预热、HTTP 连接池没复用、或是日志级别设成了 DEBUG 把全部 token 流都打出来了。









