跳到主要内容
版本:dev

Agentic RAG 对话原理

本文档讲解 DB-GPT 知识库对话如何通过 Agent + RAG 结合的方式回答用户问题,从提问到带引用的回答的完整流程。面向产品与设计同学,不含代码。

一、Agentic RAG vs 传统 RAG

传统 RAG (单次检索)
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户提问 │ → │ 一次检索 │ → │ 拼 Prompt │ → │ LLM 回答 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
检索一次 检索结果塞进 一次性生成
靠运气 context
缺点:检索质量全靠一次相似度,无法迭代修正,无法多步查找

Agentic RAG (多轮检索) ← DB-GPT 采用
┌──────────┐ ┌──────────────────────────────────────┐ ┌──────────┐
│ 用户提问 │ → │ ReAct Agent 循环 │ → │ 带引用的 │
└──────────┘ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ 最终回答 │
│ │ Thought│→ │ Action │→ │Observe │ │ └──────────┘
│ └────────┘ └────────┘ └────────┘ │
│ ↑ │ │
│ └───── 不满意再检索 ──┘ │
│ (可多轮,按需调用不同工具) │
└──────────────────────────────────────┘
优点:按需迭代检索、可选多种工具、可溯源引用

二、Agent 对话完整流程

┌─────────────────────────────────────────────────────────────────────────┐
│ 用户提问: "提示词缓存设计哲学是啥" │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 1: Agent 思考 (Thought) │
│ "用户问缓存设计哲学,我先去知识库语义搜一下" │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 2: 选择工具 (Action) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 可用工具 (Knowledge-Agent 模式只含知识库工具): │ │
│ │ • kb_semantic_search 语义搜索 │ │
│ │ • kb_grep 关键词搜 │ │
│ │ • kb_cat 读文件 │ │
│ │ • kb_ls / kb_glob 列目录/找文件 │ │
│ │ • todowrite / terminate 任务管理/结束 │ │
│ └─────────────────────────────────────────────────┘ │
│ Agent 选择: kb_semantic_search(query="提示词缓存设计") │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 3: 执行 + 观察 (Observation) │
│ 工具返回 10 个 chunks,每个带 score 和来源文件 │
│ Observation: │
│ Result 1 (score 0.67) [prompt cache.md] 设计代价对比表... │
│ Result 2 (score 0.66) [prompt cache.md] Hermes ephemeral 注入... │
│ ... │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 4: Agent 再思考 (Thought) │
│ "搜索结果丰富,但对比表被截断,我读一下完整文件" │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 5: 再选工具 (Action) → kb_cat(path="prompt cache.md") │
│ → Observation: 完整文件 315 行内容 │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 6: 收集引用 (Citation Collection) │
│ 每个工具返回的 chunk 被收集进 _cited_chunks 列表 │
│ 去重 + 清洗 HTML 标签 → 得到干净的可溯源片段 │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 7: 终止并生成回答 (Terminate) │
│ Agent 判断信息足够 → 调用 terminate(result="最终回答") │
│ │
│ 后端对回答做后处理: │
│ 1. _auto_annotate_citations: 把 [1][2] 角标插到引用处 │
│ 2. _build_references_xml: 拼接 <references> 引用数据 │
└──────────────────────────────┬──────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────┐
│ Step 8: 前端渲染带引用的回答 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Pi 每轮重建 system prompt[1] │ │
│ │ Hermes 冻结快照 + ephemeral 注入[2][6] │ │
│ │ Claude-Code 用 Beta Header[3] │ │
│ │ │ │
│ │ ↑ [1][2][3] 是蓝色角标, hover 显示对应 chunk 内容 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

三、ReAct 循环机制(Agent 的核心)

                    ┌─────────────────┐
│ 用户提问 │
└────────┬────────┘


┌─────────────────────────┐
│ Thought (LLM 推理) │ ← 分析当前状态,决定下一步
└────────────┬────────────┘


┌─────────────────────────┐
│ Action (选工具+参数) │ ← 从可用工具里选一个
└────────────┬────────────┘


┌─────────────────────────┐
│ Observation (工具返回) │ ← 执行工具,拿结果
└────────────┬────────────┘

┌────────┴────────┐
│ │
信息足够? 还需要更多?
│ │
▼ │
┌──────────┐ │
│ Terminate│ │
│ 生成回答 │ │
└──────────┘ │
│ yes → 回到 Thought (下一轮)

(最多 N 轮, 防止死循环)

关键点:Agent 不是无脑检索一次,而是根据 Observation 判断"信息够不够",不够就换工具/换 query 再搜。

四、引用溯源链路(可解释性的核心)

工具执行                          后端收集                      前端展示
─────── ──────── ────────
kb_semantic_search 返回 → _cited_chunks[0] = { -> [1] 蓝色角标
Result 1: "Pi 每轮重建..." content: "Pi 每轮重建...", hover 显示:
score: 0.67 recall_score: 0.67, "Pi 每轮重建...
召回 0.67"
kb_cat 返回 → _cited_chunks[1] = { -> [2] 蓝色角标
"Hermes 冻结快照..." content: "Hermes 冻结...", hover 显示:
recall_score: null, "Hermes 冻结..."
}

自动标注 → 回答正文里: → [1][2] 插在
_auto_annotate_citations "Pi 每轮重建[1]" 对应句子后
"Hermes 冻结[2]"

引用面板 → <references> XML -> 🔗 查看回复引用
_build_references_xml references='[{ 点击弹出 Drawer
name: "prompt cache.md", 按文档分 Tab
chunks: [{index:1,...}, 显示所有 chunk
{index:2,...}]
}]'

五、工具模式:Knowledge-Agent vs Full-Agent

知识库详情页对话 (knowledge-agent)         通用 Agent 对话 (react-agent)
───────────────────────────── ──────────────────────────
┌─────────────────────────┐ ┌─────────────────────────────┐
│ 只含知识库工具: │ │ 全部工具: │
│ • kb_semantic_search │ │ • kb_* (知识库) │
│ • kb_grep / kb_cat │ │ • shell_interpreter (Shell) │
│ • kb_ls / kb_glob │ │ • sql_query (SQL) │
│ • kb_codegraph_* │ │ • html_interpreter (报表) │
│ • todowrite / terminate│ │ • code_interpreter (代码) │
└─────────────────────────┘ │ • execute_skill_script │
↑ │ • todowrite / terminate │
聚焦知识检索 └─────────────────────────────┘
不引入无关工具噪音 ↑
适合纯知识问答 能力全面,适合复杂任务
但工具多,易跑偏

六、关键设计原则

  1. Agent 驱动检索:不是一次检索定生死,LLM 根据观察结果决定是否再搜、换什么工具
  2. 工具按场景裁剪:纯知识对话只给知识工具,避免 Agent 乱调 shell/sql
  3. 引用自动收集:每次工具返回的 chunk 都进 _cited_chunks,不依赖 LLM 自觉标注
  4. 后处理兜底:LLM 不按 prompt 标 [1][2] 时,后端用字符串匹配自动补角标
  5. chunk 内容清洗:去掉 HTML 标签后再匹配,保证 LLM 干净文本和 chunk 能对上
  6. 引用数据随回答下发<references> XML 拼在回答末尾,前端解析后渲染角标 + 引用面板
  7. 可溯源闭环:每个角标 → 对应 chunk → 对应文档 → 可在引用面板查看原文