当前位置: 首页 > news >正文

深入浅出LangChain4J

1.走进LangChain

1.1.什么是LangChain4J?

The goal of LangChain4J is to simplify integrating LLMs into Java applications.

​ -- 《LangChain4J Doc》

LangChain4J就像Java的Spring框架一样,为LLM的接入提供了一套标准的接入能力。LangChain4J是LangChain在Java生态下的具体实现,用于构建基于LLM的应用和Agent系统。

LangChain4J为不同的LLM提供了一个统一的API,屏蔽了底层API供应商的实现和调用差异,开发者可以使用LangChain无缝切换不同的LLM。

2.Architecture of LangChain4J

LangChain4J的架构可以分为两层,分别为高层和底层。

高层AI服务屏蔽了底层实现的细节,开发者可以实现一些业务服务的API和LLM进行交互。

低层具有更高的自由度,你可以任意定义组件的具体实现,控制组件的组合方式等等。

下面,就LangChain4J的核心组件,一一详细介绍。

2.1.Chat and Language Model

一般地,LLMs的API可以分为两类,

  • LanguageModel:输入输出都为String类型,现在使用的越来越少了
  • ChatModel:应用广泛的一类API,接收多个ChatMessage作为输入,输出一个AiMessage,除了文本类型之外,还支持图片、音频、视频等其他模式。

ChatModel是LangChain4J的低层API,提供强大的灵活性和可扩展性。

根据消息来源进行分类,LangChain4J支持以下五种消息类型:

消息类型描述主要方法
UserMessage用户输入的消息数据content(), name(), attributes()
AiMessageAI根据输入数据生成的消息text(), thinking(), toolExceptionRequests(), attributes()
ToolExecutionResultMessage工具执行结果消息
SystemMessage系统发送的消息,可以由开发者自定义
CustomMessage自定义消息
2.2.Chat Memory

我们知道,大模型是无状态的,模型本身并不会记录对话上下文。因此,如果你想要在对话中使用上下文的内容,就必须主动维护管理ChatMessage。但是手动维护比较麻烦,而LangChain4J提供了ChatMemory用来维护管理chatMessage.

2.2.1.History VS Memory

历史记录和记忆听起来似乎是同一种东西,但是对于LLM Agent来说,history和memory具有两种截然不同的语义:

  • history保留了用户和AI的所有会话记录,用户可以在界面中看到
  • memory记录的是专门呈现给大模型使用的信息,使其表现得好像是“记住了”对话的内容,实际底层实现是截然不同的算法。

LangChain4J目前只提供Memroy,而不提供History

下面介绍关于Memory的几点高级特性。

2.2.2.Eviction Policy 淘汰策略

为什么要使用淘汰策略?

  • 存储空间受限:Memory组件可以理解为缓存,当存放的内容超过容量大小的时候,需要使用一定的策略淘汰一些记忆;
  • Token成本昂贵:更多的上下文记忆就代表使用更多的Token,而token的增加会增加每次调用LLM的成本;
  • 控制延迟:发送的LLM的token越多,处理他们所需要的时长越长,则用户等待输出的时间越长

LangChain4J目前支持两种开箱即用的记忆淘汰策略:

  1. 基于消息滑动窗口:使用MessageWindowChatMemory作为滑动窗口,仅保留最近的N条信息,淘汰窗口之外的旧消息;
  2. 基于token的滑动窗口:TokenWindowChatMemory只保留最近的N个token。但是消息是不可再分的,因此如果消息不合适的话,整条消息会直接被丢弃。
2.2.3.Persistence 持久化

默认情况下Memory是存放在内存中的,如果需要保留消息,可以自定义实现MessageStore,将chatMessage存储在数据库中。

class PersistentChatMemroyStore implements ChatMemoryStore { @Override public List<ChatMessage> getMessages(Object memoryId) { } @Override public void updateMessages(Object memoryId, List<ChatMessage> messages) { } @Override public void deleteMessages(Object memoryId) { // TODO: Implement deleting all messages in the persistent store by memory ID. } }
2.2.4.SystemMessage

SystemMessage是一种特殊的消息,具有如下的特性:

  • 一旦添加,就会一直被保留,不会被淘汰策略淘汰
  • 一次只能持有一个SystemMessage
  • SystemMessage具有唯一性,重复的SystemMessage会被忽略,如果不一致,则会覆盖掉之前的SystemMessage
2.2.5.Tool 消息配对

AIMessage 中的ToolExecutionRequestToolExecutionResponse总是成对出现的。如果ToolExecutionRequest被淘汰了,则其对应的ToolExecutionResponse消息也会被自动淘汰。

2.3.Tools(Function Calling)

工具(Tools)允许LLM在必要的时候调用开发者定义的一个或者多个可用工具,工具是一个泛称,可以表示任何东西,例如网页搜索、外部API、或者执行特定的代码等等。

实际上LLM并不会去主动调用工具,而是通过开发人员在业务层接收LLM的回复,根据LLM的意愿进行工具的调用并将执行结果反馈给LLM。

一个良好的工具应当具有以下几个属性:

  1. 清晰明确的工具名称
  2. 工具的具体描述,以及应该何时使用工具;
  3. 每个工具的具体参数;

如果这个工具对于人来说一眼就能理解应该如何使用,那么这个工具对于LLM也是易于使用的。

Tools的定义和使用可以参考文档:LangChain4J Documents

2.4.Agent

3.实战

3.1.ChatModel
3.1.1.基本聊天
public static void main(String[] args) { // 1.创建 chatModel OpenAiChatModel chatModel = OpenAiChatModel.builder() .apiKey(System.getenv("OPENAI_API_KEY")) .baseUrl(System.getenv("OPENAI_BASE_URL")) .modelName(System.getenv("OPENAI_MODEL")) .build(); // 2.使用 chat 方法发起对话 ChatResponse response = chatModel.chat(ChatRequest.builder() .messages(UserMessage.from("Hello, could you introduce yourself ?")) .build()); // 3.控制台打印 System.out.println(response.aiMessage().text()); }
3.1.2.多轮对话

多轮对话和基本对话的实现方式相同,只不过构建对话请求的时候,需要将前文传入到messages中,LLM会参考message得出合理的响应。

private static void chatWithMultipleMessages() { // 1.构建 User 和AI 的多轮对话 UserMessage firstUserMessage = UserMessage.from("Hello, My name is shepi, could you introduce yourself ?"); AiMessage firstAiMessage = CHAT_MODEL.chat( ChatRequest.builder() .messages(firstUserMessage) .build()) .aiMessage(); UserMessage secondUserMessage = UserMessage.from("Please tell me my name"); AiMessage secondAiMessage = CHAT_MODEL.chat( ChatRequest.builder() .messages(firstUserMessage, firstAiMessage, secondUserMessage) .build()).aiMessage(); // 2.控制台打印 System.out.println(secondAiMessage.text()); }
3.2.ChatMemory

ChatMemory可以帮助我们维护上下文,LangChain4J提供了两种开箱即用的窗口聊天记忆

  • MessageWindowChatMemory
  • TokenWindowChatMemory

下面是一个基于消息数量的窗口对话记忆:

public static void main(String[] args) { // 1.新建 messageWindow,滑动窗口最大长度设置为 3 MessageWindowChatMemory chatWindow = MessageWindowChatMemory.builder() .maxMessages(4) .build(); // tryChatWithCommonMessages(chatWindow); // 测试特殊的系统消息 systemMessage tryChatWithSystemMessage(chatWindow); } /** * 系统消息永远不会被驱逐 * @param chatWindow */ private static void tryChatWithSystemMessage(MessageWindowChatMemory chatWindow) { // 创建系统消息 SystemMessage systemMessage = SystemMessage.from("The user talking with you is shepi"); chatWindow.add(systemMessage); System.out.println(systemMessage.text()); for (int i = 0; i < 4; i++) { UserMessage userMessage = null; if (i == 3) { userMessage = UserMessage.from("Please tell me my name"); } else { userMessage = UserMessage.from("let's talk about something interesting"); } System.out.println(userMessage.contents()); chatWindow.add(userMessage); // 使用 chatMemory 对话 AiMessage aiMessage = CHAT_MODEL.chat(ChatRequest.builder().messages(chatWindow.messages()).build()).aiMessage(); System.out.println(aiMessage.text()); chatWindow.add(aiMessage); } } private static void tryChatWithCommonMessages(MessageWindowChatMemory chatWindow) { // 2.模拟进行多轮对话 // 第一轮给出自己的名字,第四轮询问AI我的名字,其他两轮随便聊点什么 for (int i = 0; i < 4; i++) { UserMessage userMessage = null; if (i == 0) { userMessage = UserMessage.from("Hello, My name is shepi, could you introduce yourself ?"); } else if (i == 3) { userMessage = UserMessage.from("Please tell me my name"); } else { userMessage = UserMessage.from("let's talk about something interesting"); } System.out.println(userMessage.contents()); chatWindow.add(userMessage); // 使用 chatMemory 对话 AiMessage aiMessage = CHAT_MODEL.chat(ChatRequest.builder().messages(chatWindow.messages()).build()).aiMessage(); System.out.println(aiMessage.text()); chatWindow.add(aiMessage); } }
3.3.Tools

LangChain中定义Tool非常简单,只需要在工具接口方法上使用注解@Tool("Tool description")即可,下面是一个简答的例子。

public class WeatherService { @Tool("获取指定城市的天气情况") public String getWeather(String city) { // 模拟天气数据 return MessageFormat. format("Today's weather in {0} is sunny with a temperature of 22 degrees.", city); } }
3.4.AiService (Agent 封装)

AiService 是什么?

AiService 是 LangChain4J 提供的高层 API,用于快速构建 Agent 应用。它屏蔽了工具调用的底层细节(如检测 LLM 返回的函数调用请求、执行工具、将结果反馈给 LLM),让开发者可以专注于业务逻辑。

AiService 与 Agent 的关系:

  • AiService 是 LangChain4J 对 Agent 概念的具体实现
  • 它自动完成了 Agent Loop 中的:接收输入 → 判断是否需要 Tool → 调用 Tool → 观察结果 → 生成响应
  • 开发者只需定义接口和 Tool,AiService 会自动完成工具调用的编排

如果想要使用上面创建的 Tool,我们需要在定义AiService时,传入 Tool 对象。

private static final OpenAiChatModel CHAT_MODEL = OpenAiChatModel.builder() .apiKey(System.getenv("OPENAI_API_KEY")) .baseUrl(System.getenv("OPENAI_BASE_URL")) .modelName(System.getenv("OPENAI_MODEL")) .build(); public static void main(String[] args) { // 根据CHAT_MODEL创建一个 chatService ChatAssistant chatService = AiServices.builder(ChatAssistant.class) .chatLanguageModel(CHAT_MODEL) .tools(new WeatherService()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); // 问题 String question = "今天北京什么天气?"; String answer = chatService.chat(question); System.out.println(answer); }

4.流式响应 (Streaming)

LangChain4J 支持流式响应,即 LLM 在生成内容时实时返回每个 token,而不是等待完整响应后再返回。

使用场景
  • 需要实时显示生成过程的场景(如 ChatGPT 的打字机效果)
  • 生成较长内容时提升用户体验
  • 需要提前终止不满意的输出
实现方式

使用StreamingAiServices代替AiServices

private static final OpenAiChatModel CHAT_MODEL = OpenAiChatModel.builder() .apiKey(System.getenv("OPENAI_API_KEY")) .baseUrl(System.getenv("OPENAI_BASE_URL")) .modelName(System.getenv("OPENAI_MODEL")) .build(); public static void main(String[] args) { // 根据CHAT_MODEL创建一个 chatService ChatAssistant chatService = AiServices.builder(ChatAssistant.class) .chatLanguageModel(CHAT_MODEL) .tools(new WeatherService()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); // 问题 String question = "今天北京什么天气?"; String answer = chatService.chat(question); System.out.println(answer); }
流式 vs 非流式
特性非流式 (AiServices)流式 (StreamingAiServices)
响应方式等待完整响应后返回实时返回每个 token
用户体验有等待感实时反馈,体验更好
实现复杂度简单稍复杂(需要处理回调)
适用场景短文本、后台任务长文本、交互式对话


学习资源推荐

如果你想更深入地学习大模型,以下是一些非常有价值的学习资源,这些资源将帮助你从不同角度学习大模型,提升你的实践能力。

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!​

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示

​因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

四、AI大模型商业化落地方案

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

http://www.jsqmd.com/news/360618/

相关文章:

  • 收藏备用|程序员/小白入门大模型全攻略,转行避坑+方向拆解,看完少走1年弯路
  • 保定检查井模具选购指南:2026年口碑厂家实力解析 - 2026年企业推荐榜
  • 项目分享|SAM-Audio:音频领域的“万物分割”通用模型
  • 柑橘叶片病害数据集(5类)
  • 2026年鄂尔多斯铁路煤炭运输用抑尘剂好用的品牌有哪些 - mypinpai
  • 探讨天龙中学周边文昌鸡店口碑,珠江道附近白切鸡美食店怎么选 - 工业推荐榜
  • 收藏!小白程序员必看:Langchain、向量化、RAG大模型概念科普与实战解析
  • 让本地知识引导AI追踪社区变迁,让AI真正理解社会现象
  • 【2026最新】Xshell下载与安装教程:完整图文流程、配置详解与常见问题解决
  • 在线杀毒与沙箱分析网站
  • 梳理2026年广州PVC地板品牌供应商,排名前十的有谁 - myqiye
  • 6个AI智能体自主运营网站,无需人工值守!
  • 2026年管道自动焊机价格大揭秘,靠谱厂商费用是多少 - 工业推荐榜
  • 分享上海CE认证机构推荐,汽车零部件认证服务选哪家比较靠谱 - 工业品牌热点
  • 11.AD快捷键 (优化版)
  • 【LLM表示基础】Embedding Lookup:神经网络如何“理解“一个词
  • 深聊建筑工程律师,泓渲专业服务获认可 - 工业品网
  • 昂瑞微OM662X系列芯片介绍
  • 2026冲刺用!千笔·专业学术智能体,本科生论文写作神器
  • gemini-mcp-tool 命令注入漏洞深度分析(CVE-2026-0755)
  • 商场充电桩远程监控管理系统方案
  • 2026年昆明卫生间防水品牌企业排名,好用的卫生间防水涂料怎么选 - 工业设备
  • 天猫超市购物卡回收技巧,闲置秒变现金 - 京顺回收
  • 参考文献崩了?当红之选的AI论文网站 —— 千笔
  • [转载]Web端H.265播放器:视频解码篇
  • 指数期权指标分析未平仓量的市场信号
  • 2026河北优质玻璃钢管道厂家实力盘点与采购指南 - 2026年企业推荐榜
  • 2026年2月徐州卧室套装/全屋定制/储物柜/装饰柜厂商选型与领导者深度解析 - 2026年企业推荐榜
  • 华为eNSP模拟器综合实验之- 无线AC 配置思路及关键要点
  • 前瞻2026:廊坊环氧地坪施工销售商挑选指南 - 2026年企业推荐榜