随着大语言模型技术的快速发展Java开发者面临着一个现实问题如何在企业级应用中高效集成LLM能力不同厂商的API差异、复杂的提示工程、记忆管理和工具调用等挑战让很多团队在技术选型时陷入困境。LangChain4j作为专为JVM设计的开源库提供了一套完整的解决方案让Java开发者能够快速构建生产级的LLM应用。本文将从实战角度全面解析LangChain4j涵盖核心概念、环境搭建、代码示例到生产最佳实践无论你是刚接触LLM的Java开发者还是正在评估技术方案的技术负责人都能获得实用的指导。1. LangChain4j核心概念与架构设计1.1 什么是LangChain4jLangChain4j是一个地道的、开源的Java库专门用于在JVM上构建LLM驱动的应用程序。与Python版的LangChain不同LangChain4j是专门为Java生态系统设计的充分遵循Java的编程惯例和设计模式。该库的核心价值在于提供统一的API抽象层屏蔽了不同LLM提供商和向量数据库的技术差异。目前支持20主流LLM提供商如OpenAI、Google Vertex AI、Anthropic等和30向量存储方案如Pinecone、Milvus、Chroma等。1.2 核心架构组件LangChain4j的架构设计围绕几个关键抽象层展开LLM提供商抽象通过统一的接口调用不同厂商的LLM服务只需更改配置即可切换提供商。// 统一的LLM调用接口示例 ChatLanguageModel model OpenAiChatModel.builder() .apiKey(your-api-key) .modelName(gpt-4) .build(); String response model.generate(Hello, how are you?);向量存储抽象提供标准化的向量存储和检索接口支持多种向量数据库。工具调用框架允许LLM调用外部工具和函数扩展模型的能力边界。记忆管理管理对话历史和多轮交互的上下文信息。代理模式实现复杂的推理和决策流程让LLM能够按步骤解决问题。1.3 与Spring AI的区别很多开发者会困惑LangChain4j与Spring AI的选择问题。两者虽然目标相似但设计哲学和适用场景有所不同LangChain4j更轻量级提供更细粒度的控制支持多种Java框架Spring Boot、Quarkus、Helidon、MicronautSpring AI深度集成Spring生态系统更适合纯Spring技术栈的项目选择时需要考虑团队的技术栈偏好和项目复杂度LangChain4j在框架选择上提供了更大的灵活性。2. 环境准备与项目配置2.1 系统要求与依赖管理LangChain4j要求Java 11或更高版本支持主流的构建工具包括Maven和Gradle。建议使用IDE如IntelliJ IDEA或Eclipse进行开发。Maven依赖配置!-- 在pom.xml中添加LangChain4j BOMBill of Materials -- dependencyManagement dependencies dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-bom/artifactId version0.32.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement !-- 添加核心依赖 -- dependencies dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-core/artifactId /dependency !-- OpenAI集成 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId /dependency !-- 如果需要Spring Boot集成 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-boot-starter/artifactId /dependency /dependenciesGradle配置// build.gradle dependencies { implementation platform(dev.langchain4j:langchain4j-bom:0.32.0) implementation dev.langchain4j:langchain4j-core implementation dev.langchain4j:langchain4j-open-ai implementation dev.langchain4j:langchain4j-spring-boot-starter }2.2 多HTTP客户端冲突解决在实际项目中经常会遇到multiple HTTP clients have been found in the classpath错误。这是因为项目中存在多个HTTP客户端实现如Apache HttpClient、OkHttp等。解决方案排除冲突依赖dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId exclusions exclusion groupIdorg.apache.httpcomponents.client5/groupId artifactIdhttpclient5/artifactId /exclusion /exclusions /dependency显式指定HTTP客户端OpenAiChatModel model OpenAiChatModel.builder() .apiKey(your-api-key) .httpClient(new ApacheHttpClient()) // 明确指定使用Apache HttpClient .build();在Spring Boot中配置# application.yml langchain4j: openai: chat-model: api-key: ${OPENAI_API_KEY} http-client: type: apache # 指定使用apache客户端2.3 项目结构规划建议的项目结构如下src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── yourcompany/ │ │ └── llmapp/ │ │ ├── config/ │ │ │ └── LangChain4jConfig.java │ │ ├── service/ │ │ │ ├── ChatService.java │ │ │ └── RagService.java │ │ ├── model/ │ │ │ └── ChatRequest.java │ │ └── Application.java │ └── resources/ │ ├── application.yml │ └── prompts/ # 提示模板目录 └── test/ └── java/ └── com/yourcompany/llmapp/service/ └── ChatServiceTest.java3. 核心功能详解与代码实战3.1 基础聊天功能实现让我们从最简单的聊天功能开始了解LangChain4j的基本用法// 文件src/main/java/com/yourcompany/llmapp/service/ChatService.java package com.yourcompany.llmapp.service; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import org.springframework.stereotype.Service; Service public class ChatService { private final ChatLanguageModel chatModel; public ChatService() { this.chatModel OpenAiChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-3.5-turbo) .temperature(0.7) .maxTokens(1000) .build(); } public String chat(String message) { return chatModel.generate(message); } // 带系统提示的聊天 public String chatWithSystemPrompt(String systemPrompt, String userMessage) { String fullPrompt String.format( 你是一个专业的AI助手。请根据以下系统提示回答问题。 系统提示%s 用户问题%s , systemPrompt, userMessage); return chatModel.generate(fullPrompt); } }测试代码// 文件src/test/java/com/yourcompany/llmapp/service/ChatServiceTest.java package com.yourcompany.llmapp.service; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertNotNull; class ChatServiceTest { Test void testBasicChat() { // 注意在实际测试中应该使用Mock或测试环境的API Key ChatService chatService new ChatService(); String response chatService.chat(你好请介绍一下Java的特点); assertNotNull(response); System.out.println(AI回复 response); } }3.2 提示模板与记忆管理在实际应用中我们需要管理对话历史和上下文。LangChain4j提供了强大的记忆管理功能// 文件src/main/java/com/yourcompany/llmapp/service/ConversationService.java package com.yourcompany.llmapp.service; import dev.langchain4j.memory.ChatMemory; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.service.AiServices; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import org.springframework.stereotype.Service; // 定义AI服务接口 interface Assistant { String chat(String message); SystemMessage(你是一个专业的Java技术专家专门回答编程相关问题) String answerTechnicalQuestion(UserMessage String question); } Service public class ConversationService { private final Assistant assistant; public ConversationService() { ChatLanguageModel model OpenAiChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-3.5-turbo) .build(); ChatMemory chatMemory MessageWindowChatMemory.withMaxMessages(10); this.assistant AiServices.builder(Assistant.class) .chatLanguageModel(model) .chatMemory(chatMemory) .build(); } public String haveConversation(String userMessage) { return assistant.chat(userMessage); } public String askTechnicalQuestion(String question) { return assistant.answerTechnicalQuestion(question); } }3.3 工具调用Function Calling实战工具调用是LangChain4j最强大的功能之一允许LLM调用外部工具// 文件src/main/java/com/yourcompany/llmapp/tools/CalculatorTool.java package com.yourcompany.llmapp.tools; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; Component public class CalculatorTool { Tool(用于执行数学计算支持加减乘除等基本运算) public double calculate(Tool(数学表达式例如: 2 3 * 4) String expression) { try { // 简单的表达式计算实际项目中应该使用更安全的表达式解析器 return evaluateExpression(expression); } catch (Exception e) { throw new RuntimeException(计算表达式失败: expression, e); } } private double evaluateExpression(String expression) { // 简化实现实际项目应使用ScriptEngine或表达式解析库 expression expression.replaceAll( , ); if (expression.contains()) { String[] parts expression.split(\\); return Double.parseDouble(parts[0]) Double.parseDouble(parts[1]); } // 其他运算类似处理... return Double.parseDouble(expression); } } // 使用工具的服务 // 文件src/main/java/com/yourcompany/ll/llmapp/service/ToolService.java package com.yourcompany.llmapp.service; import dev.langchain4j.agent.tool.ToolExecutor; import dev.langchain4j.agent.tool.ToolSpecification; import dev.langchain4j.memory.ChatMemory; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.service.AiServices; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.V; import com.yourcompany.llmapp.tools.CalculatorTool; import org.springframework.stereotype.Service; interface ToolAssistant { String chat(String message); } Service public class ToolService { private final ToolAssistant assistant; public ToolService(CalculatorTool calculatorTool) { ChatLanguageModel model OpenAiChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-3.5-turbo) .build(); ChatMemory chatMemory MessageWindowChatMemory.withMaxMessages(10); this.assistant AiServices.builder(ToolAssistant.class) .chatLanguageModel(model) .chatMemory(chatMemory) .tools(calculatorTool) .build(); } public String useTool(String message) { return assistant.chat(message); } }4. RAG检索增强生成完整实现RAG是LangChain4j的核心应用场景下面实现一个完整的文档问答系统4.1 文档加载与处理// 文件src/main/java/com/yourcompany/llmapp/rag/DocumentProcessor.java package com.yourcompany.llmapp.rag; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.DocumentParser; import dev.langchain4j.data.document.parser.TextDocumentParser; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.openai.OpenAiEmbeddingModel; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.EmbeddingStoreIngestor; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import org.springframework.stereotype.Component; import java.nio.file.Paths; import java.util.List; Component public class DocumentProcessor { private final EmbeddingStoreTextSegment embeddingStore; private final EmbeddingModel embeddingModel; public DocumentProcessor() { this.embeddingStore new InMemoryEmbeddingStore(); this.embeddingModel OpenAiEmbeddingModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(text-embedding-ada-002) .build(); } public void ingestDocument(String filePath) { DocumentParser parser new TextDocumentParser(); Document document parser.parse(Paths.get(filePath)); EmbeddingStoreIngestor ingestor EmbeddingStoreIngestor.builder() .documentSplitter(DocumentSplitters.recursive(500, 50)) .embeddingModel(embeddingModel) .embeddingStore(embeddingStore) .build(); ingestor.ingest(document); } public EmbeddingStoreTextSegment getEmbeddingStore() { return embeddingStore; } public EmbeddingModel getEmbeddingModel() { return embeddingModel; } }4.2 RAG服务实现// 文件src/main/java/com/yourcompany/llmapp/rag/RagService.java package com.yourcompany.llmapp.rag; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.retriever.EmbeddingStoreRetriever; import dev.langchain4j.retriever.Retriever; import dev.langchain4j.service.AiServices; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.filter.Filter; import org.springframework.stereotype.Service; import java.util.List; import static dev.langchain4j.store.embedding.filter.MetadataFilterBuilder.metadataKey; Service public class RagService { private final RagAssistant assistant; public RagService(DocumentProcessor documentProcessor) { ChatLanguageModel chatModel OpenAiChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-3.5-turbo) .build(); EmbeddingStoreTextSegment embeddingStore documentProcessor.getEmbeddingStore(); RetrieverTextSegment retriever EmbeddingStoreRetriever.from(embeddingStore, documentProcessor.getEmbeddingModel(), 3); this.assistant AiServices.builder(RagAssistant.class) .chatLanguageModel(chatModel) .retriever(retriever) .build(); } public String askQuestion(String question) { return assistant.answer(question); } interface RagAssistant { String answer(String question); } }4.3 RAG系统测试// 文件src/test/java/com/yourcompany/llmapp/rag/RagServiceTest.java package com.yourcompany.llmapp.rag; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.nio.file.Files; import java.nio.file.Path; SpringBootTest class RagServiceTest { Autowired private DocumentProcessor documentProcessor; Autowired private RagService ragService; BeforeEach void setUp() throws Exception { // 创建测试文档 Path testDoc Path.of(test_document.txt); Files.writeString(testDoc, LangChain4j是一个用于Java的LLM集成框架。 它支持多种大语言模型提供商包括OpenAI、Anthropic等。 框架提供了统一的API简化了LLM应用的开发流程。 RAG检索增强生成是其主要应用场景之一。 ); documentProcessor.ingestDocument(testDoc.toString()); Files.deleteIfExists(testDoc); } Test void testRagQuery() { String answer ragService.askQuestion(LangChain4j支持哪些LLM提供商); System.out.println(RAG回答 answer); } }5. 高级特性与生产级配置5.1 流式响应处理对于需要实时显示响应的场景LangChain4j支持流式响应// 文件src/main/java/com/yourcompany/llmapp/service/StreamingService.java package com.yourcompany.llmapp.service; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.openai.OpenAiStreamingChatModel; import dev.langchain4j.model.output.Response; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.util.function.Consumer; Service public class StreamingService { private final StreamingChatLanguageModel streamingModel; public StreamingService() { this.streamingModel OpenAiStreamingChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-3.5-turbo) .build(); } public SseEmitter streamChat(String message, ConsumerString onComplete) { SseEmitter emitter new SseEmitter(30000L); // 30秒超时 streamingModel.generate(message, new dev.langchain4j.model.StreamingResponseHandler() { private final StringBuilder fullResponse new StringBuilder(); Override public void onNext(String token) { try { fullResponse.append(token); emitter.send(SseEmitter.event() .data(token) .id(String.valueOf(System.currentTimeMillis()))); } catch (IOException e) { emitter.completeWithError(e); } } Override public void onComplete(ResponseString response) { onComplete.accept(fullResponse.toString()); emitter.complete(); } Override public void onError(Throwable error) { emitter.completeWithError(error); } }); return emitter; } }5.2 配置管理与最佳实践生产环境配置示例# application-prod.yml langchain4j: openai: chat-model: api-key: ${OPENAI_API_KEY} model-name: gpt-4 temperature: 0.3 max-tokens: 2000 timeout: 60s log-requests: true log-responses: true embedding-model: api-key: ${OPENAI_API_KEY} model-name: text-embedding-ada-002 timeout: 30s # 自定义配置 app: llm: max-retries: 3 retry-delay: 2s cache-enabled: true cache-ttl: 1h配置类实现// 文件src/main/java/com/yourcompany/llmapp/config/LangChain4jConfig.java package com.yourcompany.llmapp.config; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.support.RetryTemplate; import java.time.Duration; Configuration EnableRetry public class LangChain4jConfig { Value(${openai.api-key}) private String openAiApiKey; Value(${app.llm.max-retries:3}) private int maxRetries; Value(${app.llm.retry-delay:2s}) private Duration retryDelay; Bean public ChatLanguageModel chatLanguageModel() { return OpenAiChatModel.builder() .apiKey(openAiApiKey) .modelName(gpt-3.5-turbo) .maxRetries(maxRetries) .timeout(Duration.ofSeconds(30)) .logRequests(true) .logResponses(true) .build(); } Bean public RetryTemplate retryTemplate() { return RetryTemplate.builder() .maxAttempts(maxRetries) .fixedBackoff(retryDelay.toMillis()) .retryOn(Exception.class) .build(); } }6. 常见问题与解决方案6.1 依赖冲突问题问题现象启动时报错multiple HTTP clients have been found in the classpath解决方案检查依赖树mvn dependency:tree或gradle dependencies排除冲突的HTTP客户端依赖显式指定使用的HTTP客户端!-- 排除冲突示例 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId exclusions exclusion groupIdcom.squareup.okhttp3/groupId artifactIdokhttp/artifactId /exclusion /exclusions /dependency6.2 内存泄漏问题问题现象长时间运行后内存持续增长解决方案合理设置ChatMemory的大小限制定期清理过期的对话记录使用外部存储如Redis管理大规模对话历史Bean public ChatMemory chatMemory() { return MessageWindowChatMemory.withMaxMessages(50); // 限制最大消息数 }6.3 性能优化建议批量处理对于多个文档的嵌入计算使用批量API缓存策略对频繁查询的结果进行缓存异步处理使用CompletableFuture进行非阻塞调用连接池配置HTTP连接池避免频繁建立连接Bean public OpenAiChatModel openAiChatModel() { return OpenAiChatModel.builder() .apiKey(apiKey) .modelName(gpt-3.5-turbo) .connectTimeout(Duration.ofSeconds(10)) .readTimeout(Duration.ofSeconds(30)) .writeTimeout(Duration.ofSeconds(30)) .build(); }7. 生产环境部署与监控7.1 健康检查配置// 文件src/main/java/com/yourcompany/llmapp/health/LlmHealthIndicator.java package com.yourcompany.llmapp.health; import dev.langchain4j.model.chat.ChatLanguageModel; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; Component public class LlmHealthIndicator implements HealthIndicator { private final ChatLanguageModel chatModel; public LlmHealthIndicator(ChatLanguageModel chatModel) { this.chatModel chatModel; } Override public Health health() { try { String response chatModel.generate(健康检查); return Health.up() .withDetail(response_length, response.length()) .build(); } catch (Exception e) { return Health.down(e) .withDetail(error, e.getMessage()) .build(); } } }7.2 监控与指标收集集成Micrometer进行指标收集# application.yml management: endpoints: web: exposure: include: health,metrics,prometheus metrics: export: prometheus: enabled: true// 自定义指标监控 Component public class LlmMetrics { private final MeterRegistry meterRegistry; private final Counter requestCounter; private final Timer responseTimer; public LlmMetrics(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; this.requestCounter Counter.builder(llm.requests) .description(LLM API请求次数) .register(meterRegistry); this.responseTimer Timer.builder(llm.response.time) .description(LLM响应时间) .register(meterRegistry); } public void recordRequest(String model) { requestCounter.increment(); meterRegistry.counter(llm.requests.by.model, model, model).increment(); } public Timer.Sample startTimer() { return Timer.start(meterRegistry); } public void stopTimer(Timer.Sample sample, String model) { sample.stop(responseTimer.tag(model, model)); } }7.3 安全最佳实践API密钥管理使用Secret管理工具避免硬编码输入验证对用户输入进行严格的验证和清理速率限制实现API调用速率限制避免超额费用内容过滤对输入输出进行适当的内容过滤Component public class SecurityService { public String sanitizeInput(String input) { // 移除潜在的恶意内容 return input.replaceAll([], ); } public boolean isRateLimited(String userId) { // 实现基于用户的速率限制逻辑 return false; } }通过本文的全面介绍你应该对LangChain4j有了深入的理解。从基础概念到高级特性从简单示例到生产级配置LangChain4j为Java开发者提供了构建LLM应用的完整工具链。在实际项目中建议根据具体需求选择合适的组件和配置并始终关注性能、安全和可维护性。