RAG 系统入门
RAG(Retrieval-Augmented Generation)是在推理时检索外部证据,再把获授权、版本正确的内容组装给模型。它解决的是知识访问与证据问题,不会自动解决业务权限、工具副作用、长期记忆或模型行为适配。
RAG 在 AI 系统中的位置
Offline path
Sources → Parse → Chunk → Metadata → Embed → Versioned Index
Online path
User + Identity → Query → Permission Filter → Retrieval
→ Context Assembly → Generation
→ Citation Validation → Human/Policy Review
RAG 是 Context Engineering 的一种动态信息来源。System Policy、当前业务状态、Tool Result 和 Memory 仍有各自的来源、权限与生命周期。
什么时候应该使用 RAG
| 问题 | RAG 是否合适 | 原因 |
|---|---|---|
| 回答企业内部政策 | 通常适合 | 需要私有、可更新证据 |
| 查询精确订单状态 | 单独 RAG 不合适 | 应调用数据库/API Tool |
| 改变固定输出语气 | 通常不需要 | Prompt 或 Fine-Tuning 候选 |
| 记住某用户长期偏好 | 不是 RAG 主职责 | 需要 Memory lifecycle |
| 根据文档生成可引用摘要 | 适合 | 证据可追溯 |
| 没有任何可靠资料的预测 | 不适合 | Retrieval 无法创造事实 |
三个必须先定义的 Contract
1. Ingestion Contract
{
"document_id": "POL-001",
"version": "2026-09-08",
"content_hash": "sha256:...",
"data_class": "internal",
"permission_scope": ["care-staff"],
"parser_version": "...",
"chunker_version": "...",
"embedding_contract": "policy-index-v3",
"status": "active"
}
它回答:来源是谁、能不能用、哪个版本有效、如何更新和删除、失败时是否进入 quarantine。
2. Retrieval Contract
定义 query normalization、query/document embedding compatibility、mandatory filters、top-k、distance/score semantics、timeout、no-result 和 trace。
3. Answer Contract
{
"answer": "...",
"claims": [{ "text": "...", "source_ids": ["POL-001#p2#c3"] }],
"status": "supported",
"review_required": false
}
status 可以是 supported、partial、conflict 或 no_answer。引用编号必须来自程序提供的 retrieved chunks,不能让模型自己发明。
Offline Ingestion Pipeline
source manifest
→ validate permission / format / hash
→ parse or OCR
→ normalize without losing lineage
→ chunk with metadata
→ embed with exact model/config
→ write versioned index
→ completeness and retrieval smoke test
Chunk 不只是 text
每个 chunk 至少保存:
document_id、document_version、chunk_id;- page、section、heading path 或 timestamp;
content_hash与 source anchor;- data class 与 permission scope;
- parser、chunker、embedding、index version;
- active/superseded/deleted 状态。
不存在通用的 chunk_size=500。合同、FAQ、表格和代码的边界不同;应该比较 structure-aware、recursive 或其他候选,并用 retrieval dataset 决定。
Retrieval Embedding 与 Index Compatibility
Query 与 Document 必须使用兼容的 embedding contract。更换 model、dimension、normalization、query prefix 或 distance function 后,通常需要新索引。
old index ── current traffic
new index ── backfill → verify → shadow query → regression
→ canary → cutover → rollback window
不能把新旧向量混进同一个空间,也不能把不同模型的 similarity score 直接横向比较。
Permission-Aware Retrieval
权限过滤必须发生在把内容交给模型之前:
actor + tenant + purpose
↓
mandatory ACL / metadata filter
↓
rank only allowed candidates
“先检索全部文档,再在 Prompt 里告诉模型不要泄露”不是访问控制。Filter decision、tenant、policy version 和 candidate IDs 应进入审计记录,但日志不能泄露完整敏感内容。
Grounding 与 Citation
Grounding 需要检查“每个 factual claim 是否被 evidence 支持”,而不是回答里是否出现 [1]。
| 状态 | 系统行为 |
|---|---|
| Evidence 完整 | 回答并绑定 source IDs |
| Evidence 部分充分 | 只回答支持部分 |
| Evidence 冲突 | 展示冲突来源与版本,进入复核 |
| Evidence 不足 | no_answer,不使用模型记忆补全 |
| Source 过期或越权 | 排除并记录原因 |
Deterministic check 可以证明 source ID 存在,但“source 是否真的支持 claim”仍需要 rubric、Judge 校准或人工抽检。
Failure Taxonomy
| 层 | 典型失败 | 先看什么 |
|---|---|---|
| Ingestion | 漏页、乱码、旧版本 | manifest、parse report、lineage |
| Chunking | 关键信息被切断 | chunk boundaries、relevant IDs |
| Retrieval | 相关证据不在 top-k | ranked results、hard negatives |
| Permission | 命中另一租户资料 | filter decision、actor scope |
| Assembly | 证据被截断或污染 | Context Trace |
| Generation | claim 无证据、过度概括 | claim-source review |
| Citation | ID 存在但不支持 claim | source content + rubric |
只有先定位层级,才知道应该改 parser、chunking、filter、retriever、context assembly 还是 answer contract。
Evaluation Dataset
一条可靠 case 至少包含:
case_id: RAG-017
question: '...'
actor_scope: ['care-staff']
reference_document_ids: ['POL-001']
reference_claims: ['...']
expected_status: supported
failure_tags: ['version-sensitive']
Dataset 需要覆盖:
- 普通相关问题;
- 关键词相似但业务不相关的 hard negatives;
no_answer;- superseded 与 conflicting policy;
- 中文、英文、缩写和拼写变化;
- tenant、role 和 permission 边界。
检索可按任务选择 Recall@k、MRR、nDCG 或命中率;生成再检查 Faithfulness、Answer Relevancy、citation support 与人工 judgement。指标必须连同 dataset、corpus、model、index 和 filter version 报告。
常见错误
| 错误 | 为什么不成立 | 修正 |
|---|---|---|
| top-k 越大越好 | 无关 context 增多 | 用 dataset 比较 |
| similarity 是置信度 | 只是当前空间的排序信号 | 校准 + no-answer cases |
| Prompt 写“不要编造”就安全 | 不提供权限或事实保证 | filters + validation + review |
| 向量库里删了 metadata 就够 | vector 可能仍存在 | deletion verification |
| 更新模型只改一行 ID | vector space 已变化 | 新索引迁移 |
| RAGAS 高分即可上线 | metric/judge 有盲区 | 人工抽检 + failure analysis |
动手练习
用一组 synthetic policy 完成:
- source manifest 与版本化 chunks;
- 一个本地 index;
- mandatory permission filter;
- supported、partial、conflict、no-answer 四类输出;
- 10 条 retrieval cases 和失败分类;
- 一次文档更新、删除与 index rebuild 演练。
完成证据
- manifest、chunk sample 与 index manifest;
- query trace 与 ranked results;
- claim-source validation;
- dataset 与真实 metric report;
- update/delete/rebuild 结果;
- 已知限制与下一步 ADR。
自检
- 能画出 offline ingestion 与 online query 两条路径。
- 能区分 retrieval failure 和 generation failure。
- Permission filter 在模型看到内容之前执行。
- Citation 能回到 document/version/page/chunk。
- 没有固定 chunk size、top-k 或 similarity threshold 的万能配方。
- 文档能更新、撤销、删除和重建索引。
- 没有足够证据时系统返回
no_answer。
📚 相关资源
❓ 常见问题
点击问题,查看本章对应的实践答案。
RAG 和直接问大模型有什么区别?什么时候该用 RAG?
RAG 让模型「先检索再回答」,解决知识时效和私有数据问题。适合企业知识库问答、文档助手、客服 FAQ、合规检索、代码库问答。不适合需要强推理但无资料支撑的任务。流程是:用户问题 → 向量化 → 检索 → 构建上下文 → LLM 生成 → 返引用/信心分。
chunk 应该切多大?overlap 设多少?
用 RecursiveCharacterTextSplitter,chunk_size 200-400 token、overlap 10-20%(约 60 token)是基础配置。表格/代码按语义块切,不要硬切。每个 chunk 必须带 metadata:文档名、章节、页码、时间戳、来源类型,用于后续过滤和引用。chunk 太小语义碎,太大检索精度降。
向量数据库选 Pinecone、Chroma 还是 Weaviate?
托管走 Pinecone / Weaviate Cloud(省运维,适合生产);自建轻量用 Chroma;要规模和过滤选 Weaviate / Milvus。选型四要点:延迟、扩展性、metadata filter 支持、多租户隔离。embedding 模型用 OpenAI text-embedding-3-small,整个项目锁定同一模型避免空间不一致;写入前用 hash 去重。
只用向量检索精度不够,rerank 有用吗?
有用。基础是相似度检索 k=3-6;想提升相关性叠 rerank(Cohere Rerank 或 bge-reranker),先召回 top-20-50 再 rerank 到 top-5。多路检索 BM25 + 向量混合也常见。同时按 metadata(文档类型、时间、租户)过滤减少误检,合并同源段落避免冗余。
构建 prompt 时 context 长度该控制在哪?
上下文 tokens 控制在模型上限的 1/2 - 2/3,留出输出空间。检索段落要带编号 [1][2][3] 和来源,prompt 里写「仅根据提供的段落回答,未找到回复'未在提供的段落中找到'」。回答必须附引用编号便于追溯。返检索得分作为信心分,低分提示「低置信」。