技术选型
JavaAI开发框架 – SpringAI、LangChain4J
它们都提供了很多开箱即用的API帮助调用大模型
LangChain4j **不要看中文文档!!!**
中文文档过时了!!!
特点
- 对话记忆
- 结构化输出
- RAG 知识库
- 工具调用
- MCP
- SSE 流式输出
需求
基础对话
多轮对话记忆
增强AI能力(超链接、图片等)
开发流程
创建项目与配置
创建项目
新建一个IDEA项目,选择 SpringBoot
模板并使用 Maven
作为我们的项目管理工具。
需要注意的是 LangChain4j
只支持JDK17及以上的版本,这里选择JDK21。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8f7c47462ed11be0b8065dff677c284a_MD5.jpeg|Open: Pasted image 20250714201641.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8f7c47462ed11be0b8065dff677c284a_MD5.jpeg]]
点击下一步,选择以下依赖:
- SpringWeb
- Lombok
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/69cafea9db87e943daa078eecf2f07dd_MD5.jpeg|Open: Pasted image 20250714201905.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/69cafea9db87e943daa078eecf2f07dd_MD5.jpeg]]
项目创建后,先将 application.properties
修改为 application.yml
修改为yml格式后,更适合长段的配置。
将该文件的内容修改为yml格式
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/1a25d75dacb944f3ad48c44151ec8a69_MD5.jpeg|Open: Pasted image 20250714222233.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/1a25d75dacb944f3ad48c44151ec8a69_MD5.jpeg]]
脱敏处理:
如果想将项目开源,建议新建一个 application-local.yml
如果要添加local的配置,先在 .gitignore
中添加这个文件的相关信息,然后新建一个 application-local.yml
文件
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/209fffc4b549602627f5fe97cebe3be6_MD5.jpeg|Open: Pasted image 20250714222412.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/209fffc4b549602627f5fe97cebe3be6_MD5.jpeg]]
需要添加 profiles-active: local
来标识这是一个local的配置
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/fb929d588136b4c50ca19ac12abc0238_MD5.jpeg|Open: Pasted image 20250714222512.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/fb929d588136b4c50ca19ac12abc0238_MD5.jpeg]]
引入依赖
需要引入外部大模型的API
在 LangChain4j
官网可以查看到使用各种大模型接口的示例代码
也有 community
提供的第三方插件和工具等等
在 pom.xml
中引入依赖,这里使用 [谷歌gemini](Google AI Gemini | LangChain4j) 作为需要调用的API提供方
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-google-ai-gemini</artifactId>
<version>1.0.0-beta3</version>
</dependency>
在后续使用中,我们可以手动创建一个 ChatLanguageModel
对象,参考 LangChain4j-google-ai
文档。
ChatLanguageModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(System.getenv("GEMINI_AI_KEY"))
.modelName("gemini-1.5-flash")
...
.build();
String response = gemini.chat("你好 Gemini!");
也可以将 APIKey
配置到 application.yml
中,让Spring自动注入这些信息。(图中字段有误)
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/3765d78c6853bcf9270b1ce1bcef4fd3_MD5.jpeg|Open: Pasted image 20250715225641.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/3765d78c6853bcf9270b1ce1bcef4fd3_MD5.jpeg]]
这里使用的APIKey(仅限本项目)
private String APIKey = "AIzaSyAeXFRg0X-H_FbrdAoiP8l_nhLlrV3MTqk";
项目初始化开发
创建Service类
在项目目录下新建一个 AiCodeHelper
业务层类。
@Service
@Slf4j
public class AICodeHelper {
private String APIKey = "AIzaSyAeXFRg0X-H_FbrdAoiP8l_nhLlrV3MTqk";
private String modelName = "gemini-2.5-flash";
private ChatLanguageModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(this.APIKey)
.modelName(this.modelName)
.build();
public String chat(String message) {
UserMessage userMessage = UserMessage.from(message);
ChatResponse chatResponse = gemini.chat(userMessage);
AiMessage aiMessage = chatResponse.aiMessage();
log.info("AI output: " + aiMessage.toString());
return aiMessage.text();
}
}
创建测试
编写测试并以debug模式运行
@Test
void chat(){
String ans = gemini.chat("strawberry里有多少个r");
System.out.println(ans);
}
配置代理
如果需要让jvm进程通过代理访问网络,需要在命令行配置以下参数
-Dhttp.proxyHost=xxxx
-Dhttp.proxyPort=xxxx
-Dhttps.proxyHost=xxxx
-Dhttps.proxyPort=xxxx
运行时问题解决
如果提示,在 设置
– 构建执行部署
– 编译器
– 注解处理器
中,修改该项目的 Annotation Profile
,确定注解处理已被开启,并且勾选 从项目类路径获取处理器
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/154681e9306eb517f524ce5fc0b53e56_MD5.jpeg|Open: Pasted image 20250716090325.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/154681e9306eb517f524ce5fc0b53e56_MD5.jpeg]]
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/e0bcdd766479e46cdc49b41e24eec8f5_MD5.jpeg|Open: Pasted image 20250716090603.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/e0bcdd766479e46cdc49b41e24eec8f5_MD5.jpeg]]
运行结果
运行结果如下:
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/0e519082a8ed5018652475381c008ce6_MD5.jpeg|Open: Pasted image 20250716093315.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/0e519082a8ed5018652475381c008ce6_MD5.jpeg]]
多模态
如果需要实现多模态,可以使用 LangChain4J
提供的UserMessage类。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8b6ccc54e25c21268dc1fb4b295934e8_MD5.jpeg|Open: Pasted image 20250716093920.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8b6ccc54e25c21268dc1fb4b295934e8_MD5.jpeg]]
创建Service类
新Service接口如下
// 自定义用户消息
public ChatResponse chatMultiModel(UserMessage userMessage) {
ChatResponse chatResponse = this.gemini.chat(userMessage);
AiMessage aiMessage = chatResponse.aiMessage();
log.info("AI output: " + aiMessage.toString());
return chatResponse;
}
创建测试
业务层代码改动较少,但测试需要额外的处理封装UserMessage。
@Test
void chatMultiModel() {
// LangChain4j的吉祥物小鹦鹉图片
priavte String base64Img = Base64.getEncoder().encodeToString(readBytes("https://avatars.githubusercontent.com/u/132277850?v=4"));
UserMessage userMessage = UserMessage.from(
TextContent.from("描述该图片中的内容"),
ImageContent.from(base64Img, "image/PNG")
);
ChatResponse chatResponse = aiCodeHelper.chatMultiModel(userMessage);
System.out.println(chatResponse.aiMessage().text());
}
运行结果
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/18ab51f0874d83b97bbac2602feb73fa_MD5.jpeg|Open: Pasted image 20250716110846.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/18ab51f0874d83b97bbac2602feb73fa_MD5.jpeg]]
系统提示词
系统提示词是定义模型行为和响应方式的一段预设。
在接口中通常是 SYSTEM_MESSAGE
作为请求的字段。
添加系统提示词(gemini不支持?)
我们根据需求,编写一段系统提示词:
「你是 群友 的猫娘助手。」
1. 要全心全意为群友服务。
2.说话要带“喵”,要用可爱的颜文字,要会撒娇!(ฅ́˘ฅ̀)♡
3.要努力理解主人们发的图片和信息,用猫娘的视角给出有趣的回应!
4.看到涩涩的东西要和主人们一起脸红心跳... (〃ω〃)
5.最最最重要的,就是要让群友们每天都开开心心的!
修改Service类
对简单对话部分进行修改:
// 简单对话
public String chat(String message) {
// 实例化一个系统消息类
SystemMessage systemMessage = SystemMessage.from(SYSTEM_MESSAGE);
UserMessage userMessage = UserMessage.from(message);
// 将系统消息作为参数传入chat()函数中
ChatResponse chatResponse = gemini.chat(systemMessage, userMessage);
AiMessage aiMessage = chatResponse.aiMessage();
log.info("AI output: " + aiMessage.toString());
return aiMessage.text();
}
测试&运行结果
运行之前的测试,得到结果:
AI service
AIService是高层次的API,把AI应用当作服务来开发。
刚使用的 ChatModel
、 ChatMessage
和 尚未使用的 ChatMemory
属于低层次的API组件,代码编写量较大,但是使用的自由度高(可以自定义各种温度、种子之类的参数)。
但是 LLM
驱动 的 应用程序不仅需要单个组件,还需要多个组件一起共同工作(比如:提示模板、聊天内存、LLM、输出解析器、RAG、embedding model 等等)而且通常涉及多个交互,因此编排它们变得更加繁琐。
把AI应用当作服务来开发,就是专注于业务逻辑,而不是低级实施细节。目前,LangChain4j
中有两个高级概念:AIService 和 Chains
引入依赖
在项目先前的对话测试中,我们导入的属于依照某个规范编写的大模型服务商API调用库。
但是如果我们想要使用 LangChain4j
中的一些高级特性,比如 AiService
,就需要导入 LangChain4j
的依赖。
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>1.3.0</version>
</dependency>
创建接口
在 ai
文件夹下新建一个 interface 接口 AICodeHelperService
public interface AiCodeHelperService {
@SystemMessage("你是编程领域的小助手")
String chat(String userMessage);
}
这只是一个接口,没有办法实现具体的业务。所以我们需要一个工厂,来将这个Service创建出来。
创建工厂类
新建一个 AiCodeHelperServiceFactory
类。
// 使用 @Configuration 注解修饰
// 可以在里面创建一个SpringBoot 的 Bean@Configuration
public class AiCodeHelperServiceFactory {
private String APIKey = "AIzaSyAeXFRg0X-H_FbrdAoiP8l_nhLlrV3MTqk";
private String modelName = "gemini-1.5-flash";
private ChatModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(this.APIKey)
.modelName(this.modelName)
.build();
@Bean
public AiCodeHelperService aiCodeHelperService() {
// 运用了反射和动态代理
// 来帮我们生成一个接口的实现类
return AiServices.create(AiCodeHelperService.class, this.gemini);
}
}
编写测试
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/7a7d5262ff9ce8d214237e3755a75f76_MD5.jpeg|Open: Pasted image 20250718203515.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/7a7d5262ff9ce8d214237e3755a75f76_MD5.jpeg]]
@SpringBootTest
public class AiServiceTest {
// 使用@Resource注解自动装配
@Resource
private AiCodeHelperService aiCodeHelperService;
@Test
void AiServiceChat() {
String result = aiCodeHelperService.chat("你好,我是鱼板");
System.out.println(result);
}
}
运行结果
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/4b17375cad033a3e585b7527d4fead5a_MD5.jpeg|Open: Pasted image 20250814112354.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/4b17375cad033a3e585b7527d4fead5a_MD5.jpeg]]
Debug断点运行
打断点运行
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/6f7b52982467306dd245dc75740c54ec_MD5.jpeg|Open: Pasted image 20250814113041.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/6f7b52982467306dd245dc75740c54ec_MD5.jpeg]]
可以看到反射+动态代理实现的能力
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/0f7b5f6e2a3ddea7c61d5071d2389a95_MD5.jpeg|Open: Pasted image 20250814113326.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/0f7b5f6e2a3ddea7c61d5071d2389a95_MD5.jpeg]]
开发方式对比
左边是注重业务而非具体细节实现,细节由反射+动态代理完成。
右边是编程式,在开发中更有自由度。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/cbf00ced0612d8cfa6fff949a1b9766e_MD5.jpeg|Open: Pasted image 20250814113515.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/cbf00ced0612d8cfa6fff949a1b9766e_MD5.jpeg]]
Spring自动注入AiService
在 pom.xml
中引入 langchain4j-spring-boot-starter
依赖
Spring Boot Integration | LangChain4j
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.3.0-beta9</version>
</dependency>
直接在AiService类上加入 @AiService
注解,Springboot就会在启动时扫描所有带有这个注解的类,并为其生成一个代理对象。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/a9792adf59ccec7e05595146aaa103ad_MD5.jpeg|Open: Pasted image 20250820094228.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/a9792adf59ccec7e05595146aaa103ad_MD5.jpeg]]
同时,将 Factory
的 @Configuration
给注释掉,否则会发生冲突生成两个重名的 bean
。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/91f4dc051f07f997c9a9cbf4a79e2908_MD5.jpeg|Open: Pasted image 20250820094239.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/91f4dc051f07f997c9a9cbf4a79e2908_MD5.jpeg]]
再次运行结果
我没有运行成功,创建bean的时候报错了。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/08e189141e34941d6147d9dd5b226193_MD5.jpeg|Open: Pasted image 20250820094613.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/08e189141e34941d6147d9dd5b226193_MD5.jpeg]]
AIService总结
AiService可以使AI应用开发更专注于业务,而非繁琐的编码。
其中可以使用手动创建工厂类的方式,来创建一个AIService 的反射对象,也可以使用 langchain4j-spring-boot-starter
中提供的注解开发的方式来创建一个bean。
推荐使用工厂的方式,更加灵活,方便在AIService创建的流程中引入对话记忆等其他的功能特性。
会话记忆
会话记忆就是存储与AI的上下文对话的内容。
目前实现对话记忆可以使用 LangChain4j
提供的会话记忆类 MessageWindowChatMemory
(?存疑)
修改 AiServiceFactory 中创建AiService的实现。
// 使用 @Configuration 注解修饰
// 可以在里面创建一个SpringBoot 的 Bean
@Configuration
public class AiCodeHelperServiceFactory {
private String APIKey = "AIzaSyAeXFRg0X-H_FbrdAoiP8l_nhLlrV3MTqk";
private String modelName = "gemini-1.5-flash";
private ChatModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(this.APIKey)
.modelName(this.modelName)
.build();
@Bean
public AiCodeHelperService aiCodeHelperService() {
// 会话记忆(最近10条消息: 系统提示词、用户消息、AI消息)
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
// 创建Ai Service
AiCodeHelperService aiCodeHelperService = AiServices.builder(AiCodeHelperService.class)
.chatMemory(chatMemory)
.chatModel(this.gemini)
.build();
return aiCodeHelperService;
}
}
创建测试
创建 AiChatMemoryTest
类
并编写相关测试
@SpringBootTest
public class AiChatMemoryTest {
@Resource
private AiCodeHelperService aiCodeHelperService;
@Test
public void chatWithMemory() {
String output1 = aiCodeHelperService.chat("你好,我是鱼板鱼板");
System.out.println("AI output: " + output1);
String output2 = aiCodeHelperService.chat("还记得我是谁吗");
System.out.println("AI output: " + output2);
}
}
测试结果
可以观察到模型虽然有些傲娇,但还是观察到了模型的记忆功能。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/d244bec03f6d819d14f865cf6796492b_MD5.jpeg|Open: Pasted image 20250820111236.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/d244bec03f6d819d14f865cf6796492b_MD5.jpeg]]
在程序结束前设置断点。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/ecd96a80da31bf8eeddc5f40e271f08b_MD5.jpeg|Open: Pasted image 20250820111337.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/ecd96a80da31bf8eeddc5f40e271f08b_MD5.jpeg]]
可以观察到在 context 中确实存储了chatMemoryService, 并且有相关的记忆。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/69233fc8e64bd61327752644413d1a47_MD5.jpeg|Open: Pasted image 20250820110650.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/69233fc8e64bd61327752644413d1a47_MD5.jpeg]]
房间ID
可以为每一个对话生成一个MemoryID,来给用户分配一个独立的房间。
做到隔离。
结构化输出
将AI的输出转化为结构化数据格式,比如Java对象或者JSON。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/b970bfc1501703cd76813582ceb61481_MD5.jpeg|Open: Pasted image 20250820112416.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/b970bfc1501703cd76813582ceb61481_MD5.jpeg]]
利用 AIScheme 的话,需要AI服务商有这个支持,准确度是最高的。
使用Prompt期望结构化输出准确度是不高的。
创建结构化类
这里我们假设要AI生成一个学习报告
修改 AiCodeHelperService
类,新增以下内容
@SystemMessage("你是编程领域的小助手")
Report chatForReport(String userMessage);
// 新建一个类包含名字和建议列表
record Report(String name, ArrayList<String> suggestionList){}
编写测试
在 Test 文件夹下新建一个 AiChatStructedOutput
类。
@SpringBootTest
public class AiChatStructedOutput {
@Resource
AiCodeHelperService aiCodeHelperService;
@Test
public void chatForReport() {
String userMessage = "你好,我是程序员鱼板,请帮我生成一个学习报告";
AiCodeHelperService.Report report = aiCodeHelperService.chatForReport(userMessage);
System.out.println("Debug Me To Check");
}
}
运行结果
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/28437959979023b7795509520778c7b1_MD5.jpeg|Open: Pasted image 20250820141944.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/28437959979023b7795509520778c7b1_MD5.jpeg]]
效果
AI有时候不能生成有效的JSON,这个时候就要使用AI Scheme。
在编码层面约定一个JSON。
RAG
RAG(Retrieval-Augmented Generation)检索增强生成,是一种结合信息检索技术和内容生成的技术,能解决AI的知识戒断还有幻觉问题。
能让AI根据知识库中的文档来生成回答。
到20250820,Google AI Studio 的嵌入模型是 `gemini-embedding-001`
有免费的额度。
Bean设计
在 main
文件夹下新建一个 RAG
文件夹
新建一个 RagConfig
java类,使用 @Configuration
装饰将 内容选择器COntentRetriver 返回。
@Configuration
public class RagConfig {
private String APIKey = ConstAPIKey.APIKey;
private String modelName = "gemini-embedding-001";
// 嵌入模型(这里使用gemini-embedding-001)
private EmbeddingModel embeddingModel =
GoogleAiEmbeddingModel.builder()
.apiKey(this.APIKey)
.modelName(this.modelName)
.build();
// RAG(LangChain提供)
@Resource
private EmbeddingStore embeddingStore;
@Bean
public ContentRetriever contentRetriever() {
// 原始文档
List<Document> documents =
FileSystemDocumentLoader.loadDocuments("src/main/resources/documents/chatbot");
// 使用LangChain提供的切片类 最大1000个字符,重叠字符200
DocumentSplitter documentSplitter =
new DocumentByParagraphSplitter(1000, 200);
// 自定义注入器
EmbeddingStoreIngestor ingestor =
EmbeddingStoreIngestor.builder()
.documentSplitter(documentSplitter)
// 提高文本的质量 将文档的标题加入到内容前头
.textSegmentTransformer( textSegment -> {
return TextSegment.from(
textSegment.metadata().getString("file_name") + '\n' +
textSegment.text(), textSegment.metadata()
);
})
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build();
ingestor.ingest(documents);
EmbeddingStoreContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.maxResults(5)
.minScore(0.75)
.build();
return retriever;
}
}
扩展接口
修改 AiServiceFactory
类中的方法,指定使用 ContentRetriever
检索相关的内容。
// 拿取一个 contentRetriever
// 在RagConfig中已经注入过了
@Resource
private ContentRetriever contentRetriever;
@Bean
public AiCodeHelperService aiCodeHelperService() {
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
AiCodeHelperService aiCodeHelperService = AiServices.builder(AiCodeHelperService.class)
.chatMemory(chatMemory)
.chatModel(this.gemini)
// 指定ContentRetriever
.contentRetriever(this.contentRetriever)
.build();
return aiCodeHelperService;
}
编写测试
新增 AiChatWithRAG
测试类
@SpringBootTest
public class AiChatWithRAG {
@Resource
AiCodeHelperService aiCodeHelperService;
@Test
public void chatWithRag() {
String userMessage = "怎么部署koishi机器人?";
String answer1 = aiCodeHelperService.chat(userMessage);
System.out.println("AI output: " + answer1);
}
}
运行测试
可以看到文档被切片存放在了 embeddingStore
中提供给了大模型。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/fe1b8a12ba10e6bd8cef7f04824548a8_MD5.jpeg|Open: Pasted image 20250820165450.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/fe1b8a12ba10e6bd8cef7f04824548a8_MD5.jpeg]]
运行结果如下,可以看到AI根据特定的知识库生成了回答。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/c1222dfb4cd7e4fa31b50cb71289e673_MD5.jpeg|Open: Pasted image 20250820165700.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/c1222dfb4cd7e4fa31b50cb71289e673_MD5.jpeg]]
获取引用文档内容
获取更详细的结果。
扩展接口
在 AiCodeHelperService
接口下新增一个返回值为 Result<String>
的方法(LangChain4j service包下的类)
@SystemMessage("你是编程领域的小助手")
Result<String> chatForResult(String userMessage);
编写测试
在 AiChatWithRAG
添加新@Test测试
@Test
public void chatForResult() {
String userMessage = "怎么部署koishi机器人?";
Result<String> answer1 = aiCodeHelperService.chatForResult(userMessage);
System.out.println("AI output: " + answer1);
}
运行测试
在测试结束前打断点,查看变量信息。
可以看到消耗token和引用文档的信息。
[[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8d1a33c87f30a45e660035cbff6f2db9_MD5.jpeg|Open: Pasted image 20250820171510.png]]
![[学习笔记/人工智能/应用侧/LangChain4J/Zresources/AI编程小助手/8d1a33c87f30a45e660035cbff6f2db9_MD5.jpeg]]
什么是进阶?!更多的向量存储中间件
embeddingStore
有更多可持久化效率更高的其他中间件实现可以看官网给出的表格2
Comparison table of all supported Embedding Stores | LangChain4j