随着业务线的拓展,我手头积累了海量的技术文档、Docker 部署配置、长篇视频的英文字幕草稿以及复杂的 OpenCC 繁体转换规则。传统的文件夹搜索已经无法满足我跨文档的知识检索需求。
与其每次都去问 ChatGPT 那些通用的废话,不如让大模型”阅读”我自己的笔记。今天,我们利用 LangChain 框架和 RAG(检索增强生成)技术,构建一个完全懂你的”第二大脑”。
一、什么是 RAG? 简单来说,RAG 就是让大模型在回答你的问题之前,先去你的私人文档库里检索相关资料,然后把这些资料和你的问题一起喂给模型。这样模型给出的就不是”通用”的答案,而是基于你自己的知识库 的精准回复。
核心流程:
1 用户提问 → 向量检索相关文档片段 → 拼接成上下文 → 发送给 LLM → 生成答案
二、环境搭建:Ollama 本地大模型 对于个人使用,完全不需要调用付费 API。Ollama 让你在本地机器上运行大模型(如 Llama 3、Mistral、Qwen 等),并且完全离线、零成本。
1 2 3 4 5 6 7 8 9 ollama pull qwen2.5:7b ollama pull nomic-embed-text ollama serve
三、文档加载与向量化 使用 LangChain 加载你的 Markdown 文档并转为向量存储:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from langchain_community.document_loaders import DirectoryLoader, TextLoaderfrom langchain_text_splitters import RecursiveCharacterTextSplitterfrom langchain_community.vectorstores import Chromafrom langchain_community.embeddings import OllamaEmbeddingsloader = DirectoryLoader( "./my_docs/" , glob="**/*.md" , loader_cls=TextLoader ) documents = loader.load() text_splitter = RecursiveCharacterTextSplitter( chunk_size=500 , chunk_overlap=50 , separators=["\n\n" , "\n" , "。" , "!" , "?" , "," , " " , "" ] ) chunks = text_splitter.split_documents(documents) print (f"共切分为 {len (chunks)} 个文档片段" )embedding = OllamaEmbeddings(model="nomic-embed-text" ) vectorstore = Chroma.from_documents( documents=chunks, embedding=embedding, persist_directory="./chroma_db" ) vectorstore.persist()
四、构建检索链 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 from langchain_community.llms import Ollamafrom langchain.chains import RetrievalQAfrom langchain.prompts import PromptTemplatellm = Ollama(model="qwen2.5:7b" , temperature=0.1 ) prompt_template = """你是一个专业的技术助手。请仅根据以下参考文档回答问题。 如果文档中没有相关信息,请诚实地说"文档中没有找到相关信息", 不要编造任何内容。 参考文档: {context} 问题:{question} 回答:""" PROMPT = PromptTemplate( template=prompt_template, input_variables=["context" , "question" ] ) qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff" , retriever=vectorstore.as_retriever(search_kwargs={"k" : 4 }), chain_type_kwargs={"prompt" : PROMPT} ) answer = qa_chain.run("我在 Docker 部署中遇到了什么坑?如何解决的?" ) print (answer)
五、检索优化:提高命中率 默认的向量检索有时会遗漏关键信息。几个优化策略:
1. 增加检索数量 :将 k 从默认的 4 改为 6-8,给模型更多上下文。
2. 使用 MMR(最大边际相关性) :
1 2 3 4 retriever = vectorstore.as_retriever( search_type="mmr" , search_kwargs={"k" : 6 , "fetch_k" : 20 } )
MMR 不仅考虑相关性,还考虑结果的多样性,避免返回 4 条几乎一样的片段。
3. 混合检索(关键词 + 向量) : 纯向量检索对精确匹配(如命令、文件名)支持不佳。可以在检索结果中加入基于 BM25 的关键词检索结果,两者取并集后重排序。
六、生产环境优化 对于个人长期使用的知识库:
增量更新 :文档变化时,不要重新向量化全部,只更新变化的文档
元数据过滤 :在存入向量库时附带元数据(日期、分类),检索时可预过滤
定期重建 :随着文档增多,索引质量会下降,建议每月全量重建一次
总结 RAG 不是遥不可及的企业级技术。用 Ollama + LangChain + ChromaDB,一个下午就能搭建起完全属于你自己的知识库。从此以后,你的技术笔记不再是躺平的 Markdown 文件,而是一个能与你对话的”第二大脑”。