RAG 子系统¶
如果说组件页讲的是“RAG 是怎么拼出来的”,那本页讲的是“RAG 为什么存在,以及该怎么用好它”。
RAG 的核心价值不是把知识库塞给模型,而是用一条可控、可追溯的流程,把“外部知识”转成“本轮回答需要的上下文”。
1. 什么时候应该用 RAG¶
下面这些场景适合用 RAG,而不是单靠模型参数记忆:
- 需要依据项目文档、平台手册或运维知识库回答问题
- 知识会频繁变化
- 回答需要引用来源
- 需要降低模型幻觉
2. RAG 的工作路径¶
flowchart LR
Docs["原始文档"] --> Clean["清洗"]
Clean --> Split["切分 chunk"]
Split --> Embed["Embedding"]
Embed --> Index["索引"]
Query["用户问题"] --> Retrieve["召回 Top-K"]
Retrieve --> Rerank["可选重排"]
Rerank --> Prompt["拼接到 Prompt"]
Prompt --> Answer["模型生成答案"]
3. 这套系统里 RAG 如何被调用¶
当前项目里,RAG 更多是被包装成工具能力后再供 Agent 调用,而不是直接裸露在 Agent 主循环里。这样做的实际收益是:
- 检索参数可在工具层封装
- 可为不同知识域定制不同工具
- Agent 只需要决定“要不要查”,不需要知道“怎么查”
4. 建索引的入口¶
项目提供独立 CLI:
go run cmd/index.go
默认会读取 component/rag/rag.yaml,并对默认文档目录执行加载、切分、嵌入和索引写入。
5. 影响效果的几个关键参数¶
chunk size / overlap¶
- 太大:召回噪声高,上下文浪费
- 太小:语义被切碎,命中率下降
embedding model¶
- 建索引和在线检索最好保持一致
- 模型切换后要警惕旧索引兼容性
top-k¶
- 太小会漏信息
- 太大容易污染 Prompt
reranker¶
- 候选多时有帮助
- 也会增加一次额外开销
6. RAG 不是银弹¶
引入 RAG 后,系统质量并不一定自动提升。常见失败原因包括:
- 检索结果虽然相关,但没有被 Prompt 正确利用
- 工具没有在需要时触发 RAG
- 文档本身结构混乱
- 索引更新不及时
所以优化 RAG 往往要同时看三层:
- 数据层:文档和索引
- 检索层:召回与重排
- 编排层:工具调用与 Prompt 整合
7. 工程实践建议¶
- 检索结果尽量带来源信息
- 对高频知识域做专门工具封装
- 控制返回 chunk 数量,避免上下文污染
- 为索引更新建立固定流程,而不是手工偶发执行