- 示例工程
【免费下载链接】langchain4j-examples
本指南以仓库中的jakartaee-microprofile-example示例应用为核心,完整讲解如何在 Jakarta EE / MicroProfile(Open Liberty 运行时)下,用 LangChain4j 集成 Hugging Face 大语言模型,构建一个集 WebSocket 聊天、REST 模型 API、配置管理与集成测试于一体的 AI 聊天机器人。读完本文,你将掌握从环境准备、Liberty 开发模式启动、网页与命令行双通道调用 LLM,到基于源码的架构剖析与测试验证的完整实战路径。
一、示例应用概览:当 Jakarta EE 遇见 LangChain4j
该示例展示了 LangChain4J 在 Jakarta EE / MicroProfile 应用中的落地方式,运行在Open Liberty上,应用形态是一个由 LangChain4J 驱动的聊天机器人。它综合使用了以下 Java 企业级规范特性:
- Jakarta CDI(依赖注入与作用域管理)
- Jakarta RESTful Web Services(REST 模型 API)
- Jakarta WebSocket(浏览器端实时聊天通道)
- MicroProfile Config(外部化配置注入)
- MicroProfile Metrics(指标埋点)
- MicroProfile OpenAPI(自动生成 API 文档与调试界面)
底层大模型能力由 Hugging Face 提供,通过 LangChain4j 的langchain4j-hugging-face集成模块接入,涉及三类模型:语言模型(补全)、聊天模型(对话)与嵌入模型(语义相似度计算)。
项目完整源码位于 jakartaee-microprofile-example,其工程声明(依赖、插件、打包方式)见 pom.xml,Liberty 服务器配置见 server.xml。
二、前置条件
2.1 Java 21
应用以 Java 21 编译运行(pom.xml中maven.compiler.source/maven.compiler.target均为21)。请确保本机已安装 JDK 21 及以上的运行时。
2.2 Hugging Face API Key
示例通过 Hugging Face Inference API 调用模型,需要访问令牌:
- 注册并登录 Hugging Face 账户;
- 进入Access Tokens设置页;
- 新建一个read角色的访问令牌(
readrole 即可满足推理调用与模型访问需求)。
该令牌在下一步环境设置中通过HUGGING_FACE_API_KEY环境变量注入,并被 MicroProfile Config 的hugging.face.api.key配置项引用。
三、环境准备与配置注入
3.1 进入示例目录并设置环境变量
首先切换到示例工程所在目录:
cd langchain4j-examples/jakartaee-microprofile-example然后设置两个环境变量:
export JAVA_HOME=<your Java 21 home path> export HUGGING_FACE_API_KEY=<your Hugging Face read token>3.2 配置文件解析:MicroProfile Config
环境变量如何进入应用?答案在 MicroProfile Config 配置文件 microprofile-config.properties:
hugging.face.api.key=set it by env variable #chat.model.id=meta-llama/Llama-3.2-1B-Instruct chat.model.id=mistralai/Mistral-Nemo-Instruct-2407 chat.model.timeout=120 chat.model.max.token=200 chat.model.temperature=1.0 chat.memory.max.messages=20 language.model.id=microsoft/Phi-3-mini-4k-instruct各配置项的作用如下:
| 配置键 | 默认值 | 作用 |
|---|---|---|
hugging.face.api.key | 占位文本 | Hugging Face 访问令牌,实际值由环境变量HUGGING_FACE_API_KEY覆盖(MicroProfile Config 的配置优先级体系中环境变量高于 properties 文件) |
chat.model.id | mistralai/Mistral-Nemo-Instruct-2407 | 聊天模型 ID,注释中保留了可选的meta-llama/Llama-3.2-1B-Instruct |
chat.model.timeout | 120 | 模型调用超时秒数,对应Duration.ofSeconds(...) |
chat.model.max.token | 200 | 生成的最大新 token 数(maxNewTokens) |
chat.model.temperature | 1.0 | 采样温度,控制回答随机性 |
chat.memory.max.messages | 20 | 聊天记忆窗口保留的最大消息条数 |
language.model.id | microsoft/Phi-3-mini-4k-instruct | REST 语言模型 API 与聊天 API 使用的模型 ID |
四、启动应用:Liberty 开发模式
使用 Maven wrapper 配合Liberty dev mode启动应用,这是 Open Liberty 的迭代开发模式,支持热部署与一键跑测试:
./mvnw liberty:dev该命令由pom.xml中的io.openliberty.tools:liberty-maven-plugin(版本 3.11.3)提供,工程最终打包为war(jakartaee-microprofile-example.war)。启动后,Liberty 服务器配置(见 server.xml)决定运行时行为:
<featureManager> <platform>jakartaee-10.0</platform> <platform>microprofile-7.0</platform> <feature>cdi</feature> <feature>jsonb</feature> <feature>mpConfig</feature> <feature>mpMetrics</feature> <feature>mpOpenAPI</feature> <feature>restfulWS</feature> <feature>websocket</feature> </featureManager> <httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/> <applicationManager autoExpand="true"/> <webApplication contextRoot="/" location="jakartaee-microprofile-example.war"/> <mpMetrics authentication="false"/> <logging consoleLogLevel="INFO"/>要点解读:
- 同时启用jakartaee-10.0与microprofile-7.0平台特性,并显式声明 CDI、JSON-B、mpConfig、mpMetrics、mpOpenAPI、RESTful WS、WebSocket 子特性;
- HTTP 端点监听
9080(HTTPS 为9443),应用上下文根为/; mpMetrics authentication="false"关闭指标端点认证,便于本地观察;pom.xml中同时配置了maven-failsafe-plugin(3.5.3),用于运行集成测试(*IT类)。
五、试用应用
5.1 网页聊天
浏览器导航到 http://localhost:9080,在输入框中尝试以下示例消息:
What are large language models?Which are the most used models?show me the documentation前端页面通过WebSocket与后端通信:输入框位于 index.html(由 web.xml 指定为 welcome file),页面 JS(chatroom.js)建立ws://localhost:9080/chat连接。
5.2 聊天背后的 WebSocket + CDI 实现
WebSocket 服务端由 ChatService.java 实现,它是一个同时标注@ApplicationScoped与@ServerEndpoint("/chat")的 CDI Bean:
@ApplicationScoped @ServerEndpoint(value = "/chat", encoders = { ChatMessageEncoder.class }) public class ChatService { @Inject ChatAgent agent = null; @OnOpen public void onOpen(Session session) { ... } @OnMessage @Timed(name = "chatProcessingTime", absolute = true, description = "Time needed chatting to the agent.") public void onMessage(String message, Session session) { String sessionId = session.getId(); answer = agent.chat(sessionId, message); session.getBasicRemote().sendObject(answer); } @OnClose ... @OnError ... }三个关键设计点:
@Timed指标埋点:onMessage方法上的@Timed(name = "chatProcessingTime", absolute = true)是 MicroProfile Metrics 注解,每次聊天耗时都会被记录,可通过 Liberty 的指标端点观测;@ServerEndpoint与 CDI 共存:@ApplicationScoped使 ChatService 成为单例 Bean,@Inject ChatAgent让 WebSocket 端点直接依赖 CDI 管理的 AI 代理;- 消息编码器:ChatMessageEncoder.java 实现
Encoder.Text<String>,负责把模型原始回复加工为适合前端渲染的文本——若回复不以句号结尾则追加...,并将换行符\n替换为<br/>。
5.3 AI 代理:AiServices + 聊天记忆
ChatAgent.java 是整个聊天能力的核心,展示了 LangChain4jAiServices与聊天记忆的标准用法:
interface Assistant { String chat(@MemoryId String sessionId, @UserMessage String userMessage); } public Assistant getAssistant() { if (assistant == null) { HuggingFaceChatModel model = HuggingFaceChatModel.builder() .accessToken(HUGGING_FACE_API_KEY) .modelId(CHAT_MODEL_ID) .timeout(ofSeconds(TIMEOUT)) .temperature(TEMPERATURE) .maxNewTokens(MAX_NEW_TOKEN) .waitForModel(true) .build(); assistant = AiServices.builder(Assistant.class) .chatModel(model) .chatMemoryProvider( sessionId -> MessageWindowChatMemory.withMaxMessages(MAX_MESSAGES)) .build(); } return assistant; }值得展开的源码级细节:
@ConfigProperty注入:HUGGING_FACE_API_KEY、CHAT_MODEL_ID、TIMEOUT、MAX_NEW_TOKEN、TEMPERATURE、MAX_MESSAGES六个字段全部通过 MicroProfile Config 注入,值来自第三节的 properties 文件与环境变量;HuggingFaceChatModel.builder():逐项映射配置——timeout由chat.model.timeout(120 秒)转换而来,waitForModel(true)表示调用时若模型尚未就绪则等待加载;@MemoryId按会话隔离记忆:接口方法签名chat(@MemoryId String sessionId, @UserMessage String userMessage)使记忆按 WebSocket session id 区分,chatMemoryProvider为每个 session 创建一个最多保留MAX_MESSAGES(默认 20)条的MessageWindowChatWindow滑动窗口记忆;- 懒加载单例:
getAssistant()仅在首次调用时构建模型与 AiServices,避免重复创建; - 回复裁剪:
chat()方法中reply.lastIndexOf(message)的逻辑,用于去除模型回显用户输入的前缀,只保留真正的回答部分。
六、通过 REST API 试用其他模型
除了 WebSocket 聊天,应用还通过 ModelResource.java 暴露 3 个 REST 端点(JAX-RS 根路径由 RestApplication.java 中的@ApplicationPath("/api")决定),并在MicroProfile OpenAPI自动生成的 UI(http://localhost:9080/openapi/ui)中提供交互式调试入口。
6.1 HuggingFaceLanguageModel:GET /api/model/language
- OpenAPI UI 操作:展开
GET /api/model/language→ 点击Try it out→ 在question字段输入When was Hugging Face launched?(或任意问题)→ 点击Execute; - curl 方式:
curl 'http://localhost:9080/api/model/language?question=When%20was%20Hugging%20Face%20launched%3F'底层实现:getLanguageModel()使用HuggingFaceLanguageModel.builder()构建,modelId来自language.model.id(microsoft/Phi-3-mini-4k-instruct),timeout为 120 秒,maxNewTokens30,temperature1.0。调用model.generate(question).content()返回纯文本补全结果,异常时返回"My failure reason is:\n\n" + e.getMessage()便于排查。
6.2 HuggingFaceChatModel:GET /api/model/chat
- OpenAPI UI 操作:展开
GET /api/model/chat→Try it out→ 在userMessage字段输入Which are the most used Large Language Models?→Execute; - curl 方式:
curl 'http://localhost:9080/api/model/chat?userMessage=Which%20are%20the%20most%20used%20Large%20Language%20Models%3F' | jq底层实现:该端点每次请求动态构建HuggingFaceChatModel(maxNewTokens为 200),手工构造消息对象并调用model.chat(...):
SystemMessage systemMessage = SystemMessage.from( "You are very knowledgeable about Large Language Models. Be friendly. Give concise answers."); AiMessage aiMessage = model.chat(systemMessage, UserMessage.from(userMessage)).aiMessage(); return List.of( "System: " + systemMessage.text(), "Me: " + userMessage, "Agent: " + aiMessage.text().trim());响应为 JSON 数组,依次包含系统提示、用户问题与模型回答,是理解 LangChain4j 消息模型(SystemMessage/UserMessage/AiMessage)的直接范例。
6.3 InProcessEmbeddingModel:GET /api/model/similarity
- OpenAPI UI 操作:展开
GET /api/model/similarity→Try it out→text1输入I like Jakarta EE and MicroProfile.,text2输入I like Python language.→Execute; - curl 方式:
curl 'http://localhost:9080/api/model/similarity?text1=I%20like%20Jakarta%20EE%20and%20MicroProfile.&text2=I%20like%20Python%20language.' | jq底层实现展示了 LangChain4j 嵌入模型的完整数据流:
- 嵌入模型使用
SENTENCE_TRANSFORMERS_ALL_MINI_LM_L6_V2(all-MiniLM-L6-v2,一个体积小巧的句子级嵌入模型,随langchain4j-hugging-face模块提供的常量引用),timeout120 秒; model.embedAll(List.of(textSegment(text1), textSegment(text2)))将两段文本编码为两个向量;CosineSimilarity.between(...)计算余弦相似度,RelevanceScore.fromCosineSimilarity(...)进一步换算为相关性分数;- 响应 JSON 同时携带分词后的
words、嵌入向量embedding-vector、similarity与relevance-score,便于直观对比语义距离。
七、运行测试
由于应用以 Liberty dev mode 启动,可以在启动 dev mode 的命令行会话中直接按enter/return键运行工程内置的集成测试(mvn failsafe:integration-test,由maven-failsafe-plugin执行)。
测试通过时,控制台输出类似如下:
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running it.dev.langchan4j.example.ChatServiceIT [INFO] ... [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.439 s... [INFO] ... [INFO] Running it.dev.langchan4j.example.ModelResourceIT [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.733 s... [INFO] [INFO] Results: [INFO] [INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0两类测试分别对应两大功能面:
- ChatServiceIT.java:使用
websocket-jakarta-client建立到ws://localhost:9080/chat的 WebSocket 连接,发送When was the LangChain4j launched?后通过CountDownLatch等待响应,并断言回复中包含2023(验证模型能正确回答 LangChain4j 的诞生年份); - ModelResourceIT.java:基于 RESTEasy Client 的三个用例,分别验证:
language端点回答包含2018(Hugging Face 成立年份);chat端点回答包含BERT;similarity端点返回的relevance-score落在(0.69, 0.70)、similarity落在(0.38, 0.39)区间——这是对嵌入计算精度的数值级断言,说明I like Jakarta EE and MicroProfile.与I like Python language.在语义空间中的距离是稳定可预期的。
依赖方面,测试所需工具类由 pom.xml 的 test scope 依赖提供(JUnit 5、RESTEasy Client、jakarta.json、Jetty WebSocket Client),日志输出由src/test/resources/log4j.properties控制。
八、退出开发模式
体验完毕,在运行liberty:dev的命令行会话中按Ctrl+C停止服务器;也可以输入q再按enter/return键优雅退出 dev mode。
九、小结:可复用的企业级 AI 集成模板
回顾整个示例,它提供了一条清晰的 Jakarta EE / MicroProfile + LangChain4j 集成范式:
- 配置层:用 MicroProfile Config(properties + 环境变量覆盖)管理 API Key、模型 ID、超时、温度、token 上限等全部参数,代码中零硬编码;
- 接入层:
HuggingFaceChatModel/HuggingFaceLanguageModel/HuggingFaceEmbeddingModel三个 builder 覆盖对话、补全、嵌入三类场景,waitForModel(true)简化模型冷启动处理; - 服务层:AiServices 结合
@MemoryId与MessageWindowChatMemory实现按 WebSocket 会话隔离的带记忆对话; - 暴露层:Jakarta WebSocket 提供浏览器实时聊天,JAX-RS + MicroProfile OpenAPI 提供可交互调试的 REST API,MicroProfile Metrics 提供耗时观测;
- 验证层:dev mode 一键触发集成测试,用确定性断言(年份、模型名、相似度区间)保证端到端链路可用。
对于希望在传统 Java 企业级技术栈中引入 LLM 能力的团队,这个示例无论是作为学习入口还是作为新项目脚手架,都具备直接的参考价值。
- 示例工程
【免费下载链接】langchain4j-examples
相关推荐
stable-diffusion.cpp × Chroma1-Radiance:从零跑通 Radiance 推理的完整链路
stable diffusion.cpp × Chroma1 Radiance:从零跑通 Radiance 推理的完整链路 Chroma1 Radiance 是
人工智能大模型本地部署推理引擎媒体生成基于Next-Forge构建AI聊天机器人实战指南
基于Next Forge构建AI聊天机器人实战指南 前言 在现代Web开发中,集成AI功能已成为提升用户体验的重要手段。本文将详细介绍如何使用next forg
前端后端示例工程CLI快速搭建AI聊天机器人:Python + FastAPI完整指南
快速搭建AI聊天机器人:Python + FastAPI完整指南 想要快速搭建一个功能强大的AI聊天机器人吗?本文将通过模块化部署方式,使用Python + F
后端AI 应用大模型RAG
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考