公司内部文档太多,新人找不到,老人记不住。用 RAG(检索增强生成)把文档变成问答机器人,是个很实用的落地方向。
RAG 是什么
简单说:用户提问 → 从文档库检索相关内容 → 把内容和问题一起给大模型 → 生成回答。核心是「先查再答」,避免模型胡编。
最小实现步骤
- 文档切分:按段落或固定长度切,每段 500~1000 字
- 向量化:用 embedding 模型把每段转成向量
- 存向量库:Chroma、Qdrant、Milvus 都行,小规模用 Chroma 够了
- 检索:用户问题也转向量,找最相似的 top k 段
- 生成:把检索到的段和问题拼成 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 不难搭,难的是把检索质量做上去。先跑通最小闭环,再逐步优化。

Comments 3 条评论
切分策略比模型还重要,认同
检索数量 k 取 3 到 5 我也这么设
文档太旧的话真的是垃圾进垃圾出