当 RAG 开始“要求找全”:一次 Agentic RAG 边界探索与 LLM Wiki 转向

9 阅读33分钟

30 秒判断:如果你也遇到“检索结果看起来都相关,但关键子主题总是漏掉”,这篇文章的价值是两个:我们替你系统试过了提示词、查询展开、facet、审计、reranker 和章节路由,并标明各自为什么不够;同时用近期论文说明,这不是单靠把项目参数再调一调就能解决的问题。

适合谁读:正在做 Agentic RAG、知识库问答、主题研究、长答案检索或 LLM Wiki 的工程师和产品负责人。

系列位置:本文接续 05 · Agentic RAG 检索侧落地。前文讲块级工具如何形成可靠的 Agent 检索链路;本篇讨论当问题从“找相关证据”变成“围绕主题找全”时,这条链路在哪里失效。

代码库:lipeidonggz/ai-study-helper-v2

研究证据:065 主题覆盖实验 · 066 章节路由实验 · 冻结 tag

证据标记:✅ 项目实测;🧪 可回归;🤔 当前判断。本文引用的公开论文和 WeKnora 实验不是本项目实测结果,会在对应段落单独标明。


1. 结论先行:不是没有方法,而是没有共识闭环

Agentic RAG 很容易给人一种错觉:只要给 Agent 更多工具、更多轮次和更多查询,它最终就能把相关内容找全。

实测并不是这样。

Agent 可以继续搜索,却无法仅凭当前的检索结果判断:

  • 这个主题应该包含哪些语义面;
  • 哪些面已经被证据覆盖;
  • 哪些只是相关但重复的总览;
  • 当前结果漏掉的,是“知识库没有”,还是“这次没搜到”;
  • 什么时候可以停止。

因此,本文要表达的核心判断不是“Agentic RAG 无法找全”,而是:

对于主题覆盖类问题,Agentic RAG 已经能扩大候选召回;但在我们查到的近期研究与工程实践中,还没有形成一套能同时处理语义面发现、覆盖判断、证据回源和知识更新的共识方案。

这个判断有两个依据。

第一,我们没有停在一次失败上,而是依次试过 Agent 提示词、强制覆盖说明、查询展开、逐名词检索、facet 规划、缺项审计、证据 reranker 和章节路由。每一步都解决了一部分问题,也都留下了新的缺口。

第二,近期研究分别在覆盖感知检索、集合覆盖选择和覆盖评价上取得了进展,但没有一项直接提供“给定主题,稳定发现该找哪些面,并证明已经找全”的端到端能力。


2. 前情:为什么一开始没有做 LLM Wiki

项目最初采用增强块检索加 Agentic RAG,是经过明确取舍的。

系统已有:

  • SectionTree/BlockSet;
  • dense 与全文检索双索引;
  • 冻结 collection 快照;
  • search_blocks、get_outline、list_blocks、scan_term 等工具;
  • Agent 多轮搜索与回查;
  • 原始 block 引用。

这套架构服务的能力可以直接落到项目的固定用例上。完整 18 条用例及其金标准见 03 · 用例集与金标准。

下面保留原始题面,不做改写:

  • c1-001:

    Anthropic《How we contain Claude》里提到过 MCP 吗?

  • c3-001:

    "用户批准了约 93% 的权限提示"这句在哪、前后文是什么?

  • c6-001:

    沙箱、出口控制、虚拟机在 containment 里各挡什么、彼此怎么配合?

  • c8-001:

    OpenAI《Harness engineering》和 Anthropic《How we contain Claude》合起来,给"agent 时代的工程"画了什么整体图景?

  • c14-001:

    "MCP 是新的攻击面"这个说法,在 Anthropic《How we contain Claude》里有原文依据吗?还是模型补充的?

  • c15-001:

    把Anthropic《How we contain Claude》里的三种隔离模式整理成一张表:模式/产品/机制/威胁模型/代价。

这些问题的共同点是:检索目标可以由一条或几条明确查询表达,即使需要跨来源综合,文档范围和比较对象也仍然清楚。块级检索负责找证据,Agent 负责继续查、筛选和综合。

存储与检索策略因此先选择:

增强的向量块 + Agentic 检索
↓
只有实测出现“面状覆盖/跨页概念归集”缺口
且现有方案反复解决不了
↓
才引入 Wiki

LLM Wiki 需要额外编译,页面还要补“段落 → 原始 block”的回源链。它不是默认起点,而是一个有触发条件的架构选项。


3. c13-003:一个看起来正常、实际很难的问题

触发条件最终由跨文档回归探针 c13-003 满足。它的完整问题是:

在当前知识库中,除了沙箱、虚拟机和出口控制,AI Agent 还有哪些隔离或控制边界?请分别说明各限制什么。

主 Agent 调用主题覆盖工具时,检索输入进一步收敛为:

AI Agent 隔离与控制边界

这一步是在划分职责:主 Agent 保留“为什么问、最终怎么答”,覆盖工具只负责围绕主题收集证据。

测试知识库是 15 篇 HTML,共 526 个 block、328 个 section-tree 节点。文档来源包括 Anthropic 6 篇、OpenAI 2 篇、Lilian Weng 3 篇、Chip Huyen 1 篇、Eugene Yan 1 篇和 Hamel 2 篇。答案所需证据并未集中在一篇文档中。

3.1 第一条必选判据(R1)要求什么

c13-003 的第一条必选判据(R1)要求“跨文档核心隔离边界全覆盖”。答案必须语义覆盖七组边界,并分别说明限制对象或限制风险;括号中的 worktree、checkpoint、独立 session 等只是可选示例。

  1. 文件与工作区可达边界:限制 Agent 能访问、读取、修改或删除的文件和数据范围;
  2. 凭证与身份边界:限制 Agent 能取得或代表使用的身份、凭证;
  3. 工具与行动能力边界:限制 Agent 能调用哪些工具、执行哪些操作;
  4. 外部内容与工具结果信任边界:限制网页、文件、工具结果等在检查前影响上下文或行动;
  5. 并行任务与工作状态边界:限制并行任务之间的修改冲突、不可回退和状态污染;
  6. 上下文与记忆生命周期边界:限制无关或受污染上下文跨任务累积,以及长期记忆的写入和复用;
  7. 子 Agent 委派边界:限制子 Agent 获得的上下文、工具、职责和返回信息。

后续实验使用其中三个具体 block 作为回归探针。它们不是与七组边界一一对应,而是分别落在一组或相邻两组证据义务上:

回归探针对应的必选边界具体含义
worktree/工作区隔离① 文件与工作区可达边界;⑤ 并行任务与工作状态边界独立 checkout 同时限制文件修改范围和并行会话之间的修改冲突
checkpoint 恢复⑤ 并行任务与工作状态边界让长任务从失败处继续,限制不可恢复状态;只有进一步说明跨任务上下文或长期记忆时,才可能支撑⑥
恢复正确性评估⑤ 并行任务与工作状态边界;局部涉及⑥检查多轮状态变化后的最终状态是否正确,但它本身不能完整覆盖上下文与记忆生命周期

它们不是一份完整的人工相关性标注集;只能验证三个已知漏点,无法计算整个主题的召回率。之所以选作探针,是因为初期版本的失败已经证明它们具体、可核对,而且最容易被单篇总览掩盖。后续比较的是这三个已知漏点分别有没有找回来。

答案可以使用自己的分类和措辞,但只列名称、不说明“限制什么”,不算覆盖。R1 不能变成“出现几个安全词就给分”。

3.2 为什么金标准要这样苛刻

如果只要求列出几种安全措施,Agent 完整读取《How we contain Claude》后就能给出一个看起来很像答案的结果:沙箱、虚拟机、出口控制、凭证隔离、工具权限、人在回路。

但 worktree、checkpoint 恢复、上下文生命周期和子 Agent 委派等机制分散在其他文档中。单篇总结可以流畅、诚实、引用正确,却仍然没有完成任务。

这条判据要检测的不是“答案像不像安全综述”,而是:

  • Agent 是否从“当前知识库”这个宽范围继续发现相关文档;
  • 是否找到了多篇文档共同构成的证据面;
  • 是否理解每个机制限制的具体对象或风险;
  • 是否把“只读了一篇”误当成“知识库已经覆盖”。

还要强调:**R1 只看最终答案是否满足判据,不是给 Agent 的提示词。**Agent 看不到这七组答案,必须自己探索出来。

除 R1 外,用例还要求从四类扩展边界中至少覆盖两类,并禁止使用“知识库中只有这些”“其它文档均未涉及”等没有核验依据的排他断言。


4. 第一层尝试:让 Agent 自觉多查一点

最自然的想法是继续用 Agentic RAG:工具都在,只要提示它注意范围、完整性和停止条件,应该就能自己扩展。

4.1 Agent 看到了全部文档,却只读一篇

在自然题面的第一次 N=10 运行中,10 个 trace 都执行了:

list_documents → get_outline → list_blocks

它也看到了当前知识库里的 15 篇文档,但没有任何一个样本真正读取第二篇。结果是 R1 七组核心边界 0/10。参考答案退化为对《How we contain Claude》这一篇的完整总结。

这说明失败点不是“Agent 不知道有哪些文档”,而是它把“当前最相关文档已经读完”解释成“宽范围问题已经覆盖”。

4.2 增加通用范围提示词,没有改变行为

下一轮把关键词规则换成更通用的“证据范围与完整性责任”,没有写“隔离”“worktree”“子 Agent”等用例术语。

这不是一句笼统的“请回答全面”。chat-v18 明确新增了下面两段规则:

对承担完整性责任的资料集合,“已找到一处高相关证据”不是停止条件;
必须在候选集合已经合理处理完,或已明确记录因预算无法继续检查的候选后,
才能按上述条件结束。
先建立候选集合,再读取证据;候选集合不得只来自标题或一次检索;
使用多个互补的证据发现角度,避免相同措辞重复搜索;
按来源聚合和去重,并检查哪些候选已处理、排除或尚未处理。

规则已经直接写到“候选集合”“多个互补角度”和“哪些候选尚未处理”的粒度,仍然没有让 Agent 读取第二篇文档。

结果是:

  • R1 仍为 0/10;
  • 10/10 trace 仍只读取一篇;
  • 多文档检索样本仍为 0;
  • 输入 token 增加约 6%。

提示词让模型更会说明“我的证据范围是什么”,却没有让它先扩展候选。

4.3 强制解释结束依据,只得到合理化理由

进一步把“结束依据”设为结构化协议必填,要求正常完成和降级都必须说明原因。

原来 finish 只需要返回答案:

{"type":"finish","answer":"最终答案"}

chat-v19 改为:

{
  "type":"finish",
  "answer":"最终答案",
  "decision_summary":"说明证据范围,以及为何可以正常结束或只能降级"
}

同时进一步收紧终止条件:

对承担完整性责任的问题,“已找到一处高相关证据”不是停止条件;
必须先建立并处理候选范围,或确认已经触发明确降级条件。

结果出现了三类结束理由:

  • “该文档范围内已完整覆盖”;
  • “其它文档主题不相关,无需继续检索”;
  • “未逐篇检查其它文档,因此降级为范围限定”。

问题是:这些解释仍然建立在只读一篇的事实上。强制 self-reflection 没有促成候选发现,反而带来:

  • 3 个产品协议失败;
  • 约 2 倍输入 token;
  • 更多轮次和工具调用;
  • 更多看似合理、实际没有证据的停止理由。

该规则最终撤回。

这一层探索得到一个重要结论:

Agentic RAG 当前缺少的不是“再想一遍”或“再解释一次”,而是一个可检查的覆盖状态。没有这张状态表,多轮循环只能增加动作,不能证明覆盖。

完整 prompt hash、三版 run 指标、原文 diff、trace 编号和失败分析见 c13-003 语义覆盖实验。


5. 第二层尝试:把覆盖问题拆成专用工具

提示词试验说明:继续要求主 Agent “更全面”,并不能改变它的检索范围。问题已经不只是 query 写得好不好,而是主 Agent 同时承担了目标理解、候选发现、完整性判断、答案组织等多个职责。

因此出现了一个关键决策:把覆盖规划与证据判断从主 Agent 的自由循环中拆出来,提供成专用工具。

5.1 关键决策:用 search_topic(topic) 承担覆盖流程

主 Agent 继续负责:

  • 判断何时需要找全;
  • 选择要交给覆盖工具的主题;
  • 使用返回的证据组织最终回答;
  • 处理冲突、取舍和表达。

专用工具只接收:

search_topic(topic)

它在内部完成一条更专注的链路:

主题
→ 主题解释
→ hybrid seed 观察当前语料
→ facet 规划
→ facet 缺项审计
→ dense/keyword 查询展开
→ 候选合并
→ 按 facet 判断证据支持
→ 返回支持块

以下是四段 prompt 的关键原文摘录,为便于阅读省略 XML 标签和大型 schema:

你负责为一个知识库检索主题生成完整解释。你不回答用户问题,也不生成查询。

请对 topic 做详细、完备、具体的解释,并用 Markdown 组织。
解释需要覆盖概念、目标、对象、机制、实现方式、边界、场景、风险和权衡,
并保留具体技术词与限制关系。

“不回答用户问题,也不生成查询”是这里最关键的职责约束。它让模型专注于构造主题语义,而不是提前把主题压成几条检索词。

这个拆分有三个直接作用。

第一,主 Agent 不必再用一段通用提示词同时完成回答和覆盖,工具内部的每个 LLM 阶段只解决一个明确问题:解释主题、提出证据义务、审计缺项、生成查询或判断候选支持。

第二,工具输入只保留 topic,不读取当前问题的 retrieval_goal 或预期答案格式。覆盖集合因此独立于某次回答,可以被复用和单独诊断。

第三,规划、审计、查询和 reranker 都进入同一 trace,使“为什么返回这些证据”可以被观察和回归,而不是藏在主 Agent 的一次自由推理里。

这一步仍然是实验假设,不是成功结论。下面的查询展开、facet contract 和 reranker,都是这个专用工具内部的组成部分。

工具职责、输入输出和失败语义见固定快照中的 11 · 语料锚定的主题覆盖检索。

5.2 只把主题解释做向量查询,不够

这一轮不是简单增加查询数量,而是在验证一种查询改写方式:既然原始 topic 太短,能否让模型先生成完整解释,再把解释按语义段切成多条 dense 查询,让每条查询自动对应一个潜在证据面。

背后的假设是:

  1. LLM 能生成比原始 topic 更完整的主题解释;
  2. 解释已经包含多个语义面;
  3. 把解释切成片段后,每一段可以作为一条独立查询;
  4. 多条查询的候选合并起来,就能覆盖知识库中分散的证据。

实验使用 17 条解释片段,每条取 Top-20,查询结果去重后形成 76~107 个候选,但三个回归探针中只找回了 0~1 个。

解释可以说明主题“大概包含什么”,却不会自动产生知识库特有的 worktree、checkpoint 等术语,也不能保证每个解释片段对应一条独立证据义务。候选会集中在总览和相似表达上,看起来都相关,却未必带来新的覆盖。

因此,这次实验真正排除的是:

“只要让模型把主题解释得更完整,再把解释切碎检索,就能自动获得主题覆盖。”

它没有排除解释本身的价值。后续解释仍然保留,但职责从“直接生成查询”变成“给 corpus-grounded facet planner 提供辅助上下文”。

5.3 从解释里逐名词做全文检索,召回够了但等于没有筛选

继续把解释拆成名词,再通过 FTS(全文检索,底层按 BM25 排序)逐项搜索,worktree、checkpoint 恢复和恢复正确性评估这三个探针全部找回。

代价是:

  • 346 条查询;
  • 召回 511/526 个 block;
  • 几乎整个知识库都被拿回来。

这在数学上叫“高召回”,在产品上没有完成检索。没有筛选能力的找全,只是把筛选成本推给了阅读阶段。

5.4 把查询、facet 和证据判断串成完整工具链

这一节不是单独评价 facet planner,而是把 facet、多查询和证据判断组合成完整覆盖工具。先看其中第一层:如何让语义面受到当前语料约束。

5.4.1 corpus-grounded facet:让语义面受当前语料约束

前一轮说明,解释式查询只能把每个片段表达得“更像主题”,却无法保证这些片段对应知识库中的真实证据义务。下一步要验证的是:

如果让模型先看到当前知识库实际命中的正文和文档结构,再规划覆盖面,能否减少通用分类,产生知识库可以检索、可以判断的具体证据义务?

这里的假设有三点:

  1. seed block 全文能提供知识库真实使用的术语、状态和机制,而不是只靠模型参数知识猜;
  2. 文档大纲能提示同一文档中与命中章节相邻、并列或上下位相关、但尚未命中的区域;
  3. 如果每个 facet 都绑定 evidence obligation、coverage question 和 seed refs,后续查询与 reranker 就能围绕同一定义工作。

因此流程先从主题做 hybrid seed 检索,把命中的 block 全文和所属文档大纲交给模型,再让它基于当前语料规划语义面(facet)。这与上一轮的区别不是“多问模型一次”,而是把 facet 从模型自拟分类变成由当前语料约束的检索义务。

每个 facet 必须带:

  • scope:语义边界;
  • evidence_obligation:需要找到什么证据;
  • coverage_question:找到后必须能回答什么;
  • required_relation:证据必须表达的机制、条件或因果关系;
  • origin:来自语料、假设还是两者;
  • seed_refs:哪些真实 block 支持这个 facet;
  • dense 查询和 keyword 查询。

facet planner 的实际 prompt 不是让模型“列几个相关方面”,关键规则是:

每个 facet 表示一种可验证的证据义务,而不是一个泛化分类。
evidence_obligation 说明必须找到哪些对象、机制、状态、流程或风险。
coverage_question 是检索完成后应能明确回答的具体问题。
required_relation 说明证据必须表达的具体限制、机制、状态、因果或作用关系。
不同 facet 不得只是同义改写;不得用一个“所有方式”的总分类代替细节。

5.4.2 facet audit:在检索前检查缺项与过宽

随后再用 facet audit 检查:

  • 重要机制是否漏进任何 facet;
  • 是否混合了多个独立证据义务;
  • 是否存在语义重复;
  • 是否有缺少语料依据的假设;
  • 是否被单一文档或单一分类框架带偏。

audit prompt 的职责和检查项原文是:

你是主题覆盖完整性审计器。你不回答用户问题,也不执行检索。

请逐项检查:
1. topic、explanation 或输入语料中出现的重要概念、机制、对象、状态、过程、
   风险和权衡,是否没有落入任何 facet;
2. 一个 facet 是否混合了多个可以独立检索和独立判断的证据义务;
3. 是否有多个 facet 只是同义改写或应当合并;
4. 是否存在泛化分类、无法指导检索或没有语料依据的 corpus facet;
5. 初始 facets 是否受单一解释、单一文档或单一分类框架影响。

这比自由 query expansion 更接近可验证的覆盖契约。

完整实现和失败探针见固定快照中的 065 切片,规划与审计实验见 facet 稳定性实验。

🧪 这条链路已有可回归测试,覆盖非法 facet、未知候选、reranker 结构化输出失败、快照边界和“失败时不得返回部分成功”。这些测试证明失败语义不会静默降级,不证明覆盖质量已经稳定。

5.4.3 多查询与 reranker:把候选收敛到支持证据

planner 为每个 facet 生成 dense 与 keyword 查询。系统先按字符串去重,再分别召回候选,按 facet 合并并归一化。每个 facet 先保留一个候选短名单,然后由 reranker 检查候选是否真正支持具体证据义务。

这里的 reranker 是判断一个 block 是否真正满足某条 facet 证据义务的模型。

它的关键判断规则原文是:

对每个 candidate 检查完整 facet_catalog;provenance_facets 只是召回提示。
判断依据是 facet 的 evidence_obligation、coverage_question 和 required_relation,
不得只依据 name 或 scope。
direct:正文明确满足该 facet 的证据义务和必要关系。
partial:正文覆盖该 facet 的部分对象、机制或风险,但没有充分满足关系。
不能因为出现相同词语就判 direct。

完整提示词见固定快照中的 corpus_grounded_coverage.py,版本分别是 explanation-v1、facet-planner-v6、facet-audit-v3 和 reranker-v3。

5.5 整条工具链的结果:能形成覆盖计划,但仍不稳定

把 facet planner、facet audit、多查询召回和 reranker 串成完整工具后,系统已经能形成结构化覆盖计划,也能返回多个获得 facet 支持的 block。但同一个主题在相同快照上的规划与最终结果仍然明显波动。

✅ 项目实测中,同一主题在相同快照上生成过约 14~24 个 facets,展开约 136~192 条查询,返回约 53~75 个支持块;三个回归探针的命中数在 1~3 个之间波动,说明同样的主题有时连已知漏点都找不全,有时能全部找回。

这些数字来自不同提示词和实现阶段的迭代,不是同一版本下的受控 A/B,因此只能用于暴露波动,不能写成稳定区间。

波动来自整条链:

seed 看到什么
→ 模型如何理解主题
→ 选择哪些语义面
→ 每个面生成哪些查询
→ 哪些候选进入短名单
→ reranker 如何判断证据义务

每一层都可能改变下一层输入。现场规划越复杂,最终集合的稳定性就越难证明。


6. 第三层尝试:把章节结构变成独立检索面

6.1 意图:验证人类章节能否成为一条独立召回通道

块 embedding 已经包含文档标题和 section_path,但块检索仍然把每个 block 当作独立对象打分。章节本身并没有成为可单独检索和展开的对象。

这一层要验证的假设是:

如果把当前快照中的 section 提升为独立检索对象,先用 topic 或 facet 找章节,再展开它的子树 block,能否补上块级向量检索漏掉的语义面?

这个尝试有三个依据:

  1. 人类章节标题和路径往往概括了一组 block 的共同语义;
  2. 章节检索可以覆盖那些没有进入 seed 文档的章节,而不只是查看已命中文档的 get_outline;
  3. section 命中后仍能展开到带 section_path 和原始 block_id 的证据,满足回源要求。

它同时检验一个更实际的问题:在不增加 LLM 预编译成本的前提下,能否先把作者已经写好的目录结构当作一张现成知识地图。

6.2 方法:snapshot-bound SectionIndex 与子树展开

✅ 我们在当前 15 篇基准语料上做了初步章节索引实验:

指标数量
文档15
block526
section-tree 节点328
可路由 section286
是否满足 95% 映射门槛是
286 个 section 的 embedding 输入18,322 tokens
索引构建耗时7.9~10.8 秒

单次 topic 查询只需要一次 query embedding 和 286 次本地余弦比较,构建成本不高。这个规模仍只是方法验证,不是产品目标中的 1,000 篇/10 万 block。

6.3 正向结果:章节路由补回了 worktree

为了只观察候选来源,我们不重新规划 facet,而是沿用固定 plan 中的 20 个 facet 名称检索章节:

  • 得到 80 个唯一 section;
  • 展开 157 个 block;
  • 找到位于 Automate and scale > Run multiple Claude sessions 下的 worktree 证据;
  • 这个目标同时被三个 facet 的章节路由命中。

原始 topic 的 block hybrid 找到了 checkpoint 恢复,但没有找到 worktree;章节路由补上了 worktree。两者合并后找回了两个回归探针,最后一个“恢复正确性评估”仍然缺失。

这说明章节路由是有价值的补充通道。

6.4 负向结果:泛化标题和 Appendix 仍是盲区

两个 checkpoint 目标仍然失败:

  • checkpoint resume 位于 Production reliability and engineering challenges 下;
  • checkpoint evaluation 位于 Appendix 下。

前者没有“checkpoint/resume/恢复”词面,后者只是无语义容器。

人类章节结构能帮助发现标题已经表达出的语义面,但无法自动发现标题没有表达的内容。

因此,章节索引不是完整知识地图。它可以帮助路由,不能单独证明主题覆盖。

6.5 与 block 检索的关系:互补,而不是替代

block 检索和 section 路由的失败方式不同:

  • block 检索保留精确词面和正文语义,但可能把结构上有意义的短块淹没在大候选池中;
  • section 路由放大了人类标题和层级语义,但展开子树时会带入同章节里只与 facet 边缘相关的 block。

因此,实验结果支持的是“block 候选与 section 候选取并集,再统一做证据判断”,而不是用章节标题替换正文检索。章节路由提供新的发现入口,最终证据仍然回到原始 block。

实现与实验见固定快照中的 066 切片和 章节路由实验。

6.6 留出主题说明候选变宽,不等于覆盖正确

在两个未参与调优的留出主题上,章节路由分别产生 158 和 172 个展开 block;与当前返回集相比,分别有 81 和 71 个“新候选”。

这只说明候选集合发生了变化,不说明新候选都正确。当前没有 block 级人工相关性全集(qrels),也没有证明章节路由提升了人工 facet 覆盖率。

只运行一次(N=1)的结果只能做方案筛选,不能写成长期效果。


7. 最新研究:为什么这不是“再调一下”就能解决

为了判断问题是否只存在于本项目,我们查了四类直接相关研究。结论是:每个局部都有人在做,但还没有一个可直接拿来闭合我们的完整任务。

7.1 CoveR:改善覆盖感知表示,但仍做单查询 Top-K

CoveR 用子问题可回答性训练覆盖感知双编码器,让向量空间更偏向覆盖。它解决了相关性训练目标不奖励覆盖的问题。

但推理时仍然是 query 单向量、文档独立打分的 Top-K。它不能保证返回集合彼此互补,也不能证明某个主题已经覆盖完整。

这里的 nugget 指答案应该覆盖的原子信息点。

7.2 Decompose, Estimate, Select:显式做集合覆盖,但受候选池和目标预算约束

Decompose, Estimate, Select 用 LLM 分解子问题,用覆盖模型预测“文档 × 子问题”覆盖矩阵,再做最大边际覆盖选择。

它证明集合级覆盖可以工程化,但实验仍是:

  • 固定 BM25 Top-100 候选池;
  • 选择固定 k=10 上下文;
  • 依赖两个训练的覆盖模型组件;
  • 优化候选池内选择,不是主题证据的无限发现。

论文还报告,更高检索覆盖不自动转化成更高答案覆盖,需要额外让生成器重新利用已检索证据。

这给出一个关键边界:

检索覆盖
≠
主 Agent 使用了覆盖
≠
最终回答覆盖

7.3 Q-CARE:重视覆盖评价,但分解完备性仍无独立保证

Q-CARE 把查询拆成子查询,把答案拆成原子 claim,用查询覆盖和主张可验证性评价 RAG。

它让“覆盖”成为可评价对象,但子查询本身仍由 LLM 现场生成。分解器漏掉的语义面不会自动进入完整性分母。无参考答案不等于没有分解假设。

7.4 TREC CAR:任务最接近,但 facet 常由人工提供

TREC Complex Answer Retrieval 从 2017 年开始研究复杂主题的多 facet 段落覆盖,任务形式非常接近。

但 TREC CAR 通常由人工 outline 给出主题 facet。它解决了“给定 facet 如何评价和检索”,把最难的“facet 从哪里来”留在了任务输入中。

7.5 四篇论文共同说明了什么

它们分别解决:

  • 覆盖感知表示;
  • 集合覆盖选择;
  • 覆盖评价;
  • 复杂主题检索任务。

但它们都没有同时解决“发现完整语义面、跨候选池召回、证明覆盖、回源和增量更新”。这就是“已有局部方法,尚无共识闭环”的证据。


8. 为什么继续堆现场查询,收益开始变小

到这里,我们并没有得出“RAG 无法找全”的结论。更准确的是:

在固定本地知识库、topic-only 输入、10 万 block 目标规模、证据必须完整且可追溯的约束下,我们还没有找到已经工程验证的一站式现场检索方案。

继续增加查询会遇到五个相互关联的问题。

8.1 语义面本身从哪里来

模型凭主题生成会偏向通用分类;只观察 seed 语料会被 seed 偏置;章节标题又只能表达部分语义。系统需要同时完成主题理解、语料观察、证据义务拆分和停止判断。

8.2 查询数量增长快于信息增量

一条 facet 能生成多组 dense 和 keyword 查询。候选越宽,去重和近重复压力越大。最终需要证明的不是“又发了多少查询”,而是“哪条查询带来了新证据”。

8.3 每次提问都重新理解同一个主题

主题覆盖只依赖主题和知识库快照,理论上可复用。但现场检索会反复执行 seed、解释、facet、查询和审计。缓存能复用计划,却不能修复一开始就错误的覆盖地图。

8.4 “找全”没有天然停止条件

Top-K 的停止条件就是返回 K 个;覆盖没有。系统需要知道有哪些证据义务、哪些已经满足、哪些仍缺失,才能停止。

这正是现场 query fan-out 缺少的“地图”。

8.5 覆盖评价和答案生成仍是另外两层

即使建立覆盖矩阵,还要判断 reranker 是否准确、主 Agent 是否使用证据、最终答案是否覆盖 facet、增加覆盖是否牺牲了连贯性。

继续把所有职责塞进一个 search_topic,会让工具同时承担主题地图、检索器、判据和回答规划,边界越来越难验证。


9. 原设计中的 LLM Wiki 触发条件已经成立

🤔 按当前项目判断,c13-003 已经满足最初写下的触发条件:

  • 出现明确的“面状覆盖/跨页概念归集”缺口;
  • 块检索、提示词、查询展开、facet、审计和章节路由都只解决了一部分;
  • 问题不是单个工具 bug,而是缺少一张可复用的主题证据地图。

因此下一步不再问“要不要做 Wiki”,而是问:

怎样把 Wiki 做成一套可检索、可回源、可增量维护、可删除、可回滚的知识层,同时保留原始 block 检索?

目标架构不是替换 RAG:

                 ┌─────────────────────┐
用户主题 ───────→│ LLM Wiki / 主题地图  │
                 │ 概念、别名、覆盖问题  │
                 │ 页面链接、证据义务    │
                 └──────────┬──────────┘
                            │ page / section refs
                            ▼
                 ┌─────────────────────┐
                 │ 原始 block 证据层     │
                 │ dense + FTS + 快照   │
                 └─────────────────────┘
                            ▲
                            │ 缺口补查与回源
                            │
                     Agent / coverage tool

Wiki 负责“知道该找哪些面”和“面之间如何组织”;block 负责真实原文与引用;在线 Agent 负责缺口补查、冲突处理和最终综合。

完整研究归档和对象说明见 067 研究快照。


10. 下一步:先尝试 LLM Wiki 预编译

现场检索这条路线已经把候选召回、facet 规划、证据判断和章节路由分别推到了各自的边界。下一步要换的不是又一个查询技巧,而是知识组织的时机:从“查询时现场理解主题”,转向“入库时先编译一层主题结构”。

预编译并不是只有一种实现。

更严格的知识图谱是一个可选路径:实体、关系类型和约束都显式建模,结构最清楚,但也需要持续设计本体、实体类型和关系规则,对人工和领域知识依赖较重。我们的目标用户是普通学习者,知识库内容还会持续变化,不适合先把人工本体设计作为前置条件。

GraphRAG 则证明了另一件事:把实体、关系和层次摘要提前到索引期,确实能处理一部分全局问题。但本系列此前对 GraphRAG 的拆解也说明,它依赖目标预知、提问方向稳定和语料大而松散等前提,当前实现作为产品基座仍缺少可观测、可配置和可复现的控制面。

因此我们准备先尝试 LLM Wiki。它不要求提前定义完整本体,而是把主题相关的概念、别名、覆盖问题、来源关系和页面组织成一张可读、可检索、可回源的证据地图,更接近当前缺失的能力:不是更多关系类型,而是“围绕这个主题还应该找哪些面”。

本系列此前也拆解过 WeKnora 的 LLM Wiki 编译。它提供了一个具体参考:抽取概念、身份对齐、匹配原文 chunk、生成页面、规划目录和注入链接;逐字原文素材、页面到 chunk 的引用和 slug 身份账本尤其值得借鉴。但它的公开实现仍有编译成本、重编译漂移、删除残留、别名/页面检索和规模问题,只能作为参考实现,不能作为已经满足我们产品约束的底座。

所以下一阶段的决定是:先验证 LLM Wiki 预编译路径,不直接进入严格知识图谱,也不把 WeKnora 视为答案。

原始 block 检索仍会保留。Wiki 负责发现和组织主题证据面,block 负责提供真实原文和回源。先用 c13-003 验证它能否形成更稳定的主题覆盖地图,再进入 held-out 主题。

完整研究归档见 067 研究快照。


11. 一页速查

  • 核心判断:Agentic RAG 能扩大召回,但在现有研究与实践中尚未形成解决主题“找全”的共识闭环。
  • 问题性质:c13-003 的难点不是单篇总结,而是从当前知识库发现多个互补证据面。
  • 第一条必选判据(R1) :七组跨文档核心边界必须全部覆盖,并说明具体限制对象或风险。
  • Agent 失败点:能看到 15 篇文档,却把“读完一篇”解释成“题目已覆盖”。
  • 提示词边界:通用范围提示词没有改变检索范围;强制结束理由只增加理由、成本和协议错误。
  • 查询展开边界:解释查询只能找回 0~1 个已知漏点;逐名词全文检索虽然把三个探针全部找回,却拿回 511/526 个 block。
  • facet 边界:corpus-grounded facet 和审计提高了结构,但 facet 生成仍有明显波动。
  • 章节边界:章节路由补上了 worktree,却被泛化标题和 Appendix 容器挡住;block 与 section 合并后仍缺“恢复正确性评估”。
  • 研究边界:CoveR、Decompose、Q-CARE、TREC CAR 分别解决局部问题,没有提供端到端主题证据发现。
  • 架构判断:继续保留块检索,同时验证可回源、可检索、可增量维护的 LLM Wiki 证据地图。
  • WeKnora 结论:七阶段编译、逐字原文、引用和 slug 账本值得借鉴;成本、漂移、删除、别名和规模问题不能忽略。
  • 下一步:先进入 LLM Wiki 预编译实验,同时保留原始 block 检索;先观察 c13-003 能否形成更稳定的主题证据地图。

最后留下一句核心判断:

我们不是从 RAG 转向 Wiki,而是从“用查询寻找证据”扩展到“先维护一张可回源的证据地图,再用查询补全它”。