公司动态
基于Ollama和LangChain的RAG智能问答系统搭建指南
1. 项目概述当大语言模型遇上外部知识库去年第一次在本地部署大语言模型时最大的痛点就是模型对专业领域知识的信口开河。直到尝试了RAG检索增强生成架构才真正让7B参数的小模型展现出了超越其体量的专业能力。今天要分享的正是如何用OllamaLangChain搭建一个能消化企业文档、技术手册甚至个人笔记的智能问答系统。这个方案最吸引人的地方在于不需要微调模型就能获得领域知识处理能力。通过将PDF/Word等文档转化为向量数据库当用户提问时系统会先检索相关知识片段再将片段和问题一起喂给大模型生成回答。实测在医疗咨询场景中采用RAG架构的Mistral-7B模型准确率比裸模型提高了63%。2. 核心组件选型与原理2.1 Ollama本地模型的瑞士军刀选择Ollama而非直接使用transformers库的原因很实际内置模型量化功能支持GGUF格式统一的REST API接口内存管理更友好自动卸载闲置模型安装时建议使用国内镜像源加速curl -fsSL https://ollama.mirror.xyz/install.sh | sh2.2 LangChain知识处理的流水线LangChain的核心价值在于提供了标准化组件Document Loaders支持PDF/Markdown/HTML等格式Text Splitters按语义切分文档推荐用RecursiveCharacterTextSplitterEmbedding Models选用bge-small-zh-v1.5中文向量模型Vector StoresChromaDB的单机版足够应付10万级文档2.3 RAG架构的工作流程文档预处理PDF→文本→语义分块→向量化查询处理问题向量化→向量数据库相似度检索答案生成将检索结果作为上下文注入prompt3. 实战搭建步骤3.1 环境准备# 最小化依赖 pip install ollama langchain chromadb sentence-transformers pypdf3.2 文档处理流水线from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter loader PyPDFLoader(医疗手册.pdf) text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , ] ) docs text_splitter.split_documents(loader.load())3.3 构建向量数据库from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma embedding HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, encode_kwargs{normalize_embeddings: True} ) vector_db Chroma.from_documents(docs, embedding, persist_directory./med_db)3.4 实现问答链from langchain.chains import RetrievalQA from langchain.llms import Ollama llm Ollama(modelmistral:7b-instruct) qa_chain RetrievalQA.from_chain_type( llm, retrievervector_db.as_retriever(search_kwargs{k: 3}), chain_typestuff ) response qa_chain.run(糖尿病患者应该怎么控制饮食)4. 性能优化技巧4.1 分块策略优化技术文档按章节标题分块用MarkdownHeaderTextSplitter会议纪要按发言者分块研究论文摘要/方法/结果分别处理4.2 混合检索方案结合关键词搜索与向量搜索from langchain.retrievers import BM25Retriever, EnsembleRetriever bm25_retriever BM25Retriever.from_documents(docs) ensemble_retriever EnsembleRetriever( retrievers[vector_db.as_retriever(), bm25_retriever], weights[0.7, 0.3] )4.3 缓存策略对高频问题答案进行内存缓存使用SQLite缓存embedding计算结果5. 常见问题排查5.1 知识检索失效症状返回无关内容 解决方案检查分块大小是否合适建议300-800字符尝试不同embedding模型如m3e-base添加query改写步骤5.2 回答质量低下症状回答偏离检索内容 优化方法from langchain.prompts import PromptTemplate custom_prompt PromptTemplate( template请严格根据以下上下文回答\n{context}\n问题{question}, input_variables[context, question] )5.3 处理长文档技巧对于超过100页的文档先提取目录结构作为元数据二级分块时保留层级关系检索时加入章节权重6. 进阶扩展方向现在这个基础系统可以进一步升级为多模态知识库处理图片/表格自动更新机制监控文档变更对话历史感知用LangGraph管理会话状态实测在16GB内存的MacBook Pro上这个系统能流畅处理200份医学论文的问答。最惊喜的是当我把自己的Obsidian笔记库接进去后模型竟然能准确引用三年前写的技术思考片段——这才是真正的第二大脑。