当前位置:首页 > AI > 正文内容

从零搭建 RAG 知识库:让 AI 记住你的私有数据

廖万里12小时前AI1

从零搭建 RAG 知识库:让 AI 记住你的私有数据

什么是 RAG?为什么需要它?

大语言模型很强大,但它有一个致命缺陷:记不住你的私有数据

你问它公司内部文档、个人笔记、专业领域知识,它要么一脸懵逼,要么一本正经地胡说八道。

RAG(Retrieval-Augmented Generation,检索增强生成)就是解决方案。简单说:先检索,再生成

核心流程:

1. 把你的文档切分成小块 2. 用 Embedding 模型转成向量存入向量数据库 3. 用户提问时,先检索相关内容 4. 把检索结果喂给大模型生成答案

环境准备

需要安装以下工具:

# 向量数据库(轻量级,适合入门)
pip install chromadb

# Embedding 模型 pip install sentence-transformers

# 大模型调用 pip install openai

硬件要求不高,普通笔记本就能跑。如果用本地 Embedding 模型,建议有 8GB 以上内存。

第一步:文档处理

先把你的文档切成小块。为什么?因为大模型上下文有限,一次性塞太多会超。

from langchain.text_splitter import RecursiveCharacterTextSplitter

def split_document(text, chunk_size=500, overlap=50): splitter = RecursiveCharacterTextSplitter( chunk_size=chunk_size, chunk_overlap=overlap, separators=["\n\n", "\n", "。", "!", "?", ";"] ) return splitter.split_text(text)

# 示例 with open("my_doc.txt", "r") as f: chunks = split_document(f.read()) print(f"切分成 {len(chunks)} 个片段")

chunk_size 是每个片段的最大字符数,overlap 是片段之间的重叠部分。重叠很重要,保证语义完整性。

第二步:向量化存储

把文本片段转成向量,存入向量数据库。

import chromadb
from chromadb.utils import embedding_functions

# 初始化向量数据库 client = chromadb.PersistentClient(path="./chromadb")

# 使用本地 Embedding 模型(中文友好) embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction( model_name="shibing624/text2vec-base-chinese" )

collection = client.get_or_create_collection( name="my_knowledge", embedding_function=embedding_fn )

# 批量添加文档 def add_documents(chunks, metadatas=None): ids = [f"doc_{i}" for i in range(len(chunks))] collection.add( documents=chunks, ids=ids, metadatas=metadatas )

add_documents(chunks) print("知识库构建完成!")

ChromaDB 是轻量级选择,生产环境可以用 Milvus、Pinecone、Weaviate 等专业方案。

第三步:检索增强生成

现在可以提问了。

from openai import OpenAI

client = OpenAI(base_url="你的API地址", api_key="your-key")

def rag_query(question, top_k=3): # 1. 检索相关内容 results = collection.query( query_texts=[question], n_results=top_k ) context = "\n\n".join(results["documents"][0]) # 2. 构建提示词 prompt = f"""基于以下知识回答问题。如果知识中没有相关信息,请诚实说明。

知识内容: {context}

问题:{question}

回答:""" # 3. 调用大模型生成 response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content

# 测试 answer = rag_query("我的文档里有什么重要内容?") print(answer)

关键优化技巧

1. 文档切分策略

不要无脑按字符切。更好的方式:

  • 按段落/章节切分:保持语义完整
  • 添加元数据:来源、标题、时间
  • 父子索引:小块检索,大块喂给模型

2. 混合检索

纯向量检索可能漏掉精确匹配。混合检索 = 向量检索 + 关键词检索。

# ChromaDB 支持全文搜索
collection = client.get_or_create_collection(
    name="hybrid_search",
    embedding_function=embedding_fn,
    metadata={"hnsw:space": "cosine"}
)

3. 重排序

检索结果不一定是最相关的,用重排序模型优化。

from sentence_transformers import CrossEncoder

reranker = CrossEncoder('BAAI/bge-reranker-base')

def rerank(query, docs, top_k=3): pairs = [[query, doc] for doc in docs] scores = reranker.predict(pairs) ranked = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True) return [doc for doc, score in ranked[:top_k]]

4. 提示词工程

让模型"知道"自己在回答什么:

你是专业的知识库助手。
请严格基于提供的知识回答,不要编造。
如果知识不足,明确告知用户需要补充哪些信息。
回答要结构化,使用列表和标题。

常见坑和解决方案

问题原因解决方案
回答不相关检索质量差优化 Embedding 模型,增加 top_k
编造事实模型幻觉强化提示词约束,降低 temperature
响应慢向量库太大分库分表,预计算缓存
中文效果差模型不匹配用中文 Embedding 模型

进阶方向

搭建完基础 RAG 后,可以探索:

  • GraphRAG:用知识图谱增强
  • 多模态 RAG:图片、表格也能检索
  • Agent + RAG:让 AI 主动调用知识库
  • 流式更新:实时同步新文档

总结

RAG 本质上是给大模型装了一个"外挂大脑"。

核心三步:切分 - 向量化 - 检索生成

入门用 ChromaDB + text2vec-base-chinese 就够了,性能和效果都还不错。生产环境再考虑 Milvus、Pinecone 等方案。

有问题欢迎留言讨论!

本文链接:https://www.kkkliao.cn/?id=683 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。