向量数据库与RAG技术实战:从文本处理到模型问答
立即解锁
发布时间: 2025-09-01 00:59:12 阅读量: 4 订阅数: 12 AIGC 

### 向量数据库与RAG技术实战:从文本处理到模型问答
在人工智能的应用场景中,如何高效地处理文本数据、进行信息检索以及利用检索结果辅助模型回答问题是非常关键的技术。本文将详细介绍向量数据库的相关操作,包括文本分割、向量存储与检索,以及如何运用RAG(检索增强生成)技术结合LangChain框架实现基于上下文的问答系统。
#### 1. 文本相似度计算与文本嵌入策略
在处理文本数据时,我们常常需要计算词语之间的相似度。例如,我们可以找出与“cake”最相似的前六个词语的索引,然后从中提取出除“cake”之外相似度最高的前五个词语。同时,还可以计算“cake”与“lie”、“sing”等词语的TF - IDF向量之间的余弦相似度,并取平均值来衡量它们的相似程度。
在文本嵌入方面,嵌入策略非常重要。如果嵌入一个大的文本块,如整本书,得到的向量将是构成该文本的所有标记位置的平均值。随着文本块大小的增加,向量会趋近于所有向量的平均值,从而丢失大量语义信息。相反,较小的文本块在向量空间中的位置更具体,在需要高精度相似度时可能更有用。但如果文本块过小,可能会因为句子或段落被截断而失去意义。因此,处理向量数据库的关键之一在于如何加载文档并将其分割成合适的块。
#### 2. 文档加载与文本分割
在AI应用中,根据用户查询的文本相似度在文档中进行搜索是一个常见的用例。例如,对于员工手册的PDF文档,我们希望根据员工的问题返回相关的文本片段。文档加载到向量数据库的方式取决于文档的结构、每次查询希望返回的示例数量以及每个提示允许的令牌数量。
以gpt - 4 - 0613为例,它有8192个令牌的限制,需要在提示模板、插入提示的示例以及模型的回复之间分配。假设为提示和回复预留约2000个单词(约3000个令牌),我们可以将五个最相似的、每个包含1000个令牌的文本块作为上下文插入提示中。然而,如果简单地将文档分割成1000个令牌的块,可能会在段落或句子中间进行分割,从而丢失语义。
LangChain提供了一系列文本分割器,其中常用的是递归字符文本分割器。它会尝试先按换行符分割,然后按空格分割,直到文本块足够小,这样可以尽可能保持段落、句子和单词的完整性,保留文本结构中固有的语义分组。以下是使用递归字符文本分割器的示例代码:
```python
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=100, # 100 tokens
chunk_overlap=20, # 20 tokens of overlap
)
text = """
Welcome to the "Unicorn Enterprises: Where Magic Happens"
Employee Handbook! We're thrilled to have you join our team
of dreamers, doers, and unicorn enthusiasts. At Unicorn
Enterprises, we believe that work should be as enchanting as
it is productive. This handbook is your ticket to the
magical world of our company, where we'll outline the
principles, policies, and practices that guide us on this
extraordinary journey. So, fasten your seatbelts and get
ready to embark on an adventure like no other!
...
As we conclude this handbook, remember that at Unicorn
Enterprises, the pursuit of excellence is a never-ending
quest. Our company's success depends on your passion,
creativity, and commitment to making the impossible
possible. We encourage you to always embrace the magic
within and outside of work, and to share your ideas and
innovations to keep our enchanted journey going. Thank you
for being a part of our mystical family, and together, we'll
continue to create a world where magic and business thrive
hand in hand!
"""
chunks = text_splitter.split_text(text=text)
print(chunks[0:3])
```
这段代码的具体步骤如下:
1. **创建文本分割器实例**:使用`from_tiktoken_encoder`方法创建`RecursiveCharacterTextSplitter`的实例。`chunk_size`参数设置为100,确保每个文本块大约包含100个令牌;`chunk_overlap`参数设置为20,表示相邻文本块之间有20个令牌的重叠,以保证上下文不丢失。
2. **准备文本**:将需要分割的文本存储在变量`text`中。
3. **分割文本**:调用`text_splitter`的`split_text`方法,根据之前定义的`chunk_size`和`chunk_overlap`将文本分割成块,返回一个文本块列表。
4. **输出分割结果**:打印分割后的前三个文本块,以验证文本是否按预期分割。
文本块的相关性很大程度上取决于分割策略。没有重叠的较短文本块可能不包含正确答案,而重叠过多的较长文本块可能会返回过多不相关的结果,使大语言模型(LLM)困惑或消耗过多的令牌。
#### 3. 使用FAISS进行内存检索
将文档处理成块后,需要
0
0
复制全文
相关推荐









