乐于分享
好东西不私藏

我给AI喂了50份文档,它变成了我的私人专家

我给AI喂了50份文档,它变成了我的私人专家

我给AI喂了50份文档,它变成了我的私人专家

前言:上一期我们用100行代码搭了个AI Agent。但Agent再聪明,脑子里没有你的数据也是白搭。这次,我给它装了个"外置大脑"——RAG,让AI拥有你的专属知识库,问什么都能答。

为什么你的AI总在"一本正经地胡说八道"?

我之前帮朋友做了个公司内部问答机器人,用的GPT-4,效果惨不忍睹。

员工问"我们公司年假政策是什么",AI答"根据劳动法,年假一般是5-15天"——听起来没毛病,但他们公司年假是20天起。AI不知道,因为它训练数据里根本没有这家公司的内部文档。

这就是大模型的知识盲区

问题类型
大模型表现
真实情况
公司内部制度
瞎编或泛泛而谈
每家公司都不一样
最新政策法规
知识截止到训练日期
政策可能上个月刚改
专业领域知识
知道大概但不够精准
需要引用具体文献
你的私人数据
完全不知道
日程、笔记、文档全是私有

RAG(检索增强生成)就是解决这个问题的。

一句话理解:RAG = 考试时允许翻书。 大模型是大脑,RAG是精准的书架——大脑再聪明,也需要书架上的书当依据,才能给出靠谱答案。


RAG到底怎么工作的?

核心流程就3步:存→找→答

第1步:存——把知识"切碎"放进向量数据库

你不能把整本100页的PDF直接扔给AI,一是塞不下,二是检索不准。得先"切碎"。

原始文档(100页PDF)     ↓ 文本分块(每块500字,重叠50字) 知识片段1(第1-2页内容摘要) 知识片段2(第2-3页内容摘要) 知识片段3(第3-4页内容摘要)     ...  知识片段N     ↓ 向量化(用Embedding模型转成数字向量) [0.12, -0.34, 0.56, ...] → 存入向量数据库 [0.08, -0.21, 0.43, ...] → 存入向量数据库 

为什么要"切碎"? 因为整篇文档太长,检索时大部分内容跟你的问题无关。切成小块后,只把相关的那几块找出来,精准又高效。

为什么要重叠50字? 防止刚好在切分点把一句话截成两半,上下文断了。

第2步:找——从知识库里"捞"出相关内容

用户问问题时,把问题也转成向量,然后去数据库里找最相似的片段。

用户问:"公司年假政策是什么?"     ↓ 向量化 问题向量 [0.15, -0.30, 0.52, ...]     ↓ 与数据库中所有片段向量计算相似度     ↓ 返回相似度最高的Top 4个片段 片段3: "员工年假政策:入职满1年享20天年假..." 片段7: "年假申请流程:提前3天在OA系统提交..." 片段12: "年假可结转至次年Q1,过期作废..." 片段45: "试用期员工按比例享受年假..." 

找的不是关键词匹配,而是语义相似。所以你问"休假规定"也能找到"年假政策",因为语义上它们是接近的。

第3步:答——让AI基于找到的内容回答

把找到的片段和用户问题一起发给大模型:

"根据以下参考资料回答用户问题。 如果资料中没有答案,就说不知道。  参考资料: [片段3] 员工年假政策:入职满1年享20天年假... [片段7] 年假申请流程:提前3天在OA系统提交... [片段12] 年假可结转至次年Q1,过期作废... [片段45] 试用期员工按比例享受年假...  用户问题:公司年假政策是什么?" 

AI回答:"根据公司政策,入职满1年享20天年假,需提前3天在OA系统申请。年假可结转至次年Q1,过期作废。试用期员工按比例享受。"

看,AI不再瞎编了,每个答案都有出处。


开干:从零搭一个RAG系统

装环境

pip install openai chromadb python-dotenv pypdf 

完整代码(不到80行)

import os import json from openai import OpenAI from dotenv import load_dotenv import chromadb  load_dotenv() client = OpenAI()  # ===== 第1步:文档加载与分块 =====  def load_and_chunk(file_path, chunk_size=500, overlap=50):     """读取文本文件并分块"""     with open(file_path, "r", encoding="utf-8") as f:         text = f.read()      chunks = []     start = 0     while start < len(text):         end = start + chunk_size         chunk = text[start:end]         chunks.append(chunk)         start = end - overlap  # 重叠部分     return chunks  # ===== 第2步:向量化与存储 =====  def get_embedding(text, model="text-embedding-3-small"):     """调用OpenAI Embedding API获取向量"""     resp = client.embeddings.create(input=text, model=model)     return resp.data[0].embedding  def build_vector_db(chunks, collection_name="my_knowledge"):     """把分块向量化并存入ChromaDB"""     db = chromadb.PersistentClient(path="./chroma_db")     collection = db.get_or_create_collection(collection_name)      for i, chunk in enumerate(chunks):         embedding = get_embedding(chunk)         collection.add(             ids=[f"chunk_{i}"],             embeddings=[embedding],             documents=[chunk],             metadatas=[{"source": "local_doc", "chunk_index": i}]         )      print(f"已存入 {len(chunks)} 个知识片段")     return collection  # ===== 第3步:检索 =====  def retrieve(collection, query, top_k=4):     """检索与问题最相关的知识片段"""     query_embedding = get_embedding(query)     results = collection.query(         query_embeddings=[query_embedding],         n_results=top_k     )     return results["documents"][0]  # ===== 第4步:生成回答 =====  def generate_answer(query, retrieved_chunks):     """让大模型基于检索到的内容回答"""     context = "\n\n---\n\n".join(retrieved_chunks)      prompt = f"""你是一个知识库问答助手。请根据以下参考资料回答问题。 如果参考资料中没有答案,请明确说"根据现有资料无法回答"。 回答时请引用资料来源。  参考资料: {context}  问题:{query}  回答:"""      resp = client.chat.completions.create(         model="gpt-4o-mini",         messages=[{"role": "user", "content": prompt}],         temperature=0.3,     )     return resp.choices[0].message.content  # ===== 完整RAG流程 =====  def rag_query(collection, question):     """一键RAG问答"""     print(f"\n问:{question}")      # 检索     chunks = retrieve(collection, question)     print(f"检索到 {len(chunks)} 个相关片段")      # 生成     answer = generate_answer(question, chunks)     print(f"答:{answer}")     return answer  # ===== 测试 =====  if __name__ == "__main__":     # 1. 加载文档并分块     chunks = load_and_chunk("公司制度.txt")      # 2. 建向量库     collection = build_vector_db(chunks)      # 3. 开始问答     rag_query(collection, "公司年假政策是什么?")     rag_query(collection, "出差报销流程是怎样的?")     rag_query(collection, "入职需要准备什么材料?") 

运行效果:

问:公司年假政策是什么? 检索到 4 个相关片段 答:根据公司制度文档,入职满1年享20天年假,满3年享25天。需提前3天在OA系统提交申请,年假可结转至次年Q1,过期作废。  问:出差报销流程是怎样的? 检索到 4 个相关片段 答:根据行政制度,出差归来后5个工作日内提交报销单,附发票原件。交通费按高铁二等座标准,住宿按城市级别限额报销。超过5000元需部门总监审批。  问:公司年会什么时候办? 检索到 4 个相关片段 答:根据现有资料无法回答。检索到的片段中未提及年会相关信息。 

注意最后一个问题——AI没有瞎编,而是诚实说"不知道"。这就是RAG的价值:减少幻觉,有据可查。


我实测踩了4个坑,你大概率也会遇到

坑1:分块太大,检索全是"废话"

一开始我把chunk_size设成2000,结果检索出来的片段又臭又长,AI在冗长文本里找不到重点,回答质量很差。

解法:chunk_size设500,overlap设50。这是我个人测下来最甜的参数。太小块语义不完整,太大块噪音多。

坑2:Embedding模型选错,中文检索效果差

用了OpenAI默认的ada-002模型,中文语义理解很弱。问"休假"找不到"年假",问"报销"找不到"费用"。

解法:中文文档优先用 text-embedding-3-small(效果比ada-002好很多),或者用国产模型如BGE-M3、M3E-Base,中文检索准确率能提升30%以上。

坑3:检索Top K太少,关键信息被漏掉

一开始设k=2,有些问题答案在第3或第4个相关片段里,导致回答不上来。

解法:k=4是性价比较高的设置。但超过6个片段后,上下文太长反而让AI分心,回答质量下降。如果需要更多内容,考虑用重排序(Reranker)先筛一轮再喂给AI。

坑4:PDF提取乱码,分块全乱了

直接用pypdf提取中文PDF,有时候段落顺序错乱、表格变成乱码,分块结果惨不忍睹。

解法:复杂PDF用PyMuPDF(fitz)提取,效果比pypdf好。如果文档有表格,先用OCR工具转成结构化文本再分块。记住:垃圾进,垃圾出。数据预处理决定了RAG的上限。


从Demo到生产级,还差什么?

维度
这个Demo
生产级需要
数据源
单个txt文件
PDF/Word/网页/数据库多源接入
分块策略
固定长度切分
语义分块+层次分块+表格特殊处理
检索方式
纯向量检索
向量+关键词混合检索(别小看BM25)
重排序
Cross-Encoder重排序,准确率再提20%
评估
肉眼看
RAGAS框架量化评估(准确率/召回率/忠实度)
更新
重新全量索引
增量更新+版本管理+失效检测
多轮对话
每次独立查询
上下文感知+对话历史+追问澄清

最值得优先做的两件事:一是混合检索(向量+关键词),二是重排序。这两个加上去,效果直接上一个台阶。


向量数据库怎么选?

实测对比了3个主流选项:

数据库
上手难度
性能
适用场景
ChromaDB
极简(pip装完就能跑)
够用
原型开发、个人项目、10万片段以内
FAISS
中等(需自己管理索引)
学术研究、大规模检索、本地部署
Milvus
较高(需Docker部署)
最强
企业级、亿级向量、高可用场景

我的建议:先用ChromaDB跑通流程,数据量大了再换Milvus。别一上来就纠结选型,先让东西跑起来。


我的真心话

RAG不是什么高深技术,核心逻辑就3步:切碎→找回→拼好。但它解决的是AI落地中最实际的问题——让AI用你的数据说话。

如果你正在做AI应用,不管是什么场景,客服机器人、文档问答、知识管理……RAG几乎都是必经之路。先花1小时把这个80行代码跑通,你会有种"原来不过如此"的感觉。然后你就会发现,真正难的不是RAG本身,而是数据清洗和检索优化——这才是拉开差距的地方。

完整代码+测试数据集,公众号回复「RAG80」获取。


你有没有尝试过搭建RAG?用的什么方案?评论区聊聊 👇


下期预告:AI Agent + RAG合体——让Agent既能动手干活,又能查资料回答问题,这才是完整的AI助手

💡 关注【AI搞事星球】

每周三篇AI实战干货,从Agent到多模态,陪你一起用AI搞大事 💪

点击上方蓝字关注,不错过下期实战案例 →

🔍 相关搜索:AI Agent · MCP协议 · Function Calling · AI工具实战 · 大模型

更多内容请在公众号对话框回复关键词获取资料