教学项目 · 虚构文档 · 最近核验:2026-10。附标准库代码,不需要模型 API;完整的模型生成与部署不在本例中。
“连上向量数据库,再把结果塞给 LLM”,确实能做出一个 RAG 演示。真正用起来,问题通常出在别处:规定已经改了,助手还在引用旧版;答案看着对,引用却支撑不了它;文档搜到了,但这个用户本来就没有权限看。
这几篇从一个小知识库开始,讲清数据怎样更新、资料怎样检索(retrieval),以及答案怎样检查。RAG(retrieval-augmented generation,检索增强生成)的基本做法是先找资料,再让模型参考资料回答。但“搜到了”不等于“搜对了”,还要检查版本、权限和内容本身。原始论文
报名日期改了,助手知道吗?
虚构的社区有一份活动规则。旧版写“报名截止到周五”,新版改成了“周三”;另有一份只有组织者可见的预算说明。普通成员问:“这次最晚哪天报名?”
| 文档 | 内容 | 能否作为这次回答的依据 |
|---|---|---|
| rules-v1 | 报名截止到周五 | 不能:已被新版取代 |
| rules-v2 | 报名截止到周三 | 可以:当前生效、成员可见 |
| budget-v1 | 组织者内部预算 | 不能:无权限,也不回答这个问题 |
理想回答很简单:“周三截止,依据是活动规则 v2。”难点在于,新版已经生效,索引却可能还没更新完。我们在这个项目中选择:暂时查不到当前规则,就说明情况,不拿旧日期来凑答案。其他场景是否允许展示带日期的旧资料,需要另行约定。
文档更新和用户提问,分开处理
- 01 / 文档更新规则改为周三记录文档版本与权限,不能只替换正文。
- 02 / 准备证据按章节切块保留原文位置;需要向量时,在这里编码。
- 03 / 更新索引v2 成为当前版本旧片段不能继续充当现行规则。
- 04 / 用户提问最晚哪天报名?结合身份,只查询可见且生效的内容。
- 05 / 选择证据把 v2 放进上下文合并、去重、重排,再选择长度允许的段落。
- 06 / 形成回答周三,依据是 v2证据不足时说明缺什么,不偷偷引用 v1。
前 3 格是更新路径,后 3 格是请求路径。文档更新时可以提前算向量;用户提问时才知道身份和问题,不能把权限交给提前算好的向量来保证。
生成模型拿到的也不应该只是一串段落。至少要带可引用的 ID、版本和原文位置。这样模型说错了,我们才分得清:材料没找到、找错了版本,还是材料在眼前却读错了。
先从关键词检索开始
| 第一步做什么 | 能回答的工程问题 | 暂时不解决什么 |
|---|---|---|
| 关键词匹配 + 当前版本/权限过滤 | 数据是否进来了、限制是否生效 | 同义改写和复杂语义 |
| 再加 embedding 检索 | 问法不同但含义相近时,是否找得更全 | 数字正确性、权限、引用真实性 |
| 在少量候选(candidate)上重排(reranking) | 前几段是否更贴近当前问题 | 不在候选里的证据 |
| 接生成模型 | 能否把证据组织成清楚的回答 | 系统是否允许看这份文档 |
例如,文档用“截止日期”,用户问“最晚哪天报名”,简单的词项匹配可能漏掉它。这时值得加入向量检索,比较它能否找回同义表达。可如果搜到的一直是旧版,首先要修的是更新流程,而不是换模型。
选择模型时,我们比较同一份文档快照、同一批问题、同一上下文预算。否则多塞几倍文字带来的收益,很容易被误写成 encoder 更好。
这 3 篇怎么读
- 本篇确定要回答什么、哪些错误不能接受。
- 文档怎么进来,证据怎么找:版本、权限、切块、两路召回和上下文预算;附可运行 Python。
- 答案有引用,就算答对了吗:证据不足、来源冲突、拒答与回归测试。我们先只处理文本,不把图片理解也算进来。
代码只用 Python 标准库。它让你看见每一步输入输出,不模拟一个已经训练好的检索器,也不声称测过模型回答质量。
第一版要通过哪些检查?
第一版先看这 4 种情况:
- 规则更新后,不再把旧版当成当前依据。
- 换成没有权限的用户,私有文档不进入模型上下文。
- 删掉支持答案的段落,系统能指出依据不足。
- 检索服务故障时,返回故障状态,不误报成“知识库里没有答案”。
这些检查通过后,再接生成模型,比较回答质量、延迟和成本。这样遇到错误时,至少知道该从哪一步查起。
本页术语 2
- 检索 retrieval
- 从外部语料里找出相关内容
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容