介绍
LangChain4j 是专为 Java 开发者设计的大语言模型(LLM)集成框架,核心价值是统一抽象多厂商模型、向量库与工具调用,让你快速构建智能应用。
LangChain4j 1.3.0 核心组件一览表
| 组件 | 作用 |
|---|---|
| ChatModel | 大模型交互顶层接口 |
| OpenAiChatModel | DeepSeek / OpenAI 通用接入(1.3.0 推荐) |
| AiServices | 构建 AI 助手(聊天、记忆、RAG、工具调用统一入口) |
| ChatMemory | 对话记忆接口 |
| MessageWindowChatMemory | 窗口式记忆(最常用) |
| PromptTemplate | 提示词模板 |
| Tool | 工具调用(AI 调用 Java 方法) |
| Document | 文档对象(RAG 用) |
| EmbeddingModel | 向量嵌入模型 |
| EmbeddingStore | 向量存储 |
| ContentRetriever | 文档检索器 |
| RagPipeline | RAG 流水线(1.3.0 最新) |
环境
jdk17
bom 用来统一版本管理 , 1.3.0 版本
java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>langchain4j</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demo</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-bom</artifactId>
<version>1.3.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
一、基础对话(deepseek版本)
实现:
OpenAiChatModel
java
package org.deepseek;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class DeepSeekBasicChat {
public static void main(String[] args) {
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com") // 关键:DeepSeek 地址
.apiKey("sk-xxxxxxxxxxxxxx") // 你的 Key
.modelName("deepseek-chat") // DeepSeek-V3
.temperature(0.7) // 创意程度
.maxTokens(1024) // 最大 token
.timeout(Duration.ofSeconds(10)) // 超时
.maxRetries(2) // 失败重试
.logRequests(true) // 打印请求日志
.logResponses(true) // 打印响应日志
.build();
String answer = model.chat("详解Langchain4j");
System.out.println("=== DeepSeek 回答 ===");
System.out.println(answer);
}
}
ChatModel
java
package org.deepseek;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import java.time.Duration;
public class LangChain4jFirstDemo {
public static void main(String[] args) {
// 1. 创建模型
ChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-xxxxxxxxxxxxxxx")
.modelName("deepseek-chat")
.temperature(0.7) // 创意程度
.maxTokens(1024) // 最大 token
.timeout(Duration.ofSeconds(10)) // 超时
.maxRetries(2) // 失败重试
.logRequests(true) // 打印请求日志
.logResponses(true) // 打印响应日志
.build();
String chat = model.chat("详解Langchain4j");
System.out.println(chat);
}
}
ChatModel 配置
一、基础网络与客户端配置
private HttpClientBuilder httpClientBuilder; // HTTP客户端构建器(底层发送请求的网络工具)
private String baseUrl; // AI服务的基础接口地址(如https://api.openai.com)
private Duration timeout; // 请求超时时间(防止请求卡死)
private Integer maxRetries; // 请求失败最大重试次数(网络波动自动重试)
private Map<String, String> customHeaders; // 自定义请求头(可添加额外认证/标识)
二、身份认证
private String apiKey; // API密钥(访问AI服务的身份凭证,核心认证)
private String organizationId; // 组织ID(多组织管理时使用)
private String projectId; // 项目ID(OpenAI等平台的项目隔离标识)
三、AI 模型基础配置
private String modelName; // 模型名称(如gpt-3.5-turbo、gpt-4)
private ChatRequestParameters defaultRequestParameters; // 默认请求参数(封装通用对话参数)
private Set<Capability> supportedCapabilities; // 支持的能力集(如流式输出、工具调用等)
四、核心生成参数(控制 AI 回答风格 / 长度)
private Double temperature; // 温度系数(0~2,值越低回答越精准/固定,越高越创意/随机)
private Double topP; // 核采样(0~1,控制词汇选择范围,和温度二选一使用)
private List<String> stop; // 停止词(AI遇到这些词会自动停止生成回答)
private Integer maxTokens; // 最大总令牌数(输入+输出总长度限制)
private Integer maxCompletionTokens;// 最大输出令牌数(仅限制AI回答长度)
private Double presencePenalty; // 存在惩罚(值越高越鼓励使用新话题)
private Double frequencyPenalty; // 频率惩罚(值越高越避免重复词汇)
private Map<String, Integer> logitBias; // 词汇偏差(强制AI偏好/规避某些词汇)
五、输出格式与结构化配置
private String responseFormat; // 响应格式(text纯文本/json结构化JSON)
private Boolean strictJsonSchema; // 是否严格校验JSON格式(避免输出非法JSON)
private Integer seed; // 随机种子(相同seed+参数可得到一致回答,用于复现)
private String user; // 用户标识(追踪不同用户的请求)
六、工具调用高级能力
private Boolean strictTools; // 是否严格执行工具调用(强制按定义调用工具)
private Boolean parallelToolCalls; // 是否允许并行调用多个工具(提升效率)
七、服务与元数据配置
private Boolean store; // 是否存储本次请求(平台日志/审计)
private Map<String, String> metadata; // 元数据(自定义标签/备注信息)
private String serviceTier; // 服务等级(如auto/standard,控制调用优先级)
private Boolean returnThinking; // 是否返回AI思考过程(OpenAI最新的思考链功能)
八、日志与监听
private Boolean logRequests; // 是否打印请求日志(调试用)
private Boolean logResponses; // 是否打印响应日志(调试用)
private List<ChatModelListener> listeners; // 监听器列表(监听请求开始/结束/失败,做扩展处理)
二、带上下文记忆的连续对话
功能:
- 你告诉 AI:我叫张三,是 Java 程序员
- 你再问:我叫什么?我是做什么的?
- AI 记得历史,正确回答你
这就是上下文对话(Chat With Memory)
java
package org.deepseek;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
public class ChatWithHistoryDemo {
public static void main(String[] args) {
// 1. 创建模型
ChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-xxxxxxxxxxxxxx")
.modelName("deepseek-chat")
.temperature(0.7) // 创意程度
.maxTokens(1024) // 最大 token
.timeout(Duration.ofSeconds(10)) // 超时
.maxRetries(2) // 失败重试
.logRequests(true) // 打印请求日志
.logResponses(true) // 打印响应日志
.build();
// 2. 用一个 List 保存对话历史(上下文)
List<ChatMessage> messages = new ArrayList<>();
// ============= 第一轮对话 =============
UserMessage firstQuestion = UserMessage.from("我叫张三,是一名Java程序员");
messages.add(firstQuestion);
AiMessage firstAnswer = model.chat(messages).aiMessage();
System.out.println("AI:" + firstAnswer.text());
messages.add(firstAnswer); // 把AI的回答也加入历史
// ============= 第二轮对话(带上下文) =============
UserMessage secondQuestion = UserMessage.from("我叫什么?我是做什么的?");
messages.add(secondQuestion);
AiMessage secondAnswer = model.chat(messages).aiMessage();
System.out.println("AI:" + secondAnswer.text());
}
}
知识点 1:消息体系
● UserMessage:用户发的消息
● AiMessage:AI 返回的消息
● ChatMessage:两者的父接口(统一存放)
知识点 2:模型接口
● ChatModel:统一聊天接口(新版本标准)
● OpenAiChatModel:兼容 OpenAI 协议的模型实现DeepSeek / 智谱 / 阿里 / 硅基 都用这个!
知识点 3:temperature(创造力)
.temperature(0.7)
● 0 ~ 2
● 0:最严谨、固定、不随机
● 2:最天马行空、乱编
● 0.7 是通用平衡值
知识点 4:maxTokens(最大长度)
.maxTokens(1024)
● 限制 AI 回答长度,防止 token 爆炸
● 单位:token(词元)
● 1024 大约 700 个汉字
知识点 5:timeout /maxRetries(网络保护)
.timeout(Duration.ofSeconds(10))
.maxRetries(2)
● 超时 10 秒
● 失败自动重试 2 次
● 生产项目必备
知识点 6:日志调试
.logRequests(true)
.logResponses(true)
● 打印完整请求体 + 响应体
● 调试神器
知识点 7:上下文对话核心(最重要!)
List messages = new ArrayList<>();
上下文 = 消息列表
AI 没有记忆,你给它什么历史,它就记得什么。
model.chat () 返回 ChatResponse
model.chat(messages) → 返回 ChatResponse
所以必须取:
.aiMessage()
必须把 AI 回答加入历史
这是上下文能生效的关键!
不存,下一轮就忘!
知识点汇总
1. 统一模型接口
ChatModel = 聊天模型顶层接口
2. 兼容 OpenAI 格式
OpenAiChatModel + baseUrl 可对接 90% 国内模型
3. 消息结构
● UserMessage 用户
● AiMessage AI
● ChatMessage 父类
4. 上下文原理
靠 List 存储全部历史
5. 调用流程
添加消息 → 调用 AI → 保存AI回答 → 循环
三、AI 工具调用 / Function Call (含 AiServices 使用简化对话)
AI 不再只 "聊天",它可以:
● 调用你写的 Java 方法
● 查时间、查天气、查订单、查数据库
● 自动判断什么时候该调用工具
● 调用完把结果整理成人话回答你
步骤 1:创建工具类(AI 可以调用的 Java 方法)
java
package org.deepseek.demo03;
import dev.langchain4j.agent.tool.Tool;
/**
* 这里封装给AI的工具
* 注解 @Tool 表示这是一个工具类,可以给AI使用
*/
public class MyTools {
@Tool("计算两个数字的和")
public int add(int a, int b) {
System.out.println("【Java方法被调用】add(" + a + ", " + b + ")");
return a + b;
}
@Tool("获取当前系统时间")
public String getCurrentTime() {
System.out.println("【Java方法被调用】getCurrentTime()");
return java.time.LocalDateTime.now().toString();
}
}
步骤 2:创建 AI 接口
1. 定义接口(遥控器)
作用:
告诉 AiServices:你要怎么和 AI 交互
● 传入:字符串(问题)
● 返回:字符串(回答)
● 方法名:chat
AiServices 是根据你接口里的方法,来生成 AI 行为的!
它需要知道 3 件事:
- 你传入什么?(String message)
- 你想要返回什么?(String answer)
- 方法名叫什么?(chat /ask/answer 都行)
你必须给它一个入口方法,它才能帮你生成代理实现。
java
interface Assistant {
String chat(String message);
}
LangChain4j 使用了 动态代理(Dynamic Proxy)
这是 Java 一种高级特性:
你给它一个接口 → 它自动生成一个实现类
你不用写实现类!它自动生成!


步骤 3:创建 AI 服务并绑定工具
1. 上下文按照条数作为记忆Demo
java
package org.deepseek.demo03;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
public class ToolCallDemo {
public static void main(String[] args) {
// 1. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-xxxxxxxxxxxxxxxxxxx")
.modelName("deepseek-chat")
.temperature(0.1)
.build();
// 记忆 :保近10条消息作为记录 ,这里写出来是为了表示可以变更
/**
* AiServices 自动开启记忆
* 默认:
* 记忆最近 10 轮对话
* 自动管理长度
* 不用你管任何 Token 计算
*/
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
// 不需要在方法里重新定义!
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(model)
.tools(new MyTools())
.chatMemory(memory)
.build();
// 测试
String answer = assistant.chat("现在几点?");
System.out.println(answer);
System.out.println(assistant.chat("123 + 456 = ?"));
}
}
上下文按照Token作为记忆Demo
java
package org.deepseek.demo03;
import dev.langchain4j.memory.chat.TokenWindowChatMemory;
import dev.langchain4j.model.TokenCountEstimator;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiTokenCountEstimator;
import dev.langchain4j.service.AiServices;
public class ToolCallDemo {
public static void main(String[] args) {
// 1. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-xxxxxxxxxxxxxxxxxxxx")
.modelName("deepseek-chat")
.temperature(0.1)
.build();
/**
* 创建一个 Token 预估器
* gpt-3.5-turbo → 用 GPT3.5 的字数统计规则
* gpt-4 → 用 GPT4 的字数统计规则
*/
TokenCountEstimator tokenCountEstimator = new OpenAiTokenCountEstimator("gpt-3.5-turbo");
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(model)
.tools(new MyTools())
.chatMemoryProvider(memoryId -> TokenWindowChatMemory.withMaxTokens(1000, tokenCountEstimator))
.build();
// 测试
String answer = assistant.chat("现在几点?");
System.out.println(answer);
System.out.println(assistant.chat("123 + 456 = ?"));
}
}
知识点 1:@Tool 注解
● 标记一个方法 可以被 AI 调用
● 里面写描述,AI 靠这个理解方法用途
java
@Tool("计算两个数字的和")
知识点 2:AiServices
LangChain4j 最核心的 "AI 工厂"帮你自动实现 (动态代理) :
● 对话
● 记忆
● 工具调用
● 重试
● 日志
你只需要写一个接口:
java
interface Assistant {
String chat(String message);
}
知识点 3:AI 自动决策
你不需要告诉 AI 什么时候调用工具它自己判断:
● 要时间 → 调用 getCurrentTime
● 要计算 → 调用 add
知识点 4:工具调用流程(面试必考)
- 用户提问
- AI 判断是否需要工具
- 调用 Java 方法
- 拿到方法返回值
- AI 整理成人话回答
知识点 5:为什么工具调用要低温度?
.temperature(0.1)
工具调用需要精准、稳定、不乱来温度越低,AI 越严谨,越不会乱调用工具。
一般在 0.1 - 0.3 之间
知识点 6:记忆管理器
TokenWindowChatMemory:
带自动裁剪功能的对话记忆管理器
功能:
- 保存对话历史
- 统计 token 数量
- 超过 maxTokens 就自动删除最早的消息
- 保证不会超长导致 AI 报错
- 保护系统提示词、工具消息
java
/**
* 创建一个 Token 预估器
* gpt-3.5-turbo → 用 GPT3.5 的字数统计规则
* gpt-4 → 用 GPT4 的字数统计规则
*/
TokenCountEstimator tokenCountEstimator = new OpenAiTokenCountEstimator("gpt-3.5-turbo");
使用:
java
.chatMemoryProvider(memoryId -> TokenWindowChatMemory.withMaxTokens(1000, tokenCountEstimator))
MessageWindowChatMemory:
MessageWindowChatMemory:
基于消息数量的简单实现,它采用滑动窗口的方式,保留最新的N条消息并淘汰旧消息。
记忆 :保近10条消息作为记录 ,这里写出来是为了表示可以变更
java
/**
* AiServices 自动开启记忆
* 默认:
* 记忆最近 10 轮对话
* 自动管理长度
* 不用你管任何 Token 计算
*/
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
使用:
java
.chatMemory(memory)
四、流式响应
增加依赖
java
<!-- LangChain4j对流式模型的依赖 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
</dependency>
完整pom
java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>langchain4j</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demo</artifactId>
<!-- 统一版本管理 -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 在这里统一定义 langchain4j 版本 -->
<langchain4j.version>1.3.0</langchain4j.version>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
</dependency>
<!-- LangChain4j对流式模型的依赖 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- BOM -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-bom</artifactId>
<version>${langchain4j.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Assistant 接口
java
import reactor.core.publisher.Flux;
public interface Assistant {
Flux<String> chat(String message);
}
StreamDemo
java
package org.deepseek.demo04;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
public class StreamDemo {
public static void main(String[] args) {
// 1. 初始化模型
OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-XXXXXXXXXXX")
.modelName("deepseek-chat")
.temperature(0.1)
.build();
// 2. AiServices 自动生成接口实现
Assistant assistant = dev.langchain4j.service.AiServices.builder(Assistant.class)
.streamingChatModel(model)
.build();
// 3. 流式输出(打字机效果)
System.out.print("AI:");
assistant.chat("用100字介绍Java")
.doOnNext(System.out::print)
.blockLast();
}
}
知识点1:OpenAiStreamingChatModel ------ 流式对话模型
专门用来做 "打字机效果" 的 AI 模型客户端
负责和大模型(DeepSeek)建立流式连接
知识点2: streamingChatModel (model) ------ 注入流式模型
告诉 AiServices:我要用流式方式生成回答!
chatModel(model) → 普通对话,一次性返回
streamingChatModel(model) → 流式对话,分段返回
它是AiServices 识别流式输出的开关。
知识点3:Flux ------ 流式响应载体
属于 Reactor 响应式编程标准
流式数据的标准返回类型
代表一段一段推送的文本流
实现打字机效果
五、结构化 JSON 输出
代码
- 先建一个结果实体类(你想要的 JSON 结构)
如:
我们让 AI 提取:
姓名
年龄
情绪
回答内容
Java
package org.deepseek.demo05;
public class UserAnalysis {
// 字段名会变成 JSON key
private String name;
private Integer age;
private String mood;
private String answer;
// 必须有无参构造
public UserAnalysis() {}
// getter + setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getMood() { return mood; }
public void setMood(String mood) { this.mood = mood; }
public String getAnswer() { return answer; }
public void setAnswer(String answer) { this.answer = answer; }
}
AI 接口
Java
package org.deepseek.demo05;
import dev.langchain4j.service.SystemMessage;
public interface Assistant {
// 强制模型:只返回 JSON,不要多余文字
@SystemMessage("""
你是一个结构化输出助手。
只返回标准 JSON,不要任何解释、不要 markdown、不要多余文字。
""")
UserAnalysis chat(String message);
}
JsonOutputDemo
package org.deepseek.demo05;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class JsonOutputDemo {
public static void main(String[] args) {
// 普通非流式模型即可
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("https://api.deepseek.com")
.apiKey("sk-XXXXXXXXXXXXXX")
.modelName("deepseek-chat")
.temperature(0.1)
.build();
Assistant assistant = dev.langchain4j.service.AiServices.builder(Assistant.class)
.chatModel(model)
.build();
// 传入一句话
String userInput = "我叫张三,今年25岁,今天心情不错,你好呀";
// 直接拿到对象!!!
UserAnalysis result = assistant.chat(userInput);
// 直接使用,不需要解析 JSON
System.out.println("姓名:" + result.getName());
System.out.println("年龄:" + result.getAge());
System.out.println("情绪:" + result.getMood());
System.out.println("回答:" + result.getAnswer());
}
}
知识点1:核心规则
返回值类型 = 响应格式
LangChain4j 自动根据接口返回值,决定让模型返回 text 还是 json:
| 接口返回类型 | 模型响应格式 | 行为 |
|---|---|---|
| String | text 纯文本 | 自由回答 |
| Java 对象 / POJO | json_object | 强制返回合法 JSON |
| List<?> | json 数组 | 自动返回 JSON 数组 |
| Flux | stream text | 流式打字机 |
知识点2:JSON 输出的底层自动处理
框架根据方法签名自动生成对应 API 调用格式
当你写:
Java
UserInfo chat(String message);
框架 自动做 3 件事:
-
自动给模型加 JSON 格式指令
告诉模型:只返回 JSON、不要解释、不要多余文字 -
自动设置 API 参数
"response_format": { "type": "json_object" }
-
自动把 JSON 字符串 → 映射为 Java 对象
不需要 Gson / Fastjson / Jackson 手动解析
知识点3:JSON 输出必须满足的条件(缺一不可)
- 返回类型必须是 自定义 POJO 对象
不能是 String、Map、JsonObject,必须是你自己写的类。 - 类必须满足 JavaBean 规范
提供 无参构造器
所有字段提供 getter / setter
字段名就是 JSON 的 key - 强烈配合 @SystemMessage 加固约束
Java
@SystemMessage("""
只返回JSON,不要任何解释、不要markdown、不要```json```包裹。
""")
模型会更稳定,不会乱说话。
常见错误(避坑)
-
返回 String 却想要 JSON → 不行
// 不会自动 JSON!只会返回 text
String chat(String msg); -
POJO 没有无参构造 → 解析失败
-
没有 getter/setter → 字段为 null
-
模型返回 markdown 包裹的 json → 解析失败
→ 必须用 @SystemMessage 严格约束。