学习向量数据库与 RAG 架构

学习向量数据库与 RAG 架构

一、基础概念:向量与向量数据库

1. 什么是向量(Embedding)?

  • 定义:将文本、图像、音频等非结构化数据转换为高维数值数组(向量),捕捉数据的语义或特征。例如,“猫”和“狗”的向量距离比“猫”和“汽车”更近。
  • 核心作用:让计算机能“理解”数据的语义相似性,通过向量距离(如余弦相似度、欧氏距离)衡量数据相关性。
  • 生成工具:OpenAI的text-embedding-ada-002、开源模型BGESentence-BERT等,可通过API或本地部署生成向量。

2. 什么是向量数据库?

  • 定义:专门存储、索引和查询向量的数据库,解决传统数据库无法高效处理高维向量相似性检索的问题。
  • 核心能力
    • 高效存储海量向量(百万到数十亿级)。
    • 快速相似性查询(毫秒级返回结果)。
    • 支持动态增删数据和向量更新。
  • 主流向量数据库
    • 开源:Milvus(分布式,适合大规模)、Chroma(轻量,适合开发)、FAISS(Facebook开源,适合单机)、Qdrant(支持地理空间向量)。
    • 商业:Pinecone、Weaviate、Zilliz Cloud(Milvus商业化)。

二、RAG 架构:核心原理与流程

1. RAG 是什么?

  • 定义:检索增强生成(Retrieval-Augmented Generation),结合“检索外部知识”和“LLM生成”,解决LLM知识过时、幻觉(生成错误信息)、无法引用特定来源等问题。
  • 核心价值:让LLM基于最新/私有数据生成准确、可控的回答,广泛用于问答系统、客服、知识库等场景。

2. RAG 基本流程(核心步骤)

  • Step 1:数据准备与预处理

    • 来源:文档(PDF/Word)、网页、数据库、对话记录等。
    • 处理:拆分(Chunking,按段落/固定长度拆分,避免超出LLM上下文)、清洗(去噪、格式标准化)。
    • 技巧:拆分时保留上下文关联(如按章节拆分),设置合理Chunk大小(如200-500 tokens)。
  • Step 2:向量生成与存储

    • 用Embedding模型将每个Chunk转换为向量。
    • 将向量及原始文本(元数据,如来源、页码)存入向量数据库。
  • Step 3:检索(Retrieval)

    • 用户提问后,将问题转换为向量。
    • 向量数据库通过相似性查询,返回与问题最相关的Top N个Chunk(如Top 3-5)。
    • 优化:可结合关键词过滤、元数据筛选(如指定来源)提升精度。
  • Step 4:生成(Generation)

    • 将检索到的Chunk作为“上下文”,与用户问题一起传入LLM(如GPT-3.5/4、LLaMA)。
    • 提示词模板示例:
      基于以下上下文回答问题,只使用上下文信息,不编造内容:
      上下文:{检索到的Chunk1} {Chunk2} ...
      问题:{用户提问}
      回答:
      
    • LLM基于上下文生成准确回答,并可引用来源(如“根据文档3.2节...”)。

三、入门实践:搭建简易RAG系统

1. 工具选择(新手友好)

  • 向量数据库:Chroma(无需部署,Python库直接调用)。
  • Embedding模型:sentence-transformers(开源,如all-MiniLM-L6-v2)。
  • LLM:OpenAI API(GPT-3.5-turbo)或开源模型(如llama.cpp本地运行)。

2. 代码实战(核心步骤)

# 1. 安装依赖
!pip install chromadb sentence-transformers openai

# 2. 初始化Chroma向量数据库
import chromadb
client = chromadb.Client()
collection = client.create_collection(name="my_rag_db")  # 创建集合(类似表)

# 3. 准备数据并拆分(示例:3个文档Chunk)
documents = [
    "Python是一种解释型、面向对象的编程语言,由Guido van Rossum于1989年发明。",
    "Python的设计哲学强调代码可读性,使用缩进来定义代码块。",
    "Python广泛应用于数据分析、人工智能、Web开发等领域。"
]
ids = ["doc1", "doc2", "doc3"]  # 每个Chunk的唯一ID

# 4. 生成向量并入库
from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = embedding_model.encode(documents)  # 生成向量
collection.add(documents=documents, embeddings=embeddings, ids=ids)

# 5. 检索相关Chunk
query = "Python适合做什么?"
query_embedding = embedding_model.encode([query])  # 问题向量
results = collection.query(
    query_embeddings=query_embedding,
    n_results=2  # 返回Top 2相关结果
)
retrieved_docs = results["documents"][0]  # 获取检索到的文本

# 6. 调用LLM生成回答

import openai
openai.api_key = "YOUR_API_KEY"
prompt = f"基于以下信息回答:{retrieved_docs}\n问题:{query}"
response = openai.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)
# 输出示例:Python广泛应用于数据分析、人工智能、Web开发等领域。

四、进阶优化:提升RAG效果

1. 检索优化

  • Chunking策略
    • 动态拆分:根据语义(如用LangChain的RecursiveCharacterTextSplitter按标点拆分)。
    • 重叠拆分:相邻Chunk保留部分重叠(如50 tokens),避免上下文割裂。
  • 混合检索:结合向量检索(语义)和关键词检索(精确匹配),如Weaviate的hybrid模式。
  • Reranking(重排序):用模型(如cross-encoder)对初筛结果重新排序,提升相关性(如LangChain的Reranker)。

2. 向量数据库优化

  • 索引选择
    • 小规模数据:暴力搜索(Brute-force),精度100%但速度慢。
    • 大规模数据:近似索引(如Milvus的IVF_FLAT、HNSW),平衡速度与精度。
  • 参数调优:索引构建时调整参数(如HNSW的M值控制邻居数量,影响查询速度)。

3. 生成优化

  • 提示工程:明确要求LLM引用来源(如“回答中需注明信息来自哪个文档ID”)。
  • 多轮对话:在对话中保留历史检索结果,避免重复检索。
  • 知识冲突处理:当检索到矛盾信息时,提示LLM标注冲突并说明。

五、生产级部署:关键考量

  1. 数据管道自动化
    • 用Apache Airflow、Prefect定时同步新数据(如每日更新文档),自动拆分、生成向量并入库。
  2. 高可用与扩展性
    • 向量数据库集群化部署(如Milvus分布式集群),支持水平扩展。
    • 缓存热门查询结果(如用Redis),降低API调用成本。
  3. 监控与评估
    • 监控检索精度(如人工标注Top N结果相关性)、LLM回答准确率。
    • 用工具如LangSmith、RAGAs评估RAG系统性能。
  4. 隐私与安全
    • 敏感数据本地部署Embedding模型和LLM(如用LLaMA 2、通义千问本地化版本)。
    • 向量数据库加密存储(如Milvus的加密功能)。

六、深入与拓展

  1. 深入向量数据库原理

    • 学习高维向量索引算法(HNSW、IVF、PQ等)的数学原理。
    • 理解分布式向量数据库的分片、副本机制(如Milvus的DataNode、QueryNode架构)。
  2. RAG高级架构

    • 多模态RAG:支持图像、音频等数据(如用CLIP模型生成跨模态向量)。
    • 增量RAG:动态更新知识库,避免全量重新嵌入(如Chroma的upsert功能)。
    • 自主RAG:让LLM自主决定是否检索、如何调整查询(如AutoRAG框架)。
  3. 结合其他技术

    • 与知识图谱(KG)结合,提升检索逻辑推理能力(如RAG + KG架构)。
    • 结合Agent框架(如LangChain Agent),让系统自主规划检索步骤。

学习资源


本人自动发布于:https://github.com/giscafer/blog/issues/79