作者简介大家好我是唐璜Taro全栈 领域创作者✒️ 个人主页 唐璜Taro 支持我点赞 评论 ⭐️收藏上一篇讲述了RAGRetrieval-Augmented Generation的理论以及应用场景这一章节讲解RAG的核心实现。四、核心实现4.1 文档加载支持多种格式的文档读取fromlangchain_community.document_loadersimport(PyPDFLoader,# PDFDocx2txtLoader,# WordTextLoader,# TXTCSVLoader,# CSVUnstructuredMarkdownLoader,# Markdown)# 加载单个文件loaderPyPDFLoader(公司制度手册.pdf)documentsloader.load()# 批量加载目录下所有文件fromlangchain_community.document_loadersimportDirectoryLoader loaderDirectoryLoader(./docs,glob**/*.pdf,loader_clsPyPDFLoader,show_progressTrue# 显示进度条)documentsloader.load()print(f共加载{len(documents)}页文档)print(f第一页内容预览{documents[0].page_content[:200]})中文文档注意PDF 中文提取可能乱码推荐先转成 Markdown 或 TXT。4.2 文本分块Chunking这是 RAG 中最关键的环节之一。分块质量直接影响检索效果。fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size500,# 每块最大字符数chunk_overlap50,# 块之间重叠字符数length_functionlen,separators[\n\n,\n,。,,,, ,]# 中文优化优先按段落 → 句号 → 换行 → 空格 切分)chunkssplitter.split_documents(documents)print(f共生成{len(chunks)}个文本块)分块参数怎么调参数值太小值太大推荐范围chunk_size语义碎片化丢失上下文检索不精确噪音多300 - 1000 字符chunk_overlap块之间语义断裂重复内容多浪费空间50 - 150 字符经验法则问答场景chunk_size 小一些300-500检索更精确总结场景chunk_size 大一些800-1000保留更多上下文4.3 向量化Embedding将文本转成高维向量用于后续相似度计算fromlangchain_community.embeddingsimportHuggingFaceEmbeddings# 首次运行会自动下载模型约 100MBembeddingsHuggingFaceEmbeddings(model_nameBAAI/bge-small-zh-v1.5,model_kwargs{device:cpu},# 无 GPU 用 cpuencode_kwargs{normalize_embeddings:True}# 归一化提高余弦相似度效果)# 测试把一段文字转成向量vectorembeddings.embed_query(什么是退货政策)print(f向量维度{len(vector)})# 512 维print(f前5个值{vector[:5]})Embedding 模型对比模型维度中文效果大小说明BAAI/bge-small-zh512好~100MB推荐入门用BAAI/bge-large-zh1024更好~1.3GB精度更高text-embedding-3-small1536好API 调用OpenAI 付费text-embedding-3-large3072很好API 调用OpenAI 付费最贵4.4 向量数据库存储fromlangchain_community.vectorstoresimportChroma# 创建并持久化vectorstoreChroma.from_documents(documentschunks,embeddingembeddings,persist_directory./chroma_db,# 本地存储目录collection_namemy_knowledge# 集合名称)print(f成功索引{vectorstore._collection.count()}个文本块)# 加载已有数据库下次运行时不需要重新建库# vectorstore Chroma(# persist_directory./chroma_db,# embedding_functionembeddings,# collection_namemy_knowledge# )4.5 检索测试# 基础检索resultsvectorstore.similarity_search(退货政策,k3)fori,docinenumerate(results):print(f\n--- 结果{i1}---)print(f来源{doc.metadata.get(source,未知)})print(f内容{doc.page_content[:200]})4.6 构建 RAG 问答链fromlangchain_openaiimportChatOpenAIfromlangchain.chainsimportRetrievalQAfromlangchain.promptsimportPromptTemplate# 初始化大模型llmChatOpenAI(modeldeepseek-chat,openai_api_keyyour-api-key,openai_api_basehttps://api.deepseek.com,temperature0.1,# 低温度回答更稳定max_tokens1024)# 自定义 Prompt 模板prompt_template你是一个专业的客服助手。请基于以下参考资料回答用户问题。 规则 1. 只根据参考资料回答不要编造信息 2. 如果参考资料中没有相关内容请回答根据现有资料我无法回答这个问题 3. 回答时注明信息来源 参考资料 {context} 用户问题{question} 回答PROMPTPromptTemplate(templateprompt_template,input_variables[context,question])# 创建检索器retrievervectorstore.as_retriever(search_typesimilarity,search_kwargs{k:3}# 检索最相似的 3 个文本块)# 构建 RAG 链qa_chainRetrievalQA.from_chain_type(llmllm,chain_typestuff,# 把所有检索结果拼接后一次性发送retrieverretriever,chain_type_kwargs{prompt:PROMPT},return_source_documentsTrue# 返回来源文档方便溯源)# 提问resultqa_chain.invoke({query:退货需要满足什么条件})print(回答,result[result])print(\n来源)fordocinresult[source_documents]:print(f -{doc.metadata.get(source,未知)})4.7 运行效果示例用户提问退货需要满足什么条件 回答根据公司退货政策退货需要满足以下条件 1. 商品签收后 7 天内可申请退货 2. 商品需保持原包装完好不影响二次销售 3. 食品、贴身衣物等特殊商品不支持退货 4. 需提供订单号和购买凭证 来源 - docs/售后服务政策.pdf (第3页) - docs/常见问题FAQ.txt五、完整项目结构rag-knowledge-base/ ├── docs/ # 原始文档目录 │ ├── 售后服务政策.pdf │ ├── 产品使用手册.docx │ └── 常见问题FAQ.txt ├── chroma_db/ # 向量数据库自动生成 ├── build_index.py # 建库脚本 ├── query.py # 问答脚本 ├── config.py # 配置文件 └── requirements.txtconfig.py — 统一配置importos# API 配置DEEPSEEK_API_KEYos.getenv(DEEPSEEK_API_KEY,your-api-key)DEEPSEEK_BASE_URLhttps://api.deepseek.com# Embedding 配置EMBEDDING_MODELBAAI/bge-small-zh-v1.5# 分块配置CHUNK_SIZE500CHUNK_OVERLAP50# 检索配置TOP_K3# 向量数据库配置CHROMA_DIR./chroma_dbCOLLECTION_NAMEmy_knowledge# 文档目录DOCS_DIR./docsbuild_index.py — 一键建库fromlangchain_community.document_loadersimportDirectoryLoader,TextLoader,PyPDFLoaderfromlangchain.text_splitterimportRecursiveCharacterTextSplitterfromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportChromafromconfigimport*defbuild():print(1/4 加载文档...)loaders[DirectoryLoader(DOCS_DIR,glob**/*.txt,loader_clsTextLoader,show_progressTrue),DirectoryLoader(DOCS_DIR,glob**/*.pdf,loader_clsPyPDFLoader,show_progressTrue),]documents[]forloaderinloaders:documents.extend(loader.load())print(f 加载了{len(documents)}个文档)print(2/4 分块处理...)splitterRecursiveCharacterTextSplitter(chunk_sizeCHUNK_SIZE,chunk_overlapCHUNK_OVERLAP,separators[\n\n,\n,。,,,, ,])chunkssplitter.split_documents(documents)print(f 生成{len(chunks)}个文本块)print(3/4 向量化...)embeddingsHuggingFaceEmbeddings(model_nameEMBEDDING_MODEL,model_kwargs{device:cpu},encode_kwargs{normalize_embeddings:True})print(4/4 存入数据库...)vectorstoreChroma.from_documents(documentschunks,embeddingembeddings,persist_directoryCHROMA_DIR,collection_nameCOLLECTION_NAME)print(f完成共索引{vectorstore._collection.count()}个文本块)if__name____main__:build()query.py — 问答入口fromlangchain_openaiimportChatOpenAIfromlangchain.chainsimportRetrievalQAfromlangchain.promptsimportPromptTemplatefromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportChromafromconfigimport*defcreate_qa_chain():embeddingsHuggingFaceEmbeddings(model_nameEMBEDDING_MODEL,model_kwargs{device:cpu},encode_kwargs{normalize_embeddings:True})vectorstoreChroma(persist_directoryCHROMA_DIR,embedding_functionembeddings,collection_nameCOLLECTION_NAME)llmChatOpenAI(modeldeepseek-chat,openai_api_keyDEEPSEEK_API_KEY,openai_api_baseDEEPSEEK_BASE_URL,temperature0.1)promptPromptTemplate(template基于以下参考资料回答问题。如果资料中没有相关内容请回答无法回答。 参考资料{context} 问题{question} 回答,input_variables[context,question])returnRetrievalQA.from_chain_type(llmllm,retrievervectorstore.as_retriever(search_kwargs{k:TOP_K}),chain_typestuff,chain_type_kwargs{prompt:prompt},return_source_documentsTrue)defmain():qacreate_qa_chain()print(知识库问答系统已启动输入 quit 退出\n)whileTrue:questioninput(请输入问题).strip()ifquestion.lower()in(quit,exit,q):breakifnotquestion:continueresultqa.invoke({query:question})print(f\n回答{result[result]})print(来源,[d.metadata.get(source,)fordinresult[source_documents]])print()if__name____main__:main()六、优化技巧6.1 混合检索Hybrid Search单一向量检索可能漏掉关键词精确匹配的结果。混合检索结合语义检索 关键词检索fromlangchain.retrieversimportEnsembleRetrieverfromlangchain_community.retrieversimportBM25Retriever# BM25 关键词检索bm25_retrieverBM25Retriever.from_documents(chunks)bm25_retriever.k3# 向量语义检索vector_retrievervectorstore.as_retriever(search_kwargs{k:3})# 混合检索各占 50% 权重hybrid_retrieverEnsembleRetriever(retrievers[bm25_retriever,vector_retriever],weights[0.4,0.6]# BM25 占 40%向量检索占 60%)6.2 Rerank 重排序检索后对结果重新排序提高相关性# pip install sentence-transformersfromlangchain.retrieversimportContextualCompressionRetrieverfromlangchain_cohereimportCohereRerank# 使用 Cohere Rerank需要 API KeyrerankerCohereRerank(modelrerank-multilingual-v3.0,top_n3)compression_retrieverContextualCompressionRetriever(base_compressorreranker,base_retrievervector_retriever)6.3 多轮对话fromlangchain.memoryimportConversationBufferWindowMemoryfromlangchain.chainsimportConversationalRetrievalChain memoryConversationBufferWindowMemory(k5,# 保留最近 5 轮对话memory_keychat_history,return_messagesTrue)qa_chainConversationalRetrievalChain.from_llm(llmllm,retrievervectorstore.as_retriever(),memorymemory)6.4 分块优化策略策略方法适用场景按语义分块用 NLP 模型判断语义边界文章、报告按固定长度RecursiveCharacterTextSplitter通用场景按文档结构按标题/章节切分Markdown、技术文档递归分块先大块再小块长文档七、常见问题排查Q1: 检索结果不相关检查 chunk_size 是否合适太大容易混入噪音尝试不同的 Embedding 模型增加chunk_overlap减少语义断裂Q2: 回答总是说无法回答降低 Prompt 中的限制性描述增大 Top_K 值比如从 3 改到 5检查文档是否正确加载和分块Q3: 响应速度慢Embedding 模型换用更小的如 bge-small使用 GPU 加速model_kwargs{device: cuda}向量数据库换用 Milvus 等高性能方案Q4: 中文 PDF 乱码# 用 OCR 方案pip install rapidocr-onnxruntimefromlangchain_community.document_loadersimportPDFPlumberLoader# 或使用 PaddleOCR 等工具预处理八、进阶方向方向说明Web UI用 Streamlit / Gradio 做可视化界面增量更新文档变更后只更新变化的部分不重建全量索引多模态 RAG支持图片、表格的检索Agent RAG让模型自主决定是否需要检索、检索什么生产级部署Milvus FastAPI Redis 缓存九、总结RAG 搭建的核心流程文档 → 分块 → Embedding → 向量数据库 ↓ 用户提问 → Embedding → 相似度检索 → Top-K 文档 ↓ Prompt(问题 文档) → 大模型 → 回答学习路线建议先跑通 — 用 LangChain Chroma DeepSeek 跑一个最小 demo优化检索 — 试不同的 chunk_size、overlap、Top-K 值混合检索 — 关键词检索BM25 向量检索结合效果更好进阶 — 多轮对话、引用来源标注、Rerank 重排序入门建议先把最小 demo 跑通再逐步优化分块策略、检索方式和 Prompt 模板。RAG 的效果 80% 取决于数据处理和检索质量而不是模型本身。
从零搭建 RAG 知识库:让大模型读懂你的私有数据(下篇)
发布时间:2026/5/21 6:54:23
作者简介大家好我是唐璜Taro全栈 领域创作者✒️ 个人主页 唐璜Taro 支持我点赞 评论 ⭐️收藏上一篇讲述了RAGRetrieval-Augmented Generation的理论以及应用场景这一章节讲解RAG的核心实现。四、核心实现4.1 文档加载支持多种格式的文档读取fromlangchain_community.document_loadersimport(PyPDFLoader,# PDFDocx2txtLoader,# WordTextLoader,# TXTCSVLoader,# CSVUnstructuredMarkdownLoader,# Markdown)# 加载单个文件loaderPyPDFLoader(公司制度手册.pdf)documentsloader.load()# 批量加载目录下所有文件fromlangchain_community.document_loadersimportDirectoryLoader loaderDirectoryLoader(./docs,glob**/*.pdf,loader_clsPyPDFLoader,show_progressTrue# 显示进度条)documentsloader.load()print(f共加载{len(documents)}页文档)print(f第一页内容预览{documents[0].page_content[:200]})中文文档注意PDF 中文提取可能乱码推荐先转成 Markdown 或 TXT。4.2 文本分块Chunking这是 RAG 中最关键的环节之一。分块质量直接影响检索效果。fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size500,# 每块最大字符数chunk_overlap50,# 块之间重叠字符数length_functionlen,separators[\n\n,\n,。,,,, ,]# 中文优化优先按段落 → 句号 → 换行 → 空格 切分)chunkssplitter.split_documents(documents)print(f共生成{len(chunks)}个文本块)分块参数怎么调参数值太小值太大推荐范围chunk_size语义碎片化丢失上下文检索不精确噪音多300 - 1000 字符chunk_overlap块之间语义断裂重复内容多浪费空间50 - 150 字符经验法则问答场景chunk_size 小一些300-500检索更精确总结场景chunk_size 大一些800-1000保留更多上下文4.3 向量化Embedding将文本转成高维向量用于后续相似度计算fromlangchain_community.embeddingsimportHuggingFaceEmbeddings# 首次运行会自动下载模型约 100MBembeddingsHuggingFaceEmbeddings(model_nameBAAI/bge-small-zh-v1.5,model_kwargs{device:cpu},# 无 GPU 用 cpuencode_kwargs{normalize_embeddings:True}# 归一化提高余弦相似度效果)# 测试把一段文字转成向量vectorembeddings.embed_query(什么是退货政策)print(f向量维度{len(vector)})# 512 维print(f前5个值{vector[:5]})Embedding 模型对比模型维度中文效果大小说明BAAI/bge-small-zh512好~100MB推荐入门用BAAI/bge-large-zh1024更好~1.3GB精度更高text-embedding-3-small1536好API 调用OpenAI 付费text-embedding-3-large3072很好API 调用OpenAI 付费最贵4.4 向量数据库存储fromlangchain_community.vectorstoresimportChroma# 创建并持久化vectorstoreChroma.from_documents(documentschunks,embeddingembeddings,persist_directory./chroma_db,# 本地存储目录collection_namemy_knowledge# 集合名称)print(f成功索引{vectorstore._collection.count()}个文本块)# 加载已有数据库下次运行时不需要重新建库# vectorstore Chroma(# persist_directory./chroma_db,# embedding_functionembeddings,# collection_namemy_knowledge# )4.5 检索测试# 基础检索resultsvectorstore.similarity_search(退货政策,k3)fori,docinenumerate(results):print(f\n--- 结果{i1}---)print(f来源{doc.metadata.get(source,未知)})print(f内容{doc.page_content[:200]})4.6 构建 RAG 问答链fromlangchain_openaiimportChatOpenAIfromlangchain.chainsimportRetrievalQAfromlangchain.promptsimportPromptTemplate# 初始化大模型llmChatOpenAI(modeldeepseek-chat,openai_api_keyyour-api-key,openai_api_basehttps://api.deepseek.com,temperature0.1,# 低温度回答更稳定max_tokens1024)# 自定义 Prompt 模板prompt_template你是一个专业的客服助手。请基于以下参考资料回答用户问题。 规则 1. 只根据参考资料回答不要编造信息 2. 如果参考资料中没有相关内容请回答根据现有资料我无法回答这个问题 3. 回答时注明信息来源 参考资料 {context} 用户问题{question} 回答PROMPTPromptTemplate(templateprompt_template,input_variables[context,question])# 创建检索器retrievervectorstore.as_retriever(search_typesimilarity,search_kwargs{k:3}# 检索最相似的 3 个文本块)# 构建 RAG 链qa_chainRetrievalQA.from_chain_type(llmllm,chain_typestuff,# 把所有检索结果拼接后一次性发送retrieverretriever,chain_type_kwargs{prompt:PROMPT},return_source_documentsTrue# 返回来源文档方便溯源)# 提问resultqa_chain.invoke({query:退货需要满足什么条件})print(回答,result[result])print(\n来源)fordocinresult[source_documents]:print(f -{doc.metadata.get(source,未知)})4.7 运行效果示例用户提问退货需要满足什么条件 回答根据公司退货政策退货需要满足以下条件 1. 商品签收后 7 天内可申请退货 2. 商品需保持原包装完好不影响二次销售 3. 食品、贴身衣物等特殊商品不支持退货 4. 需提供订单号和购买凭证 来源 - docs/售后服务政策.pdf (第3页) - docs/常见问题FAQ.txt五、完整项目结构rag-knowledge-base/ ├── docs/ # 原始文档目录 │ ├── 售后服务政策.pdf │ ├── 产品使用手册.docx │ └── 常见问题FAQ.txt ├── chroma_db/ # 向量数据库自动生成 ├── build_index.py # 建库脚本 ├── query.py # 问答脚本 ├── config.py # 配置文件 └── requirements.txtconfig.py — 统一配置importos# API 配置DEEPSEEK_API_KEYos.getenv(DEEPSEEK_API_KEY,your-api-key)DEEPSEEK_BASE_URLhttps://api.deepseek.com# Embedding 配置EMBEDDING_MODELBAAI/bge-small-zh-v1.5# 分块配置CHUNK_SIZE500CHUNK_OVERLAP50# 检索配置TOP_K3# 向量数据库配置CHROMA_DIR./chroma_dbCOLLECTION_NAMEmy_knowledge# 文档目录DOCS_DIR./docsbuild_index.py — 一键建库fromlangchain_community.document_loadersimportDirectoryLoader,TextLoader,PyPDFLoaderfromlangchain.text_splitterimportRecursiveCharacterTextSplitterfromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportChromafromconfigimport*defbuild():print(1/4 加载文档...)loaders[DirectoryLoader(DOCS_DIR,glob**/*.txt,loader_clsTextLoader,show_progressTrue),DirectoryLoader(DOCS_DIR,glob**/*.pdf,loader_clsPyPDFLoader,show_progressTrue),]documents[]forloaderinloaders:documents.extend(loader.load())print(f 加载了{len(documents)}个文档)print(2/4 分块处理...)splitterRecursiveCharacterTextSplitter(chunk_sizeCHUNK_SIZE,chunk_overlapCHUNK_OVERLAP,separators[\n\n,\n,。,,,, ,])chunkssplitter.split_documents(documents)print(f 生成{len(chunks)}个文本块)print(3/4 向量化...)embeddingsHuggingFaceEmbeddings(model_nameEMBEDDING_MODEL,model_kwargs{device:cpu},encode_kwargs{normalize_embeddings:True})print(4/4 存入数据库...)vectorstoreChroma.from_documents(documentschunks,embeddingembeddings,persist_directoryCHROMA_DIR,collection_nameCOLLECTION_NAME)print(f完成共索引{vectorstore._collection.count()}个文本块)if__name____main__:build()query.py — 问答入口fromlangchain_openaiimportChatOpenAIfromlangchain.chainsimportRetrievalQAfromlangchain.promptsimportPromptTemplatefromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportChromafromconfigimport*defcreate_qa_chain():embeddingsHuggingFaceEmbeddings(model_nameEMBEDDING_MODEL,model_kwargs{device:cpu},encode_kwargs{normalize_embeddings:True})vectorstoreChroma(persist_directoryCHROMA_DIR,embedding_functionembeddings,collection_nameCOLLECTION_NAME)llmChatOpenAI(modeldeepseek-chat,openai_api_keyDEEPSEEK_API_KEY,openai_api_baseDEEPSEEK_BASE_URL,temperature0.1)promptPromptTemplate(template基于以下参考资料回答问题。如果资料中没有相关内容请回答无法回答。 参考资料{context} 问题{question} 回答,input_variables[context,question])returnRetrievalQA.from_chain_type(llmllm,retrievervectorstore.as_retriever(search_kwargs{k:TOP_K}),chain_typestuff,chain_type_kwargs{prompt:prompt},return_source_documentsTrue)defmain():qacreate_qa_chain()print(知识库问答系统已启动输入 quit 退出\n)whileTrue:questioninput(请输入问题).strip()ifquestion.lower()in(quit,exit,q):breakifnotquestion:continueresultqa.invoke({query:question})print(f\n回答{result[result]})print(来源,[d.metadata.get(source,)fordinresult[source_documents]])print()if__name____main__:main()六、优化技巧6.1 混合检索Hybrid Search单一向量检索可能漏掉关键词精确匹配的结果。混合检索结合语义检索 关键词检索fromlangchain.retrieversimportEnsembleRetrieverfromlangchain_community.retrieversimportBM25Retriever# BM25 关键词检索bm25_retrieverBM25Retriever.from_documents(chunks)bm25_retriever.k3# 向量语义检索vector_retrievervectorstore.as_retriever(search_kwargs{k:3})# 混合检索各占 50% 权重hybrid_retrieverEnsembleRetriever(retrievers[bm25_retriever,vector_retriever],weights[0.4,0.6]# BM25 占 40%向量检索占 60%)6.2 Rerank 重排序检索后对结果重新排序提高相关性# pip install sentence-transformersfromlangchain.retrieversimportContextualCompressionRetrieverfromlangchain_cohereimportCohereRerank# 使用 Cohere Rerank需要 API KeyrerankerCohereRerank(modelrerank-multilingual-v3.0,top_n3)compression_retrieverContextualCompressionRetriever(base_compressorreranker,base_retrievervector_retriever)6.3 多轮对话fromlangchain.memoryimportConversationBufferWindowMemoryfromlangchain.chainsimportConversationalRetrievalChain memoryConversationBufferWindowMemory(k5,# 保留最近 5 轮对话memory_keychat_history,return_messagesTrue)qa_chainConversationalRetrievalChain.from_llm(llmllm,retrievervectorstore.as_retriever(),memorymemory)6.4 分块优化策略策略方法适用场景按语义分块用 NLP 模型判断语义边界文章、报告按固定长度RecursiveCharacterTextSplitter通用场景按文档结构按标题/章节切分Markdown、技术文档递归分块先大块再小块长文档七、常见问题排查Q1: 检索结果不相关检查 chunk_size 是否合适太大容易混入噪音尝试不同的 Embedding 模型增加chunk_overlap减少语义断裂Q2: 回答总是说无法回答降低 Prompt 中的限制性描述增大 Top_K 值比如从 3 改到 5检查文档是否正确加载和分块Q3: 响应速度慢Embedding 模型换用更小的如 bge-small使用 GPU 加速model_kwargs{device: cuda}向量数据库换用 Milvus 等高性能方案Q4: 中文 PDF 乱码# 用 OCR 方案pip install rapidocr-onnxruntimefromlangchain_community.document_loadersimportPDFPlumberLoader# 或使用 PaddleOCR 等工具预处理八、进阶方向方向说明Web UI用 Streamlit / Gradio 做可视化界面增量更新文档变更后只更新变化的部分不重建全量索引多模态 RAG支持图片、表格的检索Agent RAG让模型自主决定是否需要检索、检索什么生产级部署Milvus FastAPI Redis 缓存九、总结RAG 搭建的核心流程文档 → 分块 → Embedding → 向量数据库 ↓ 用户提问 → Embedding → 相似度检索 → Top-K 文档 ↓ Prompt(问题 文档) → 大模型 → 回答学习路线建议先跑通 — 用 LangChain Chroma DeepSeek 跑一个最小 demo优化检索 — 试不同的 chunk_size、overlap、Top-K 值混合检索 — 关键词检索BM25 向量检索结合效果更好进阶 — 多轮对话、引用来源标注、Rerank 重排序入门建议先把最小 demo 跑通再逐步优化分块策略、检索方式和 Prompt 模板。RAG 的效果 80% 取决于数据处理和检索质量而不是模型本身。