
这次我们来看一个 RAG 实战项目重点不是讲概念而是直接动手搭建一个从检索到生成的完整流程。如果你关心本地部署、显存占用、接口调用和批量任务处理这篇文章可以直接收藏备用。RAGRetrieval-Augmented Generation技术现在在企业知识库、智能问答系统中应用越来越广泛但很多教程只讲理论缺少可落地的实操指南。本文基于RAG实战第4课从 Retrieval 到 Generation主题将带你完成从向量数据库搭建、嵌入模型选择到生成式问答的完整链路验证。最核心的特点是支持 CPU/GPU 混合部署显存要求灵活提供完整的 API 接口适合本地测试和小型项目部署。我们将使用 Chroma 作为向量数据库BGE 嵌入模型配合开源大模型完成检索增强生成的全流程。1. 核心能力速览能力项说明技术栈Chroma BGE嵌入模型 开源LLM显存需求嵌入模型约1-2GBLLM根据模型大小调整启动方式命令行启动 WebUI/API服务主要功能文档检索、语义搜索、问答生成支持平台Windows/Linux/macOS接口能力RESTful API支持批量处理适合场景企业知识库、智能客服、文档问答2. 适用场景与使用边界这个 RAG 系统最适合需要处理大量文档资料的场景。比如企业内部的规章制度查询、技术文档检索、客服知识库问答等。通过将文档向量化存储可以实现基于语义的智能检索而不是简单关键词匹配。但需要注意几个边界首先涉及敏感数据的文档需要做好权限控制其次专业领域知识需要针对性训练嵌入模型最后生成内容可能存在幻觉重要决策需要人工复核。对于中小型知识库文档量在万级以内这个方案可以在单机部署成本可控。如果文档量达到百万级需要考虑分布式向量数据库方案。3. 环境准备与前置条件开始前需要准备以下环境操作系统要求Windows 10/11 或 Linux Ubuntu 18.04macOS 10.15 也可运行Python环境# 推荐使用Python 3.8-3.10 python --version # 应显示 Python 3.8.x 或更高版本依赖包管理# 创建虚拟环境推荐 python -m venv rag_env source rag_env/bin/activate # Linux/macOS rag_env\Scripts\activate # Windows # 安装核心依赖 pip install chromadb sentence-transformers flask硬件要求最低配置8GB内存支持CPU推理推荐配置16GB内存GPU显存≥4GB磁盘空间至少5GB可用空间含模型文件4. 安装部署与启动方式4.1 Chroma向量数据库安装Chroma是轻量级向量数据库支持本地部署# 安装ChromaDB pip install chromadb # 验证安装 python -c import chromadb; print(Chroma安装成功)4.2 嵌入模型选择与下载我们选用BAAI/bge-small-zh-v1.5中文嵌入模型from sentence_transformers import SentenceTransformer # 下载嵌入模型首次运行会自动下载 model SentenceTransformer(BAAI/bge-small-zh-v1.5) print(嵌入模型加载完成)4.3 大模型集成根据硬件条件选择合适的大模型# 方案1使用Ollama本地部署推荐 # 安装Ollama后部署千问模型 # ollama pull qwen2:7b # 方案2使用API接口适合低配置设备 # 如OpenAI API、智谱AI等5. 功能测试与效果验证5.1 文档入库测试首先测试文档向量化存储功能import chromadb from sentence_transformers import SentenceTransformer # 初始化Chroma客户端 client chromadb.Client() collection client.create_collection(knowledge_base) # 加载嵌入模型 embedder SentenceTransformer(BAAI/bge-small-zh-v1.5) # 准备测试文档 documents [ RAG技术结合检索和生成两大模块, 向量数据库用于存储文档的嵌入表示, 嵌入模型将文本转换为数值向量, 大语言模型负责根据检索结果生成答案 ] # 生成嵌入并入库 embeddings embedder.encode(documents).tolist() collection.add( embeddingsembeddings, documentsdocuments, ids[fdoc_{i} for i in range(len(documents))] ) print(文档入库完成共处理, len(documents), 个文档)5.2 检索功能验证测试语义检索效果# 测试查询 query 什么是向量数据库 query_embedding embedder.encode([query]).tolist() # 执行检索 results collection.query( query_embeddingsquery_embedding, n_results2 ) print(检索结果) for i, doc in enumerate(results[documents][0]): print(f{i1}. {doc})5.3 生成式问答测试集成大模型完成问答生成def rag_generation(query, retrieved_docs, llm_client): RAG生成函数 context \n.join(retrieved_docs) prompt f基于以下上下文信息回答问题。 上下文 {context} 问题{query} 请根据上下文提供准确的答案如果上下文信息不足请说明。 # 调用大模型生成答案 response llm_client.generate(prompt) return response # 测试完整RAG流程 query RAG技术包含哪些组件 retrieved_docs results[documents][0] # 使用上一步的检索结果 answer rag_generation(query, retrieved_docs, llm_client) print(生成答案, answer)6. 接口 API 与批量任务6.1 Web服务搭建使用Flask搭建RAG API服务from flask import Flask, request, jsonify import chromadb from sentence_transformers import SentenceTransformer app Flask(__name__) # 初始化组件 client chromadb.Client() collection client.get_collection(knowledge_base) embedder SentenceTransformer(BAAI/bge-small-zh-v1.5) app.route(/api/search, methods[POST]) def search_api(): 检索API接口 data request.json query data.get(query, ) n_results data.get(n_results, 3) query_embedding embedder.encode([query]).tolist() results collection.query( query_embeddingsquery_embedding, n_resultsn_results ) return jsonify({ query: query, results: results[documents][0] }) app.route(/api/rag, methods[POST]) def rag_api(): 完整RAG流程API data request.json query data.get(query, ) # 检索阶段 query_embedding embedder.encode([query]).tolist() retrieved_docs collection.query( query_embeddingsquery_embedding, n_results3 )[documents][0] # 生成阶段 answer rag_generation(query, retrieved_docs, llm_client) return jsonify({ query: query, retrieved_docs: retrieved_docs, answer: answer }) if __name__ __main__: app.run(host0.0.0.0, port5000, debugTrue)6.2 批量任务处理对于大量文档的批量处理import os from tqdm import tqdm def batch_process_documents(doc_folder, batch_size100): 批量处理文档目录 documents [] # 读取文档文件 for filename in os.listdir(doc_folder): if filename.endswith(.txt): with open(os.path.join(doc_folder, filename), r, encodingutf-8) as f: content f.read() documents.append(content) # 分批处理避免内存溢出 for i in tqdm(range(0, len(documents), batch_size)): batch_docs documents[i:ibatch_size] batch_embeddings embedder.encode(batch_docs).tolist() collection.add( embeddingsbatch_embeddings, documentsbatch_docs, ids[fbatch_{ij} for j in range(len(batch_docs))] ) print(f批量处理完成共入库{len(documents)}个文档)7. 资源占用与性能观察7.1 内存与显存占用不同组件的资源需求Chroma数据库内存占用约200-500MB取决于文档数量BGE嵌入模型加载后显存占用1-2GBGPU或内存占用2-3GBCPU大语言模型7B模型需要4-8GB显存13B模型需要8-16GB显存监控命令示例# Linux查看内存占用 nvidia-smi # GPU显存 htop # 内存和CPU # Windows任务管理器查看资源占用7.2 性能优化建议分批处理大量文档入库时采用分批处理避免内存溢出索引优化Chroma支持多种索引类型默认HNSW适合大部分场景缓存机制频繁查询的结果可以加入缓存异步处理批量任务使用异步提高吞吐量8. 常见问题与排查方法问题现象可能原因排查方式解决方案嵌入模型下载失败网络连接问题检查网络状态使用国内镜像源Chroma连接失败端口冲突或服务未启动检查5000端口更换端口或重启服务检索结果不相关嵌入模型不匹配或文档质量差检查查询和文档相似度更换嵌入模型或优化文档生成答案质量差检索结果不足或LLM能力有限检查检索到的文档相关性增加检索数量或优化提示词内存溢出批量处理尺寸过大监控内存使用减小batch_size参数8.1 嵌入模型选择问题如果检索效果不理想可以尝试其他嵌入模型# 可选的中文嵌入模型 models { bge-small: BAAI/bge-small-zh-v1.5, bge-base: BAAI/bge-base-zh-v1.5, m3e-base: moka-ai/m3e-base } # 测试不同模型效果 def test_embedding_models(query, documents, model_name): model SentenceTransformer(models[model_name]) # ... 测试代码8.2 向量数据库性能调优Chroma配置优化import chromadb from chromadb.config import Settings client chromadb.Client(Settings( chroma_db_implduckdbparquet, persist_directory./chroma_db )) # 持久化存储避免每次重启重新加载9. 最佳实践与使用建议9.1 文档预处理规范高质量的输入文档是RAG系统成功的关键def preprocess_document(text): 文档预处理函数 # 清理特殊字符 text re.sub(r\s, , text) # 分段处理每段200-500字为宜 segments segment_text(text, max_length300) return segments def segment_text(text, max_length300): 文本分段函数 # 按句号、问号等自然边界分段 sentences re.split(r[。!?], text) segments [] current_segment for sentence in sentences: if len(current_segment) len(sentence) max_length: current_segment sentence 。 else: if current_segment: segments.append(current_segment.strip()) current_segment sentence 。 if current_segment: segments.append(current_segment.strip()) return segments9.2 检索策略优化多路检索提升召回率def hybrid_retrieval(query, collection, embedder, n_results3): 混合检索策略 # 语义检索 query_embedding embedder.encode([query]).tolist() semantic_results collection.query( query_embeddingsquery_embedding, n_resultsn_results ) # 关键词检索可选 keyword_results keyword_search(query, collection) # 结果融合 combined_results combine_results(semantic_results, keyword_results) return combined_results9.3 生成提示词工程优化提示词提升生成质量def build_rag_prompt(query, context): 构建RAG提示词 prompt f你是一个专业的助手请根据提供的上下文信息回答问题。 上下文信息 {context} 用户问题{query} 要求 1. 答案必须基于上下文信息不要编造不存在的内容 2. 如果上下文信息不足以回答问题请明确说明 3. 答案要简洁明了重点突出 4. 如果问题涉及多个方面请分点回答 请开始回答 return prompt10. 项目部署与扩展10.1 生产环境部署对于正式项目部署建议# docker-compose.yml 示例 version: 3.8 services: rag-api: build: . ports: - 5000:5000 environment: - CHROMA_HOSTchroma-db - EMBEDDING_MODELBAAI/bge-small-zh-v1.5 depends_on: - chroma-db chroma-db: image: chromadb/chroma ports: - 8000:8000 volumes: - chroma_data:/chroma/chroma10.2 监控与日志添加系统监控import logging from datetime import datetime # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(rag_system.log), logging.StreamHandler() ] ) def log_rag_request(query, retrieved_count, response_time): 记录RAG请求日志 logging.info(fQuery: {query}, Retrieved: {retrieved_count}, Time: {response_time}s)这个RAG实战项目最值得尝试的点是完整的端到端流程验证。先从小的文档集开始测试确保检索和生成的基本功能正常再逐步扩展到真实业务场景。最容易踩的坑是文档质量问题和嵌入模型选择不当建议先用标准测试集验证效果。下一步可以探索多模态RAG、图数据库增强检索、Agentic RAG等进阶方向进一步提升系统的智能水平和实用性。建议收藏本文的代码示例在具体项目实施时参考使用。