1.向量数据库
关系型数据库MySQL,内存分布型数据库Redis,向量数据库
Vector是向量或矢量的意思,一个是数学概念,另一个是物理的概念。
Embedding Model:向量化模型,前面章节使用了ChatModel和StreamChatModel。
概念:Embedding Model的工作原理是将文本、图像、和视频转换为向量的浮点数数组。这些向量旨在捕捉文本、图像和视频的含义。嵌入数组的长度称为向量的维度(Dimensionality)。
指征特点:捕捉复杂的词汇关系(如语义相似性、同义词、多义词)
超越传统词袋模型的简单计数方式。
动态嵌入模型(如BERT)可根据上下文生成不同的词向量。
向量嵌入为现代搜索和检索增强升成(RAG)应用程序提供支持。
向量存储(Vector Store):向量存储是一种用于存储和检索高维向量数据的数据库或存储解决方案,它特别适用于处理那些经过嵌入模型转化后的数据。在VectorStore中,查询与传统关系数据库不同。它们执行相似性搜索,而不是精确匹配。当给定一个向量作为查询时,VectorStore返回与查询向量相似的向量。
本次使用Qdrant向量数据库和PostgreSQL,同时也可以存入内存中。
引入Qdrant依赖:
html
<!--qdrant-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
</dependency>
专业的事情交给专业的模型,这次我们将大模型换成相应的向量存储大模型
修改LLMConfig的内容
java
@Configuration
public class LLMConfig
{
@Bean
public EmbeddingModel embeddingModel()
{
return OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("aliQwen-api"))
.modelName("text-embedding-v3")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
/**
* 创建Qdrant客户端
* @return
*/
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient.Builder grpcClientBuilder =
QdrantGrpcClient.newBuilder("127.0.0.1", 6334, false);
return new QdrantClient(grpcClientBuilder.build());
}
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return QdrantEmbeddingStore.builder()
.host("127.0.0.1")
.port(6334)
.collectionName("test-qdrant")
.build();
}
}
Payload意思是主体。
与MySQL查询相似,但是向量数据库是相似度不是相等。
每个向量都有X,Y,Z轴。
2.检索增强生成RAG(Retrival-Augmented Generation)
LLM到模型的知识仅限于它所接受的训练数据。如果你想让一个LLM了解特定领域的知识或专有数据。简单来说,RAG是一种从你的数据中查找相关信息,并在将提示发送给LLM之前将其注入到提示中的方法。这样一来,LLM就能获得(希望是)相关的信息,并基于这些信息进行回答,从而降低产生幻觉的概率。就想给AI大模型装上了实时百科大脑,为了让大模型获取足够的上下文,以便获得更加广泛的信息源,通过先查资料后回答的机制,让AI摆脱传统模型的知识遗忘和幻觉回复困境。就像是考试时的小抄。幻觉就是,已读乱回,已读不回,答非所问。
通过引入外部知识源来增强LLM的输出能力,传统的LLM通常基于其训练数据生成响应,**但这些数据可能过时或不够全面。**RAG允许模型在生成答案之前,从特定的知识库中检索相关信息,从而提供更准确和上下文相关的回答。
这个小抄就存入了向量数据库中,用户可以将自定义文档上传给LLM大模型。
RAG流程分为两个不同的阶段:索引和检索。
索引阶段:这个小抄就存入了向量数据库中,用户可以将自定义文档上传给LLM大模型。
检索阶段:通常在线进行,此时用户提交的问题应使用索引文档来回答。
主要内容:
1.Embedding StoreIngestor组织结构分析
2.Document Loader(文档加载器) ,加载我们提供的"小抄"
3.Document Parser(文档解析器)
4.Document Transformer(文档转换器)
5.Document Splitter(文档拆分器) ,按什么格式拆分。
使用LangChain加载RAG:
|----------|----------------------------------------|
| 1.加载文档 | 使用适当的DocumentLoader和DocumentParser加载文档 |
| 2.转换文档 | 使用DocumentTransformer清理或增强文档(可选) |
| 3.拆分文档 | 使用DocumentSplitter将文档拆分为更小的片段(可选) |
| 4.嵌入文档 | 使用EmbeddingModel将文档片段转换为嵌入向量 |
| 5.存储嵌入 | 使用EmbeddingStoreIngestor存储嵌入向量。 |
| 6.检索相关内容 | 根据用户查询,从EmbeddingStore检索最相关的文档片段 |
| 7.生成响应 | 将检索到的相关内容与用户查询一起提供给语言模型,生成最终响应。 |
引入RAG依赖:
html
<!--easy-rag-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
</dependency>
修改LLMConfig配置大模型类:
java
@Configuration
public class LLMConfig
{
@Bean
public ChatModel chatModel()
{
return OpenAiChatModel.builder()
.apiKey(System.getenv("aliQwen-api"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
/**
* 需要预处理文档并将其存储在专门的嵌入存储(也称为矢量数据库)中。当用户提出问题时,这对于快速找到相关信息是必要的。
* 我们可以使用我们支持的 15 多个嵌入存储中的任何一个,但为了简单起见,我们将使用内存中的嵌入存储:
*/
@Bean
public InMemoryEmbeddingStore<TextSegment> embeddingStore() {
return new InMemoryEmbeddingStore<>();
}
@Bean
public ChatAssistant assistant(ChatModel chatModel, EmbeddingStore<TextSegment> embeddingStore)
{
return AiServices.builder(ChatAssistant.class)
.chatModel(chatModel)
.chatMemory(MessageWindowChatMemory.withMaxMessages(50))
.contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore))
.build();
}
}
接口:
java
public interface ChatAssistant {
String chat(String message);
}
还有高阶RAG等。