07
7 / 50

RAG 系统入门

⏱️ 60分钟

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 可以是 supportedpartialconflictno_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_iddocument_versionchunk_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-kranked results、hard negatives
Permission命中另一租户资料filter decision、actor scope
Assembly证据被截断或污染Context Trace
Generationclaim 无证据、过度概括claim-source review
CitationID 存在但不支持 claimsource 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 需要覆盖:

  1. 普通相关问题;
  2. 关键词相似但业务不相关的 hard negatives;
  3. no_answer
  4. superseded 与 conflicting policy;
  5. 中文、英文、缩写和拼写变化;
  6. 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
更新模型只改一行 IDvector space 已变化新索引迁移
RAGAS 高分即可上线metric/judge 有盲区人工抽检 + failure analysis

动手练习

用一组 synthetic policy 完成:

  1. source manifest 与版本化 chunks;
  2. 一个本地 index;
  3. mandatory permission filter;
  4. supported、partial、conflict、no-answer 四类输出;
  5. 10 条 retrieval cases 和失败分类;
  6. 一次文档更新、删除与 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 里写「仅根据提供的段落回答,未找到回复'未在提供的段落中找到'」。回答必须附引用编号便于追溯。返检索得分作为信心分,低分提示「低置信」。