如何在不使用框架的情况下用 10 行 Python 代码构建 RAG 系统
利用这个10行Python代码教程解锁RAG(检索增强生成)的力量。深入了解信息检索,构建您自己的文档系统,并利用LLM获得强大的响应 - 无需依赖复杂的框架。优化您的内容以提高SEO和参与度。
2025年2月24日

探索如何在仅 10 行 Python 代码中从头构建强大的检索增强型生成 (RAG) 系统,无需依赖任何外部框架。这种简洁而全面的方法为您提供了对核心组件的深入理解,使您能够为基于文档的应用程序创建强大且可定制的 AI 驱动解决方案。
理解检索增强型生成(RAG)的概念
理解检索增强型生成(RAG)的概念
检索增强生成(RAG)是一种用于从自己的文档中检索信息的技术。它涉及两个步骤:
-
知识库创建: 将文档划分为较小的子文档,并计算每个块的嵌入。这些嵌入和原始块通常存储在向量存储中。
-
检索和生成: 当有新的用户查询时,会计算查询的嵌入。通过比较查询嵌入和存储的块嵌入来检索最相关的块。然后将检索到的块附加到原始查询上,并输入到语言模型(LLM)中生成最终响应。
这种设置被称为"检索增强生成"管道,因为LLM的生成是通过从知识库中检索到的相关信息进行增强的。
虽然有像Langchain和LlamaIndex这样的框架可以简化RAG管道的实现,但核心组件可以仅使用Python、嵌入模型和LLM来构建。这种方法可以更好地理解底层概念,并允许更灵活地定制管道。
学习将文档分块为段落
学习将文档分块为段落
在构建检索增强生成(RAG)系统时,一个关键步骤是将输入文档划分为更小、更易管理的片段。在这个例子中,我们将输入文档(一篇维基百科文章)划分为段落。
这种方法的理由是,段落通常代表可以有效检索和用于增强用户查询的信息单元。通过以这种方式分解文档,我们可以更好地识别要包含在最终响应中的最相关部分。
这一步的代码如下:
# 将文档划分为段落
chunks = [paragraph.strip() for paragraph in text.split('\n') if paragraph.strip()]
这里,我们使用一种简单的方法,将输入文本按换行符分割来提取单个段落。然后我们去除每个段落开头和结尾的空白字符,以确保干净的表示。
结果chunks
列表包含单个段落,这些段落可以被嵌入并存储在向量存储中。这使我们能够有效地根据用户的查询检索最相关的段落,并将它们包含在语言模型生成的最终响应中。
使用句子变换器嵌入文档和用户查询
使用句子变换器嵌入文档和用户查询
为了嵌入文档块和用户查询,我们将使用Sentence Transformers库。这个库提供了预训练的模型,可以为文本生成高质量的嵌入。
首先,我们加载嵌入模型:
from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer('all-mpnet-base-v2')
接下来,我们计算文档块的嵌入:
chunk_embeddings = embedding_model.encode(chunks, normalize_embeddings=True)
这里,chunks
是文档中的文本块列表。normalize_embeddings=True
选项确保嵌入被归一化,这对于后续的相似性计算很重要。
要获得用户查询的嵌入,我们只需运行:
query_embedding = embedding_model.encode([user_query], normalize_embeddings=True)[0]
现在,我们有了文档块和用户查询的嵌入,可以用于检索步骤。
基于余弦相似度检索相关块
基于余弦相似度检索相关块
要根据用户查询检索最相关的块,我们首先需要计算查询嵌入和文档块嵌入之间的余弦相似度。以下是我们可以做的:
- 使用与文档块相同的嵌入模型计算用户查询的嵌入。
- 计算查询嵌入与每个文档块嵌入之间的点积。这给我们提供了余弦相似度分数。
- 根据余弦相似度分数对文档块进行排序,并选择前K个最相关的块。
- 检索选定块的文本内容,作为语言模型的上下文。
关键步骤如下:
- 计算查询嵌入
- 计算余弦相似度分数
- 排序并选择前K个块
- 检索块文本内容
这种简单的方法使我们能够有效地从文档集合中检索最相关的信息,以增强用户的查询,然后将其传递给语言模型进行生成。
使用OpenAI GPT-4增强用户查询并生成响应
使用OpenAI GPT-4增强用户查询并生成响应
要使用检索到的块和用户查询生成响应,我们首先创建一个包含相关块和用户查询的提示。然后我们使用OpenAI GPT-4模型根据这个提示生成响应。
这里是代码:
# 获取用户查询
user_query = "What is the capital of France?"
# 根据用户查询检索最相关的块
top_chunk_ids = [6, 8, 5]
top_chunks = [chunks[i] for i in top_chunk_ids]
# 创建提示
prompt = "Use the following context to answer the question at the end. If you don't know the answer, say that you don't know and do not try to make up an answer.\n\nContext:\n"
for chunk in top_chunks:
prompt += chunk + "\n\n"
prompt += f"\nQuestion: {user_query}"
# 使用OpenAI GPT-4生成响应
response = openai_client.chat.create(
model="gpt-4",
messages=[
{"role": "user", "content": prompt}
],
max_tokens=1024,
n=1,
stop=None,
temperature=0.7,
).choices[0].message.content
print(response)
在这段代码中,我们首先根据用户查询检索最相关的三个块。然后我们创建一个包含这些块和用户查询的提示。最后,我们使用OpenAI GPT-4模型根据这个提示生成响应。
生成的响应将是一个简洁、相关的答复,利用了检索到的块中的信息。
结论
结论
在本教程中,我们学习了如何使用仅10行Python代码构建一个带有文档检索系统的完整聊天系统。我们介绍了检索增强生成(RAG)管道的关键组件,包括知识库创建、文档分块、嵌入、检索和使用大型语言模型进行生成。
关键要点如下:
- 您可以在不使用Langchain或LlamaIndex等复杂框架的情况下实现基本的RAG管道。纯Python和几个库就足够了。
- 根据结构(如段落)对文档进行分块是一种简单而有效的策略,适用于大多数用例。
- 嵌入文档块和用户查询,然后计算相似度分数,可以让您检索最相关的信息来增强用户的查询。
- 将检索到的块与用户的查询集成,并输入到大型语言模型中,可以生成相关和有信息的响应。
虽然这个例子提供了一个坚实的基础,但还有很多机会来构建更强大和更高级的RAG系统。像Langchain和LlamaIndex这样的框架在与各种向量存储和语言模型集成时可能会有帮助。但是,从一个纯Python实现开始可以帮助您更好地理解RAG管道的核心概念和组件。
如果您对探索更高级的RAG技术感兴趣,我建议您查看我的课程"RAG Beyond Basics
它深入探讨了构建复杂、面向生产的RAG系统。
FAQ
FAQ