1. 简介
LangChain4j 是一个基于 Java 的开源框架,用于开发 人工智能驱动的应用程序,尤其是涉及 大语言模型(LLM)交互 的场景。它的设计目标是简化开发者与大语言模型的集成过程,提供一套工具和组件来处理复杂的 LLM 应用逻辑,例如对话管理、提示工程、工具调用等。
核心功能与特点
- 大语言模型集成
- 支持多种 LLM 接入方式,包括:
- 本地运行的开源模型(如 Llama 2、ChatGLM 等)。
- 第三方 API 模型(如 OpenAI 的 GPT 系列、Anthropic 的 Claude 等)。
- 通过统一的接口抽象,降低模型切换的成本。
- 支持多种 LLM 接入方式,包括:
- 提示工程工具
- 提供模板化的提示构建器,帮助开发者结构化输入(如填充变量、管理上下文历史)。
- 支持动态组合提示链(Prompt Chain),例如根据用户问题逐步调用不同的提示模板。
- 对话状态管理
- 维护多轮对话的上下文,支持记忆管理(如设置上下文窗口大小、选择性遗忘旧信息)。
- 可集成外部知识库(如向量数据库)实现长期记忆。
- 工具调用能力
- 支持调用外部工具(如计算器、数据库查询、API 接口等),并将工具返回结果整合到 LLM 的回答中。
- 提供工具调用的决策逻辑(如判断何时需要调用工具、如何解析工具返回结果)。
- 链式流程编排
- 通过 Chain 机制编排多个组件(如提示生成、工具调用、结果处理),形成复杂的工作流。
- 典型场景:问答系统中先调用搜索引擎获取实时数据,再用 LLM 生成回答。
- 扩展性与生态
- 基于 Java 生态,可轻松与 Spring框架集成。
- 支持自定义组件(如自定义提示策略、工具适配器),灵活适配业务需求。
2. 话不多说,直接展示
本章主要通过单元测试的方式展示LangChain4j的各项功能,后续会出通过LangChain4j Starter
的方式快速集成SpringBoot。
使用SDK版本信息如下:
AI 模型主要使用的是阿里的百炼平台免费的token,需要ApiKey
的可以自行去申请, 平台地址如下:
https://bailian.console.aliyun.com/?tab=model#/model-market
3. Maven
4. 构建模型对象
5. 返回字符串
测试结果如下:
[main]
INFO
com
.ldx
.langchaintest
.lowapi
.AiChatTest
--
call
ai
q: 你是谁
a: 我是通义千问,阿里巴巴集团旗下的超大规模语言模型。我能够回答问题、创作文字,比如写故事、公文、邮件、剧本等,还能进行逻辑推理、编程,甚至表达观点和玩游戏。我在多国语言上都有很好的掌握,能为你提供多样化的帮助。有什么我可以帮到你的吗?
6. 返回流
这里使用flux对象接收流式返回的结果
如果想流式的返回给前端,也可以使用SSE的方式返回(代码注释的部分)
测试结果如下:
7. 提示词/模板
@Test
public
void
should_return_prompt_content_when_use_prompt
() {
// 申明系统提示词
// SystemMessage systemMessage = Prompt.from("你是一名java专家,请协助用户解决相应的专业性问题").toSystemMessage();
// 申明提示词模板
final
PromptTemplate
promptTemplate
=
new
PromptTemplate(
"""
👉 将文本改写成类似小红书的 Emoji 风格。
请使用 Emoji 风格编辑以下段落,该风格以引人入胜的标题、每个段落中包含表情符号和在末尾添加相关标签为特点。请确保保持原文的意思。
用户的提问信息如下:
{{question}}
""");
final
UserMessage
userMessage
= promptTemplate
.apply(Map.of(
"question",
"你是谁"))
.toUserMessage();
ChatResponse
chatResponse
= chatModel.chat(userMessage);
String
content
= chatResponse
.aiMessage()
.text();
log.info(
"call ai q: {}\na: {}", userMessage.singleText(), content);
}
测试结果如下:
[main] INFO
com.ldx.langchaintest.lowapi.AiChatTest --
call ai q: 👉 将文本改写成类似小红书的 Emoji 风格。
请使用 Emoji 风格编辑以下段落,该风格以引人入胜的标题、每个段落中包含表情符号和在末尾添加相关标签为特点。请确保保持原文的意思。
用户的提问信息如下:
你是谁
a: ✨你是谁?来认识一下我吧!💬
嗨,亲爱的朋友们!我是通义千问,阿里巴巴集团旗下的超大规模语言模型🤖。我可以通过学习海量文本数据,帮你回答问题、创作文字,甚至玩游戏哦~是不是很酷呢?🔥
如果你有任何问题或需要帮助,尽管告诉我!我会尽力为你提供支持和支持❤️。让我们一起开启有趣的探索之旅吧!🌍
#人工智能 #聊天机器人 #新知探索 #科技生活
8. 聊天记忆
中心逻辑其实就是:将最近的聊天内容存储起来,然后一股脑扔给AI😓
@Test
public
void
should_return_memory_content_when_use_memory_chat
() {
String
id
=
"zhangtieniu_01";
String
q1
=
"你是谁";
ChatMemory
chatMemory
= MessageWindowChatMemory
.builder()
// 会话隔离(不同用户的聊天信息互不干扰)
.id(id)
// 最大存储最近的5条聊天内容(存储太多影响性能&token)
.maxMessages(
5)
.build();
// 将聊天内容放入记忆对象中
chatMemory.add(UserMessage.from(q1));
// SystemMessage 始终保存在messages中 且占用maxMessage名额
chatMemory.add(SystemMessage.from(
"""
👉 将文本改写成类似小红书的 Emoji 风格。
请使用 Emoji 风格编辑以下段落,该风格以引人入胜的标题、每个段落中包含表情符号和在末尾添加相关标签为特点。请确保保持原文的意思。
"""));
final
ChatResponse
chatResponse
= chatModel.chat(chatMemory.messages());
// 将ai的返回结果放入记忆对象中
chatMemory.add(chatResponse.aiMessage());
String
q2
=
"我刚刚问了啥";
chatMemory.add(UserMessage.from(q2));
final
ChatResponse
chatResponse2
= chatModel.chat(chatMemory.messages());
log.info(
"call ai q1: {}\na1: {}", q1, chatResponse
.aiMessage()
.text());
log.info(
"==========================分隔符==========================");
log.info(
"call ai q2: {}\na2: {}", q2, chatResponse2
.aiMessage()
.text());
}
测试结果如下:
9. 聊天内容持久化
9.1 store handler
这里简单的使用map存储会话内容
9.2 实现
@Test
public
void
should_return_memory_content_when_use_store_chat
() {
String
id
=
"zhangtieniu_01";
String
q1
=
"张铁牛是一个高富帅,你是张铁牛的助手";
PersistentChatMemoryStoreTest
store
=
new
PersistentChatMemoryStoreTest();
ChatMemory
chatMemory
= MessageWindowChatMemory
.builder()
.id(id)
.chatMemoryStore(store)
.maxMessages(
5)
.build();
chatMemory.add(UserMessage.from(q1));
final
ChatResponse
chatResponse
= chatModel.chat(chatMemory.messages());
chatMemory.add(chatResponse.aiMessage());
String
q2
=
"张铁牛是谁";
chatMemory.add(UserMessage.from(q2));
final
ChatResponse
chatResponse2
= chatModel.chat(chatMemory.messages());
chatMemory.add(chatResponse2.aiMessage());
// 获取当前会话的存储内容并打印
List<ChatMessage> chatMessages = store.messagesStore.get(id);
for (ChatMessage chatMessage : chatMessages) {
log.info(
"session id: {}, message type: {}, message: {}", id, chatMessage.type(), chatMessage);
}
}
测试结果如下:
10. function call
10.1 user svc
声明一个自定义的user svc, 让ai去调用我们的业务方法
10.2 实现
测试结果如下:
11. dynamic function call
因为有的时候我们使用已有的svc时,我们可能无法直接给目标方法标注对应的注解让AI来识别方法(比如第三方包里的方法)
所以就需要动态的创建tool的描述类,如下
@Test
public
void
should_return_func_content_when_use_dynamic_function_call
() {
final
String
q
=
"张铁牛的code是多少";
final List<ChatMessage> chatMessages =
new
ArrayList<>();
chatMessages.add(UserMessage.from(q));
final
UserServiceTest
userServiceTest
=
new
UserServiceTest();
final
ToolSpecification
toolSpecification
= ToolSpecification
.builder()
.name(
"getUserCodeByUsername")
.description(
"根据用户的名称获取对应的code")
.parameters(JsonObjectSchema
.builder()
.addStringProperty(
"username",
"用户姓名")
.build())
.build();
final
ChatRequest
chatRequest
= ChatRequest
.builder()
.messages(UserMessage.from(q))
.toolSpecifications(toolSpecification)
.build();
final
ChatResponse
chatResponse
= chatModel.chat(chatRequest);
AiMessage
aiMessage
= chatResponse.aiMessage();
chatMessages.add(aiMessage);
String
a
= aiMessage.text();
if (aiMessage.hasToolExecutionRequests()) {
for (ToolExecutionRequest toolExecutionRequest : aiMessage.toolExecutionRequests()) {
ToolExecutor
userToolExecutor
=
new
DefaultToolExecutor(userServiceTest, toolExecutionRequest);
final
String
uuid
= UUID
.randomUUID()
.toString();
final
String
executeResult
= userToolExecutor.execute(toolExecutionRequest, uuid);
log.info(
"execute user tool, name: {}, param:{}, result: {} ", toolExecutionRequest.name(), toolExecutionRequest.arguments(), executeResult);
final
ToolExecutionResultMessage
toolExecutionResultMessages
= ToolExecutionResultMessage.from(toolExecutionRequest, executeResult);
chatMessages.add(toolExecutionResultMessages);
}
a = chatModel
.chat(chatMessages)
.aiMessage()
.text();
}
log.info(
"call ai q:{}\na:{}", q, a);
}
测试结果如下:
12. 小结
本章使用了LangChain4j
一些比较底层的(原生的)api来请求大模型, 展示了AI服务中常见的使用方法,下一章我们将使用LangChain4j
的AI Service
功能来展示LangChain4j
高阶用法。
__EOF__

本文链接: https://www.cnblogs.com/ludangxin/p/18913321.html
关于博主:评论和私信会在第一时间回复。或者 直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 【推荐】一下。您的鼓励是博主的最大动力!