
对应第一个月计划第 2 周第 1 天理解 RAG 的完整链路、离线与在线阶段、适用场景、失败边界和评测拆分。建议投入45 小时。当天交付RAG 架构说明、场景决策清单、最小关键词检索演示、实验记录与学习复盘。一、今天完成后要达到什么程度完成学习后你应当能够用自己的话解释 RAG并说明它不会修改大模型权重。画出“用户问题 → 检索 → 上下文 → 生成 → 引用验证”的在线链路。区分离线知识处理与在线问答不把所有步骤混成一次模型调用。判断一个需求是否适合使用 RAG并能说明理由。区分检索失败、生成失败与引用失败。理解 RAG 仍可能产生幻觉检索结果不能直接当成正确答案。用纯 Python 完成一个最小关键词检索演示观察 RAG 中“检索”的职责。为后续的文档解析、分块、Embedding 和向量库学习建立正确接口边界。今天重点是架构与边界。不要提前引入 LangChain、复杂向量数据库、混合检索或 Agent。二、当天必须掌握的知识点1. RAG 是什么RAG 是 Retrieval-Augmented Generation即“检索增强生成”。它把两个能力组合起来检索从外部知识源中找到与问题相关的内容生成把问题与检索内容一起交给 LLM生成自然语言回答。最小表达式回答 LLM用户问题 检索到的上下文 回答约束RAG 不会自动训练模型也不会修改模型权重。知识主要保存在外部文档和索引中因此资料更新后可以重新处理或更新索引而不必重新训练模型。2. 为什么需要 RAG仅依赖模型自身知识通常存在这些限制不知道企业内部或个人私有资料训练数据有时间截止点无法自动获得最新内容可能编造看似合理但不存在的事实很难说明答案来自哪份资料无法直接满足文档级权限与审计要求。RAG 的目标不是“让模型无所不知”而是在回答前提供一组可检查的外部证据。3. RAG 的两阶段架构离线知识处理知识源 ↓ 采集与解析 ↓ 清洗与分块 ↓ 补充 metadata ↓ 建立索引 ↓ 保存可检索知识离线阶段关注“如何把资料变成可检索的数据”。典型知识源包括 Markdown、PDF、网页、数据库记录和内部 API。在线问答用户问题 ↓ 查询处理 ↓ 召回候选内容 ↓ 筛选并组装上下文 ↓ LLM 基于上下文回答 ↓ 返回答案、引用和状态在线阶段关注“如何在一次请求中找到证据并生成答案”。必须能够回答哪些步骤可以提前完成哪些步骤必须等用户提问后执行文档更新时需要重做哪些步骤用户问题本身是否应该进入知识库4. RAG 中各组件的职责知识源提供原始事实。知识源本身的正确性、时效性和权限决定了系统质量上限。文档解析器把 PDF、Markdown、网页等格式转成可处理文本同时尽量保留标题、页码、章节和来源。分块器把长文档拆成较小单元。块太大容易引入噪声块太小可能丢失语义和上下文。Day 09 再专门实现解析、分块与 metadata今天先理解它们在架构中的位置。索引与检索器索引让系统能够快速查找候选内容。检索器接收查询并返回相关片段及分数。今天使用关键词重叠实现最小检索Day 10 再学习 Embedding 和本地向量库。上下文构建器负责去除明显重复内容控制上下文长度保留来源信息按稳定格式排列片段明确资料之间的边界。生成器LLM 根据问题、上下文和约束生成回答。它仍可能忽略证据、混淆来源或编造内容所以必须限制“只能依据资料回答”并在应用侧继续验证。引用与验证引用必须能回到原始文档、章节、页码或稳定记录 ID。只显示一个无法定位的“来源 1”不等于可核验引用。5. 哪些场景适合 RAGRAG 通常适合企业制度、产品手册和内部知识库问答内容经常更新无法等待重新训练回答必须附带来源数据不能进入公开搜索引擎需要按用户权限检索不同资料已有大量非结构化文档需要自然语言访问。判断时至少确认是否存在明确的外部知识源用户的问题是否能被这些资料回答资料是否需要频繁更新是否需要引用、审计或权限控制检索延迟和调用成本是否可接受6. 哪些场景不应优先使用 RAG以下需求不一定需要 RAG纯创作、改写、翻译或头脑风暴简单固定规则普通代码即可稳定完成数据已经是结构化字段直接查询数据库更准确要求强事务一致性的余额、库存、支付状态问题本身不依赖外部知识权限模型尚未建立无法保证用户只能看到被授权内容。关键原则能直接查数据库就不要先把数据库内容转成文本再让模型猜。RAG 是知识访问方案不是所有业务查询的通用替代品。7. RAG 的主要失败模式检索失败正确文档没有进入知识库解析丢失了关键内容分块切断了重要语义查询与文档措辞不同top_k太小正确片段未被召回top_k太大噪声淹没证据。上下文失败片段之间互相冲突旧版本与新版本同时出现来源与正文对应关系丢失上下文超过模型窗口不可信文档包含提示注入内容。生成失败模型没有遵守“仅依据上下文”上下文不足时仍强行回答把多个来源错误合并引用编号与实际证据不一致答案表述正确但依据并不支持结论。8. 评测必须拆开不能只问“最终回答看起来好不好”。至少拆成检索质量正确证据是否出现在候选结果中排名是否足够靠前返回内容是否相关而非仅关键词相同是否包含过多重复和噪声生成质量回答是否真正解决问题每个关键结论是否能被上下文支持资料不足时是否明确拒答是否添加了上下文中不存在的事实引用质量引用是否指向正确来源用户是否能定位到原文引用片段是否真的支持相邻结论文档版本与权限是否正确系统指标在线检索耗时首字与总响应时间输入、输出 Token 和费用空结果率、拒答率与错误率。9. 权限与安全边界RAG 会把外部内容送入模型上下文因此必须考虑先做权限过滤再把内容交给 LLM不依赖 Prompt 隐藏用户无权查看的资料文档中的命令只是数据不能覆盖系统规则记录来源 ID不在日志中泄露敏感正文删除或更新资料时同步更新索引对个人信息、密钥和内部数据实施最小化处理。错误做法先检索全部文档 → 交给模型 → 要求模型不要泄露无权限内容正确顺序认证用户 → 计算权限范围 → 仅检索允许的内容 → 生成回答三、一步步达成今天的学习目标第 0 步检查前置基础约 15 分钟确认已经完成或理解Day 01 的模型 API 调用Day 02 的 Token、上下文窗口和多轮消息Day 03 的结构化 Prompt 与结果校验Day 04 的测试集与对比评测Day 05 的成本、超时和错误分类Day 06 的完整调用流程Day 07 的第一周复盘与 RAG 预习。通过标准能够解释“模型上下文有长度上限应用不能无限塞入所有文档”。第 1 步阅读路线图并制作概念卡片约 30 分钟参考顶部图片为以下概念各写一张不超过 100 字的卡片RAG离线知识处理在线问答检索器上下文构建忠实度可核验引用权限前置过滤。每张卡片必须包含一句话定义在链路中的作用一个常见误区。通过标准不看文档能在 2 分钟内讲清完整 RAG 链路。第 2 步手动画两阶段架构约 25 分钟在纸上或笔记中分别画出离线与在线流程。离线图必须包含文档 → 解析 → 分块 → metadata → 索引在线图必须包含问题 → 检索 → 上下文 → 生成 → 引用在两张图之间标出共同的数据接口可检索片段 正文 来源 标题 版本 权限信息然后回答文档内容修改后需要更新哪个阶段用户每次提问时哪些步骤会重复执行为什么来源信息必须在分块时保留下来第 3 步完成场景决策练习约 30 分钟对下面六个需求分别判断根据公司员工手册回答休假制度将一段中文翻译成英文查询用户当前账户余额根据最新版产品说明书排查故障写一个科幻故事开头在授权范围内搜索项目历史设计文档。每个需求使用以下模板记录需求 是否优先使用 RAG 可用知识源 为什么 主要风险 更合适的替代方案参考判断1、4、6 通常适合 RAG2、5 通常直接调用模型即可3 应优先调用受控数据库或业务 API而不是依赖文本检索结果。不要只写“适合/不适合”必须说明知识源、时效、引用和一致性要求。第 4 步创建最小实验项目约 15 分钟在day08中创建mkdirrag-boundary-labcdrag-boundary-labtouchcorpus.json retrieval_demo.py experiment-record.md建议结构rag-boundary-lab/ ├── corpus.json ├── retrieval_demo.py └── experiment-record.md本实验只使用 Python 标准库不接入 Embedding、向量库或框架。目标是观察“先检索再把证据组装成上下文”的架构不是实现生产级搜索。第 5 步准备带来源的最小知识库约 20 分钟将以下内容写入corpus.json[{id:leave-annual,title:年假制度,source:employee-handbook.md#annual-leave,text:正式员工每年享有 10 天带薪年假。年假需要至少提前 3 个工作日申请。},{id:leave-sick,title:病假制度,source:employee-handbook.md#sick-leave,text:病假超过 1 个工作日需要提交医疗证明。病假申请应在考勤系统中登记。},{id:remote-work,title:远程办公制度,source:employee-handbook.md#remote-work,text:远程办公需要直属主管批准每周最多 2 天。},{id:expense,title:差旅报销制度,source:finance-policy.md#travel,text:差旅费用应在行程结束后 10 个工作日内提交报销。}]检查点每条内容有稳定idtext与来源分离source可以定位到原文样本不包含真实公司敏感数据。第 6 步实现最小关键词检索约 40 分钟创建retrieval_demo.pyimportjsonimportrefrompathlibimportPathdeftokenize(text:str)-set[str]:texttext.lower()english_wordsre.findall(r[a-z0-9],text)chinese_charsre.findall(r[\u4e00-\u9fff],text)chinese_bigrams[.join(chinese_chars[index:index2])forindexinrange(len(chinese_chars)-1)]returnset(english_wordschinese_charschinese_bigrams)defretrieve(query:str,documents:list[dict],top_k:int2)-list[dict]:query_tokenstokenize(query)scored[]fordocumentindocuments:document_tokenstokenize(f{document[title]}{document[text]})overlapquery_tokensdocument_tokens scorelen(overlap)ifscore0:scored.append({**document,score:score,matched_tokens:sorted(overlap),})scored.sort(keylambdaitem:item[score],reverseTrue)returnscored[:top_k]defbuild_context(results:list[dict])-str:ifnotresults:return没有检索到可用资料。blocks[]forindex,iteminenumerate(results,start1):blocks.append(f[资料{index}]\nf标题{item[title]}\nf来源{item[source]}\nf正文{item[text]})return\n\n.join(blocks)defmain()-None:documentsjson.loads(Path(corpus.json).read_text(encodingutf-8))queryinput(请输入问题).strip()resultsretrieve(query,documents)print(\n检索结果)foriteminresults:print(f-{item[title]}| score{item[score]}| fsource{item[source]})print(\n准备交给模型的上下文)print(build_context(results))if__name____main__:main()运行python3 retrieval_demo.py输入年假要提前几天申请检查点返回内容包含“年假制度”输出保留来源上下文中没有整个知识库程序只完成检索和上下文组装没有假装自己是完整 RAG能解释关键词检索为什么无法可靠处理同义词和复杂语义。第 7 步做四组检索边界实验约 35 分钟依次测试1. 年假要提前几天申请 2. 生病两天要提供什么材料 3. 居家办公一周可以几天 4. 公司食堂几点关门把结果写入experiment-record.md# Day 08 RAG 边界实验记录 ## 实验 1 - 问题 - 预期证据 - 实际 top_k - 是否召回正确资料 - 是否包含噪声 - 观察 ## 实验结论 1. 关键词匹配有效的情况 2. 关键词匹配失败的情况 3. 为什么后续需要 Embedding 4. 空检索时系统应该如何回答第 4 个问题不在资料中。正确行为是返回空结果并明确“资料不足”而不是根据常识编造营业时间。第 8 步设计生成阶段 Prompt约 25 分钟先只设计模板不要求今天一定接入模型System 你是企业知识库问答助手。 只能依据“参考资料”回答。 资料不足或互相冲突时必须明确说明不能自行补充。 每个关键结论后标注对应的 [资料 N]。 User 问题 {{query}} 参考资料 {{context}} 请输出 1. 简洁回答 2. 引用列表 3. 如果资料不足说明缺少什么信息。检查模板是否覆盖仅依据上下文缺失时拒答冲突时不静默选择结论与引用绑定没有把文档中的指令提升为系统命令。即使 Prompt 写得很好也不能保证绝对忠实应用仍需评测。第 9 步拆分检索与生成评测约 25 分钟为问题“年假要提前几天申请”分别定义检索通过标准leave-annual出现在 top 2返回片段包含“提前 3 个工作日”来源为employee-handbook.md#annual-leave。生成通过标准回答包含“至少提前 3 个工作日”没有添加资料中不存在的审批流程引用指向年假制度而不是病假制度资料为空时不生成具体天数。通过标准能解释“检索通过但最终回答仍可能失败”的至少两个原因。第 10 步完成安全与权限检查约 20 分钟对你的架构逐项确认用户身份在检索前已经确定检索范围按权限过滤未授权片段不会进入模型上下文文档正文不会覆盖 system 指令日志不记录敏感全文引用可定位但不会泄露无权限路径删除资料时有同步删除索引的方案测试知识库不包含真实密钥或隐私数据。写一句话解释为什么“模型答复时不显示秘密”不能替代检索前的权限过滤第 11 步复盘与口头验收约 25 分钟不看文档回答RAG 的三个英文单词分别代表什么RAG 与模型微调有什么区别离线阶段和在线阶段分别做什么为什么不能把全部文档直接塞进 Prompt哪三类需求通常适合 RAG为什么余额查询不应优先使用 RAG检索到相关片段后为什么答案仍可能错误检索评测与生成评测为什么必须拆开什么样的引用才算可核验权限过滤为什么必须发生在内容进入 LLM 之前关键词检索有什么局限Day 09 与 Day 10 将分别补齐哪部分能力第 12 题参考答案Day 09文档解析、分块和 metadataDay 10Embedding 与本地向量库检索。四、今天必须遵守的工程原则检索到不等于回答正确检索只能提供候选证据。模型仍可能忽略、误读、混合或补充上下文中不存在的内容。有上下文不等于没有幻觉必须要求资料不足时拒答并使用测试集检查忠实度不能只相信 Prompt。引用必须可核验来源应该指向稳定文档、章节、页码或记录 ID不能只显示无法追踪的编号。权限必须在检索前生效不应该把无权限内容交给模型后再期待模型通过文字约束保密。先建立基线再学习复杂检索今天的关键词检索是可解释基线。后续加入 Embedding、混合检索和 rerank 时应与基线使用同一测试集比较。结构化数据优先使用确定性接口余额、库存、订单状态等实时结构化数据应优先通过数据库或业务 API 获取LLM 只负责解释不负责猜测。五、常见问题排查关键词检索完全没有结果检查查询分词、中文字符处理、文档字段是否加载成功以及当前工作目录中是否存在corpus.json。检索结果相关但回答错误分别检查正确证据是否真的进入上下文上下文是否混入冲突旧版本Prompt 是否要求仅依据资料模型是否把引用与结论对应错误。不要仅通过增大top_k解决。更多结果也会带来更多噪声。空结果时模型仍然回答在 Prompt 中明确“资料不足必须拒答”并在调用模型前加入应用侧判断检索结果为空时直接返回缺少资料的状态。引用编号与来源错位上下文构建时为每个片段生成稳定编号并让答案引用该编号。返回后还应检查引用编号是否存在。文档更新后仍回答旧内容检查旧片段是否已删除、索引是否重建、缓存是否过期以及新旧版本是否同时可检索。中文关键词匹配效果差今天的字符与二元组方案只是教学基线。它不能可靠理解同义词、语序和语义关系。Day 10 再用 Embedding 改善语义召回。资料中包含“忽略之前指令”将文档内容视为不可信数据使用清晰分隔符包裹不执行文档中的命令并通过系统规则、输入清洗和权限策略降低提示注入风险。六、当日验收清单能用自己的话解释 RAG且不会把它说成模型训练。能画出离线知识处理与在线问答两条链路。能说明解析、分块、索引、检索、上下文、生成和引用的职责。已完成六个场景的适用性判断并写出理由。corpus.json包含正文、稳定 ID 与来源。retrieval_demo.py能返回关键词检索结果并组装上下文。已完成四个查询实验其中包含一个资料外问题。空检索不会被伪装成有效答案。已写出只依据上下文、资料不足时拒答的 Prompt 模板。能分别定义检索、生成和引用的通过标准。能解释至少三种 RAG 失败模式。能说明为什么权限过滤必须发生在检索阶段。没有在资料、代码、日志或图片中写入真实密钥。能脱离文档回答十二个复盘问题。全部完成后Day 08 即为通过。此时你应理解 RAG 的架构与适用边界Day 09 再进入文档解析、分块和 metadataDay 10 再实现 Embedding 与本地向量检索。