RAG 入门:把公司文档喂给大模型

Cold 发布于 2025-05-27 66 次阅读 527 字 预计阅读时间: 2 分钟 AI


公司内部文档太多,新人找不到,老人记不住。用 RAG(检索增强生成)把文档变成问答机器人,是个很实用的落地方向。

RAG 是什么

简单说:用户提问 → 从文档库检索相关内容 → 把内容和问题一起给大模型 → 生成回答。核心是「先查再答」,避免模型胡编。

最小实现步骤

  1. 文档切分:按段落或固定长度切,每段 500~1000 字
  2. 向量化:用 embedding 模型把每段转成向量
  3. 存向量库:Chroma、Qdrant、Milvus 都行,小规模用 Chroma 够了
  4. 检索:用户问题也转向量,找最相似的 top k 段
  5. 生成:把检索到的段和问题拼成 prompt,调 LLM

用 Python 快速搭一个

from langchain_community.document_loaders import DirectoryLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.llms import Ollama

# 加载文档
loader = DirectoryLoader('./docs', glob='**/*.md')
docs = loader.load()

# 切分
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100)
chunks = splitter.split_documents(docs)

# 向量化存储
embeddings = OllamaEmbeddings(model='nomic-embed-text')
db = Chroma.from_documents(chunks, embeddings, persist_directory='./chroma')

# 检索 + 生成
retriever = db.as_retriever(search_kwargs={'k': 4})
llm = Ollama(model='qwen2.5:7b')

def ask(q):
    docs = retriever.invoke(q)
    context = '\n\n'.join(d.page_content for d in docs)
    prompt = f'根据以下资料回答问题,不知道就说不知道。\n\n资料:\n{context}\n\n问题:{q}'
    return llm.invoke(prompt)

效果好坏的关键

  • 切分策略:按语义切比按字数切好,Markdown 按标题切
  • embedding 模型:中文用 bge-m3 或 nomic-embed-text
  • 检索数量:k 太小漏信息,太大噪音多,3~5 常见
  • prompt 约束:明确要求「只根据资料回答」
  • 文档质量:垃圾进垃圾出,过期文档先清理

进阶方向

  • 混合检索:向量 + 关键词(BM25)
  • 重排序:用 rerank 模型对召回结果二次排序
  • 多轮对话:带上历史上下文
  • 权限控制:不同人只能检索到有权限的文档

RAG 不难搭,难的是把检索质量做上去。先跑通最小闭环,再逐步优化。

和喜欢的一切在一起~
最后更新于 2025-05-27