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 等只是可选示例。
- 文件与工作区可达边界:限制 Agent 能访问、读取、修改或删除的文件和数据范围;
- 凭证与身份边界:限制 Agent 能取得或代表使用的身份、凭证;
- 工具与行动能力边界:限制 Agent 能调用哪些工具、执行哪些操作;
- 外部内容与工具结果信任边界:限制网页、文件、工具结果等在检查前影响上下文或行动;
- 并行任务与工作状态边界:限制并行任务之间的修改冲突、不可回退和状态污染;
- 上下文与记忆生命周期边界:限制无关或受污染上下文跨任务累积,以及长期记忆的写入和复用;
- 子 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 查询,让每条查询自动对应一个潜在证据面。
背后的假设是:
- LLM 能生成比原始 topic 更完整的主题解释;
- 解释已经包含多个语义面;
- 把解释切成片段后,每一段可以作为一条独立查询;
- 多条查询的候选合并起来,就能覆盖知识库中分散的证据。
实验使用 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:让语义面受当前语料约束
前一轮说明,解释式查询只能把每个片段表达得“更像主题”,却无法保证这些片段对应知识库中的真实证据义务。下一步要验证的是:
如果让模型先看到当前知识库实际命中的正文和文档结构,再规划覆盖面,能否减少通用分类,产生知识库可以检索、可以判断的具体证据义务?
这里的假设有三点:
- seed block 全文能提供知识库真实使用的术语、状态和机制,而不是只靠模型参数知识猜;
- 文档大纲能提示同一文档中与命中章节相邻、并列或上下位相关、但尚未命中的区域;
- 如果每个 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,能否补上块级向量检索漏掉的语义面?
这个尝试有三个依据:
- 人类章节标题和路径往往概括了一组 block 的共同语义;
- 章节检索可以覆盖那些没有进入 seed 文档的章节,而不只是查看已命中文档的
get_outline; - section 命中后仍能展开到带
section_path和原始block_id的证据,满足回源要求。
它同时检验一个更实际的问题:在不增加 LLM 预编译成本的前提下,能否先把作者已经写好的目录结构当作一张现成知识地图。
6.2 方法:snapshot-bound SectionIndex 与子树展开
✅ 我们在当前 15 篇基准语料上做了初步章节索引实验:
| 指标 | 数量 |
|---|---|
| 文档 | 15 |
| block | 526 |
| section-tree 节点 | 328 |
| 可路由 section | 286 |
| 是否满足 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。
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,而是从“用查询寻找证据”扩展到“先维护一张可回源的证据地图,再用查询补全它”。