[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"learning-part-8-rag-optimization":3,"learning-all":13},{"id":4,"slug":5,"title":6,"description":7,"level":8,"topic":9,"url":10,"content":11,"sortOrder":12},6,"part-8-rag-optimization","Part 8 · RAG 优化与评估","站 5 你做出了\"能跑\"的 RAG。这一站把它做到\"能打\"：","INTERMEDIATE","RAG",null,"# Part 8 · RAG 优化与评估\r\n\r\n\r\n---\r\n\r\n## Section 1 · 三大范式再深入（概念日）\r\n\r\n**Subsection 1 · 记清楚三范式**\r\n```\r\nNaive RAG     索引→检索→生成（你站5做的）\r\nAdvanced RAG  在检索前后加优化：\r\n              预检索：查询改写、HyDE\r\n              检索中：混合检索、重排 Rerank\r\n              后检索：上下文压缩、融合\r\nModular RAG   检索模块可插拔、可编排，按场景组合\r\n```\r\n- 💡 Part 8 的目标：把 Naive 升级成 Advanced。\r\n\r\n**Subsection 2 · 过关自测**\r\n能说出 Advanced 在\"检索前\u002F中\u002F后\"各加了什么 = Section 1 完成。\r\n\r\n---\r\n\r\n## Section 2 · RAG 变体认识（面试点）\r\n\r\n**Subsection 1 · 记 5 个变体**\r\n```\r\nT-RAG      时序感知：资料带时间，回答考虑时效性\r\nCRAG       纠错增强：检索结果不可靠时，自动\"修正检索\"\r\nSelf-RAG   自反思：模型自己判断\"要不要检索\u002F答得对不对\"\r\nRAG-Fusion 多查询融合：把一个问题拆成几个查，结果合并去重\r\nRewrite    查询重写：先把问题改得更清晰，再去检索\r\n```\r\n- 💡 面试被问\"你了解哪些 RAG 变体\"，报出这 5 个名字 + 一句话定位即可。\r\n\r\n**Subsection 2 · 过关自测**\r\n能说出其中 3 个各解决什么问题 = Section 2 完成。\r\n\r\n---\r\n\r\n## Section 3 · 索引优化（概念 + 动手看结构）\r\n\r\n**Subsection 1 · 记三种索引技巧**\r\n```\r\n元数据索引   每块存\"来源\u002F章节\u002F时间\"等标签，检索时按标签过滤\r\n父子索引     大块当\"父\"存上下文，小块当\"子\"做检索，命中子再取父\r\n摘要索引     给每块写摘要，先按摘要粗检索，再定位原文\r\n```\r\n\r\n**Subsection 2 · 给 rag_tool 加元数据**\r\n在 rag_tool.py 的 `add_document` 里，把 metadata 改成带来源和章节：\r\n```python\r\nmetadatas=[{\"source\": file_path, \"chapter\": blocks[i][:10]} for i in range(len(blocks))]\r\n```\r\n- 再跑一次入库，验证 metadata 生效。\r\n- 💡 这就是\"元数据索引\"的最简形态：以后可以按章节过滤。\r\n\r\n**过关**：能说出三种索引技巧，并跑通加元数据 = Section 3 完成。\r\n\r\n---\r\n\r\n## Section 4 · 混合检索：BM25 + 向量（重点日）\r\n\r\n> 向量搜索找\"意思相近\"，关键词搜索（BM25）找\"字面相同\"。\r\n> 混合 = 两个都搜，结果合并，更稳。\r\n\r\n**Subsection 1 · 装库**\r\ncmd：`pip install rank-bm25`\r\n\r\n**Subsection 2 · 写混合检索**\r\nVS Code 新建 `hybrid_search.py`：\r\n```python\r\nimport chromadb, jieba\r\nfrom rank_bm25 import BM25Okapi\r\nfrom sentence_transformers import SentenceTransformer, util\r\nfrom pathlib import Path\r\n\r\n# 准备分块（用站5的数据）\r\nclient = chromadb.PersistentClient(path=\"chroma_db\")\r\ncollection = client.get_or_create_collection(\"company_rules\")\r\nall_docs = collection.get()[\"documents\"]\r\n\r\n# ---- 向量检索 ----\r\nmodel = SentenceTransformer(\"BAAI\u002Fbge-small-zh-v1.5\")\r\ndef vector_search(q, k=3):\r\n    q_vec = model.encode([q]).tolist()\r\n    r = collection.query(query_embeddings=q_vec, n_results=k)\r\n    return list(zip(r[\"documents\"][0], r[\"distances\"][0]))\r\n\r\n# ---- 关键词检索 BM25 ----\r\ndef tokenize(text):\r\n    return [w for w in jieba.cut(text) if w.strip()]\r\n# 先装 jieba：pip install jieba\r\nbm25 = BM25Okapi([tokenize(d) for d in all_docs])\r\ndef keyword_search(q, k=3):\r\n    scores = bm25.get_scores(tokenize(q))\r\n    idx = sorted(range(len(scores)), key=lambda i: -scores[i])[:k]\r\n    return [(all_docs[i], float(scores[i])) for i in idx]\r\n\r\n# ---- 测试 ----\r\nq = \"迟到怎么处理\"\r\nvs = vector_search(q)\r\nks = keyword_search(q)\r\nprint(\"向量检索:\", vs[0][0][:40], \"分:\", round(vs[0][1],3))\r\nprint(\"关键词检索:\", ks[0][0][:40], \"分:\", round(ks[0][1],3))\r\n```\r\n- 先装 jieba：cmd `pip install jieba`\r\n- 运行\r\n- ✅ 预期看到：两种检索各自给出结果。\r\n- 💡 真实项目里把两个结果按分数归一化后合并（RRF 融合），就是\"混合检索\"。\r\n\r\n**过关**：能跑出两种检索并说清各自优势 = Section 4 完成。\r\n\r\n---\r\n\r\n## Section 5 · Rerank 重排（把结果排得更准）\r\n\r\n**Subsection 1 · 理解 Rerank**\r\n```\r\n第一步（召回）：向量\u002F关键词搜出 10 条，可能不准\r\n第二步（精排）：用专门的 Rerank 模型，把这 10 条按\"和问题真正相关度\"重新排序，取前 3\r\n```\r\n- 💡 召回要\"多而全\"，精排要\"准\"——两步走是生产级 RAG 标配。\r\n\r\n**Subsection 2 · 用 DeepSeek 模拟 Rerank**\r\nVS Code 新建 `rerank_demo.py`：\r\n```python\r\nimport os\r\nfrom dotenv import load_dotenv\r\nfrom openai import OpenAI\r\n\r\nload_dotenv()\r\nllm = OpenAI(api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https:\u002F\u002Fapi.deepseek.com\")\r\n\r\n# 假设检索回 4 条候选\r\ncandidates = [\r\n    \"公司每月15日发工资\",\r\n    \"员工考勤：9:30前打卡，迟到三次扣补贴\",\r\n    \"报销单笔500元以上需审批\",\r\n    \"加班可申请调休，需主管审批\",\r\n]\r\nquestion = \"迟到有什么处罚？\"\r\nprompt = f\"问题：{question}\\\r\n下面几条资料，按与问题的相关度从高到低排序，只输出序号，不要解释：\\\r\n\" + \"\\\r\n\".join(f\"{i+1}. {c}\" for i, c in enumerate(candidates))+\r\n\r\nresp = llm.chat.completions.create(model=\"deepseek-chat\", messages=[{\"role\": \"user\", \"content\": prompt}])\r\nprint(\"重排结果:\", resp.choices[0].message.content)\r\n```\r\n- ✅ 预期看到：模型把\"迟到扣补贴\"排到最前。\r\n- 💡 生产项目用专门的 Rerank 模型（如 bge-reranker、Cohere Rerank），效果更稳；用 LLM 排也行，只是贵。\r\n\r\n**过关**：能跑通并说清\"召回 + 精排\"两步 = Section 5 完成。\r\n\r\n---\r\n\r\n## Section 6 · 查询改写 + HyDE\r\n\r\n**Subsection 1 · 查询改写**\r\n思路：用户问题可能含糊，先让 LLM 把问题改清晰，再去检索。\r\n新建 `rewrite.py`：\r\n```python\r\nimport os\r\nfrom dotenv import load_dotenv\r\nfrom openai import OpenAI\r\n\r\nload_dotenv()\r\nllm = OpenAI(api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https:\u002F\u002Fapi.deepseek.com\")\r\n\r\nraw = \"报销那个事儿\"\r\nprompt = f\"把用户这句含糊的问题改写成适合检索的清晰问题，只输出改写结果：\\\r\n{raw}\"\r\nresp = llm.chat.completions.create(model=\"deepseek-chat\", messages=[{\"role\": \"user\", \"content\": prompt}])\r\nprint(\"改写后:\", resp.choices[0].message.content)\r\n```\r\n- ✅ 预期看到：`公司报销需要什么流程\u002F条件？` 之类清晰问题。\r\n\r\n**Subsection 2 · HyDE 概念**\r\n```\r\nHyDE（假设性文档嵌入）\r\n= 先让 LLM 根据问题\"写一个假设答案\"，再用这个假设答案去检索\r\n原因：答案往往比问题更容易和资料\"撞上\"相似语义\r\n```\r\n- 💡 记住名字和思路即可，实现可选。\r\n\r\n**过关**：能跑通改写 + 说清 HyDE 思路 = Section 6 完成。\r\n\r\n---\r\n\r\n## Section 7 · 后检索优化：上下文压缩\r\n\r\n**Subsection 1 · 理解压缩**\r\n检索回的原文可能又长又有噪音。压缩 = 只把和问题相关的句子留给模型，省 token + 提准度。\r\n\r\n**Subsection 2 · 跑压缩 demo**\r\n新建 `compress.py`：\r\n```python\r\nimport os\r\nfrom dotenv import load_dotenv\r\nfrom openai import OpenAI\r\n\r\nload_dotenv()\r\nllm = OpenAI(api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https:\u002F\u002Fapi.deepseek.com\")\r\n\r\nquestion = \"加班怎么算\"\r\ncontext = \"\"\"公司实行弹性工作制，工作日加班1小时以上可申请调休。\r\n调休需在当月内使用，过期作废。加班需提前在系统登记并经主管审批。\r\n法定节假日加班按国家规定支付加班费。\"\"\"\r\n\r\nprompt = f\"问题：{question}\\\r\n从下面资料中提取与问题最相关的 1-2 句话，其余删掉：\\\r\n{context}\"\r\nresp = llm.chat.completions.create(model=\"deepseek-chat\", messages=[{\"role\": \"user\", \"content\": prompt}])\r\nprint(\"压缩后:\", resp.choices[0].message.content)\r\n```\r\n- ✅ 预期看到：只保留\"加班可申请调休\u002F需审批\"相关内容。\r\n\r\n**过关**：能跑通压缩并说清它解决什么 = Section 7 完成。\r\n\r\n---\r\n\r\n## Section 8 · RAGAS 评估（用量化分数说话）\r\n\r\n**Subsection 1 · 装 RAGAS**\r\ncmd：`pip install ragas langchain-openai`\r\n\r\n> ⚠️ ragas 依赖较重，如果安装报 `ChatVertexAI` 相关 ImportError，是 langchain_community 版本不兼容，跑 `pip install \"langchain-community\u003C0.4\"` 降级即可。\r\n\r\n**Subsection 2 · 跑评估**\r\n新建 `evaluate_ragas.py`：\r\n```python\r\nimport os\r\nfrom dotenv import load_dotenv\r\nfrom langchain_openai import ChatOpenAI\r\nfrom ragas import evaluate\r\nfrom ragas.metrics.collections import faithfulness, answer_relevancy\r\nfrom ragas.llms import LangchainLLMWrapper\r\nfrom datasets import Dataset\r\n\r\nload_dotenv()\r\n\r\n# ragas 不接受原生 openai SDK，需要用 langchain 的 ChatOpenAI 包装\r\nllm = ChatOpenAI(model=\"deepseek-chat\", api_key=os.getenv(\"DEEPSEEK_API_KEY\"), base_url=\"https:\u002F\u002Fapi.deepseek.com\")\r\nragas_llm = LangchainLLMWrapper(llm)\r\n\r\n# 手工准备一组\"问题-回答-资料\"，评估质量\r\ndata = {\r\n    \"question\": [\"迟到有什么处罚？\", \"报销要什么手续？\"],\r\n    \"answer\": [\"迟到三次扣发当日补贴。\", \"单笔500元以下凭发票报销，以上需审批单。\"],\r\n    \"contexts\": [[\"员工9:30前打卡，迟到3次以上扣发当日补贴。\"], [\"单笔500元以下凭发票直接报销，以上需附审批单。\"]],\r\n}\r\ndataset = Dataset.from_dict(data)\r\n\r\n# 新版 ragas：context_relevancy 已移除，用 faithfulness + answer_relevancy 两个核心指标\r\nscore = evaluate(dataset, metrics=[faithfulness, answer_relevancy], llm=ragas_llm)\r\nprint(score)\r\n```\r\n- 运行（第一次会下载评估用的模型，稍等）\r\n- ✅ 预期看到：两个指标分数（0~1）：\r\n```\r\nfaithfulness      忠实度：回答有没有照着资料说（不胡编）\r\nanswer_relevancy  答案相关度：答非所问会低\r\n```\r\n- 💡 记下分数，这就是你 RAG 的\"体检报告\"。\r\n- ⚠️ 新版变化：① `from ragas.metrics import` 改成 `from ragas.metrics.collections import`；② `context_relevancy` 已移除；③ LLM 必须用 langchain 包装，不能直接传原生 OpenAI client。\r\n\r\n**过关**：能跑出三个分数，并说出每个分数代表什么 = Section 8 完成。\r\n\r\n---\r\n\r\n## Section 9 · 部署一个开源 RAG 项目对照\r\n\r\n**Subsection 1 · 部署 FastGPT**\r\n- 打开 https:\u002F\u002Fgithub.com\u002Flabring\u002FFastGPT 看 README。\r\n- 按 README 的 Docker 部署方式启动（需要先装 Docker Desktop：https:\u002F\u002Fwww.docker.com\u002Fproducts\u002Fdocker-desktop\u002F 下载安装）。\r\n- 启动后进入 FastGPT 网页，导出一份知识库，问几个问题。\r\n- 💡 目的：看看\"生产级 RAG 产品\"长什么样，对照你的 rag_tool 找差距。\r\n- ❌ Docker 装不动\u002F资源不够：改看 README 的架构图 + 功能截图，写一篇\"它比我的强在哪\"笔记，也算完成。\r\n\r\n**过关**：部署成功或写出对比笔记 = Section 9 完成。\r\n\r\n---\r\n\r\n## Section 10 · 站 6 验收\r\n\r\n**勾选**\r\n- [ ] 能说出三大范式，Advanced 在检索前\u002F中\u002F后加什么\r\n- [ ] 能说出 5 个 RAG 变体各解决什么\r\n- [ ] 跑通元数据索引（Section 3）\r\n- [ ] 跑通 BM25+向量混合检索（Section 4）\r\n- [ ] 跑通 Rerank，理解\"召回+精排\"（Section 5）\r\n- [ ] 跑通查询改写 + 理解 HyDE（Section 6）\r\n- [ ] 跑通上下文压缩（Section 7）\r\n- [ ] RAGAS 分数跑出来，能解读（Section 8）\r\n- [ ] FastGPT 部署或对比笔记完成（Section 9）\r\n\r\n**写 300 字Part 6 总结**：你的 RAG 做了哪些优化，哪个优化效果最明显，RAGAS 分数多少。\r\n\r\n**全勾选 = Part 8 通过** → 进入下一站 Part 9 · LangChain，15 天）。",8,[14,21,27,33,39,45,50,55,56,62,68,75,81,87,93,99,105,111,117,123,129],{"id":15,"slug":16,"title":17,"description":18,"level":19,"topic":20,"url":10,"content":10,"sortOrder":15},1,"part-1-llm-basics","Part 1 · 大模型基础认知","小白零基础友好。这一站不写代码，只建立\"大模型到底是什么\"的骨架。","BEGINNER","大模型认知",{"id":22,"slug":23,"title":24,"description":25,"level":19,"topic":26,"url":10,"content":10,"sortOrder":22},2,"part-2-llm-principles","Part 2 · 大模型原理 · 入门实操","这一站不卷数学，只把\"理解模型所需的知识\"讲透。；站 2A 解决\"理解模型\"，站 2B 解决\"面试能答\"。；这一层是\"有余力再做\"，不做也不影响你进入站 3。","大模型原理",{"id":28,"slug":29,"title":30,"description":31,"level":19,"topic":26,"url":10,"content":10,"sortOrder":32},100,"part-3-llm-principles-deep","Part 3 · 大模型原理 · 面试深入","数学基础、机器学习、神经网络、词向量、思维链等面试必考原理",3,{"id":34,"slug":35,"title":36,"description":37,"level":8,"topic":26,"url":10,"content":10,"sortOrder":38},101,"part-4-llm-principles-advanced","Part 4 · 大模型原理 · 进阶可选","从零写迷你模型、RLHF、PPO、分布式训练实操等进阶内容",4,{"id":32,"slug":40,"title":41,"description":42,"level":19,"topic":43,"url":10,"content":10,"sortOrder":44},"part-5-prompt-engineering","Part 5 · Prompt 提示词工程","从这里开始，你每天都要真的调大模型 API。","提示工程",5,{"id":38,"slug":46,"title":47,"description":48,"level":19,"topic":49,"url":10,"content":10,"sortOrder":4},"part-6-llm-api","Part 6 · 大模型 API 调用","站 3 你已经调通了 API。这一站把\"调用\"做成专业水准：","API 工程",{"id":44,"slug":51,"title":52,"description":53,"level":8,"topic":9,"url":10,"content":10,"sortOrder":54},"part-7-rag","Part 7 · RAG 检索增强生成","这一站是\"能落地\"的关键：让模型回答**你的私有知识**。",7,{"id":4,"slug":5,"title":6,"description":7,"level":8,"topic":9,"url":10,"content":10,"sortOrder":12},{"id":54,"slug":57,"title":58,"description":59,"level":8,"topic":60,"url":10,"content":10,"sortOrder":61},"part-9-langchain","Part 9 · LangChain 框架","目标：用 LangChain 把\"模型、提示词、检索、记忆、工具\"串成可复用的链和 Agent。","LangChain",9,{"id":12,"slug":63,"title":64,"description":65,"level":8,"topic":66,"url":10,"content":10,"sortOrder":67},"part-10-agent","Part 10 · Agent 基础","让模型从\"会聊天\"变成\"能干活\"：自己拆任务、调工具、看结果、再行动。","Agent",10,{"id":61,"slug":69,"title":70,"description":71,"level":72,"topic":73,"url":10,"content":10,"sortOrder":74},"part-11-multi-agent","Part 11 · 多 Agent 与 Agent IDE","从\"单个 Agent\"升级到\"多 Agent 协作\"，并掌握 AutoGen \u002F LangGraph \u002F GPTs \u002F Coze \u002F Dify 五个工具。","ADVANCED","多 Agent",11,{"id":67,"slug":76,"title":77,"description":78,"level":72,"topic":79,"url":10,"content":10,"sortOrder":80},"part-12-llamaindex","Part 12 · LlamaIndex","站 5~7 你用了 LangChain 做 RAG。LlamaIndex 是另一条专攻\"数据 + LLM\"的路线。","LlamaIndex",12,{"id":74,"slug":82,"title":83,"description":84,"level":72,"topic":85,"url":10,"content":10,"sortOrder":86},"part-13-transformer","Part 13 · Transformer 深入","站 2A 建立了直觉，这一站把手写代码跑通——从\"懂概念\"到\"写得出\"。","Transformer",13,{"id":80,"slug":88,"title":89,"description":90,"level":72,"topic":91,"url":10,"content":10,"sortOrder":92},"part-14-open-models","Part 14 · 开源模型与私有化部署","目标：把主流开源模型在本地\u002F服务器跑通，理解服务化工程（显存、量化、并发）。","模型部署",14,{"id":86,"slug":94,"title":95,"description":96,"level":72,"topic":97,"url":10,"content":10,"sortOrder":98},"part-15-finetuning","Part 15 · 模型微调 Fine-Tuning","目标：理解\"什么时候必须微调、怎么选基座、怎么备数据\"，并完整跑通一次业务微调。","微调",15,{"id":92,"slug":100,"title":101,"description":102,"level":72,"topic":103,"url":10,"content":10,"sortOrder":104},"part-16-peft-lora","Part 16 · PEFT 参数高效微调","重点吃透 **LoRA**：用极少量可训练参数微调大模型（消费级显卡就能跑）。","PEFT\u002FLoRA",16,{"id":98,"slug":106,"title":107,"description":108,"level":72,"topic":109,"url":10,"content":10,"sortOrder":110},"part-17-quantization","Part 17 · 模型量化","目标：理解\"为什么量化、主流算法各自思路\"，能动手量化并评估效果。","量化",17,{"id":104,"slug":112,"title":113,"description":114,"level":72,"topic":115,"url":10,"content":10,"sortOrder":116},"part-18-data-evaluation","Part 18 · 训练数据与模型评估","数据决定模型上限，评估决定你\"能不能交付\"。","数据与评估",18,{"id":110,"slug":118,"title":119,"description":120,"level":72,"topic":121,"url":10,"content":10,"sortOrder":122},"part-19-multimodal","Part 19 · 多模态应用","让 AI 同时\"看得懂图、听得了音、说得出话\"。","多模态",19,{"id":116,"slug":124,"title":125,"description":126,"level":72,"topic":127,"url":10,"content":10,"sortOrder":128},"part-20-projects-career","Part 20 · 项目实战 + 求职备战","把 0→1 到 1→100 学到的全部收敛成**能展示、能讲、能面试**的项目。","项目与求职",20,{"id":130,"slug":131,"title":132,"description":133,"level":72,"topic":134,"url":10,"content":10,"sortOrder":135},102,"extra-2026-ai-tech","额外篇 · 2026 年 AI 应用开发必学的 5 项成熟技术","从近半年爆发的技术里，挑出已经过了尝鲜期、能真正用在项目里的 5 项：推理模型、MCP、多模态、GraphRAG、AI 编程工具链，每项都给到能跑通的代码。","AI 工程实践",21]