RAG:让 AI 使用私有知识
RAG 是 AI 学习路线的第四章。
前三章分别解决了三个基础能力:Prompt 让需求表达更清楚,Structured Output 让输出可以被程序处理,Tool Calling 让 AI 可以调用外部工具。到了第四章,我们要解决一个更贴近真实项目的问题:如何让 AI 基于你的私有资料回答问题。
通用模型知道很多公开知识,但它并不了解你的公司文档、项目代码、内部接口、产品需求、测试用例、运维手册和历史决策。直接让模型回答这些问题,很容易出现猜测、漏答或编造。RAG 的作用,就是把真实资料检索出来,放进模型上下文里,让回答尽量基于可追溯的资料。
这一章要解决的问题是:
如何让 AI 基于文档、代码和知识库回答问题,并给出可检查的来源。
学完这一章,你应该能做到三件事:
- 把文档切分、向量化并建立可检索知识库
- 根据用户问题检索相关内容并拼接上下文
- 评估回答是否基于资料、是否引用准确、是否降低幻觉
1. RAG 是什么
RAG 全称是 Retrieval-Augmented Generation,意思是“检索增强生成”。
它的基本思路是:先从知识库中检索相关资料,再把资料交给模型生成回答。
典型流程如下:
用户提问 ↓把问题转换成检索查询 ↓从知识库中检索相关片段 ↓筛选、排序、拼接上下文 ↓把问题和上下文一起发给模型 ↓模型基于上下文生成回答 ↓输出答案和引用来源示例:
用户:登录接口密码错误时会返回什么错误码?
RAG 系统检索:- docs/api-login.md- tests/auth/login-cases.md- src/routes/auth.ts
模型基于检索结果回答:密码错误时返回 401,错误码为 INVALID_PASSWORD,响应体包含 message 字段。来源:docs/api-login.md。RAG 的核心价值,是让 AI 回答时有资料依据。
2. 为什么需要 RAG
在真实项目里,很多问题只有内部资料里才有答案。
常见场景包括:
- 根据产品需求回答功能规则
- 根据接口文档生成调用示例
- 根据代码库解释实现逻辑
- 根据测试用例查覆盖情况
- 根据运维手册定位部署问题
- 根据公司制度回答流程问题
- 根据历史会议纪要追溯决策原因
如果没有 RAG,模型只能依赖训练知识和当前对话上下文。对于私有资料、最新资料、项目细节,它很容易给出不可靠答案。
RAG 能带来几个直接收益:
- 回答更贴近真实资料
- 可以引用来源,方便核查
- 知识库可以持续更新
- 减少模型编造
- 支持企业内部文档问答
- 支持代码库理解和项目助手
- 降低每次手动粘贴资料的成本
RAG 很适合需要“有据可查”的 AI 场景。
3. RAG 的基本组成
一个基础 RAG 系统通常包含这些部分:
- 原始资料
- 文档解析
- chunking
- embedding
- 向量数据库
- vector search
- rerank
- context 拼接
- 回答生成
- 引用来源
- 检索质量评估
可以把它分成两个阶段:
离线阶段:资料入库原始文档 → 解析 → 切分 → embedding → 存入向量库
在线阶段:用户问答用户问题 → embedding → 检索 → rerank → 拼接上下文 → 模型回答离线阶段决定知识库质量,在线阶段决定回答质量。
4. 原始资料
RAG 的效果首先取决于资料质量。
常见资料来源包括:
- Markdown 文档
- Word / PDF 文档
- 接口文档
- 产品需求文档
- 设计稿说明
- 代码文件
- 测试用例
- FAQ
- 会议纪要
- 工单记录
- 数据库导出的知识条目
资料入库前要先整理几个问题:
- 哪些资料允许被 AI 使用
- 哪些资料需要脱敏
- 哪些资料已经过期
- 哪些资料有版本差异
- 哪些资料需要保留来源路径
- 哪些资料需要按权限隔离
RAG 不能自动修复脏资料。资料本身混乱,回答也会跟着混乱。
5. 文档解析
文档解析的目标,是把不同格式的资料转换成可处理文本。
常见解析内容包括:
- 标题
- 正文
- 表格
- 列表
- 代码块
- 图片说明
- 页码
- 文件路径
- 元数据
不同格式需要不同策略:
- Markdown:保留标题层级、代码块和列表
- PDF:注意分页、页眉页脚、表格错位
- Word:注意标题样式、表格和批注
- HTML:去掉导航、广告、脚本等无关内容
- 代码:保留文件路径、函数名、类名和注释
解析质量会直接影响 chunking 和检索效果。
示例元数据:
{ "source": "docs/api-login.md", "title": "登录接口说明", "section": "错误码", "page": null, "updated_at": "2026-05-28"}元数据越完整,后续引用和过滤越方便。
6. chunking
chunking 指的是把长文档切成适合检索的小片段。
模型上下文有限,向量检索也不适合直接处理整本文档。所以需要把资料切成 chunk。
常见切分方式:
- 按固定字数切分
- 按段落切分
- 按标题层级切分
- 按语义完整单元切分
- 按代码函数或类切分
- 按表格行或业务条目切分
6.1 固定长度切分
固定长度切分实现简单。
示例:
每 800 字切一段,相邻段落重叠 100 字。优点:
- 实现简单
- 适合快速原型
- chunk 大小容易控制
缺点:
- 可能切断句子
- 可能切断表格或代码
- 可能破坏语义完整性
6.2 按标题切分
Markdown、Word、HTML 文档通常适合按标题切分。
示例:
# 登录接口## 请求参数## 响应字段## 错误码每个标题下的内容可以成为一个 chunk,并保留标题路径:
{ "source": "docs/api-login.md", "heading_path": ["登录接口", "错误码"], "content": "密码错误时返回 401,错误码 INVALID_PASSWORD。"}这种方式更容易保留语义边界。
6.3 按代码结构切分
代码库 RAG 适合按文件、函数、类、接口切分。
示例:
{ "source": "src/routes/auth.ts", "symbol": "loginHandler", "kind": "function", "content": "async function loginHandler(...) { ... }"}代码 chunk 最好保留:
- 文件路径
- 符号名
- 类型
- 注释
- 导入关系
- 调用关系
如果只是按固定长度切代码,容易切断函数和上下文。
6.4 chunk 大小
chunk 太小,容易丢上下文。chunk 太大,容易带入无关内容。
常见经验值:
- FAQ:100-300 字
- 产品文档:400-1000 字
- 技术文档:500-1200 字
- 代码函数:按函数或类边界
- 表格:按业务行或主题分组
可以先从 500-800 字开始,再根据检索效果调整。
7. embedding
embedding 指的是把文本转换成向量。
向量可以理解成文本在语义空间里的坐标。意思相近的文本,向量距离通常更近。
示例:
文本 A:如何重置密码?文本 B:忘记密码怎么办?这两句话字面不同,但语义接近,embedding 后的向量距离应该比较近。
RAG 中通常会对两类内容生成 embedding:
- 文档 chunk
- 用户问题
检索时,把用户问题的向量和知识库中 chunk 的向量做相似度比较,找出最相关的资料。
embedding 需要注意:
- 使用同一个 embedding 模型处理文档和问题
- 入库后记录 embedding 模型版本
- 文档更新后重新生成对应向量
- 多语言场景要选择支持中文的模型
- 长文本要先切分再生成 embedding
embedding 是语义检索的基础。
8. vector search
vector search 指的是向量检索。
常见流程:
用户问题 → 生成问题向量 → 在向量库中查相似 chunk → 返回 topK 结果常见相似度指标包括:
- cosine similarity
- dot product
- Euclidean distance
一般实现时不用手写底层算法,可以使用现成向量数据库或检索引擎。
常见选择包括:
- PostgreSQL + pgvector
- Elasticsearch / OpenSearch
- Qdrant
- Milvus
- Weaviate
- Chroma
- SQLite 向量扩展
vector search 适合解决“语义相似”的问题。
示例:
用户问:用户登录失败有哪些原因?
可能检索到:- 登录接口错误码- 用户状态说明- 密码校验逻辑- 登录测试用例9. 关键词检索和混合检索
向量检索擅长语义相似,但对精确关键词有时不够敏感。
例如:
- 错误码:E10032
- 接口名:POST /api/v1/login
- 函数名:createUserSession
- 配置项:ENABLE_RAG_CACHE
- 文件名:wrangler.toml
这类内容更适合关键词检索。
所以真实系统里常用 hybrid search,也就是混合检索:
向量检索 + 关键词检索 + 过滤条件常见过滤条件包括:
- 文档类型
- 文件路径
- 更新时间
- 业务模块
- 权限范围
- 语言
- 标签
示例:
{ "query": "登录失败错误码", "filters": { "module": "auth", "doc_type": "api" }}混合检索通常比单一向量检索更稳。
10. rerank
初次检索返回的结果不一定最适合回答问题。rerank 的作用是对候选结果重新排序。
常见流程:
向量库先返回 top 30 ↓reranker 对 top 30 重新评分 ↓选出最相关的 top 5 ↓拼接进模型上下文rerank 可以改善这些问题:
- 向量相似但内容不回答问题
- 关键词命中但上下文无关
- 多个 chunk 重复
- 重要资料排名靠后
rerank 策略包括:
- 使用 rerank 模型
- 使用关键词命中加权
- 使用标题和路径加权
- 使用更新时间加权
- 使用用户权限过滤
- 去除重复或高度相似 chunk
RAG 系统复杂后,rerank 对回答质量影响很大。
11. context 拼接
检索到资料后,需要把资料拼接成模型能理解的上下文。
拼接时要注意:
- 保留来源路径
- 保留标题层级
- 控制总长度
- 删除重复内容
- 优先放高相关资料
- 给每个片段编号
- 区分资料内容和用户问题
示例:
请只基于以下资料回答问题。如果资料不足,请说明缺少哪些信息。
[资料 1]来源:docs/api-login.md标题:登录接口 / 错误码内容:密码错误时返回 401,错误码 INVALID_PASSWORD。
[资料 2]来源:tests/auth/login-cases.md标题:密码错误测试内容:输入错误密码时,预期返回 401,并提示用户名或密码错误。
用户问题:登录接口密码错误时会返回什么?这种格式能让模型更容易引用资料,也方便后续检查答案来源。
12. 引用来源
RAG 回答最好带来源。
引用来源可以帮助用户:
- 核对答案
- 判断资料是否过期
- 找到原文继续阅读
- 追溯决策依据
- 发现知识库缺口
常见引用信息包括:
- 文件路径
- 文档标题
- 章节标题
- 页码
- chunk 编号
- 更新时间
- URL
示例回答:
密码错误时,登录接口返回 401,错误码为 INVALID_PASSWORD。
来源:1. docs/api-login.md / 登录接口 / 错误码2. tests/auth/login-cases.md / 密码错误测试引用要和实际检索资料一致。不能在没有资料支撑的情况下编造来源。
13. 幻觉控制
RAG 可以降低幻觉,但不能完全消除幻觉。
常见幻觉来源包括:
- 检索结果不相关
- 检索结果不完整
- 资料本身过期
- 多份资料互相矛盾
- 模型忽略上下文
- Prompt 允许自由发挥过多
- 用户问题超出资料范围
控制方法:
- 要求模型只基于资料回答
- 资料不足时明确说无法确认
- 回答中标注推断内容
- 给结论附来源
- 对关键字段做程序校验
- 用 Eval 测试回答质量
- 检测引用是否真实存在
- 对高风险答案增加人工审核
示例 Prompt:
请只基于提供的资料回答问题。如果资料中没有答案,请回答“资料不足,无法确认”。如果需要推断,请单独标注为“推断”。每个关键结论都要给出来源。这个规则能明显减少无依据扩写。
14. 知识库更新
RAG 系统必须处理资料更新。
常见更新场景:
- 新增文档
- 修改文档
- 删除文档
- 文档改名
- 权限变化
- 版本发布
- 历史资料归档
更新策略包括:
- 全量重建
- 增量更新
- 定时同步
- 文件变更监听
- 手动触发重建
- 按文档版本保留历史
每个 chunk 建议记录:
- source
- content_hash
- embedding_model
- updated_at
- version
- permission_scope
示例:
{ "source": "docs/api-login.md", "chunk_id": "api-login-error-codes-001", "content_hash": "a1b2c3", "embedding_model": "text-embedding-model-x", "updated_at": "2026-05-28", "version": "v1.3", "permission_scope": "internal"}这样可以判断哪些 chunk 需要重新生成 embedding。
15. 权限和隐私
RAG 很容易接触敏感资料,权限和隐私必须提前设计。
需要重点关注:
- 用户是否有权限访问某份文档
- 检索结果是否包含敏感信息
- 回答是否泄露 token、密钥、手机号、身份证号等内容
- 日志是否保存了敏感资料
- embedding 数据是否可以被外部服务读取
- 删除资料后,向量库是否同步删除
常见措施:
- 入库前脱敏
- 查询时按用户权限过滤
- 敏感字段不入库
- 高敏文档单独隔离
- 回答前做敏感信息检测
- 删除资料时同步删除 chunk 和向量
- 记录访问审计日志
RAG 系统一旦进入企业内部资料,权限控制就是基础能力。
16. 检索质量评估
RAG 系统需要评估检索质量。只看最终回答好不好,往往难以定位问题。
可以从两个层面评估:
- 检索是否找到了正确资料
- 回答是否正确使用了资料
常见指标包括:
- Recall@K:正确资料是否出现在前 K 个结果里
- Precision@K:前 K 个结果里有多少真正相关
- MRR:第一个正确结果排名是否靠前
- Answer Accuracy:回答是否正确
- Citation Accuracy:引用是否支撑结论
- Hallucination Rate:无依据内容比例
示例测试集:
[ { "question": "登录接口密码错误时返回什么错误码?", "expected_sources": ["docs/api-login.md"], "expected_answer_keywords": ["401", "INVALID_PASSWORD"] }, { "question": "如何重置用户密码?", "expected_sources": ["docs/user-password.md"], "expected_answer_keywords": ["验证码", "新密码", "确认密码"] }]有了测试集,才能判断 chunking、embedding、rerank、Prompt 调整后效果是否变好。
17. 常见 RAG 问题
17.1 检索不到正确资料
可能原因:
- chunk 切得太碎
- chunk 切得太大
- embedding 模型不适合中文
- 关键词内容没有命中
- 文档没有成功入库
- 查询改写效果差
- 权限过滤过严
排查方法:
- 直接搜索原文关键词
- 查看 topK 检索结果
- 检查 chunk 内容和元数据
- 检查 embedding 模型版本
- 临时放宽过滤条件
- 对比向量检索和关键词检索结果
17.2 检索结果相关但回答错误
可能原因:
- Prompt 没有限制只基于资料回答
- 上下文里有互相矛盾的资料
- 模型忽略了关键片段
- 引用和结论没有绑定
- 问题需要多跳推理
处理方式:
- 把资料编号
- 要求每个结论附来源
- 去除重复和过期资料
- 增加 rerank
- 对冲突资料提示模型说明差异
17.3 回答没有引用来源
可能原因:
- context 里没有保留来源
- Prompt 没有要求引用
- 输出格式没有来源字段
- 模型把来源省略了
处理方式:
- 在每个 chunk 前加来源信息
- 输出格式中固定
sources字段 - 对无来源结论进行校验
17.4 知识库过期
可能原因:
- 文档更新后没有重新入库
- 删除文档后向量库仍保留旧 chunk
- 多版本文档混在一起
- 没有记录更新时间
处理方式:
- 增加 content_hash
- 增加增量同步
- 增加版本字段
- 检索时优先使用最新资料
- 对过期资料做归档或降权
18. RAG Prompt 示例
基础问答 Prompt:
你是一个项目知识库问答助手。
请只基于提供的资料回答用户问题。
规则:1. 如果资料中有明确答案,请给出简洁回答。2. 如果资料不足,请回答“资料不足,无法确认”。3. 如果资料之间存在冲突,请说明冲突点。4. 每个关键结论都要标注来源。5. 不要补充资料中没有出现的功能、字段或规则。
资料:[资料 1]来源:...内容:...
[资料 2]来源:...内容:...
用户问题:...结构化输出 Prompt:
请根据资料回答问题,并输出 JSON。
输出格式:{ "answer": "回答内容", "confidence": "high | medium | low", "sources": [ { "source": "文件路径或 URL", "section": "章节标题", "evidence": "支撑结论的简短原文摘要" } ], "missing_information": ["资料不足时列出缺失信息"]}
规则:1. 只基于资料回答。2. 没有来源支撑的内容不要写入 answer。3. 资料不足时,confidence 使用 low。RAG 和 Structured Output 结合后,答案更容易进入后续程序流程。
19. RAG 实战练习
可以按下面顺序练习:
- 做一个本地 Markdown 文档问答系统
- 给每个回答附上来源路径
- 调整 chunk size,对比检索结果
- 给知识库增加关键词检索
- 实现向量检索和关键词检索的混合检索
- 给 topK 结果增加 rerank
- 做一个代码库问答系统
- 做一个产品需求知识库
- 设计 30 条 RAG 测试问题
- 统计回答准确率和引用准确率
每个练习都可以检查三个问题:
- 是否检索到了正确资料
- 回答是否基于资料
- 来源是否能支撑结论
20. 阶段验收标准
学完这一章,可以用下面的问题检查自己:
- 我能不能把文档解析成可入库文本?
- 我能不能选择合适的 chunking 策略?
- 我能不能为 chunk 生成 embedding?
- 我能不能使用 vector search 找到相关资料?
- 我能不能结合关键词检索提升精确匹配能力?
- 我能不能对检索结果 rerank?
- 我能不能把检索结果拼接成清晰上下文?
- 我能不能让回答带来源?
- 我能不能处理资料不足和资料冲突?
- 我能不能设计 RAG 测试集评估效果?
如果这些问题大多数都能做到,说明 RAG 阶段已经基本合格。
21. 本章总结
RAG 的核心是把真实资料检索出来,交给模型基于资料回答问题。
一套可用的 RAG 系统,建议至少包含:
- 清晰的资料范围
- 稳定的文档解析
- 合理的 chunking 策略
- 可追踪的 embedding 入库流程
- vector search
- 关键词检索或混合检索
- rerank
- 清晰的 context 拼接
- 引用来源
- 幻觉控制
- 知识库更新机制
- 权限和隐私控制
- 检索质量评估
RAG 是 AI 工程化路线中非常重要的一步。它让 AI 可以使用你的项目文档、代码、需求、测试用例和内部知识库。
这一章的目标很明确:让 AI 回答时有资料依据,让用户能检查来源,让系统能持续更新和评估。