Langchain4j Rag 知识库教程
Rag 原理
RAG,Retrieval Augmented Generation,检索增强生成。通过检索外部知识库的方式增强大模型的生成能力。

基础大模型训练完成后,随着时间的推移,产生的新数据大模型是无法感知的;而且训练大模型的都是通用数据,有关专业领域的数据大模型也是不知道的。此时就需要外挂一个知识库。
其中,2.3 组织Prompt、3.1 发送Prompt、3.2 生成结果、3.3 返回响应、4 返回响应的流程由 Langchain4j 来完成。
向量知识库
向量数据库: Milvus、Chroma、Pinecone、RedisSearch(Redis)、pgvector(PostgreSQL) 向量是表示具有大小和方向的量。

向量余弦相似度,用于表示坐标系中两个点之间的距离远近
多维向量余弦相似度

向量知识库索引和检索
索引(存储)

向量存储步骤:
- 把最新或者专业的数据存储到文档(Document)中
- 文本分割器把一个大的文档切割成一个一个小的文本片段(Segments)
- 这些小的文本片段需要用一种专门擅长文本向量化的向量大模型转换成向量(Embeddings)
- 把文本片段对应的向量存储到向量数据库(Embedding Store)中

检索
检索阶段通常在线进行,当用户提交一个应该使用索引文档回答的问题时。
这个过程可能因使用的信息检索方法而异。 对于向量搜索,这通常涉及嵌入用户的查询(问题) 并在嵌入存储中执行相似度搜索。 然后将相关片段(原始文档的片段)注入到提示中并发送给 LLM。 
如果余弦相似度 > 0.5的数据会被检索出来,然后再把检索结果和用户输入发送给大模型,大模型响应后返回给用户。
Rag 快速入门
存储:构建向量数据库操作对象
引入依赖
xml
<!-- 提供向量数据库和向量模型 -->
<dependency>
<groupld>dev.langchain4j</groupld>
<artifactld>langchain4j-easy-rag</artifactld>
<version>1.0.1-beta6</version>
</dependency>
加载知识数据文档
java
List<Document> documents = ClassPathDocumentLoader.loadDocuments("文档路径");
构建向量数据库操作对象
java
InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();
把文档切割、向量化并存储到向量数据库中
java
EmbeddingStorelngestor ingestor = EmbeddingStorelngestor.builder()
.embeddingStore(store)
.build();
ingestor.ingest(documents);
检索:构建向量数据库检索对象
构建向量数据库检索对象
java
ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(store) // 指定向量数据库
.maxResults(3) // 最高、最多检索结果的数量
.minScore(0.6) // 最小余弦相似度
.build();
配置向量数据库检索对象
java
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
contentRetriever = "retriever"
)
Rag 核心 API

Document Loader 文档加载器
用于把磁盘或者网络中的数据加载进程序,常用的文档加载器:
- FileSystemDocumentLoader,根据本地磁盘绝对路径加载
- ClassPathDocumentLoader,相对于类路径加载
- UrlDocumentLoader,根据url路径加载
Document Parser 文档解析器
用于解析使用文档加载器加载进内存的内容,把非纯文本数据转化成纯文本,常用的文档解析器:
- TextDocumentParser,解析纯文本格式的文件
- ApachePdfBoxDocumentParser,解析pdf格式文件
- ApachePoiDocumentParser,解析微软的office文件,例如DoC、PPT、XLS
- ApacheTikaDocumentParser(默认),几乎可以解析所有格式的文件
Document Splitter 文档分割器
用于把一个大的文档,切割成一个一个的小片段,常用的文档分割器:
- DocumentByParagraphSplitter,按照段落分割文本
- DocumentByLineSplitter,按照行分割文本
- DocumentBySentenceSplitter,按照句子分割文本
- DocumentByWordSplitter,按照词分割文本
- DocumentByCharacterSplitter,按照固定数量的字符分割文本
- DocumentByRegexSplitter,按照正则表达式分割文本
- DocumentSplitters.recursive(...)(默认),递归分割器,优先段落分割, 再按照行分割,再按照句子分割,再按照词分割
Embedding Model 向量模型
用于把文档分割后的片段向量化或者查询时把用户输入的内容向量化
Langchain4j 内置的向量模型
内置的向量模型可能不是那么强大,需要在application.yml中配置第三方更强大的向量模型
配置完成后 Langchain4j 会根据配置信息向容器中注入一个向量模型对象,我们只需要把该向量模型对象设置给EmbeddingStoreIngestor和EmbeddingStoreContentRetriever即可。
java
EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.embeddingStore(store)
.documentSplitter(ds)
.embeddingModel(embeddingModel)
.build();
java
ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(store)
.embeddingModel(embeddingModel)
.minScore(0.5)
.maxResults(3)
.build();
EmbeddingStore 向量数据库操作对象
配置 RedisSearch 向量数据库
参考链接: