别再检索,去导航:把企业知识蒸馏成可导航 Agent Skill 的 QA 与 RAG 方案(Corpus2Skill)
- 关联论文:2604.14572
- 作者:flyP
- 更新:2026-07-08
一句话结论
Corpus2Skill 把传统 RAG 的「黑盒检索」重写为「Agent 在已编译好的分层 Skill 目录里自顶向下浏览并回溯」——离线一次把语料蒸馏成文件系统形式的 SKILL.md / INDEX.md 树,服务时 LLM 用渐进披露(progressive disclosure)方式从鸟瞰层钻到文档层,在企业客服基准 WixQA 上以中等代价换得答案质量与引用 grounding 的双重提升。
解决的真问题
企业知识库(客服工单、产品手册、合规条款)动辄几千到上十万篇异构文档。传统 RAG 把 LLM 当成检索结果的被动消费者——它只看到 top-k 个段落,看不到「整片森林长什么样」「最优证据是否根本没进检索窗口」。这带来三个连锁缺陷:
- 多跳查询常常因为某条关键证据不在 top-k 而直接失败;
- Agentic RAG 允许多次重查询,但每条新 query 仍是盲打,因为 Agent 不知道语料里到底有什么;
- 层次化方法(RAPTOR、GraphRAG、StructRAG、BookRAG)虽然建了树或图,但 query 时仍走 embedding 检索,模型看不到产出这棵树的结构本身。
论文把这层缺口命名为「corpus navigability」(语料可导航性)——一个有结构的语料,Agent 应当能在浏览过程中获得「还剩几条没看」「这条分支是否值得继续」的结构性感知,而不是只能盲目打分。
核心方法
设计取舍:从 procedural skill 到 informational skill
论文先把概念锚清楚。Agent skill 此前一直指「如何做事」(workflow、决策树、代码模式),形如 S = (C, π, T, R)——适用条件、执行策略、终止条件、可复用接口。Corpus2Skill 反过来把 skill 当成「这段语料里有什么」来用:每个 skill 目录代表语料的一个主题分区,目录里同样是 SKILL.md + INDEX.md 的形式,Agent 走的还是 description → SKILL.md → INDEX.md → document 这套渐进披露流程,只是导航对象从「执行指令」换成了「信息层级」。
这个重构的好处是:文件系统 + Skills API 自带 progressive disclosure,能让上下文开销与目录规模解耦,目录再大也不会撑爆 context window;同时不需要专门的向量库或检索基础设施,部署就是一堆文件。
离线编译(Compile Phase)
输入:.md / .txt / .json / .jsonl 的文档集 D = {d₁, …, d_N}。 输出:K 个根 skill 组成的 skill 森林 S = {s₁, …, s_K},每个 s_k 是树状子目录。
四步流水线(伪代码):
def compile(D, p=10, K=10, tau=margin):
# 1. 文档表征
for d in D:
card[d] = LLM.summarize(d) # title + one-liner + distinctive phrases
emb[d] = embed(card[d] + d[:chunk])
# 2. 自底向上聚类建树
level = [emb[d] for d in D]
while len(clusters) >= K:
groups = kmeans(level, n = ceil(len(level)/p))
for g in groups:
summary[g] = LLM.summarize(members_of(g))
# verify-and-repartition:合并混淆簇、拆分混合簇
flags = LLM.verify(sibling_summaries)
groups = repartition(groups, flags)
level = [embed(summary[g]) for g in groups]
# 3. 跨分支导航
entities[g] = LLM.tag(summary[g]) # 命名实体 + 文档类型
related[g] = jaccard(entities) # → ## Related skills
# 4. 文件化
for root in top_K:
write_SKILL_md(root, summary[root], related[root])
for child in root.children:
write_INDEX_md(child, rows=[card[d] for d in child.docs])
write_entity_index(entities)
write_documents_json(D)
两个值得记的关键技巧:
- 跨引用而非复制:每篇文档只有一个 home cluster,但若 top-1 与 top-2 余弦相似度差距小于 τ,会被交叉列出到 runner-up 的 INDEX.md,避免硬聚类在边界文档上「劈错」。
- verify-and-repartition:兄弟簇汇总一起交给 LLM 看,标记「confusable」(覆盖同一主题)和「mixed」(单一簇跨多主题),flagged 的就在 ID 层重分并重新摘要。这步直接借自 RAPTOR 的思路,但结果落到了文件系统而不是扁平向量库。
复杂度:深度 L = ⌈log_p N⌉,单次导航只需浏览 O(p · log_p N) 条摘要,不是 O(N)。论文报告 WixQA (N = 6221, p = 10) 上 L = 3、每查约 30 条摘要,宣称可线性扩到 10 万级语料(多 1 层)。每个导航文件控制在 2 KB 以内,方便 agent 在拿完整文档前廉价巡览。
在线服务(Serve Phase)
编译产物上传到 Anthropic Skills API。Agent 只拿到两份预加载信息:所有 skill 的 name + 一行 description(约 200 token 总开销)和 corpus 级 entity_index.json。运行时只配两个工具:
- code_execution:标准的 shell 工具,能
ls/cat/grepSKILL.md / INDEX.md / entity_index.json——这就是为什么部署不需要向量库,连专门的检索 API 都不需要; - get_document(doc_id):按文档 ID 取完整文本。
典型一次 query 的 2-3 个回合:
- 从预加载的 skill 描述 + 实体索引挑 1-2 个最相关 skill,读其 SKILL.md;
- 进入最相关分组的 INDEX.md,看到该组所有文档的卡片(标题/一行简介/关键词);
- 调 get_document 拉 1-N 篇完整文本,写出 grounded answer。
系统 prompt 显式约束三条行为:保留至少 2 个候选 skill、命中具名实体时查 entity_index.json、初始分支空了立刻通过 ## Related skills 横向跳。论文把这条结构性感知称为「可以知道自己还剩九条没看」,并把它拆成两个动作:targeted backtracking(放弃无产出分支)和 cross-branch synthesis(跨分支合并证据)——后者对应论文 Figure 1 强调的 RAG 与 navigation 范式分水岭。
关键实验与数据
主要评测在 WixQA(Wix 客服支持领域的工业基准,6,221 篇文档),对照 5 个 baseline:BM25、Dense、Hybrid、RAPTOR、Agentic RAG。
论文给出的核心结论(abstract + intro 明确表述):
- 质量与 grounding 同时提升:在答案质量与 grounding(是否引用到正确文档)两条指标上都优于全部 5 个 baseline;
- 代价为中等:调用成本高于单次 dense retrieval(因为多了多轮浏览 + LLM 调用),但仍在企业可接受区间;
- 消融三件套:cluster 结构、探索预算(exploration budget)、服务模型三个维度展开 ablation,验证「树结构本身」「足够的回溯预算」「足够强的 serving model」各自贡献。
泛化实验(10-subset generalization study on RAGBench):Corpus2Skill 在大多数子集上赢过 flat retrieval,但 HAGRID / TatQA / CUAD 三个子集上 flat retrieval 反而更好。论文把这条边界画得很明确:navigation 适合「单域、可恢复出主题层级」的语料;在「开放域事实池」「同质表格型语料」上,顶层聚类直接失效,回到 flat retrieval 更划算。这不是失败——是设计准则。
代码与数据集在 https://github.com/dukesun99/Corpus2Skill 开源。
亮点与局限
亮点
- 范式重命名:把 RAG 从「黑盒检索函数 f(q, D)」换成「可被 Agent 主动遍历的有结构目录」;
- 部署零门槛:完全用文件系统 + shell 工具 + Skills API,不依赖向量数据库或定制检索服务;
- 渐进披露解耦成本:skill 描述 ≈ 200 token 全局预加载,每条 INDEX.md < 2 KB,10 万级语料只多 1 层;
- 跨分支导航:通过 entity_index.json + Related skills 块,把硬聚类的边界损失降到可接受;
- 显式刻画了「什么时候 navigation 不 work」的失败模式,是少有的不藏短的 RAG 工作。
局限
- 编译是一次性成本——语料结构性变(如新增一类主题、合并两个大类)就要重新编译整棵树;
- 强依赖 LLM 摘要质量,编译阶段需要多次 LLM 调用,离线成本不可忽视(原文未明确具体每千文档的编译耗时与 token 量);
- 在 HAGRID / TatQA / CUAD 等异构或纯表格语料上不如 flat retrieval,意味着「navigation 不是 RAG 的银弹」;
- Skills API 现状有约束(原文未明确具体 Skills API 版本及其限制数值,但提到这些约束影响了默认参数 p、K 的选择);
- 实验只在 WixQA + RAGBench 上做,没报告在更大规模工业语料上的吞吐、延迟、冷启动表现——这些恰恰是企业最关心的数字。
对工程落地的启发
- 先看你的语料是不是「树形」:能从粗到细划分主题、有清晰上下层级的(产品文档、政策文件、内部 wiki)才值得上 Corpus2Skill;开放域 FAQ / 同质表格型语料继续走 dense retrieval 更划算;
- 渐进披露是核心收益,不是噱头:论文最实用的工程贡献其实是「用文件系统 + progressive disclosure 替代向量库的可行性证明」——即使你不上 Corpus2Skill 这一整套,把内部文档按 SKILL.md / INDEX.md 模板组织一次也大概率能降本;
- 跨切分文档的边界问题:靠 top-2 余弦 gap < τ 做交叉引用,是简单但有效的边界修正,工程上可以拿过来直接复用;
- 评测对齐很重要:论文把「grounding」单独拉出来做指标,提示落地时不能只看 faithfulness 这类通用指标,还要按业务场景拉「引用文档准确率」;
- 回溯预算要预算化:把探索轮数 / 候选 skill 数作为产品参数暴露出来,而不是 hard-code,运营可以按客户层级调档;
- 冷启动方案:实体索引 + Related skills 让 Agent 命中具名实体时不必从根开始搜,可以直接侧跳,对冷启动和低频长尾查询很有用。
与同方向工作的关系
- vs. RAPTOR / GraphRAG / StructRAG / BookRAG:这一族用相同思想(聚类—摘要—层次化),但 query 时仍然走 embedding 检索,模型看不到产出层次的结构本身。Corpus2Skill 真正把「层次」从索引结构提升为 Agent 直接浏览对象;
- vs. NaviRAG / HCAG:也做主动导航,区别在于 Corpus2Skill 走文件系统 + SKILL.md / INDEX.md 模板 + 标准 shell 工具,不依赖专门检索 API;这一点在 Table 5 的 feature comparison 里被作者明确指出;
- vs. Agentic RAG(ReAct / IRCoT / Self-RAG):Agentic RAG 让 Agent 多发检索 query,但每条 query 仍然是基于相似度的 blind shot;Corpus2Skill 给 Agent 看到结构之后再选 query;
- vs. Voyager / SkillX / EvoSkill:这三个也是构建 skill,但 skill 来源是 agent 轨迹,Corpus2Skill 的 skill 来源是文档语料——输入模态根本不同;
- vs. Anthropic Skills API 与 progressive disclosure:Corpus2Skill 直接构建在 Skills API 的渐进披露机制上,可以看作是该 API 在 RAG 场景的范式用例。
适合谁读
- 企业知识库 / 客服 Copilot 架构师:要决定继续走 dense retrieval 还是上层次化导航,这是当下最直接的对照实验;
- RAG 平台工程师:想找一种不依赖向量库的兜底/混合方案,Corpus2Skill 给了一种工程上极轻的备选;
- Agent 框架设计者:评估把 progressive disclosure 与 skill 文件系统纳入自己 agent runtime 的收益;
- 学术读者:研究层次化 RAG、Agentic RAG、Skill 形式化方向的,可以把这篇作为「informational skill」的起点案例;
- 不那么适合:还在用「先把所有文档灌进向量库再 top-k」的早期 PoC 阶段读者,先把基础 RAG 跑稳再考虑范式切换。
工程落地与核查(Jay)
事实核查
| 声明 | 核查结论 | 备注 |
|---|---|---|
| 质量与 grounding 同时优于全部 5 个 baseline | ✅ abstract/intro 明确 | 原文未给出具体提升幅度数字 |
| GitHub 仓库 https://github.com/dukesun99/Corpus2Skill | ⚠️ 链接格式合理但未实测 | 需实际访问确认仓库可用性 |
| WixQA 基准,6,221 篇文档 | ✅ 解读与原文一致 | 属于工业基准,非学术标准 benchmark |
| Corpus2Skill 在 HAGRID / TatQA / CUAD 上不如 flat retrieval | ✅ 原文明确 | 边界条件被正确描述 |
| 每查约 30 条摘要(p=10, L=3) | ✅ 来自复杂度分析 | 理论值,实际可能因 backtracking 更高 |
| 每个 INDEX.md < 2 KB | ✅ 来自原文设计约束 | 文件大小受控是工程实现细节 |
| Skill 描述约 200 token 总开销 | ✅ 来自原文 | 全局预加载开销控制得当 |
| Skills API 约束影响 p、K 参数选择 | ⚠️ 原文未给出具体限制值 | 参数选择背后的约束无法独立核实 |
| 编译阶段 token 量未给出 | ✅ 原文未给出,解读无误 | 离线成本无法事前预估 |
存疑项:GitHub 仓库未实测,实际代码质量和维护状态未知。若仓库不可用或代码与论文描述不符,工程团队不应直接依赖。建议:正式引用前先 clone 验证。
可读性精修
- 「中等代价」的「中等」未量化,解读中已指出「调用成本高于单次 dense retrieval,但仍在企业可接受区间」——但若无具体数字,这个判断更多是定性描述;
- 论文的 pseudo-code 中
jaccard(entities)的计算对象是 LLM.tag() 输出的命名实体列表,实践中 Jaccard 相似度对短列表敏感,建议在工程实现中对 entity tag 做二次过滤(去掉停用词和过于通用的标签); - 「cross-branch synthesis」被描述为 RAG 与 navigation 的范式分水岭,但这个说法是解读者的提炼,原文主要通过 Figure 1 说明,并未在正文中用同样强度的表述。
工程落地关键坑
1. 编译成本是隐性的一次性高峰
编译阶段需要对每篇文档做 LLM summarize、对每个簇做 LLM verify-and-repartition、对每个节点做 LLM entity tagging。对于 10 万级语料(论文宣称可扩规模),假设每篇文档 3-5 次 LLM 调用、每次 500-1000 token,单次编译的 token 成本可能达 150 万-500 万 token,折算费用不可忽视。工程建议:编译前先在 1% 语料上做成本预估;考虑对静态语料做增量编译(新增文档只编译局部受影响分支)。
2. Skills API 并发限制是生产部署的真实瓶颈
原文提到 Skills API 有约束但未给出具体数值。生产环境中若多个 Agent 实例同时访问同一个 skill 森林,Skills API 的并发限制会直接限制吞吐量。工程建议:在接入 Skills API 前确认并发限制;若限制过严,考虑自己实现一套基于文件系统的 progressive disclosure 逻辑(完全自托管,不需要 Skills API)。
3. τ 阈值和 p/K 参数的调优是半经验性的
τ(相似度 gap 阈值,控制跨引用灵敏度)和 p/K(聚类参数)都是工程参数,需要根据具体语料结构做调优。原文未给出自动调参方法。工程建议:对 τ,从 0.05 开始网格搜索 5-10 个候选值,用有标注的 query set 做评估;对 p/K,直接用论文默认的 p=10, K=10 起步,在实际语料上测 L 和导航深度再做调整。
4. 跨分支合并不等于跨簇合并
cross-branch synthesis(跨分支合成)要求 Agent 能在多个 skill 分支下找到相关文档并合并,论文假设这个过程天然正确,但实际上 LLM 在合并来自不同 cluster 的证据时可能产生幻觉(hallucination),尤其是当两个 cluster 的文档用词风格差异大时。工程建议:在 Agent prompt 中强制要求每个答案 claim 附带 source: doc_id,并对答案做引用完整性检查(所有引用的 doc_id 都应在答案中出现)。
5. 语料更新需要整树重建
Corpus2Skill 的编译输出是静态文件系统。一旦语料发生结构性变化(如新增一类主题、合并两个业务线),聚类结构可能需要重建。工程建议:设计 compilation_timestamp 元数据,对小于 X% 的增量变化做局部更新策略(只重新编译受影响的分支),避免全量重建;准备好「切换时无感 reload」的机制。
6. WixQA 到其他语料的 gap
论文的实验环境是 Wix 客服领域,特点是主题相对集中、文档格式较规范。迁移到更异构的语料(如混排的 PDF 合规文档、内部混用 Markdown 和 Word 的技术文档)时,compile 阶段的文档表征质量会下降,导致树结构本身就有偏差。工程建议:上线前在自己语料上做「聚类质量审计」——抽 50-100 篇文档,验证 LLM summarize 后的 title + one-liner 是否准确反映原文主题。
实际系统怎么用
适合引入 Corpus2Skill 的场景: - 内部知识库规模在 1,000-100,000 篇,主题可分层次 - 已有明确的 Agent 框架(支持 code_execution 和 get_document 工具) - 不想维护向量数据库,希望最小化基础设施依赖 - 需要强 grounding(每个答案必须引用具体文档)
不适合的场景: - 语料高度同质(FAQ、表格型数据)—— flat retrieval 更划算 - 开放域事实查询(维基百科类)—— navigation 层次结构收益有限 - 实时性要求极高(毫秒级响应)——多轮浏览的延迟叠加需要评估 - 编译阶段无法接受 LLM 调用成本