初识LangChain4j

LangChain4j 的目标是简化将大语言模型(LLM)集成到 Java 应用程序中。它提供了统一 API 和丰富的工具箱,让你能轻松切换不同的 LLM 提供商(如 OpenAI、Google Vertex AI)和嵌入存储(如 Pinecone、Milvus)。

核心概念与功能模块

LangChain4j 的功能围绕以下核心模块构建:

  • 统一 API:为 ChatLanguageModelEmbeddingStore 等核心组件提供标准接口,屏蔽底层服务差异。
  • AI 服务高层次抽象的核心。通过定义接口并添加注解,即可将 LLM 交互逻辑声明为业务方法,自动处理提示模板、对话历史和输出解析。
  • 提示模板:支持使用 Mustache 或 printf 格式创建和管理提示词,实现提示词的复用和动态填充。
  • 聊天记忆:内置多种记忆算法(如消息窗口、令牌窗口),可轻松为聊天机器人添加多轮对话的上下文理解能力。
  • 函数调用:允许 LLM 在生成回复时,根据请求调用你指定的 Java 方法,从而执行具体操作或获取实时信息。
  • 检索增强生成:提供一整套数据摄取(从多种数据源加载、解析、分割文档,并生成向量存入数据库)和检索(查询转换、检索、重排序)的工具,帮助你构建基于私有数据的问答系统。
  • 输出解析器:能将 LLM 的文本输出自动解析为布尔值、数字、List 或自定义的 POJO 对象。

两个抽象层次与模块化设计

框架允许你在两个层次上工作:

  • 低层次:直接使用 ChatLanguageModelEmbedding 等“原语”进行编程,拥有最大控制权。
  • 高层次:通过 AI 服务声明式地调用 LLM,框架处理所有样板代码。

模块化设计让你按需引入依赖:

  • **langchain4j-core**:核心接口与抽象。
  • **langchain4j**:主模块,包含文档加载器、聊天记忆、AI 服务等高级功能。
  • **langchain4j-{integration}**:与具体 LLM 提供商(如 langchain4j-open-ai)或向量数据库的集成模块。

1. 环境准备与依赖配置

1.1 核心依赖

pom.xml 中引入 LangChain4j 的 Spring Boot Starter 和具体模型集成(以 OpenAI 兼容 API 为例,如通义千问、DeepSeek、Kimi 等):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- LangChain4j 核心 Starter(提供 AI Service 等高级功能) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>${langchain4j.version}</version>
</dependency>

<!-- 具体模型集成:OpenAI 风格 API(兼容通义千问、DeepSeek、Kimi 等) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>${langchain4j.version}</version>
</dependency>

<!-- 可选:流式响应支持 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>

注意:如果使用阿里云百炼平台,需引入 langchain4j-community-dashscope-spring-boot-starter 并调整配置前缀 。

1.2 配置文件

application.propertiesapplication.yml 中配置模型参数:

1
2
3
4
5
6
7
# 以 OpenAI 风格 API 为例(通义千问、DeepSeek 等通用)
langchain4j.open-ai.chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.open-ai.chat-model.base-url=https://dashscope.aliyuncs.com/compatible-mode/v1
langchain4j.open-ai.chat-model.model-name=qwen-plus
# 可选:开启请求/响应日志
langchain4j.open-ai.chat-model.log-requests=true
langchain4j.open-ai.chat-model.log-responses=true

配置后,Spring Boot 会自动装配 OpenAiChatModelChatLanguageModel 的实现)实例 。

2. 两种使用层次

2.1 低层次:直接注入 ChatModel

直接注入 ChatLanguageModel 进行简单对话 。

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class ChatController {

// 自动注入由 Starter 配置好的 ChatModel
@Autowired
private ChatLanguageModel chatModel;

@GetMapping("/chat")
public String chat(@RequestParam(defaultValue = "你好") String message) {
// 简单生成回复
return chatModel.generate(message);
}
}

这种方式适合快速测试和简单场景,但需要自行处理提示模板、记忆管理等。

2.2 高层次:声明式 AI 服务

定义接口并标注 @AiService,LangChain4j 会在运行时生成实现类并注册为 Spring Bean 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import dev.langchain4j.service.AiService;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;

@AiService
public interface Assistant {

@SystemMessage("你是一个专业的Java技术顾问,请用中文回答。")
String chat(@UserMessage String userMessage);
}

// 在 Controller 中使用
@RestController
public class AssistantController {

@Autowired
private Assistant assistant;

@GetMapping("/assistant")
public String ask(String question) {
return assistant.chat(question);
}
}

3. 高级特性实战

3.1 流式响应

结合 Project Reactor 返回 Flux<String> 实现流式输出 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@AiService
public interface StreamingAssistant {

@SystemMessage("你是一名AI助手,请逐字输出思考过程。")
Flux<String> chat(@UserMessage String userMessage);
}

@RestController
public class StreamingController {

@Autowired
private StreamingAssistant assistant;

@GetMapping(value = "/stream", produces = "text/event-stream")
public Flux<String> stream(String prompt) {
return assistant.chat(prompt);
}
}

3.2 函数调用(Tools)

通过 @Tool 注解将 Spring Bean 中的方法暴露给 LLM 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Component
public class BookingTools {

private final BookingService bookingService;

public BookingTools(BookingService bookingService) {
this.bookingService = bookingService;
}

@Tool("根据预订号、客户姓名和姓氏查询预订详情")
public Booking getBookingDetails(
@P("预订号") String bookingNumber,
@P("客户名") String customerName,
@P("客户姓") String customerSurname) {
return bookingService.findBooking(bookingNumber, customerName, customerSurname);
}

@Tool("根据预订号、客户姓名和姓氏取消预订")
public void cancelBooking(
@P("预订号") String bookingNumber,
@P("客户名") String customerName,
@P("客户姓") String customerSurname) {
bookingService.cancel(bookingNumber, customerName, customerSurname);
}
}

在 AI Service 中,Starter 会自动检测并注册 BookingTools,无需额外配置 。

3.3 聊天记忆持久化

结合 ChatMemoryStore 接口实现记忆存储(如 MongoDB)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {

@Autowired
private MongoTemplate mongoTemplate;

@Override
public List<ChatMessage> getMessages(Object memoryId) {
// 从 MongoDB 查询并反序列化
Query query = Query.query(Criteria.where("memoryId").is(memoryId));
ChatMessages record = mongoTemplate.findOne(query, ChatMessages.class);
return record != null ?
ChatMessageDeserializer.messagesFromJson(record.getContent()) :
new ArrayList<>();
}

@Override
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
Query query = Query.query(Criteria.where("memoryId").is(memoryId));
Update update = Update.update("content",
ChatMessageSerializer.messagesToJson(messages));
mongoTemplate.upsert(query, update, ChatMessages.class);
}

@Override
public void deleteMessages(Object memoryId) {
Query query = Query.query(Criteria.where("memoryId").is(memoryId));
mongoTemplate.remove(query, ChatMessages.class);
}
}

3.4 显式装配与多模型共存

当存在多个相同类型的组件(如多个 ChatLanguageModel Bean)时,需使用显式装配模式 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Configuration
public class MultiModelConfig {

@Bean
@ConfigurationProperties("langchain4j.open-ai.chat-model")
public OpenAiChatModel openAiChatModel() {
return OpenAiChatModel.builder().build();
}

@Bean
@ConfigurationProperties("langchain4j.ollama.chat-model")
public OllamaChatModel ollamaChatModel() {
return OllamaChatModel.builder().build();
}
}

@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "openAiChatModel")
interface OpenAiAssistant {
String chat(String message);
}

@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "ollamaChatModel")
interface OllamaAssistant {
String chat(String message);
}

3.5 检索增强生成

配置 ContentRetriever 实现基础 RAG 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Configuration
public class RagConfig {

@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
// 使用内存存储或实际向量数据库
return new InMemoryEmbeddingStore<>();
}

@Bean
public EmbeddingModel embeddingModel() {
return new AllMiniLmL6V2EmbeddingModel(); // 本地模型
}

@Bean
public ContentRetriever contentRetriever(
EmbeddingStore<TextSegment> store,
EmbeddingModel model) {
return EmbeddingStoreContentRetriever.builder()
.embeddingStore(store)
.embeddingModel(model)
.maxResults(3)
.minScore(0.7)
.build();
}
}

@AiService
interface RagAssistant {
String chat(@UserMessage String message);
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2026 Immanuel
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

微信