LangChain4J快速入门与实战指南
LangChain4J
快速入门
第一种方式
- 引入依赖
<!--langchain4j起步依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
注意版本兼容。1.0.1-beta6版本不兼容springboot 4.x,建议使用springboot 3.4.1
- 编写配置文件
langchain4j:
open-ai:
chat-model:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # api-key
model-name: qwen3-max # 模型名称
log-requests: true # 打印日志
log-responses: true # 打印日志
# 开启日志级别
logging:
level:
org.langchain4j: debug
- 项目里引入OpenAiChatModel调用chat方法
package com.xample.langchain4jdemo.controller;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
@Autowired
private OpenAiChatModel openAiChatModel;
@RequestMapping("chat")
public String chat(@RequestParam("message") String message) {
return openAiChatModel.chat(message);
}
}
这是不流行的写法,下面方式是比较流行的!
第二种方式
- 引入依赖
<!--langchain4j起步依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
- 定义一个接口
public interface ConsultantService {
/**
* 用于聊天的接口
*
* @param message
* @return
*/
String chat(String message);
}
- 写一个配置类
@Configuration
public class CommonConfig {
@Autowired
private OpenAiChatModel openAiChatModel;
@Bean
public ConsultantService consultantService() {
return AiServices.builder(ConsultantService.class)
.chatModel(openAiChatModel)
.build();
}
}
- 使用
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
@RequestMapping("chat")
public String chat(@RequestParam("message") String message) {
return consultantService.chat(message);
}
}
第三种方式
- 引入依赖
<!--langchain4j起步依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.0.1-beta6</version>
</dependency>
- 定义一个接口,并添加@AiService注解
chatModel:指定模型,后写model的类,openAiChatModel是OpenAiChatModel类,因为bean的名称是默认首字母小写
wiringMode = AiServiceWiringMode.EXPLICIT 手动装配
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
@AiService(chatModel = "openAiChatModel",wiringMode = AiServiceWiringMode.EXPLICIT)
public interface ConsultantService {
/**
* 用于聊天的接口
*
* @param message
* @return
*/
String chat(String message);
}
- 使用
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
@RequestMapping("chat")
public String chat(@RequestParam("message") String message) {
return consultantService.chat(message);
}
}
流式调用
- 引入依赖
<!-- 引入流式调用相关的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.0.1-beta6</version>
</dependency>
- 编写配置文件
langchain4j:
open-ai:
chat-model:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # api-key
model-name: qwen3-max
log-requests: true
log-responses: true
# 添加流式model的配置文件,与上面一致
streaming-chat-model:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # api-key
model-name: qwen3-max
log-requests: true
log-responses: true
- 修改AiService中的注解
添加属性:streamingChatModel = “openAiStreamingChatModel”
并且修改chat方法的返回值为:Flux<String>
@AiService(chatModel = "openAiChatModel",
wiringMode = AiServiceWiringMode.EXPLICIT,
streamingChatModel = "openAiStreamingChatModel")
public interface ConsultantService {
/**
* 用于聊天的接口
*
* @param message
* @return
*/
Flux<String> chat(String message);
}
- 前端乱码
为了让前端不乱码要在@RequestMapping注解中添加:produces = “text/html;charset=UTF-8”
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
@RequestMapping(value = "chat",produces = "text/html;charset=UTF-8")
public Flux<String> chat(@RequestParam("message") String message) {
return consultantService.chat(message);
}
}
消息注解(提示词)
- 在AiService中chat方法上添加@SystemMessage注解,可以约定系统提示词,规定大模型一些行为!
public interface ConsultantService {
/**
* 用于聊天的接口
*
* @param message
* @return
*/
// @SystemMessage("你叫小美!不要回答与政治相关的信息")
@SystemMessage(fromResource = "system.txt")
Flux<String> chat(String message);
}
如果系统提示词过于长,可以在根目录创建system.txt文件,这里使用fromResource指定即可
会话记忆
- 引入redis,将会话记忆存储在redis中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 编写RedisChatMemoryStore,继承ChatMemoryStore,实现ChatMemoryStore的方法
@Component
public class RedisChatMemoryStore implements ChatMemoryStore {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public List<ChatMessage> getMessages(Object memoryId) {
String messages = redisTemplate.opsForValue().get(memoryId);
if (messages != null) {
return ChatMessageDeserializer.messagesFromJson(messages);
}
return List.of();
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> list) {
String messages = ChatMessageSerializer.messagesToJson(list);
redisTemplate.opsForValue().set(memoryId.toString(), messages, 1, TimeUnit.DAYS);
}
@Override
public void deleteMessages(Object memoryId) {
redisTemplate.delete(memoryId.toString());
}
}
- config中定义刚才的Provider
@Bean
public ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId) // 一定要指定memoryId,否则没有记忆隔离
.maxMessages(20) // 最大保存20条记录
.chatMemoryStore(redisChatMemoryStore) // 指定刚才写的RedisChatMemoryStore
.build();
}
- AiService添加chatMemoryProvider 属性,只能使用哪个Provider
- 在@AiService注解中添加:chatMemoryProvider = “chatMemoryProvider”
- 并在chat方法中添加:@MemoryId String memoryId
这里如果有两个属性,一定要添加添加相应的注解,告诉它哪个是memoryId(@MemoryId),哪个是用户消息(@UserMessage)
@AiService(chatModel = "openAiChatModel",
wiringMode = AiServiceWiringMode.EXPLICIT,
streamingChatModel = "openAiStreamingChatModel",
chatMemoryProvider = "chatMemoryProvider"
)
public interface ConsultantService {
/**
* 用于聊天的接口
*
* @param message
* @return
*/
@SystemMessage(fromResource = "system.txt")
Flux<String> chat(@MemoryId String memoryId, @UserMessage String message);
}
- controller中接收memoryId
然后controller中传参也要添加memoryId,这个memoryId可以是前端自定义生成,uuid什么的,尽可能的唯一
@RequestMapping(value = "chat", produces = "text/html;charset=UTF-8")
public Flux<String> chat(@RequestParam("memoryId") String memoryId, @RequestParam("message") String message) {
return consultantService.chat(memoryId, message);
}
RAG知识库
- 引入依赖
<!--rag-easy依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
<version>1.0.1-beta6</version>
</dependency>
- 编写操作向量数据库的方法
/**
* 构建向量数据库操作对象
* 往向量数据库中添加
*
* @return
*/
@Bean
public EmbeddingStore store() {
// 1.加载文档进内存
List<Document> documents = ClassPathDocumentLoader.loadDocuments("content", new ApachePdfBoxDocumentParser());
// 2. 构建向量数据库操作对象(这里是内存向量数据库,重启后数据就没了,下面会换成redis向量数据库)
InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();
// 3. 构建一个EmbeddingStoreIngestor对象, 完成文本数据切割, 向量化存储
EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.embeddingStore(store)
.build();
ingestor.ingest(documents);
return store;
}
/**
* 构建向量数据库检索对象
* 获取向量数据库中的数据
*
* @param store
* @return
*/
@Bean
public ContentRetriever contentRetriever(EmbeddingStore store) {
return EmbeddingStoreContentRetriever.builder()
.embeddingStore(store)
.minScore(0.5) // 分数大于0.5
.maxResults(3) // 最多检索3条相关的数据
.build();
}
- AiService中添加向量数据库检索对象的方法

启动发现数据能够被切片,并且能够根据切片内容进行回答问题
核心API

主要是上图中五个紫色的部分:
- 文件加载器
文档加载器, 用于把磁盘或者网络中的数据加载进程序
| 名称 | 说明 |
|---|---|
| FileSystemDocumentLoader | 根据本地磁盘绝对路径加载 |
| ClassPathDocumentLoader | 相对于类路径加载 |
| UrlDocumentLoader | 根据url路径加载 |
- 文档解析器
大模型只能分析文本,所以要将其他格式的文件转为文本格式
| 名称 | 说明 |
|---|---|
| TextDocumentParser | 解析纯文本格式的文件 |
| ApachePdfBoxDocumentParser | 解析pdf格式文件 |
| ApachePoiDocumentParser | 解析微软的office文件, 例如DOC、PPT、XLS |
| ApacheTikeDocumentParser (默认) | 几乎可以解析所有格式的文件 |
默认的解析器可以解析很多格式的文件,但是在具体某些格式的文件时,没有那些专门处理某种格式的解析器专业
以解析pdf文件为例:
<!--pdf解析器依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-document-parser-apache-pdfbox</artifactId>
<version>1.0.1-beta6</version>
</dependency>

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)