
LangChain4j 核心抽象ChatMessage、UserMessage 与模型无关设计前言LangChain4j 的核心设计理念是模型无关——通过统一的抽象层让开发者能够轻松切换不同的 LLM 提供商OpenAI、Ollama、Anthropic 等而无需重写业务代码。这一设计的基石就是 ChatMessage 体系。本文将深入剖析 LangChain4j 的核心抽象包括消息类型体系、Content 抽象、多模态支持以及如何实现模型提供商的无缝切换。一、消息类型体系1.1 ChatMessage 层级结构LangChain4j 定义了完整的消息类型继承体系ChatMessage (抽象基类) │ ├── SystemMessage # 系统消息 ├── UserMessage # 用户消息 ├── AiMessage # AI 响应消息 ├── ToolExecutionResultMessage # 工具执行结果消息 └── Content ... # 消息内容抽象1.2 消息类型详解1.2.1 SystemMessage系统消息用于定义 AI 的角色和行为规则。importdev.langchain4j.data.message.SystemMessage;// 创建系统消息SystemMessagesystemMessageSystemMessage.from(你是一个专业的Java技术顾问擅长解答Spring Boot相关问题);// 在 AI Service 中使用SystemMessage(你是一个专业的Java技术顾问)publicinterfaceAssistant{Stringchat(StringuserMessage);}使用场景定义 AI 角色如你是一个客服助手设定输出格式如请以JSON格式返回限制行为范围如只回答技术问题1.2.2 UserMessage用户消息表示用户的输入支持多模态内容文本 图像。importdev.langchain4j.data.message.UserMessage;importdev.langchain4j.data.message.ImageContent;importdev.langchain4j.data.message.TextContent;// 纯文本消息UserMessagetextMessageUserMessage.from(什么是Spring Boot);// 图文混合消息1.4.0 新特性UserMessagemultiModalMessageUserMessage.from(ImageContent.from(https://example.com/screenshot.png),TextContent.from(请解释这张截图中的错误信息));使用场景用户提问多模态输入文本 图像/音频/视频历史上下文传递1.2.3 AiMessageAI 响应消息表示 LLM 的响应内容。importdev.langchain4j.data.message.AiMessage;// 创建 AI 消息AiMessageaiMessageAiMessage.from(Spring Boot 是基于 Spring 框架的快速开发框架...);// 获取工具调用Function Callingif(aiMessage.hasToolExecutionRequests()){ListToolExecutionRequestrequestsaiMessage.toolExecutionRequests();for(ToolExecutionRequestrequest:requests){System.out.println(调用工具: request.name());System.out.println(参数: request.arguments());}}使用场景LLM 文本响应工具调用请求保存对话历史1.2.4 ToolExecutionResultMessage工具执行结果表示工具执行后的返回值。importdev.langchain4j.data.message.ToolExecutionResultMessage;// 创建工具执行结果消息ToolExecutionResultMessageresultMessageToolExecutionResultMessage.from(tool-execution-id-123,查询结果北京今天气温 25°C);// 在对话中使用ListChatMessagemessagesnewArrayList();messages.add(UserMessage.from(北京今天天气如何));messages.add(AiMessage.from(tool-execution-id-123,null));// AI 调用工具messages.add(resultMessage);// 工具执行结果Stringresponsemodel.generate(messages);使用场景Function Calling 流程多步骤工具调用Agent 决策循环1.3 消息流转图┌─────────────────────────────────────────────────────────────┐ │ ChatMessage 消息流转 │ └─────────────────────────────────────────────────────────────┘ 用户 LLM 工具系统 │ │ │ │ 1. UserMessage │ │ ├─────────────────────│ │ │ 北京天气 │ │ │ │ │ │ │ 2. 生成工具调用请求 │ │ ├────────────────────│ │ │ ToolExecutionRequest│ │ │ │ │ │ 3. 执行工具 │ │ │─────────────────────┤ │ │ 返回结果 │ │ │ │ │ │ 4. 生成最终响应 │ │─────────────────────┤ │ │ 5. AiMessage │ │ │ 北京今天25°C │ │ │ │ │ └──────────────────────┴───────────────────────┘ 对话历史保存 ChatMemory ├── MessageWindowChatMemory窗口滑动 └── TokenWindowChatMemoryToken 预算二、Content 抽象多模态支持2.1 Content 层级结构LangChain4j 1.4.0 引入了统一的 Content 抽象支持多模态输入Content (接口) │ ├── TextContent # 文本内容 ├── ImageContent # 图像内容1.4.0 新增 ├── AudioContent # 音频内容预留 └── VideoContent # 视频内容预留2.2 TextContent文本内容importdev.langchain4j.data.message.TextContent;// 创建文本内容TextContenttextContentTextContent.from(Hello, LangChain4j!);// UserMessage 支持多个 TextContentUserMessagemessageUserMessage.from(TextContent.from(问题1什么是Spring Boot),TextContent.from(问题2如何快速开始));2.3 ImageContent图像内容1.4.0 新增特性支持图像输入适配 GPT-4V、Claude-3V 等视觉模型。importdev.langchain4j.data.message.ImageContent;// 从 URL 创建ImageContentfromUrlImageContent.from(https://example.com/image.jpg);// 从 Base64 创建ImageContentfromBase64ImageContent.from(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...);// 从字节数组创建byte[]imageBytesFiles.readAllBytes(Paths.get(screenshot.png));ImageContentfromBytesImageContent.from(imageBytes);// 图文混合输入UserMessagevisionMessageUserMessage.from(ImageContent.from(https://example.com/code.png),TextContent.from(请解释这段代码的功能));// 调用支持视觉的模型Stringresponsegpt4VisionModel.generate(visionMessage);2.4 多模态组合示例// 示例图文混合同步查询UserMessagecomplexQueryUserMessage.from(TextContent.from(请分析以下内容),ImageContent.from(https://example.com/diagram.png),TextContent.from(图表中的数据趋势如何));Stringanalysismodel.generate(complexQuery);// 示例多图对比UserMessagecomparisonUserMessage.from(TextContent.from(对比这两张图片的差异),ImageContent.from(https://example.com/before.png),ImageContent.from(https://example.com/after.png));Stringdiffmodel.generate(comparison);三、模型提供商切换3.1 统一接口设计LangChain4j 提供了统一的模型接口支持无缝切换提供商importdev.langchain4j.model.chat.ChatLanguageModel;importdev.langchain4j.model.openai.OpenAiChatModel;importdev.langchain4j.model.anthropic.AnthropicChatModel;importdev.langchain4j.model.ollama.OllamaChatModel;// 统一接口ChatLanguageModelmodel;// 切换到 OpenAImodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).build();// 切换到 Anthropic ClaudemodelAnthropicChatModel.builder().apiKey(System.getenv(ANTHROPIC_API_KEY)).modelName(claude-3-sonnet-20240229).build();// 切换到 Ollama本地模型modelOllamaChatModel.builder().baseUrl(http://localhost:11434).modelName(llama3.1).build();// 使用相同的代码调用Stringresponsemodel.generate(你好);3.2 配置差异对比配置项OpenAIAnthropicOllamaAPI Key✅ 必需✅ 必需❌ 不需要Base URL默认默认必需http://localhost:11434Model Namegpt-4o, gpt-3.5-turboclaude-3-sonnet, claude-3-opusllama3.1, qwen2温度支持支持支持流式响应支持支持支持多模态gpt-4-vision-previewclaude-3-opus-20240229依赖模型成本按用量计费按用量计费免费本地3.3 配置工厂模式publicclassModelFactory{publicstaticChatLanguageModelcreateModel(Stringprovider,StringmodelName){switch(provider.toLowerCase()){caseopenai:returnOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(modelName).build();caseanthropic:returnAnthropicChatModel.builder().apiKey(System.getenv(ANTHROPIC_API_KEY)).modelName(modelName).build();caseollama:returnOllamaChatModel.builder().baseUrl(http://localhost:11434).modelName(modelName).build();default:thrownewIllegalArgumentException(Unsupported provider: provider);}}}// 使用配置工厂ChatLanguageModelmodelModelFactory.createModel(openai,gpt-4o);Stringresponsemodel.generate(你好);3.4 模型切换流程图┌─────────────────────────────────────────────────────────────┐ │ 模型提供商切换流程 │ └─────────────────────────────────────────────────────────────┘ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │ 配置源 │ - │ ModelFactory │ - │ ChatLanguageModel │ │ 配置文件 │ │ 创建模型 │ │ 统一接口 │ │ 环境变量 │ │ │ │ │ └─────────────┘ └──────────────┘ └────────┬────────┘ │ ┌──────────────────────┼──────────────────────┐ │ │ │ ▼ ▼ ▼ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ OpenAI │ │ Anthropic │ │ Ollama │ │ gpt-4o │ │ claude-3 │ │ llama3.1 │ │ 云端API │ │ 云端API │ │ 本地部署 │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ └──────────────────────┼──────────────────────┘ │ ▼ ┌──────────────┐ │ 统一调用接口 │ │ generate() │ └──────────────┘ │ ▼ ┌──────────────┐ │ 返回结果 │ │ String │ └──────────────┘四、通用参数标准化4.1 温度Temperature控制输出的随机性范围 0.0-2.0。OpenAiChatModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).temperature(0.7)// 默认值 0.7.build();// 温度值解释// 0.0 - 0.2确定性输出适合代码生成、事实问答// 0.3 - 0.7平衡输出适合大多数场景// 0.8 - 1.5创造性输出适合故事创作、头脑风暴// 1.6 - 2.0高度随机适合生成多样内容4.2 Token 限制Max Tokens控制输出的最大长度。OpenAiChatModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).maxTokens(1000)// 默认值因模型而异.build();// Token 计算参考// 1 Token ≈ 4 英文字符 或 2 个汉字// 1000 Tokens ≈ 750 英文单词 或 500 汉字4.3 超时Timeout控制请求的超时时间。OpenAiChatModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).timeout(Duration.ofSeconds(60))// 默认 60 秒.build();// 超时处理策略try{Stringresponsemodel.generate(长文本生成任务...);}catch(TimeoutExceptione){System.err.println(请求超时请重试或调整超时时间);}4.4 停止序列Stop Sequences定义输出停止的标记。OpenAiChatModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).stop_sequences(\n\n,###)// 遇到这些标记停止生成.build();4.5 Top-P 与 Top-KOpenAiChatModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).topP(0.9)// 核采样范围 0.0-1.0默认 1.0.topK(40)// 选择前 K 个词仅部分模型支持.build();五、实战示例多模型问答系统5.1 定义统一接口importdev.langchain4j.service.AiService;importdev.langchain4j.service.SystemMessage;importdev.langchain4j.service.UserMessage;AiServicepublicinterfaceQuestionAssistant{SystemMessage(你是一个知识渊博的助手用简洁的语言回答问题)Stringanswer(UserMessageStringquestion);}5.2 构建多模型实例publicclassMultiModelSystem{privatefinalMapString,QuestionAssistantassistantsnewHashMap();publicvoidinit(){// OpenAI 实例ChatLanguageModelopenaiModelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).modelName(gpt-4o).build();QuestionAssistantopenaiAssistantAiServices.builder(QuestionAssistant.class).chatLanguageModel(openaiModel).build();assistants.put(openai,openaiAssistant);// Ollama 实例ChatLanguageModelollamaModelOllamaChatModel.builder().baseUrl(http://localhost:11434).modelName(llama3.1).build();QuestionAssistantollamaAssistantAiServices.builder(QuestionAssistant.class).chatLanguageModel(ollamaModel).build();assistants.put(ollama,ollamaAssistant);}publicStringanswer(Stringprovider,Stringquestion){QuestionAssistantassistantassistants.get(provider);if(assistantnull){thrownewIllegalArgumentException(Unknown provider: provider);}returnassistant.answer(question);}}5.3 使用示例publicclassMain{publicstaticvoidmain(String[]args){MultiModelSystemsystemnewMultiModelSystem();system.init();Stringquestion什么是 LangChain4j;// 使用 OpenAI 回答StringopenaiAnswersystem.answer(openai,question);System.out.println(OpenAI: openaiAnswer);// 使用 Ollama 回答StringollamaAnswersystem.answer(ollama,question);System.out.println(Ollama: ollamaAnswer);}}六、常见问题Q1: 如何处理不同模型的 Token 限制差异A:使用maxTokens参数或自动调整intmaxTokensswitch(provider){caseopenai-4096;caseanthropic-4096;caseollama-2048;// 本地模型通常限制较小default-1024;};Q2: 多模态输入支持哪些模型A:当前支持以下视觉模型OpenAI: gpt-4-vision-preview, gpt-4oAnthropic: claude-3-opus-20240229, claude-3-sonnet-20240229Google AI: gemini-pro-visionQ3: 如何迁移现有代码到新模型A:只需修改模型创建代码业务逻辑无需改动// 旧代码ChatLanguageModelmodelOpenAiChatModel.builder().apiKey(System.getenv(OPENAI_API_KEY)).build();// 新代码切换到 AnthropicChatLanguageModelmodelAnthropicChatModel.builder().apiKey(System.getenv(ANTHROPIC_API_KEY)).build();// 业务逻辑无需改动Stringresponsemodel.generate(你好);七、小结本文深入剖析了 LangChain4j 的核心抽象包括消息类型体系SystemMessage、UserMessage、AiMessage、ToolExecutionResultMessageContent 抽象TextContent、ImageContent 支持多模态输入模型提供商切换统一接口设计支持无缝切换 OpenAI、Anthropic、Ollama通用参数标准化温度、Token 限制、超时、停止序列等实战示例多模型问答系统核心思想通过统一的抽象层实现模型无关的设计让开发者能够灵活切换 LLM 提供商而无需重写业务代码。下一步学习文章 3《LangChain4j 异常处理与测试框架企业级健壮性实践》参考文献LangChain4j 官方文档https://docs.langchain4j.dev/OpenAI API 文档https://platform.openai.com/docs/api-reference/chatAnthropic Claude 文档https://docs.anthropic.com/claude/reference/messages