Files
playbook/cangjie-skill/docs/plans/2026-08-23-cangjie-skill-optimization-plan.md
T
2026-08-31 05:00:46 +08:00

130 KiB
Raw Blame History

仓颉 Skill 优化详细方案

版本:Draft v1.3 日期:2026-08-24 范围:仓颉 Skill 核心蒸馏流水线、单 Skill / Skill Pack 双输出模式、增量迭代、定向修复、数据预处理、视频多模态与 Token 成本 本文性质:实施前设计方案,不代表相关功能已经开发完成

v1.3.1 修订(2026-08-25:统一阈值预注册口径(§0/§10.5/§16.14 与 §5.3 对齐);§0.11 改为按 §10.6 分级处置;Phase 1 补“改写阶段 2—5 产出 Capability Bundle”交付物;新增生成文件本地手改检测;Phase 0 增加宿主锁定与 compact pack 原型产出方式说明;修正 routing_trace 示例归属;重要度需附依据;host_fingerprint 格式标 TBD。

v1.3 主要修订:明确 compact pack 为“1 个来源路由入口 + 少量晋级 Skill”,保证所有未晋级能力仍可运行时访问;修正路线 C 下的缓存与可观测指标;把 SourceDocument / Chunk 契约留在核心、仅把预处理适配器移出;补齐 Registry v1/v2 兼容策略、Capability 生命周期、Phase 0 交叉试用协议、Phase 2A/2B 排期、干净 worktree 基线冻结、并发与崩溃恢复要求,并加入 4 份 ADR。

0. 一页结论

仓颉 Skill 现有 RIA-TV++ 的方法论骨架是成立的:先理解全局,再并行抽取、三重验证、构造可执行能力、建立关联、压力测试、交付。当前方案的工程底座总体可行,但还缺少一个重要的产品决策层:一本内容最终应编译成一个统一 Skill,还是一组原子 Skill。读者反馈“蒸馏出来的 Skill 太多”不是单纯的命名或安装问题,而是输出粒度没有根据用户目的自动收敛。

因此,本版新增明确结论:保留两种输出产物,默认采用 auto 选择器,并遵循 single-first(不确定时先单 Skill、使用证据足够后再拆分)的原则。 单 Skill 模式不是普通摘要,而是一个小型路由入口,内部继续保存仓颉验证过的 RIA 能力卡、反例、边界和证据;Skill Pack 只服务于真正需要独立触发、组合、测试和复用的工作流。

同时必须纠正 v1.1 的一个定位错误:单 Skill 的主要收益是产品与认知收益,不是 Token 收益。 对当前 19 个 Skill 的 name + description 做快照计数,结果约为 3,897 个 cl100k_base tokens、2,682 个 o200k_base tokens,说明结果明显依赖 tokenizer。压成 single 后发现目录会更小,但不能拿宿主的最大上下文窗口当成本分母;而且 single 命中后要加载“主入口 + 能力卡”,单次任务的模型载荷可能高于 pack 命中单个原子 Skill。因此输出粒度和 Token 优化是两个独立问题,必须分开立项、分开验收,所有报告都要同时记录 tokenizer_id、输入文件集合和计数口径。

因此,推荐的最优路线是:

  1. 保留现有七阶段及其人类可读产物,不推倒重写。
  2. 新增一个兼容现有目录的 .cangjie/ 侧车层:Phase 1 只落最小 capabilities/ 编译事实源;来源、标准化内容、块级哈希、依赖图、缓存、变更集、评测与用量数据属于 Phase 2A—2B,不进入 Phase 0。
  3. 把两个维度明确拆开:
    • 生命周期操作:createupdaterepair
    • 输出策略:auto(默认决策)、single(一个统一入口)、pack(一个来源路由入口 + 少量晋级 Skill 的 compact pack)。
  4. 新增单 Skill 模板:主 SKILL.md 负责触发、总原则和路由,详细章节、能力卡、证据、术语、决策速查表进入 references/ 按需读取。
  5. 保留 Skill Pack,但将新生成的 compact pack 固定为“1 个来源路由入口 + 少量晋级 Skill + 内部能力卡”,并新增“独立 Skill 晋级门”和默认软预算;一个知识点通过内容验证,不等于它必须成为一个独立 Skill,未晋级能力必须仍可经来源路由入口访问。
  6. 把当前“5 个 extractor 各自反复读长文本”按 extractor 类型分化framework / principle 需要全局视野,保持全量扫描;case / counter-example / glossary 是局部命中型,改为按索引取相关块、必要时回原文核验。一刀切改成检索式会损害阶段 1 的覆盖率目标(见缺口 B)。
  7. 把压力测试从单次主流程自测升级为两层评测:
    • 触发评测:该不该调用、会不会和兄弟 Skill 抢调用;
    • 输出评测:用了 Skill 后是否比旧版本/不用 Skill 更好,代价是多少。
  8. (移出主线,独立仓库) 文档预处理采用可插拔路由,而不是押注单一解析器:
    • 原生文本和结构良好的 Office/HTML 走轻量路径;
    • Docling 作为跨格式统一表示与本地基础实现;
    • 中文复杂 PDF、扫描件、公式和跨页表格以 MinerU 作为高精度候选,通过样本基准决定默认路由;
    • 任何解析器都必须输出统一的 SourceDocument 中间表示和质量报告。
  9. (移出主线,独立仓库) 视频采用“音频转写 + 双路抽帧 + OCR/VLM + 时间轴对齐”,不能只看口播;视频号只做来源适配层,不把非公开下载或绕过平台限制写进核心能力。
  10. 优先级重排为两条独立线:P0-产品 = 输出粒度(single/pack,验收看能力覆盖、路由命中和真实读者反馈;P1-工程 = Token 与增量,验收看可静态计算的代理指标。文档与视频预处理拆为独立仓库/独立 Skill,不进主线排期。
  11. 在写任何基础设施之前,先用一次低成本证伪回答“single 是否真的更好”。若答案为否,按 §10.6 的终止条件分级处置:可能是 auto 默认改推 compact pack、single 降级为纯查阅模式,或整体终止 §4.6 的默认策略改造——不是一刀切作废。

关于验收阈值的原则性修订:v1.1 在没有任何基线的情况下写死了 30%、95%、2 个百分点、F1 >= 0.85<= 10% 等数字,并把它们设为阻塞式发布门。这是错误的做法,会导致两种坏结果——为了过门槛而回头调门槛,或者为了过门槛而做浅测(现有 19 个 test-results.md 全部是“降级自测、100% 通过”,文件内已自述可信度低于盲测,这正是该风险的现实样本)。

因此本版规定:Phase 0 产出基线之前,本文所有数值阈值一律视为 TBD-after-baseline,仅作为待检验假设保留,不得作为发布门。 基线之前唯一允许阻塞发布的硬条件只有两类:

  1. critical 能力与安全边界用例 100% 通过;
  2. Agent Skills 格式、相对引用、JSON/YAML schema 校验 100% 通过。

其余一律以“预注册的非劣设计 + 人工复核分歧样本”判断。特别提示:在 50 条规模的任务集上,“下降不超过 2 个百分点”只对应 1 条用例的计数粒度,单凭这个百分比无法建立统计非劣;若要保留门槛,必须先定义配对检验、非劣效界值,并把样本量或重复次数提高到能支撑该精度的水平。

0.1 前置决策:执行模型分叉(必须在 Phase 0 之前拍板)

这是 v1.1 遗漏的关键矛盾。仓库现状是:整条流水线由纯 Markdown prompt 描述(SKILL.md 168 行 + methodology/ 8 篇 + extractors/ 5 篇),没有任何流水线代码——全仓唯一的 Python 是约 225 行的 scripts/generate_star_history.py。蒸馏实际由 Agent 在宿主(Claude Code / Cursor / 其他兼容客户端)内读文档执行。

在这个执行模型下,本文原 §5.1 与 §5「第五级」中的三项设计不可实现

原设计 为什么在当前模型下做不到
每次模型调用记录 input_tokens / cached_input_tokens / cache_write_tokens 宿主不把 per-call token 用量暴露给 Skill
固定 system/tool 顺序、静态前缀在前以命中 API Prompt Caching 请求体由宿主拼装,Skill 无法控制前缀顺序
cache_key 包含 model_provider_and_versionnormalized_parameters Skill 不知道自己运行在哪个模型和参数下

而 §12 又声明“统一入口只负责编排和确定性操作,真正的蒸馏仍由 Agent 按 Skill 指令完成”。这与上述三项直接冲突。必须先在三条路线中选一条:

路线 做法 代价
A 自建 harness 用 Agent SDK / 直接调 API 接管全部模型调用 能拿到真实 token 与缓存指标,但仓颉从 Agent Skill 变成程序,安装门槛上升,与“降低使用成本”的产品目标相反
B 纯 Agent Skill 完全保持现状 放弃一切 per-call 计量,Token 优化只能凭感觉做
C 混合(推荐) 确定性预处理与编译做成脚本(可精确计量),蒸馏留在 Agent 内(用代理指标衡量) 需要接受蒸馏阶段只有代理指标,但保住了开放 Agent Skill 的形态

本版选择路线 C。 相应地,Token 验收改为以下三个固定 tokenizer 下可离线复算的文件计数或静态载荷模型,不再冒充宿主真实调用成本:

  1. 发现目录载荷模型:所有已安装 Skill 的 name + description 文件计数;
  2. 单任务路由载荷模型:命中后按路由表预计读取的 SKILL.md + references 上下界;
  3. 产物文件总量:整个 Skill Pack / single 包的全部可读内容计数。

蒸馏过程本身的成本改用可观测代理量:各阶段准备给 Agent 的字符数与块数、任务次数、被淘汰候选数、重试次数。这些都能在不接管 API 的前提下记录,但若宿主没有确认真正提交,就只能叫 prepared_input,不能叫真实 Prompt 输入。


1. 已确认的任务清单

2026-08-23 已从飞书多维表格“仓颉 Skill 优化与项目跟进”实时回读,当前共 5 条记录,均为“待评估”。

原优先级 本版调整 任务 当前问题 目标结果
P0 P1-工程 在效果不降的前提下降低 Token 消耗 长材料被重复读取、上下文堆叠、重复抽取、全量返工 分阶段计量、去重、缓存、按需读取,质量不降
P1 P1-工程 支持蒸馏后增量补充资料 新书、文章、案例加入后只能重跑 识别差异、合并新增知识、处理重复/冲突、保留来源
P1 P1-工程 支持对既有 Skill 定向优化 局部效果不理想时倾向全量重蒸馏 从失败案例诊断问题,只修改受影响部分并回归验证
P1 移出主线 新增通用数据预处理 Skill PDF、扫描件、网页、Office、表格、字幕格式不一 统一转为高质量、可追溯、带质量报告的结构化内容
P1 移出主线 增强视频蒸馏前置预处理与视觉理解 只靠语音转写会漏掉界面、图表、代码、动作和步骤 带时间戳转写、关键帧、OCR/VLM 描述、音画对齐

两处调整的理由:

  • Token 从 P0 降为 P1-工程:见 §0,输出粒度的收益是产品收益,Token 的收益是工程收益,两者混在一个 P0 里会让 30% 的 Token 门槛把资源吸走,去做收益最小的那部分。且 Token 精确计量受 §0.1 执行模型分叉制约,必须在路线拍板后才能定验收口径。
  • 预处理与视频移出主线:这两项要引入 Docling、MinerU、WhisperX、PySceneDetect、VLM 等重依赖(Docling 模型为 GB 级)。每加一个重依赖,普通读者越装不动,与本方案自身“降低安装与理解成本”的目标直接冲突。它们应作为独立仓库、独立 Skill、独立版本发布,由需要的用户单独安装,主线只依赖其输出的 SourceDocument 契约。

本版另加入一条来自读者反馈的 P0-产品 设计问题:默认产物过度碎片化。它不替代飞书里的 5 条任务,而是决定这些底层能力最终如何交付给用户:

优先级 新增设计问题 当前表现 目标结果
P0-产品 单 Skill / Skill Pack 输出选择 一本书可能产出十几个甚至更多 Skill,安装、理解、选择和触发成本高 同一蒸馏底座支持两种产物;默认自动推荐,用户只需做一次轻确认

这 6 条(5 条原任务 + 1 条输出粒度)并不是 6 个平行插件。它们有明确依赖关系,且顺序与 v1.1 不同:

flowchart TD
  P0["Phase 0 证伪<br/>基线 + single/pack 原型 + 读者反馈"] --> OUT["输出粒度 single/pack<br/>P0-产品"]
  OUT --> REG["Registry schema v2 + 官网联动"]
  OUT --> CAP["稳定 capability ID"]
  CAP --> BASE["统一来源清单与中间表示<br/>缓存 + 检索索引"]
  BASE --> LEAN["低成本蒸馏<br/>P1-工程"]
  BASE --> INC["增量差异与依赖图"]
  INC --> UPD["增量补充资料"]
  INC --> REP["既有 Skill 定向修复"]
  LEAN --> EV["统一回归评测"]
  UPD --> EV
  REP --> EV
  PRE["文档预处理路由"] -.SourceDocument 契约.-> BASE
  VID["视频多模态时间轴"] -.SourceDocument 契约.-> BASE

  classDef offline fill:#f5f5f5,stroke:#999,stroke-dasharray: 4 4;
  class PRE,VID offline;

灰色虚线的两项是移出主线的独立产品线,它们与主线只通过 SourceDocument 契约耦合,可以完全并行开发、独立发版。

依赖关系上有两点必须先立:输出粒度决定了后面所有东西编译成什么,所以它排在最前;稳定 capability ID 是 single 与 pack 可比较的前提,也是依赖图的节点标识,必须在底座之前定下来。除此之外才是共同底座——否则每做一个需求都会重复造一套来源追踪、缓存和评测逻辑。


2. 当前仓库基线与关键缺口

2.1 已有能力

当前仓库已经具备:

  • RIA-TV++ 七阶段方法论;
  • 5 类 extractor:框架、原则、案例、反例、术语;
  • PIPELINE_STATE.md 断点续跑约定;
  • BOOK_OVERVIEW.mdverified.mdINDEX.mdGLOSSARY.mdDIGEST.md 等完整产物约定;
  • 原子 Skill 的 R / I / A1 / A2 / E / B 模板;
  • should_triggershould_not_triggeredge_case 和兄弟 Skill 混淆测试;
  • Registry22 个 packskill_count 加总 300)、官网校验和网站 CI
  • 一个完整的《纳瓦尔宝典》样本包,含 19 个 Skill 及测试文件(每个 SKILL.md 119—125 行)。

需要一并记录的工程底座现状,它决定了本方案的可行边界:

  • 整条流水线由纯 Markdown prompt 描述(SKILL.md 168 行 + methodology/ 8 篇 + extractors/ 5 篇 + templates/ 5 份),无任何流水线执行代码
  • 全仓唯一的 Python 是约 225 行的 scripts/generate_star_history.py
  • 无根级 pyproject.toml / package.json / Makefile / CLI
  • CI 仅有 3 个 workflow,实质校验只覆盖 registry 与官网,books/methodology/extractors/ 无任何自动校验。

这些都应该保留,尤其是“边界、反例、用户轻确认、审计轨迹”四项,它们是仓颉 Skill 与普通摘要/RAG 的差异化资产。

2.2 已发现的真实缺口

缺口 A:断点续跑不是增量计算

PIPELINE_STATE.md 只记录“跑到哪个阶段”,没有记录:

  • 哪个来源版本参与了本次运行;
  • 哪些块发生了变化;
  • 哪个候选/Skill 依赖哪些来源块;
  • 哪个阶段的结果可以复用;
  • Prompt、模型、参数或模板变化是否使缓存失效。

所以它能“从某阶段继续”,但不能“只重算受影响节点”。

缺口 B:长文本被多视角重复读取

现有阶段 1 要求 5 个 extractor 独立读取整份长文本。它有利于独立视角,但也造成约 5 份长上下文输入;如果长文本又被分块,后续验证、构造和测试还会继续重复携带大段材料。

优化目标不应取消五视角,而应把“独立判断”和“重复传输全文”拆开:所有 extractor 共享同一份可追溯内容地图,但 framework / principle 用它做全量扫描中的定位与审计,case / counter-example / glossary 才用它做检索召回;五者仍使用独立任务上下文。

但这里有一个 v1.1 低估的质量风险,必须显式处理。 methodology/02-stage1-parallel-extract.md 把并行的三个理由写得很明确,其中“独立性”是为了让阶段 1.5 的 V1 跨域验证真正成立;而该阶段的目标是“不做筛选,宁错杀”——追求的是覆盖率。一旦 extractor 只看检索返回的块,它就不再是“扫描全书”,覆盖率必然下降,而覆盖率恰恰是这个阶段唯一的目标。

因此不能对 5 个 extractor 一刀切,而应按其查找对象的分布特性分开处理:

extractor 查找对象的分布特性 本版策略
framework 思维模型常跨章节隐性分布,需要全局视野 保持全量扫描
principle 原则散落全书,且需判断“是否反复出现” 保持全量扫描
case 案例是局部命中型,有明确文本锚点 走检索式取块
counter-example 反例是局部命中型,有明确警告性措辞 走检索式取块
glossary 术语是局部命中型,可先用确定性方法预筛 走检索式取块 + 脚本预筛

这样保住了最有价值的两类产出的覆盖率,并在理论上去掉 5 条全量扫描路径中的 3 条。由于不同 extractor 的输入长度、重试次数和宿主调度成本并不相同,不能把“3/5 的路径”直接写成“节省 60% 成本”;实际字符数、块数、任务次数与时长必须等 Phase 2A 基线后再报告。

并且必须设一道硬门:改造后在基准集上的候选覆盖率相对全量扫描基线不得下降,尤其是最终通过三重验证的候选,漏检数必须为 0。若做不到,退回全量扫描,Token 收益从别处找。

缺口 C:测试结果缺少可信基线

《纳瓦尔宝典》19 个 Skill 的 test-results.md 都明确标注为主流程降级自测,虽然记录为 100% 通过,但可信度低于独立盲测。当前测试还缺少:

  • 同一问题“旧 Skill vs 新 Skill”的盲测对比;
  • “使用 Skill vs 不使用 Skill”的增益对比;
  • 多次运行与波动统计;
  • train/validation 隔离;
  • Token、时延和缓存命中率;
  • 对文档解析、事实覆盖和来源定位的机械断言。

所以目前无法可靠证明“效果不降”。

缺口 D:产出的 Skill 尚未完全利用渐进式披露

官方 Agent Skills 规范建议:启动时只加载 name + description,触发后加载 SKILL.md,详细资料再从 references/ 按需读取;主 SKILL.md 建议少于 500 行和 5000 tokens。

当前单个 Skill 大约 119—125 行,未超规范,但 R、A1、长证据、审计信息全部位于主文件中。执行任务时真正高频需要的是 A2、E、B,而详细原文和案例可迁移到 references/evidence.md。这会成为 Token 优化的一部分,但必须用评测验证,不能机械删减导致质量下降。

缺口 E:核心仓库与当前本地分支状态不一致

截至 2026-08-24,本地当前分支为 codex/website-mvpHEAD 为 f8f9e9b2026-07-21);远端 main HEAD 为 a47a604(2026-08-24)。本地分支落后远端,且存在多项未提交改动和未跟踪目录。这里的 commit 只是一份核对快照,Phase 0 开始时必须重新读取远端状态,不能把本文数字当成永久事实。

其中最关键的一条:整个 books/naval-almanack-skill/73 个文件、19 个 Skill)目前处于 untracked 状态。 它是本方案全部 A/B 对比的基线样本。基线不可复现,后续所有对比数字都没有意义。

因此 Phase 0 的第一个动作不是在当前目录直接提交,而是:

  1. 读取并记录当时的 origin/main commit
  2. 从该 commit 创建独立干净 worktree / 临时基线分支,不得复用当前脏工作区;
  3. 只把 books/naval-almanack-skill/ 复制到干净 worktree,生成文件清单与 SHA-256,运行静态校验;
  4. 校验通过后再选择“提交并打 tag”或“归档 tarball + SHA-256”中的一种冻结方式;
  5. 网站、Registry 试验和当前用户改动继续留在原工作区,不混入基线提交。

本文只新增方案文档,不修改或覆盖现有改动。

缺口 F:候选单元与可发现 Skill 之间缺少“晋级门”

现有流程把阶段 1.5 验证通过的方法论单元,近似一一映射为独立 Skill。《纳瓦尔宝典》样本因此产出 19 个 Skill。这个做法对构建可组合能力库有价值,但对“我只想随时调用这本书”的普通读者并不友好:

  • 安装后需要理解 19 个名字及差别;
  • happiness-skillacceptanceself-liberationmonkey-mind-meditation 等相邻能力存在潜在路由竞争,需要更多负例维护;
  • 所有 Skill 的 name + description 都可能进入宿主的发现目录,Skill 数越多,静态目录载荷与用户认知负担通常越高;具体宿主是否完整加载必须以兼容矩阵实测为准;
  • “内容上是一个好方法”不等于“用户会把它作为一个独立意图调用”。

根因是当前只有“这个候选是否值得保留”的内容验证,没有第二个问题:它是否值得成为一个独立、可发现、可安装的 Skill。新方案必须把“知识保留”和“Skill 数量”解耦:未晋级为独立 Skill 的方法仍应完整保留在统一 Skill 的能力卡或 references 中,而不是被删掉。

缺口 G:执行模型未定,导致 Token 目标不可测量

见 §0.1。当前流水线是纯 prompt 驱动,Skill 无法获知 per-call token 用量,也无法控制请求前缀顺序。在路线 A/B/C 拍板之前,任何以真实调用 token 百分比表述的目标都是不可验证的。本版选择路线 C,并把验收改为“固定 tokenizer 下的文件计数 + 静态路由载荷模型 + 过程代理指标”。

缺口 H:Registry 与官网未纳入方案,但会最先被输出粒度改造打破

这是 v1.1 完全遗漏的一环。实际状态:

  • registry/22 个 packskill_count 加总为 300
  • schemas/registry-entry.schema.jsonskill_count 是结构化字段;
  • 官网首页按 Skill 数量展示统计,website/src/lib/install.ts 据此生成安装提示词;
  • .github/workflows/registry-check.yml 是全仓唯一有实质校验的 CI,且只覆盖这一层(books/methodology/extractors/ 无任何 CI)。

一旦默认输出改为 single,会立刻出现四个无解问题:

  1. 一个 single 模式的 packskill_count 填 1 还是填内部能力卡数?
  2. 已发布的 22 个 pack 是否重编?由谁承担成本?
  3. 官网“300 个 Skill”的规模叙事与“Skill 不该太多”的新哲学正面冲突;
  4. §11.1 的 frontmatter 迁移会波及这 300 个已发布产物。

本版新增 §11.5 专门处理这一层。这条不做,方案落地当天官网就会自相矛盾。


3. 在线调研结论与技术选型

以下资料在 2026-08-23 至 2026-08-24 期间重新在线核对。工具能力和 API 价格会变化,实施时仍需锁定具体版本并重新跑基准。

3.1 Agent Skill 结构与评测

一手方案 可直接借鉴的机制 对仓颉 Skill 的结论
Agent Skills Specification name/description 负责发现;SKILL.md 触发后加载;references/scripts/ 按需读取;建议主文件少于 500 行 用渐进式披露重构生成模板;详细证据移到 references,核心执行/边界留在 SKILL.md
Optimizing skill descriptions 约 20 条真实触发 query;正负近邻样本;每条多跑 3 次;60/40 train-validation;按验证集选最佳版本 当前每个 Skill 仅 6 条单次自测不足;升级为触发精度/召回率和验证集机制
Evaluating skill output quality 同一用例 with-skill / without-skill 或 old-skill 对比;记录可获得的成本与时长;机械断言优先;盲评与人工复核 定向优化必须以旧版本为基线;路线 C 只记录静态路由载荷与可观测时长,不伪造宿主未暴露的 Token
Agent Skills best practices validate loop、plan-validate-execute、重复逻辑沉淀到 scripts 将解析、去重、变更分析、校验固化成脚本,避免每次让模型临时写代码

3.2 增量处理、缓存与语义分块

一手方案 可直接借鉴的机制 对仓颉 Skill 的结论
LlamaIndex Ingestion Pipeline node + transformation 缓存;doc_id -> document_hash;未变化跳过、变化后 upsert;并行执行 建立内容寻址的阶段缓存与来源哈希,但不直接把仓颉 Skill 绑定死在 LlamaIndex
Unstructured Chunking 基于文档元素而不是纯字符切块;by_title 保留章节边界;原始元素元数据可回溯 块必须尊重章节/表格/列表/页面,保留页码、坐标、标题路径和原始元素映射
DoclingDocument 统一表示文本、表格、图片、层级、布局和 provenance 可作为跨格式中间表示的主要参考,但仓颉应定义自己的最小稳定 schema,避免上游升级绑架

3.3 文档预处理候选

方案 优势 局限 建议角色
Docling 本地运行;多格式;统一结构;OCR、表格、图片、公式;支持 macOS/MPS;还能处理音视频 中文复杂扫描件仍需本地样本验证;完整模型依赖较重 默认统一转换器与结构化 IR 参考
MinerU 面向 PDF/Office/图像;中文、扫描件、公式、多栏、跨页表格能力强;支持 CPU/GPU/MPS 官方性能数字主要来自自身基准;安装和模型较重;许可证需在集成前逐条核对与本仓 AGPL-3.0 的兼容性,不接受“自定义开源许可证”这种含糊表述 中文复杂 PDF/扫描件高精度路由和 A/B 候选
Unstructured 元素级分区和语义 chunking 成熟,原始元素可恢复 作为全套解析主引擎未必是本项目最轻路线 借鉴 chunking 规则,必要时作为可选后端

不存在对所有资料都最优的单一解析器。正确的“最优解”是有质量探针的路由器:先低成本解析,质量不足时升级到 OCR/VLM 或另一后端;对目标用户最常见的中文材料建立自己的 golden set,以实测决定默认值。

3.4 视频多模态候选

一手方案 可直接借鉴的机制 对仓颉 Skill 的结论
Docling 音视频处理 Whisper 转写;固定间隔或场景变化抽帧;可选说话人分离;输出统一 DoclingDocument 可快速搭建本地 MVP,并与文档预处理复用同一表示
WhisperX 批量 ASR、词级时间戳、VAD、强制对齐、说话人分离 需要额外模型和依赖;说话人分离可能需要受许可模型/令牌
PySceneDetect AdaptiveDetector 用相邻帧滚动平均减少快速运动误判 只做镜头变化,不理解画面语义
Gemini Video Understanding 原生音视频理解、时间戳问答;官方说明默认约 1 FPS,快速变化可能漏细节 云端上传涉及成本、隐私和数据治理;1 FPS 不适合快速 UI 操作

视频“最优解”不是每秒都送进大模型。推荐先本地提取音频、场景变化、固定间隔帧和 OCR 差异,只把有信息增量的帧送入视觉模型;低置信度片段再升级为短视频窗口分析。

3.5 Token 优化与缓存

一手方案 可直接借鉴的机制 对仓颉 Skill 的结论
OpenAI Prompt Caching 相同前缀才命中;稳定指令/工具/schema 放前面,变量放后面;可在自建请求层监控缓存字段 仅路线 A 能控制请求与验收缓存;路线 C 只保持文件内容稳定,不承诺命中
Anthropic Prompt Caching 静态内容置前;缓存前缀按 tools/system/messages 构成;默认短 TTL,可选更长 TTL 仅路线 A 能直接实施;任何路线都不能用 API 短期缓存替代本地内容寻址缓存
Agent Skills 渐进式披露 只在触发后加载 SKILL.md,资源继续按需读取 减少 Skill 主文件体积和不必要证据加载,比单纯换便宜模型更稳健

关键判断:Prompt 缓存不是持久化增量系统。它会过期、受模型/前缀/路由影响,只能作为最后一层优化;核心收益必须来自本地内容去重、阶段缓存、按需检索和受影响范围计算。

3.6 book-to-skill 项目复核与可借鉴点

本次先完整检查了 virgiliojr94/book-to-skill 的固定评审快照 3a97a71(2026-08-19),并在本机对该快照运行测试,结果为 494 passed, 4 skipped。截至 2026-08-24,其 master 已推进到 7bcfcd5,最新正式版仍为 v1.4.0。文中的生成规范与性能结论继续链接固定快照,避免上游变化导致证据漂移;master 只用于补充观察最新工程改进。

它的核心产物始终是一个统一 Skill:约 4,000 tokens 的主 SKILL.md 保存核心框架、章节索引和主题索引,章节文件、glossary、patterns、cheatsheet 按需加载。详见其 生成规范架构说明

值得借鉴的机制:

机制 借鉴方式 不应照搬的部分
一个入口 + 章节/主题索引 + 按需文件 作为仓颉 single 模式的导航骨架,解决 Skill 数量和发现面过大 不能只做逐章摘要;仓颉应保留 RIA 执行步骤、边界、反例和验证证据
reference / study 两种深度 根据“快速查阅”或“深入学习/应用”调节能力卡和案例密度 输出深度不能替代 single/pack 粒度决策;这是两个独立维度
大于约 50K tokens 后用 grep/offset 定向读取 纳入长内容预处理和阶段检索,禁止每章重复读取全文 只能作为轻量路径;复杂 PDF、表格和图像仍需结构化 IR
转换前展示页数、章节数、输入/输出 Token 估算 在昂贵阶段前给出成本预估和模式建议 不硬编码模型价格;实际使用量仍要在 run 账本回读
cheatsheet 是“决策层”而非术语表 单 Skill 模式增加决策规则、权衡矩阵、阈值和快速识别信号 不能把作者判断改写成无来源的通用常识
内容类型和使用目的决定章节密度 text/technical × reference/study 影响生成预算 不用固定字数硬凑篇幅,内容密度和评测优先
输入清洗 + 生成产物二次安全扫描 在来源进入模型前清除隐藏 Unicode,并对最终 Skill 扫描越权/注入模式 扫描器只做告警,不能替代人工审查和最小权限
按宿主做格式校验、失败回退、多语言章节识别 借鉴其 host lens、依赖预检、CJK 估算和解析失败不拖垮整批任务 不把多宿主差异写成一个最低公分母模板
每次运行使用隔离工作目录 仓颉采用 per-run workdir、目标包 writer lock、staging 构建和原子发布,避免并发任务串写 不能只改目录名;仍需处理中断标记、缓存原子性和失败恢复

需要保持判断的地方:

  1. 它的 Token 报告 主要衡量“回答单个章节问题时,进入上下文的 tokens”,适合证明按需加载价值,但不能直接证明生成质量、触发准确率或对仓颉现有 19 个可执行能力的覆盖率。
  2. 它的 Update/Fold-in 主要靠 Agent 读取旧索引后语义合并;缺少本文方案中的内容哈希、依赖图、最小影响范围、版本化回滚和 old/new 行为回归。
  3. 统一 Skill 的 description 会覆盖较宽主题,减少兄弟 Skill 抢调用,却可能和其他书籍型/领域型 Skill 竞争;因此 single 模式仍需独立做 trigger precision/recall,而不是认为“只有一个就不会误触发”。
  4. 其公开性能报告中的 discovery loop 是带明确假设的模型,不是对具体 Agent 的真实多轮运行记录;仓颉应同时报告可复现实测与模型估算,不能直接移植“24×—51×”结论。
  5. 上游 7bcfcd5 修复了并行任务共用固定工作目录导致的内容串扰,说明本地 CLI 同样需要把并发与崩溃一致性当成一等需求,而不是等问题发生后再补锁。

结论:借鉴它的统一入口、主题索引、章节按需加载、决策型 cheatsheet、成本预检和供应链安全;不要用它替换仓颉的 RIA-TV++ 验证、可执行性、边界、反例、依赖图和行为评测。


4. 目标架构:RIA-TV++ Incremental

4.1 生命周期操作:createupdaterepair

create  新内容首次蒸馏:完整走 RIA-TV++
update  新增/替换/删除资料:只重算受影响的候选、Skill 与测试
repair  基于失败案例修复既有 Skill:诊断、生成补丁、回归,不重新读全书

三种模式共用同一份来源清单、中间表示、缓存、依赖图和评测集。

这里的 create/update/repair 回答“这一次对既有内容做什么”,不是回答“最后产出几个 Skill”。输出粒度是另一条正交配置轴,不能继续都叫 mode

4.2 兼容现有目录的侧车结构

不改变现有用户可见产物,在每个书/内容包中新增 .cangjie/

books/<content-slug>/
├── PIPELINE_STATE.md                 # 继续保留,给人看
├── BOOK_OVERVIEW.md
├── verified.md
├── INDEX.md
├── GLOSSARY.md
├── DIGEST.md
├── <skill-slug>/
│   ├── SKILL.md
│   ├── references/
│   │   ├── evidence.md
│   │   └── examples.md
│   ├── evals/
│   │   ├── trigger-train.json
│   │   ├── trigger-validation.json
│   │   └── output-evals.json
│   └── test-prompts.json             # 兼容旧 darwin 格式
└── .cangjie/
    ├── manifest.yaml                 # 来源及版本清单
    ├── config.yaml                   # 模型、解析器、阈值和策略
    ├── normalized/
    │   └── <source-id>/<version-id>/
    │       ├── document.json         # 稳定中间表示
    │       ├── document.md           # 便于人看
    │       ├── assets/               # 图、帧、表格等
    │       └── quality.json          # 解析质量报告
    ├── chunks/chunks.jsonl           # 块、哈希、来源定位
    ├── index/lexical.sqlite          # FTS5MVP 默认
    ├── index/embeddings.*            # 可选,不作为 MVP 必需
    ├── capabilities/
    │   ├── verified.yaml             # 唯一可编译 Capability Bundle
    │   └── destinations.json         # single/pack 的 owner 与去向映射
    ├── graph/dependencies.json       # source→chunk→candidate→capability→entrypoint→eval
    ├── changes/<change-id>.json      # 增量变更集
    ├── cache/<stage>/<cache-key>/    # 阶段缓存
    ├── runs/<run-id>/
    │   ├── run.json
    │   ├── stage-usage.jsonl        # B 类过程代理指标(字符数/块数/次数),非真实 token
    │   ├── timings.jsonl
    │   ├── patch.diff
    │   └── report.md
    └── snapshots/<version>/          # 关键发布版本快照

选择侧车结构的原因:

  • 现有 BOOK_OVERVIEW.md 和 Skill Pack 不需要迁移后才能继续使用;
  • .cangjie/ 可以整体加入 .gitignore 的缓存部分,也可选择性提交 manifest、变更和报告;
  • 新能力失败时可回退到原有全量流程;
  • 对外发布仍是标准 Agent Skill,不把内部流水线元数据强塞进用户上下文。

4.3 稳定中间表示 SourceDocument

所有解析后端最终输出相同的最小字段:

{
  "schema_version": 1,
  "source_id": "src-book-main",
  "version_id": "sha256:...",
  "title": "资料标题",
  "media_type": "pdf",
  "language": ["zh-CN"],
  "elements": [
    {
      "element_id": "el-000123",
      "type": "heading|paragraph|list|table|image|formula|transcript|frame",
      "text": "...",
      "heading_path": ["第二章", "2.3"],
      "page": 42,
      "time_start_ms": null,
      "time_end_ms": null,
      "bbox": [0.1, 0.2, 0.8, 0.3],
      "asset_ref": null,
      "confidence": 0.97,
      "content_hash": "sha256:..."
    }
  ]
}

必须保证:

  • source_id 稳定,文件改名不能自动变成一个全新来源;
  • version_id 由规范化字节或确定性内容计算;
  • 每个 element 可定位回页码、时间戳、坐标或 DOM 路径;
  • Markdown 是展示格式,JSON 才是增量计算和审计的事实源;
  • 解析器版本、模型版本和参数写入 quality.json

4.4 阶段缓存键

路线 C 必须把缓存分成两类,不能假装 Skill 能看到宿主模型信息。

A. 确定性缓存(默认开启,可安全复用)

适用于规范化、切块、哈希、索引、静态编译、格式校验等脚本阶段:

deterministic_cache_key = sha256(
  stage_name
  + implementation_version
  + stage_schema_version
  + ordered_input_hashes
  + normalized_script_parameters
)

以下任何变化都必须使对应确定性缓存失效:

  • 输入块变更;
  • 中间 schema 变更;
  • 脚本实现或关键参数变更;
  • 编译模板变更。

B. Agent 生成物复用(默认不跨宿主自动命中)

蒸馏、判断、重写等结果由宿主 Agent 生成。路线 C 拿不到真实的 model_provider_and_versionnormalized_parameters,因此不能构造安全的模型感知缓存键。首版只允许两种复用方式:

  1. 同一次 run 内、同一个明确任务的断点续跑;
  2. 宿主或高级用户显式提供 host_fingerprint 后,把它连同 prompt_template_hash、输入哈希写进复用键。
agent_artifact_key = sha256(
  stage_name
  + stage_schema_version
  + ordered_input_hashes
  + prompt_template_hash
  + host_fingerprint
)

host_fingerprint 的格式为 TBD(首版建议 host_name/host_version/model_hint,由用户显式填写,不自动探测)。它缺失时,旧 Agent 生成物只能作为“待复核候选”,不得静默当成命中结果。即使 fingerprint 相同,涉及高风险纠错、冲突覆盖或安全边界的产物仍需重新验证。

时间戳、run ID、输出目录等无关变量不得参与 Prompt 静态前缀,也不应影响语义缓存键。

4.5 依赖图与影响范围

图中的边必须带类型和证据:

source_version -> contains -> element
element -> grouped_into -> chunk
chunk -> supports|contradicts|examples -> candidate
candidate -> validates_into -> capability
capability -> compiled_as|served_by -> entrypoint
entrypoint -> compared_with|depends_on|composes_with -> sibling_entrypoint
eval_case -> covers -> capability

当一个块变更时,只沿图向下找:

  1. 直接依赖它的候选;
  2. 由这些候选生成的 Skill
  3. 与这些 Skill 有依赖/对比/组合关系的邻居;
  4. 覆盖这些能力的测试。

这就是 updaterepair 不需要全量重跑的关键。

4.5.1 稳定 Capability 生命周期

capability_id 不能只是一个第一次生成后永不解释的字符串。每个能力至少包含:

capability_id: cap.naval.decision-heuristics
revision: 3
status: active            # active | deprecated | merged | split
aliases: []               # 旧 ID 或历史名称
supersedes: []            # 本能力替代的旧 ID
merged_into: null         # 合并后的目标 ID
split_into: []            # 拆分后的新 ID 列表
source_evidence: []       # source/version/element 定位

约束:

  • 文案润色、证据补充和输出模板变化只增加 revision,不创建新 ID
  • 能力语义发生实质拆分或合并时创建新 ID,并保留 supersedes / merged_into / split_into
  • Single 与 Pack 必须引用同一组能力 ID,禁止分别蒸馏出两套不可比较的能力;
  • 删除默认表现为 deprecated,只有确认无来源、无依赖、无历史兼容需求时才能物理清理。

4.6 输出粒度:singlepack 两种产物

两种产物的规范化编译输入不是原始书籍,而是同一份 Capability Bundle:经过 RIA-TV++ 验证的能力、来源证据、关系、评测与去向映射。Phase 0 可以人工生成最小 BundlePhase 1 起由 schema 固化。CLI 只负责从 Bundle 做确定性编译,Agent 仍负责把原始来源蒸馏成 Bundle。

原始来源 --Agent/RIA-TV++--> Capability Bundle --确定性编译器--> single | pack
flowchart LR
  A["统一来源与 RIA-TV++ 蒸馏"] --> B["稳定 Capability Bundle / Graph"]
  B --> C["auto 输出决策器"]
  C -->|"学习 / 查阅 / 高内聚"| D["Single1 个入口 + 按需能力卡"]
  C -->|"独立工作流 / 组合 / 分发"| E["Pack1 个来源路由入口 + 晋级 Skills + 能力卡"]
  D --> F["共同能力覆盖与行为评测"]
  E --> F
  F --> G["选择一个版本安装"]

4.6.1 命令与配置

对外暴露两个产物选项,另加一个默认决策器:

--output auto     默认;系统先推荐 single 或 pack,展示理由后让用户轻确认
--output single   最终只安装一个统一 Skill
--output pack     最终安装一个来源路由入口 + 少量晋级 Skill

示例:

python scripts/cangjie.py create --pack books/naval-almanack-skill --output auto
python scripts/cangjie.py create --pack books/naval-almanack-skill --output single
python scripts/cangjie.py create --pack books/naval-almanack-skill --output pack --skill-budget 8

建议把决策持久化到 .cangjie/config.yaml

operation: create
output:
  requested: auto
  selected: single
  decision_policy: single-first-v1
  skill_budget: 8                 # pack 的可发现入口总预算,包含 1 个来源路由入口
  preserve_strategy_on_update: true
  decision_report: .cangjie/runs/<run-id>/output-decision.md

updaterepair 默认保持原输出策略,不得因为新加一篇材料就从 1 个 Skill 静默膨胀成十几个。只有显式使用 --replan-output 时才重新评估;即使建议变更,也先生成预览,不自动删除或覆盖已安装版本。

4.6.2 单 Skill 模式不是“大而全的 SKILL.md”

single 的目标是把一份书/资料集编译成一个可发现入口 + 多个按需能力卡

<content-slug>/
├── SKILL.md                         # 触发、总原则、路由、最常用能力
├── references/
│   ├── overview.md                  # 全局骨架、适用范围、作者局限
│   ├── capability-index.md          # 意图/问题 → 能力卡映射
│   ├── capabilities/
│   │   ├── wealth-structure.md      # 内部 RIA 能力卡,不是独立 Skill
│   │   ├── decision-heuristics.md
│   │   └── ...
│   ├── chapters/ch01-*.md           # 章节证据与上下文,按需读
│   ├── glossary.md
│   ├── patterns.md
│   └── cheatsheet.md                # 决策规则、权衡矩阵、阈值、tells
├── scripts/                         # 可选的确定性检索/校验
└── evals/
    ├── trigger-validation.json
    ├── routing-evals.json
    └── output-evals.json

SKILL.md 不复制所有能力全文,只保留:

  1. 这个 Skill 何时触发、何时不触发;
  2. 全书最核心的 3—7 个决策原则;
  3. “用户意图 → 能力卡/章节”的一级索引;
  4. 加载规则:先读最小相关能力卡,证据不足再读章节,禁止默认全量加载;
  5. 输出契约、风险边界和判停条件。

每个 references/capabilities/*.md 继续使用仓颉的 R / I / A1 / A2 / E / B,只是它不再拥有独立 frontmatter 和发现入口。这样减少的是用户可见 Skill 数量,不是蒸馏深度,也不是能力覆盖。

4.6.3 Skill Pack 模式增加“独立 Skill 晋级门”

pack 不再是“若干原子 Skill + 一堆运行时不可见的 references”,而是固定输出一个混合 compact pack

<content-slug>-pack/
├── <content-slug>/                       # 来源路由入口:书名/作者/主题查阅,以及未晋级能力
│   ├── SKILL.md
│   └── references/capabilities/          # 全部稳定能力卡,保持在该 Skill 根目录内
├── <promoted-skill-a>/                   # 不提书名也会自然触发的独立任务
│   ├── SKILL.md                           # 从同一 Bundle 编译出的自包含执行入口
│   └── references/evidence.md
├── <promoted-skill-b>/
│   └── SKILL.md
└── capability-destinations.json          # 发布审计清单,不作为宿主发现入口

来源路由入口只覆盖“基于这本书/作者/资料集回答”和未晋级能力;晋级 Skill 只覆盖不依赖书名的独立任务。两者必须有互斥的正负触发样本,避免同一请求双触发。这样每个 capability 都有运行时入口,同时仍允许高价值任务被宿主直接发现。晋级 Skill 不得依赖跨 Skill 根目录的相对路径;需要的最小执行内容从 Capability Bundle 编译进自身目录,来源路由入口则保留完整能力卡。

阶段 1.5 的“知识验证”之后增加阶段 1.6“产品化验证”。一个候选只有同时满足以下硬条件,才有资格成为晋级 Skill:

  1. 独立意图:用户会自然地单独提出这个任务,而不是必须先说书名或章节名;
  2. 独立契约:有自己的输入、步骤、输出和完成标准,不只是一个观点或术语;
  3. 独立运行:不加载全书或多个兄弟 Skill 也能正确执行;
  4. 独立复用:预计会在多个任务/项目中重复调用,或需要被其他 Skill 组合;
  5. 独立评测:能写出明确的正向、负向、近邻和输出断言。

其中前 3 条必须通过,后 2 条至少通过 1 条。未晋级候选不进入 rejected,而是进入共享 references/capabilities/,并在来源路由入口的 capability-index.md 中有唯一可达映射。

Pack 的目标函数从“把所有通过候选都拆出来”改为“用最少的可发现入口覆盖最多的高价值用户意图,同时不让任何能力失联”。建议默认 skill_budget: 8 作为软预算,包含 1 个固定来源路由入口,即默认最多再晋级 7 个原子 Skill:

  • 预算内按预期调用频率、跨场景复用、独特性、证据强度和触发可分性排序;
  • 超出预算的候选先降为能力卡;
  • 只有当用户明确选择 exhaustive,且验证证明不能安全合并时,才允许超过 8;
  • 不能为了卡数量,把输出契约不同的能力强行拼成一个模糊 Skill。

编译器必须输出 capability-destinations.json,并满足以下硬不变量:

每个 active capability 恰好有一个主要去向:
  promoted_to: <atomic-skill-id>
  或 served_by: <source-router-id>

允许晋级 Skill 与来源路由入口包含同一能力的不同编译视图,
但唯一 owner 永远是 Capability Bundle;生成目录只读、不可反向各自编辑,
避免更新时出现两份分叉事实源。

“只读”必须有执行机制,不能只是约定:编译器为每个生成文件记录发布哈希;update / 重编译前先比对当前文件与发布哈希,检测到用户本地手工修改时不得静默覆盖,必须让用户三选一——丢弃本地修改 / 把修改回填进 Capability Bundle 再重编译 / 中止本次操作。

“8”是首轮可测假设,不是永恒规则;Phase 0 应用真实用户任务校准为更合适的默认值。

4.6.4 两种产物的选择边界

判断维度 更适合 single 更适合 pack
用户目的 学习、查阅、咨询“这本书/这套资料怎么看” 把方法嵌入日常工作流,由 Agent 自动调用
内容关系 章节强关联,共享一套世界观和上下文 存在多个边界清楚、可独立执行的工作流
调用语言 用户常会提书名、作者、章节或主题 用户不会提书名,只会提出任务,如“帮我做定价决策”
输出契约 多数回答是解释、比较、引用、综合应用 不同能力有不同输入、步骤、文件或操作结果
组合与分发 作为一个私人知识库整体安装/更新 需要跨书复用、单独分享、单独授权、单独版本化
维护成本 希望少安装、少命名、少处理触发冲突 能承受更多测试和 description 维护以换取精确触发
Token 形态 发现目录更小;单次调用可能加载“主入口 + 能力卡” 发现目录更大;命中后通常只加载一个更小原子 Skill

推荐默认原则:

  • 一本书、一位作者、一套连贯思想、面向普通读者:默认 single
  • 操作手册、团队 SOP、技术规范,或一本书中有多个独立工作任务:优先考虑 pack
  • 信息不足或评分接近:选择 single 以后再把高频独立意图对应的能力卡提升为独立 Skill;拆分应由使用证据驱动,而不是由章节数或候选数驱动。
split-on-evidence 的证据从哪里来

v1.1 把这条迁移路径寄托在“真实使用日志”上,但没有说明日志来源。这是一个空洞:产物安装在用户本地宿主中,作者看不到调用日志,也不应该看。 没有反馈回路,single-first 就会退化成一扇单向门——永远停在 single,所谓“演进”永不发生。

因此本版明确三条可行的证据来源,不依赖任何远程遥测:

  1. 用户显式请求(默认,且必须始终可用):提供 replan-output --dry-run 手工入口,用户觉得某个能力想独立出来时自己发起,系统给出 side-by-side 预览。
  2. 可选本地使用记录(默认关闭):single Skill 内可附一段可选的本地路由日志(只记 capability_id 与时间戳,不记内容),文件留在用户机器上;用户自愿导出后才进入拆分决策。开启方式、存储位置、字段清单和删除方法必须写在 Skill 的显著位置。
  3. 社区反馈聚合:通过 issue / 反馈表收集“我希望 X 能单独触发”的诉求,作为 registry 层面的拆分依据。

任何情况下都不得在用户不知情时上报使用数据。若三条来源都拿不到证据,就诚实地保持 single,不要用猜测代替证据。

4.6.5 auto 选择器

自动选择分两次进行:

  1. 阶段 0 初判:根据用户目的、内容骨架、独立任务数量,给出低成本预推荐;
  2. 阶段 1.5 复判:候选通过知识验证后,运行独立 Skill 晋级门和小规模兄弟触发测试,生成最终建议。

建议报告只呈现一屏(下列数字仅演示格式,必须由实际评测生成):

推荐:single
理由:19 个知识候选中只有 6 个具备独立工作流;幸福类 7 个候选意图重叠较高;
      你的目标是学习和随时咨询本书,而非构建可组合 Agent 能力库。
产物:1 个 Skill + 19 张内部能力卡 + 章节/术语/速查 references
备选:compact pack(预计 1 个来源路由入口 + 5 个晋级 Skill,共 6 个可发现入口)

用户只需回答“按推荐 / 改成 single / 改成 pack”。默认值只是推荐,不能取消用户的显式选择。

auto 的首版判定规则:

  • 用户明确选择学习、查阅、作者视角或私人知识库 → single
  • 用户明确选择自动工作流、跨书组合、独立分发 → pack
  • 未明确目的时,若至少 3 个候选通过晋级门,且小规模触发验证达到设定阈值(假设 F1 >= 0.85、兄弟混淆率 <= 10%TBD-after-baseline),才推荐 pack
  • 其他情况一律推荐 single

阈值属于 Phase 0 的初始假设,必须在 validation 集校准,不能拿训练集调到刚好过线。

4.6.6 以《纳瓦尔宝典》为例

  • 面向读者的默认结果应是 1 个 naval-almanack Skill;现有 19 个 RIA 单元全部进入内部能力卡,财富、判断、幸福、哲学形成 4 个导航域。
  • 如果用户要把它接入长期工作的 Agent 能力库,可推荐 compact pack,而不是直接安装 19 个;pack 保留 1 个 naval-almanack 来源路由入口,并优先晋级 productize-yourselfwealth-structuredecision-heuristics 等独立意图强的能力。相近的幸福/接受/冥想内容先由来源入口在统一能力域内路由,因此不会因未晋级而消失。
  • 若真实使用记录显示 acceptance 被频繁独立调用,并能和 happinessdecision 稳定区分,再将它从能力卡提升为独立 Skill。

这条迁移路径称为 single-first, split-on-evidence。它既解决当前“Skill 太多”的反馈,也不牺牲仓颉最有价值的原子化、可测试和可追溯能力。


5. 详细方案一:P1-工程 Token 优化

本章全部内容以 §0.1 选定的**路线 C(混合)**为前提。若后续改选路线 A(自建 harness),5.1 可升级为真实 per-call 账本,5.3 可恢复百分比门槛;若改选路线 B,本章只剩 5.2 的第一至第四级,5.1 与第五级作废。

5.1 两类指标:可静态计算的产物指标 + 过程代理指标

v1.1 原设计要求每次模型调用记录 input_tokens / cached_input_tokens / cache_write_tokens。在路线 C 下这做不到——宿主不向 Skill 暴露 per-call 用量。因此拆成两类。

A 类:固定 tokenizer 的文件计数 + 静态路由载荷模型

用固定 tokenizer 对明确的文件集合计数。文件 Token 数是精确可复算的;宿主实际发现与任务加载成本仍是模型值,因为宿主可能改写 frontmatter、追加系统指令或追读额外文件。

指标 定义 性质与用途
发现目录载荷 所有已安装 Skill 的 name + description 文件载荷 固定 tokenizer 下精确计数;用于模拟宿主发现目录,不声称等于真实请求 Token
单任务路由载荷(下界) SKILL.md + 命中的最小能力卡 按路由 Trace 建模的典型下界
单任务路由载荷(上界) SKILL.md + 能力卡 + 允许追读的章节证据 按路由规则建模的最坏预算,用于设 §15.11 的体积门
产物文件总量 整个 pack / single 包全部可读内容 固定 tokenizer 下精确计数;用于分发与审阅,不代表一次任务会全部加载

每条记录必须包含 tokenizer_id、tokenizer 版本、文件清单或 glob、文件哈希、路由规则版本。只有“文件计数”可以称为精确值;“发现目录成本”和“单任务成本”必须分别写成“目录载荷模型”和“路由载荷模型”。Phase 0 就能得到这些可复算数据,不需要接管宿主 API。

B 类:过程代理指标(近似、用于定位瓶颈而非验收)

在不接管 API 的前提下能记录的量:

{
  "run_id": "run-20260823-001",
  "stage": "extract.framework",
  "task_id": "chunk-0042",
  "prepared_input_chars": 48200,
  "prepared_input_chunks": 3,
  "reused_from_cache": false,
  "output_chars": 3600,
  "duration_ms": 8400,
  "retry_count": 0,
  "status": "ok"
}

聚合报告至少包含:每阶段准备交给 Agent 的字符数与块数占比、任务次数、被淘汰候选的处理次数、重试与失败次数、确定性缓存命中率、路由 Trace(routing_trace 只出现在 Skill 使用侧的评测 run 中,不属于蒸馏提取阶段的记录)和可观测墙钟时间。若宿主没有确认真正提交了这些内容,就不得把 prepared_input_* 改称实际 Prompt 输入。

这些是代理量,不是 Token。 报告中必须标注为估算,禁止把 prepared_input_chars / 1.5 之类的换算结果写成“Token 消耗”对外发布。

5.2 优化顺序

第一级:不调用模型也能完成的工作

  • 格式识别、哈希、页码/时间戳映射;
  • 精确重复检测;
  • 标题层级恢复;
  • 章节切块;
  • 机械 schema 校验;
  • 已存在缓存查找;
  • 文件路径、引用和 JSON 合法性校验。

第二级:一次处理,多阶段复用

  • 统一标准化一次,不让 5 个 extractor 分别重新解析原文;
  • 为每块生成一次关键词、实体、简短摘要和来源定位;
  • 阶段 0 生成的内容地图供后续检索,不把整份 BOOK_OVERVIEW.md 和全文无差别塞进每个请求;
  • 同一来源块的视觉/OCR/ASR 结果采用内容寻址、解析器版本化缓存;缓存可按保留策略垃圾回收,不能承诺“永久”且无限增长。

第三级:按需检索而不是全文广播

casecounter-exampleglossary 三类局部命中型 extractor 先查询内容地图;frameworkprinciple 继续全量扫描。检索式 extractor 的流程是:

  1. 召回相关章节和块;
  2. 获取邻接块防止断章取义;
  3. 发现证据不足时再扩大窗口;
  4. 三重验证时按候选反查第二处独立证据;
  5. 最终写 Skill 前只加载该候选、关键证据、相关反例和邻居摘要。

MVP 使用 SQLite FTS5 即可,不需要一开始引入向量数据库。只有当关键词召回在基准集中漏掉同义表达时,才增加本地 embedding 和混合检索。

第四级:按输出策略做渐进式 Skill 内容

生成后的主 SKILL.md 建议只保留:

  • 精确 description
  • 方法骨架 I
  • 触发 A2
  • 执行 E
  • 边界 B
  • 必要的短示例和 references 指针。

Pack 模式下,详细原文、长案例、完整审计证据放入:

references/evidence.md
references/examples.md

Single 模式下,主文件只保留全局触发、核心原则和一级路由,具体执行加载一张 references/capabilities/*.md,必要时再读一份章节证据。两种模式都要满足“触发时先加载最小可执行上下文,只有需要解释来源、核验事实或处理边界时才读取证据”。

第五级:API Prompt 缓存(仅在路线 A 下可实施)

前置条件:本级要求由自己拼装请求体。在路线 C 下,请求由宿主构造,以下各条都无法执行,本级整体挂起。这里保留设计,是为了在将来确实需要自建 harness 时不必重新推导。

  • 固定 system/developer 指令、工具定义、JSON schema 和 extractor prompt 的顺序;
  • 静态前缀在前,来源块和用户变量在后;
  • 对同一批任务使用稳定的 cache key;
  • 监控缓存读写,不把“启用了缓存”当作“真的命中”;
  • 不把短 TTL 缓存当作跨天增量存储。

路线 C 下唯一仍然成立的、且免费的做法是:保持 extractors/*.mdmethodology/*.md 的文件内容稳定,不要在每次运行时往里注入时间戳、run ID 或路径。宿主自身的缓存机制能否命中不由我们控制,但至少不要主动破坏它。

第六级:模型分层与早停

  • 机械分类、关键词、格式修复优先脚本;
  • 简单摘要、标签、初筛可使用便宜模型,但所有模型必须进入同一基准;
  • V1/V2/V3 任一明确失败后停止对该候选继续做昂贵构造;
  • 当一个 chunk 的所有转换缓存已命中时直接跳过;
  • 候选重复时合并证据,不再重新生成第二份完整 Skill。

5.3 验收标准

分两类,且 Phase 0 之前所有百分比均为 TBD-after-baseline

硬门(可精确验证,允许阻塞发布)

  • A 类指标全部有据可查:发现目录载荷、单任务路由载荷上下界、产物文件总量四个数字随每次发布一起产出,并附 tokenizer、文件集合、哈希和路由规则,使第三方可复算;报告明确区分精确文件计数与静态成本模型;
  • 阶段 1 覆盖率不回退:改造后最终通过三重验证的候选,相对全量扫描基线漏检数为 0(见缺口 B);
  • critical 能力与安全边界用例 100% 通过
  • 格式、相对引用、schema 校验 100% 通过

观察项(记录趋势,基线前不设阈值,不阻塞发布)

  • 各阶段准备输入字符数与块数的下降幅度;
  • 阶段调用次数变化;
  • 确定性缓存命中率;
  • 触发验证集 precision / recall 相对基线的变化;
  • 输出断言通过率相对基线的变化;
  • 单任务路由载荷的变化方向——注意 single 很可能上升(见 §0),这是预期内的,只要能解释来源即可,不算失败。

Phase 0 出基线后,再从观察项中挑选 2—3 个转为带阈值的门。阈值与非劣效界值必须在查看 validation 结果前预注册,并由产品风险决定;基线数据只用于估计波动和样本量,不能用“基线第 25 百分位”等事后规则挑出最容易通过的门槛。

排查顺序:若过程代理量没有明显下降,先检查全文是否仍在重复发送、检索是否返回过宽、失败候选是否淘汰过晚。任何情况下都不允许通过降低输出质量来“完成指标”——这也是本版取消 30% 门槛的直接原因:在质量指标尚无可信基线时设定成本门槛,等于鼓励拿质量换数字。


6. 详细方案二:蒸馏后增量补充资料

6.1 来源清单

manifest.yaml 示例:

schema_version: 1
content_pack: naval-almanack-skill
sources:
  - source_id: src-main-book
    kind: book
    title: 纳瓦尔宝典:财富与幸福指南
    author: Eric Jorgenson
    uri: file:///authorized/local/path/book.md
    rights: user-provided
    trust: primary
    versions:
      - version_id: sha256:abc123
        added_at: 2026-08-01T15:00:00+08:00
        parser: native-markdown@1
        status: active
  - source_id: src-new-interview
    kind: interview
    title: 补充访谈
    uri: file:///authorized/local/path/interview.md
    rights: user-provided
    trust: primary
    versions:
      - version_id: sha256:def456
        added_at: 2026-08-23T12:00:00+08:00
        parser: native-markdown@1
        status: active

6.2 变更类型

新增资料后先生成 change-set,不直接改 Skill

变更 判断 默认动作
exact_duplicate 内容哈希相同 跳过,记录重复来源
near_duplicate 语义高度相似,事实无新增 合并来源引用,不生成新单元
additive 新案例、新证据、新边界、新方法 进入影响分析
correction 新资料明确修正旧事实/步骤 标为高风险冲突,要求人工确认
contradiction 两个来源给出不兼容主张 两者都保留,记录来源、时间和适用条件
deletion 来源撤回或失效 计算受影响 Skill,不立刻物理删除历史证据

6.3 增量更新流程

flowchart LR
  A["登记新来源"] --> B["标准化与质量检查"]
  B --> C["块级哈希与去重"]
  C --> D["提取增量候选"]
  D --> E["与既有候选/Skill 对齐"]
  E --> F["生成 change-set"]
  F --> G{"是否有冲突或删除"}
  G -- "是" --> H["用户确认"]
  G -- "否" --> I["生成局部补丁"]
  H --> I
  I --> J["受影响 Skill + 邻居回归"]
  J --> K{"质量门通过"}
  K -- "是" --> L["提交新版本与变更报告"]
  K -- "否" --> M["回滚并进入 repair"]

6.4 合并规则

按信息类型分别处理,避免“大模型自由合并”:

  • 证据新增:追加到 references/evidence.md,不必修改核心执行步骤;
  • 新案例:追加到 examples,除非它暴露了新边界;
  • 新 trigger:修改 description/A2,并强制重跑触发训练集和验证集;
  • 步骤变化:修改 E,强制重跑全部输出评测;
  • 边界变化:修改 B,并增加至少 2 个 near-miss 负例;
  • 术语变化:更新 GLOSSARY 和依赖它的 Skill
  • 核心方法冲突:不自动覆盖,生成决策记录。

6.5 增量更新验收

  • 未变化来源不重新解析;
  • 未受影响 Skill 文件哈希保持不变;
  • 检测到用户手工修改过的生成文件时,update 中止并给出三选一提示(丢弃 / 回填 Bundle / 中止),不静默覆盖;
  • 新内容可追溯到 source_id + version_id + page/time
  • exact duplicate 不产生重复候选;
  • 冲突不被静默“综合”为一个模糊结论;
  • 生成修改前后 diff、受影响节点清单和回归结果;
  • 旧版本可以一条命令恢复。

7. 详细方案三:既有 Skill 定向优化

7.1 用失败案例驱动,而不是“帮我润色一下”

repair 的最小输入:

skill: decision-heuristics
failure_case:
  prompt: 用户真实输入
  actual: 当前实际输出或执行轨迹
  expected: 希望发生什么
  severity: critical|major|minor
  attachments: []

7.2 诊断分类器

类别 典型现象 主要修改点 必跑测试
activation_miss 该触发但没触发 description、A2 trigger 正例、验证集
false_activation 不该触发却触发 description、B、兄弟 Skill 区分 near-miss 负例、兄弟混淆
knowledge_gap 缺事实、案例或术语 references、I、A1 来源事实断言
execution_gap 会讲道理但不会做 E、脚本、输出契约 output eval
boundary_gap 在不适用场景硬套 B、判停条件 edge/negative eval
structure_gap 步骤顺序错误或前置条件缺失 E、checklist 流程断言
tool_gap 每次临时写重复脚本或工具调用失败 scripts、compatibility 集成测试
preprocessing_gap 上游漏字、表格错、时间轴错 parser/IR,不应修 Skill 文案 预处理 golden set
eval_gap 测试本身错误或过拟合 eval 标签/断言 独立复核

这一分类非常重要。解析错字不能靠改 Skill 修;触发误判也不能靠重蒸馏一本书解决。

7.3 修复事务

每次 repair 都是一个可回滚事务:

  1. 对当前 Skill 做只读快照;
  2. 复现失败案例;
  3. 读取宿主实际可提供的失败输出、可选本地路由日志、相关来源和既有评测;若宿主没有执行 Trace,就明确记录为 unavailable,不得推测补齐;
  4. 给出诊断类别和证据;
  5. 生成最小补丁,而非自由重写;
  6. 运行目标失败案例;
  7. 运行该 Skill 全部回归;
  8. 运行相邻 Skill 混淆回归;
  9. 对比 old/new 的输出质量、固定 tokenizer 下的静态路由载荷,以及可观测墙钟时间;不得把静态载荷写成真实调用 Token;
  10. 通过后写入 changelog,否则自动回滚。

7.4 防止针对单个案例过拟合

  • 修复只能使用 trigger train set 观察失败;
  • validation set 在选择最终版本前保持隐藏;
  • 不把失败案例中的专有名词原样塞进 description
  • 每修一个正例至少补一个语义近邻负例;
  • 触发类查询每条至少跑 3 次;
  • 选择验证集最好版本,不默认选择最后一轮;
  • 新旧版本输出采用匿名 A/B 盲评。

7.5 定向优化验收

  • 原失败案例达到预期;
  • 只修改诊断影响范围内的文件;
  • 修改前后 diff 清楚;
  • 旧版全部关键回归通过;
  • validation 集不下降;
  • 邻居 Skill 的误触发率不升高;
  • 新版静态路由载荷/可观测墙钟时间没有无解释的异常增长;
  • 快照可恢复。

8. 详细方案四:通用数据预处理 Skill(移出主线)

排期状态:本章设计完整保留,但不进入 v2.1—v3.0 主线,作为独立仓库 / 独立 Skill 推进。理由见 §1 与 §13「移出主线」。主线在此之前继续沿用当前做法——要求用户自备转写文本。它与主线的唯一耦合点是 SourceDocument 契约。

8.1 设计目标

预处理 Skill 只负责把来源转成高质量、可追溯、可评测的 SourceDocument,不负责提取方法论。这样它既能服务仓颉 Skill,也能服务 RAG、研究、写作和其他 Agent Skills。

建议名称:content-preprocessor,避免名称只写 pdf-to-markdown,因为真实范围包括文档、网页、字幕、音频和视频。

8.2 输入路由

TXT / MD / JSON / CSV
  -> 原生确定性解析

HTML / 网页快照
  -> 正文与 DOM 结构提取 -> SourceDocument

EPUB
  -> 章节/目录原生解析 -> SourceDocument

DOCX / PPTX / XLSX
  -> Docling 默认;必要时原生 OOXML fallback

Born-digital PDF
  -> Docling fast path -> 质量探针
  -> 中文复杂布局不达标时 MinerU hybrid/high

Scanned PDF / 图片
  -> 语言检测 -> OCR + layout/table -> 质量探针
  -> 低置信度页升级 VLM 或请求人工复核

SRT / VTT / 字幕 JSON
  -> 时间轴解析与重叠/断句修复

音频 / 视频
  -> 转交 media-preprocessor

8.3 质量探针

解析完成后自动检查:

  • 空页率和异常短页;
  • OCR 平均/最低置信度;
  • 标题层级是否连续;
  • 页眉页脚重复率;
  • 多栏阅读顺序异常;
  • 表格行列一致性;
  • 数字、百分比、货币、年份保真;
  • 专有名词与用户词表一致性;
  • 公式是否丢失或乱码;
  • 图片、图注与正文关联;
  • 页码/坐标/来源映射覆盖率;
  • 重复块率;
  • Unicode、乱码和不可见字符。

quality.json 示例:

{
  "status": "pass_with_warnings",
  "parser": "docling@x.y.z",
  "pages": 268,
  "text_coverage": 0.992,
  "provenance_coverage": 1.0,
  "ocr_mean_confidence": 0.94,
  "duplicate_ratio": 0.013,
  "warnings": [
    {"page": 74, "code": "TABLE_LOW_CONFIDENCE", "action": "reroute_mineru"}
  ]
}

8.4 解析器选择基准

不要直接根据官方宣传选默认后端。建立本项目样本:

  • 中文纯文本 PDF
  • 中文双栏论文;
  • 扫描书页;
  • 含复杂表格的报告;
  • 含公式的技术资料;
  • DOCX、PPTX、XLSX 各 1 份;
  • 低清拍照和倾斜页面。

每类人工标注 5—20 页,比较:

  • 字符准确率;
  • 标题/段落/list F1
  • 表格单元格准确率;
  • 阅读顺序准确率;
  • 公式保留率;
  • provenance 覆盖率;
  • 秒/页、内存峰值、磁盘占用;
  • 本地安装成功率与许可证适配。

最终路由由实测矩阵决定,不在代码里宣称某个引擎“永远最好”。

8.5 输出契约

每次预处理必须输出:

  • document.json:机器事实源;
  • document.md:人类审阅版;
  • quality.json:质量和警告;
  • assets/:图片、表格、帧等;
  • provenance.jsonl:元素到原始位置映射;
  • run.json:工具、版本、参数、时长和哈希。

8.6 预处理验收

  • 常见输入格式有确定路由;
  • 扫描件可 OCR
  • 标题、列表、表格的结构满足 golden set;
  • 关键数字和专名通过抽样校验;
  • 每个输出块可定位回来源;
  • 低置信度不会被静默当作正确结果;
  • 重跑相同输入和配置时命中缓存;
  • 后端切换不影响下游 schema。

9. 详细方案五:视频蒸馏与视觉理解(移出主线)

排期状态:同 §8,设计保留但不进入主线排期。当前 SKILL.md 已建议“视频/播客先用 video-downloader 类工具拿到转写文本”,这个做法在主线完成前继续有效。

9.1 来源边界

核心能力优先接受:

  • 用户提供的本地 MP4/MOV/MKV
  • 用户有权访问并明确授权处理的下载文件;
  • 公开且平台/API 明确支持的 URL。

“视频号适配”单独做 connector:

  • 能通过合法导出/下载获得本地媒体时进入统一管线;
  • 需要登录态时只在用户授权的浏览器会话中只读获取;
  • 平台限制、DRM、验证码或权限不足时明确失败;
  • 不把绕过访问控制写入核心 Skill。

9.2 音视频双路处理

flowchart TD
  A["本地视频"] --> B["媒体探针 ffprobe"]
  B --> C["音频轨"]
  B --> D["视频轨"]
  C --> E["VAD + ASR + 词/句时间戳"]
  E --> F["可选说话人分离"]
  D --> G["场景变化抽帧"]
  D --> H["固定间隔抽帧"]
  G --> I["清晰度/重复帧过滤"]
  H --> I
  I --> J["OCR 与视觉变化检测"]
  J --> K["VLM 描述高信息帧/短窗口"]
  F --> L["按时间轴对齐"]
  K --> L
  L --> M["多模态 SourceDocument"]
  M --> N["质量报告与人工抽查"]

9.3 为什么必须双路抽帧

  • 只按固定 10 秒:会漏掉快速操作和短暂弹窗;
  • 只按场景变化:PPT 同一页逐项出现、代码滚动、鼠标操作可能没有明显切镜;
  • 只让云端模型按默认 1 FPS 看整条视频:成本高,官方也提示可能漏掉快速变化;
  • 最优组合是场景变化 + 固定间隔 + OCR/感知哈希变化,再去重。

推荐初始策略:

  • 讲座/PPT:场景变化目标约 2 cuts/minute,外加 10 秒固定兜底;
  • UI 教程:2—5 秒固定兜底,检测 OCR 文本和局部区域变化;
  • 访谈:场景变化为主,固定 15—30 秒兜底,重点保留说话人;
  • 快速演示:低置信度片段切成 3—10 秒短窗口送 VLM,而不是只送单帧。

具体阈值必须通过测试视频调优。

9.4 时间轴中间表示

{
  "segment_id": "seg-0042",
  "start_ms": 125000,
  "end_ms": 139800,
  "speaker": "SPEAKER_01",
  "transcript": "接下来我们打开设置页面……",
  "frames": [
    {
      "time_ms": 131200,
      "asset_ref": "assets/frame-0131200.jpg",
      "ocr": "Settings > Agent Skills",
      "visual_description": "界面右侧展开 Agent Skills 设置,开关处于关闭状态",
      "confidence": 0.92
    }
  ],
  "merged_fact": "讲者在设置页打开 Agent Skills 开关",
  "provenance": ["audio:125000-139800", "frame:131200"]
}

9.5 多模态冲突处理

  • 口播说“点击左上角”,画面实际在右上角:标记 audio_visual_conflict
  • OCR 与 ASR 专名不同:保留两者和置信度,使用用户词表/上下文仲裁;
  • 画面出现关键步骤但口播未提及:作为 visual_only_fact
  • 口播有结论但画面无证据:作为 audio_only_fact,不伪造视觉佐证;
  • 快速操作无法确认:保留低置信度,要求短窗口重分析或人工抽查。

9.6 视频验收

  • 输出句级或词级时间戳;
  • 关键帧包含场景变化和固定兜底;
  • OCR、视觉描述、ASR 在同一时间轴;
  • 能识别测试视频中只存在于画面的关键知识;
  • 所有结论可点击/定位回时间点和帧;
  • 对 UI 教程的步骤顺序准确;
  • 重复帧率和 VLM 调用量可控;
  • 视频号来源失败时给出明确原因和替代输入方式。

10. 新评测体系

10.1 四层指标

L1:预处理质量

  • text/structure/table/formula/OCR 准确率;
  • 来源定位覆盖率;
  • 低置信度召回;
  • 视频画面独有信息召回率;
  • 数字和专名错误率。

L2:知识蒸馏质量

  • 方法论候选覆盖率;
  • 候选重复率;
  • V1/V2/V3 一致性;
  • 来源证据充分率;
  • 人工审阅的有用性/独特性评分。

L3Skill 行为质量

  • trigger precision / recall / F1
  • 兄弟 Skill 混淆率;
  • single 内部“意图 → 能力卡/章节”的路由准确率;
  • output assertions pass rate
  • with-skill 相对 without/old-skill 的增益;
  • 边界与判停遵循率。

L4:工程效率

区分精确指标与代理指标(见 §5.1):

固定 tokenizer 下精确计数name + description 文件载荷;各 SKILL.md / reference 文件载荷;产物文件总量;最终安装入口数;内部能力卡数。

静态模型与过程代理(仅看趋势):单任务路由载荷上下界;各阶段准备输入字符数与块数;Agent 任务次数;确定性缓存命中率;增量复用率;受影响 Skill 比例;可观测墙钟时间;人工确认次数。

在路线 C 下不存在可信的 input/output/cached tokens,报告中不得出现这三项。

10.2 基准集建议

分批建设,不要一次铺开。

Phase 0 必需(主线)

  1. 当前《纳瓦尔宝典》Markdown:用于与既有 19 Skill 对比;
  2. 一组 20 条三版本共用任务集:书名/章节查询、主题咨询、可执行任务、近邻意图和超范围问题各若干,19-Skill、single 与 compact pack 使用完全相同的源材料和能力目标。

Phase 2A—3 补充(主线)

  1. 三组增量包:纯新增、重复+新增、纠错/冲突;
  2. 每个代表 Skill 约 20 条 trigger query,正负各 8—10,近邻负例优先;
  3. 每个代表 Skill 2—5 条 output eval,含真实输入文件和机械断言;
  4. 把三版本共用任务集从 20 条扩到 50 条以上。

移出主线(随预处理独立仓库走):中文 born-digital PDF、中文扫描页、含复杂表格/公式的资料、20—30 分钟 UI 教程视频。

为什么 Phase 0 只用 20 条

v1.1 要求 Phase 0 就建 50 条任务集。实际成本被严重低估了:50 条 × 3 个版本(19-Skill / single / compact pack)× 3 次重复 = 450 次 Agent 运行。在没有任何 eval runner 的当前状态下(全仓无流水线测试、CI 只跑官网),这是纯手工工作量,会直接把 Phase 0 拖成数周。

20 条 × 3 个版本 × 1 次 = 60 次,一到两天可完成,足以暴露明显路由缺陷和 critical 能力缺失,但不足以证明统计非劣。Phase 0 只做探索性证伪并报告原始配对计数;要估计差异幅度时再扩集,那时也应该已经有 runner 了。

10.3 评测运行方式

  • trigger query 每条至少运行 3 次(Phase 0 的 20 条粗筛集可放宽为 1 次,仅用于发现明显缺陷);
  • 60% train、40% validation,固定随机种子;
  • output eval 同时跑 old-skill/new-skill,必要时加 without-skill
  • 机械断言先于 LLM judge
  • LLM A/B 评审隐藏版本名称和顺序;
  • 人工只审阅高风险、低置信度和 A/B 分歧样本;
  • 每次迭代生成 benchmark.json 和可读报告;
  • 不允许用 validation 失败内容继续调 Prompt 后仍把它称为 validation。

关于样本量与精度的约束1 / 样本量 只是单个计数变化对应的百分比粒度,不是统计显著性门槛。Phase 0 必须报告每条任务的配对结果、原始成功/失败数和分歧样本,不得用“差异小于 1/n”自动宣布无显著差异或非劣。进入正式评测后,对二元配对结果使用 McNemar 精确检验或配对 Bootstrap 置信区间;对评分使用配对 Bootstrap。方法、样本量与非劣效界值必须在查看 validation 结果前预注册。

10.4 发布质量门

分两级。Phase 0 产出基线之前,只有第一级生效。

第一级:确定性硬门(始终阻塞发布,可脚本自动判定)

  • Agent Skills 格式校验通过;
  • 所有相对引用存在;
  • 所有 JSON/YAML schema 通过;
  • 关键来源映射完整;
  • 输出策略、选择理由、能力 ID 映射和 Skill/能力卡去向可审计;
  • critical 能力与安全边界用例 100% 通过;
  • 无未确认的纠错/冲突覆盖;
  • 变更报告和回滚快照存在。

这些条件的共同特点是判定结果不依赖抽样,不受样本量影响,不可能因噪声误判。这是它们能作为硬门的原因。

第二级:统计性判断(基线之后启用,默认只警告不阻塞)

  • trigger validation 相对基线非劣;
  • output eval 相对基线非劣;
  • 产物 Token 指标(A 类)没有不可解释的显著变化;
  • 时延没有不可解释的显著退化。

“非劣”不能由 1/n 自动判定。要把其中任何一条升格为阻塞门,需要同时满足:指标已有至少两轮稳定基线;非劣效界值已按产品风险预注册;样本量与检验方法能支撑该界值;分歧样本已人工复核。Phase 0 不满足这些条件时,只报告探索性结果,不作统计非劣声明。

10.5 19-Skill / Single / Compact Pack 三版本对照评测

不能用“最终只有 1 个 Skill”直接宣布优化成功。对同一份《纳瓦尔宝典》来源,必须同时构建:

  • A:当前 19-Skill 基线;
  • B:新的 single 版本;
  • C:按晋级门生成的 compact pack。

三者在同一盲测任务集上比较:

指标 目的
能力覆盖率(按重要度加权) 防止 single 为了少而丢掉关键方法
首次路由成功率 测 single 是否找到正确能力卡,pack 是否命中正确 Skill
近邻混淆率 测幸福/接受/冥想、判断/决策等相邻意图
output assertions / 盲评胜率 测实际答案或产物,而不是只测路由
发现目录载荷模型 衡量安装很多 Skill 的发现负担;这是 single 唯一确定为下降的静态载荷项
单任务路由载荷模型 防止 single 每次把全部 references 拉进上下文;预期 single 会高于 pack,不作为失败判据
可观测任务时延与 Agent 任务数 衡量多一步内部路由是否带来可接受代价;不把 Agent 任务数冒充模型 API 调用数
安装/理解成本(真实读者评分) 验证“Skill 太多”这一真实产品问题是否改善——这是本项改造的第一目标指标

Phase 0 真实读者协议

3—5 名读者只用于可用性发现,不能单独决定正式默认模式。采用 19-Skill、single、compact pack 三版本的 within-subject 交叉试用;使用拉丁方或尽可能平衡的顺序,并为三个版本轮换难度相近的任务,降低学习效应和固定任务偏差。主持人不告诉读者“哪一版是优化版”,并使用中性问题:

  1. 完成指定安装分别用了多久,在哪一步停顿?
  2. 给定任务时,能否找到并触发合适能力?
  3. 是否完成任务,结果是否满足预期?
  4. 对结果的正确性与可控性有多大信心?
  5. 如果只能保留一个版本,会选哪个,原因是什么?

同时记录安装失败、误触发、人工提示次数和任务完成证据。禁止只问“single 是否比 19 个更好用”这种带方向的问题。

Single 的首版发布门(阈值均为 TBD-after-baseline,括号内为待检验假设):

  • critical 能力与安全边界用例 100% 通过 —— 这一条不是假设,是硬门
  • 路由失败必须能回退到主题索引或章节检索,不能编造不存在的能力 —— 硬门
  • 任何一次任务不得无条件加载全部能力卡和全部章节 —— 硬门,可脚本检查
  • 加权能力覆盖率(假设 >= 95%;正式阈值在基线之后、查看 validation 结果之前按产品风险预注册,Phase 0 数据只用于估计波动与样本量,见 §5.3);
  • output eval 相对 19-Skill 基线非劣(v1.1 的“不超过 2 个百分点”在 20—50 条样本上无统计意义,已删除)。

Compact pack 的首版发布门(同上):

  • 每个 Skill 都通过阶段 1.6 晋级门 —— 硬门
  • 每个 active capability 都在 capability-destinations.json 中唯一映射为 promoted_toserved_by;被降为能力卡的候选必须能经来源路由入口实际到达,不能因为“控数量”而消失 —— 硬门,可脚本检查 + 路由用例验证
  • 可发现入口总数(包含 1 个来源路由入口;假设 <= 8,超出需逐项解释);
  • validation F1 与兄弟混淆率(假设 F1 >= 0.85、混淆率 <= 10%,由 Phase 0 实测校准)。

10.6 终止条件(v1.1 缺失)

v1.1 只规划了成功路径,默认 single 一定赢。必须补上:如果 Phase 0 的数据说 single 不更好,怎么办?

触发条件 处置
加权能力覆盖率显著低于 pack 基线,且缺口集中在 critical 能力 放弃 single 作为默认,改为 auto 默认推荐 compact pack;§4.6 降级为可选特性
首次路由成功率明显低于 pack 的直接命中率 说明“主入口 + 能力卡”这层间接寻址代价过高;保留 single 但仅用于纯查阅场景,不用于可执行任务
交叉试用持续显示 single 在安装、查找或任务完成上没有实际优势 single 不再作为默认;保留为可选查阅模式,默认尝试带来源路由入口的 compact pack;若两者都无优势,再终止 §4.6 的默认策略改造
Phase 0 超过 8 个工作日仍未产出可对比数据 停止扩大范围,先交付一个纯静态的 single 原型供用户试用,用定性反馈代替定量评测

明确写下终止条件的意义在于:它让 Phase 0 成为一次真正的检验,而不是一次已经知道结论的论证。


11. Agent Skills 规范兼容改造

11.1 生成模板调整

官方规范明确的 frontmatter 字段包括 namedescription,可选 licensecompatibilitymetadataallowed-tools。当前模板把 source_booksource_chaptertagsrelated_skills 放在顶层。为提高跨客户端兼容性,建议迁移到 metadata

---
name: inversion-thinking
description: >
  Use this skill when the user is making a consequential decision...
license: AGPL-3.0-only
compatibility: Works with Agent Skills-compatible clients; optional scripts require Python 3.11+.
metadata:
  cangjie.source-title: 穷查理宝典
  cangjie.source-location: 第三讲
  cangjie.version: "1.0.0"
  cangjie.related-skills: "decision-checklist, second-order-thinking"
---

实施前要在目标客户端上验证未知顶层字段是否真的造成兼容问题;迁移工具必须保持旧版可读,不能无依据批量重写用户已有 Skill。

影响面提醒:这项改动波及的不只是本仓的 19 个样本 Skill,而是 registry 收录的 22 个 pack、合计 300 个已发布 Skill(其中多数托管在各自的 GitHub 仓库中,不在本仓)。因此:迁移必须是可选的、向后兼容的,旧格式永久保持可读;不得把新 frontmatter 格式设为 registry 的准入条件;本仓只提供迁移脚本和说明,不代替第三方作者重写他们的 Skill。

11.2 description 优化

每个 description 都应包含:

  • 用户意图,而非内部实现;
  • 正向触发情境;
  • 高价值关键词和自然表达;
  • 关键排除项;
  • 与最相近 Skill 的区别。

但 description 不是越长越好。最终版本由 validation 触发率决定,不能按字数或主观“写得更完整”决定。

11.3 引用深度

保持一层引用:

SKILL.md -> references/evidence.md
SKILL.md -> scripts/validate.py

避免:

SKILL.md -> references/a.md -> references/b.md -> references/c.md

深链会增加查找成本和漏读概率。

11.4 单 Skill 路由模板

Single 模式的 description 应描述整套资料解决的上位意图,同时列出 3—6 个最关键主题和明确排除项;不能把所有候选关键词堆进 description。主文件增加确定性路由表:

## Capability Router

| 用户意图 | 先读 | 必要时补读 |
|---|---|---|
| 设计财富结构、产权和杠杆 | references/capabilities/wealth-structure.md | references/chapters/ch01-wealth.md |
| 重大选择、拿不定主意 | references/capabilities/decision-heuristics.md | references/cheatsheet.md |
| 幸福、欲望与当下 | references/capabilities/happiness.md | references/chapters/ch02-happiness.md |

只加载命中的最小集合。意图不明确时先问一个短问题;资料不覆盖时明确越界。

路由表使用稳定的 capability_id,与 .cangjie/graph/dependencies.json 中的候选/证据映射一致。Single 和 Pack 只是同一组稳定能力 ID 的两种编译目标,不能各自重新蒸馏出两套不可比较的内容。

11.5 Registry 与官网联动改造(v1.1 缺失)

见缺口 H。输出粒度改造一旦落地,最先被打破的不是流水线,而是对外的分发层。

现状事实

组件 现状 受影响点
registry/ 22 个 packskill_count 加总 300 single 模式下该字段语义失效
schemas/registry-entry.schema.json skill_count 为结构化字段,无输出模式概念 需扩展
website/src/pages/index.astro 首页以 Skill 总数作为规模叙事 与“Skill 不该太多”的新哲学冲突
website/src/lib/install.ts 按 pack 生成安装提示词 single 与 pack 安装方式不同
.github/workflows/registry-check.yml 全仓唯一有实质校验的 CI,只覆盖 registry + 官网 需要新增流水线产物校验

改造方案

Schema 版本分发(真正向后兼容,而不是直接把 const: 1 改成 const: 2):

schemas/
├── registry-entry.schema.json       # dispatcher: oneOf(v1, v2)
├── registry-entry-v1.schema.json    # 冻结当前契约,继续验证旧条目
└── registry-entry-v2.schema.json    # 新输出模式使用

v2 示例:

schema_version: 2
slug: naval-almanack-skill
output_mode: single          # single | pack | legacy-packv2 必填
skill_count: 1               # 兼容字段;v2 中必须等于 entrypoint_count
entrypoint_count: 1          # 宿主可发现入口数;single 恒为 1
capability_count: 19         # 经验证的能力总数,可以大于入口数
router_entrypoint: naval-almanack

规则:

  • schema_version: 1 条目永远走 v1 schema,字段语义不变;无需给 22 个存量 pack 补字段,也不能让 CI 因 v2 上线而使它们失败。
  • schema_version: 2entrypoint_count 是可发现入口数;skill_count 暂时作为兼容别名保留,且必须与它相等。未来主版本再评估移除,不能在同一次改造中破坏网站和第三方工具。
  • capability_count 是经验证能力总数;允许大于 entrypoint_count。legacy 一能力一 Skill 时通常相等,single 与 compact pack 通常不相等。
  • single 必须满足 entrypoint_count = 1;新 pack 必须有 1 个 router_entrypoint,所有 active capability 必须有 promoted_toserved_by 去向;legacy-pack 不强求来源路由入口。
  • 读取层把 v1 条目规范化为内部 output_mode: legacy-pack,但不回写文件。第三方作者愿意重编时再提交 v2。

官网展示调整

  • 迁移期首页先准确显示“22 个 Pack / 300 个 legacy 可发现 Skill”,不能在没有 v2 capability_count 的情况下把 300 直接改名为能力数
  • 单独聚合 v2 条目的 entrypoint_countcapability_count,并展示统计覆盖率;只有全部或绝大部分条目具备真实能力计数后,才把首页主叙事迁移为“入口数 / 能力数”;
  • pack 详情页显示“安装后新增 N 个可发现 Skill”,这是用户做安装决策时真正需要的数字;
  • install.tsoutput_mode 分支生成安装提示词;
  • 列表页支持按 output_mode 筛选,让偏好“少而整”的用户能直接过滤。

CI 扩展:现有 registry-check.yml 先按 schema_version 分发校验,再检查 v2 的 output_modeentrypoint_countskill_countcapability_count 与 router 不变量。另需新增一条独立 workflow,校验 books/ 下产物的格式、相对引用和 capability-destinations.json 完整性——这是目前完全的空白区。

排期

本节内容进 Phase 1,与 --output 开关同批交付。理由很直接:开关一旦可用,第一个用它产出 single 包的人就会来提交 registry,那时 schema 必须已经能表达这件事。


12. 脚本与 Schema 建设清单

v1.1 一次性列出 9 个 schema 和 16 个脚本。对照现状——根目录没有 pyproject.toml、没有 package.json、没有 Makefile,流水线零测试,全仓唯一的 Python 是约 225 行的 star history 生成器——这个清单等于要求把项目重写成一个数据工程平台。本版按阶段切分,并标注哪些是主线必需。

Phase 0 必需(3 个小脚本 + 1 份人工映射)

scripts/
├── count_tokens.py              # 固定 tokenizer 文件计数 + 静态目录/路由载荷模型
├── compile_single.py            # 能力映射 + 现有 Skill Pack → single 原型,不调模型
└── validate_skill_pack.py       # 格式、相对引用、frontmatter 校验
benchmarks/naval/
└── capability-map.yaml          # 人工确认:稳定 ID、owner、路由意图、重要度、去向

三个脚本都是纯确定性工具,不调用任何模型,无重依赖count_tokens.py 只需 tokenizer 库)。但主入口 description、核心原则和意图路由不能靠“机械搬文件”可靠推断,因此 capability-map.yaml 必须由人基于现有 19 个 Skill 明确填写,再交给编译器。其中“重要度”不得纯自评,每条必须附依据(INDEX 引用图入度、DIGEST 篇幅占比、任务集命中数或读者任务映射),因为它直接作为加权能力覆盖率的权重。Phase 0 不建设平台基础设施;这些小工具可以复用,但是否进入长期 API 由 Phase 0 结论决定。

Phase 1—3 主线

schemas/
├── capability.schema.json
├── capability-bundle.schema.json
├── output-decision.schema.json
├── source-manifest.schema.json
├── change-set.schema.json
├── dependency-graph.schema.json
├── eval-suite.schema.json
└── contracts/
    ├── source-document.schema.json   # 核心共享契约,外部预处理器也必须遵守
    └── chunk.schema.json

scripts/
├── cangjie.py                   # 统一入口,薄 CLI
├── select_output_strategy.py    # single/pack 推荐与解释报告
├── compile_pack.py              # Capability Bundle → 来源路由入口 + 晋级 Skills
├── build_chunks.py              # 结构感知切块
├── build_index.py               # SQLite FTS5
├── diff_sources.py              # 来源/块差异
├── impact_analysis.py           # 依赖图影响范围
├── apply_skill_patch.py         # 最小补丁与快照
├── run_trigger_evals.py         # 多次触发评测
├── run_output_evals.py          # old/new/without 对比
└── benchmark.py                 # 聚合报告

移出主线(随预处理独立仓库走)

adapters/docling.py / adapters/mineru.py / adapters/media.py
preprocess.py / quality_probe.py / parser-benchmark.py

边界原则:契约留在核心,适配器移出核心。 外部预处理仓库依赖或复制已发布、带版本的 contracts,并接受兼容性测试;不能各自发展同名但不兼容的 SourceDocument

已删除

collect_usage.py——在路线 C 下无法采集真实 token,其代理指标由 benchmark.py 顺带产出,不值得单独立项。

统一命令建议:

python scripts/cangjie.py doctor
python scripts/cangjie.py compile --bundle books/<slug>/.cangjie/capabilities/verified.yaml --output auto
python scripts/cangjie.py update --pack books/<slug> --add <new-source>
python scripts/cangjie.py repair --pack books/<slug> --case failure.yaml
python scripts/cangjie.py replan-output --pack books/<slug> --dry-run
python scripts/cangjie.py eval --pack books/<slug> --compare previous
python scripts/cangjie.py benchmark --pack books/<slug>
python scripts/cangjie.py rollback --pack books/<slug> --to <version>

统一入口只负责编排和确定性操作;compile 的输入必须是已验证 Capability Bundle,不能声称一条纯脚本命令能从原始书籍完成蒸馏。update / repair 遇到需要语义判断的节点时生成待处理任务和下一步说明,由 Agent 按 Skill 指令完成,再交回 CLI 校验与发布。外部预处理器单独提供 preprocess,核心 CLI 不伪装拥有该能力。这样仓颉 Skill 仍是开放的 Agent Skill,而不是被改造成只能由某个后端运行的封闭 SaaS。


13. 实施阶段与交付物

工作量口径说明:以下天数按一名开发者全职估算。若为兼职推进,请按 3—4 倍折算实际日历时间。v1.1 全部 7 个 Phase 合计 41—64 个工作日,兼职口径下约 6—12 个月——期间 Agent Skills 规范与上游工具都会发生变化,这本身就是方案的最大风险。本版移出预处理与视频两个重依赖产品线,同时把原来低估的 Phase 2 拆为 2A / 2B;主线现实估算为 30—46 个工作日

Phase 0:低成本证伪(3—5 个工作日)

Phase 0 的唯一目的是在写任何平台基础设施之前,回答“single 是否真的更好”。允许编写 3 个无重依赖的小工具和 1 份人工能力映射,但它们只是证伪工具,不提前承诺为长期公共 API。

交付:

  1. 冻结基线:重新读取 origin/main;从该 commit 建立独立干净 worktree/临时分支;只复制 untracked 的 books/naval-almanack-skill/73 文件 / 19 Skill);生成文件清单和 SHA-256,校验后再提交/tag,或改用 tarball + SHA-256 归档。不得在当前脏工作区直接提交或打 tag。
  2. 建立最小 Capability 映射:为现有 19 个 Skill 人工确认稳定 ID、重要度、路由意图、owner 和 single/pack 去向;不重新蒸馏原书。
  3. 静态编译两个原型single 为 1 个入口 + 19 张能力卡;compact pack 为 1 个来源路由入口 + 若干晋级 Skill,总入口软预算 ≤8。主入口 description、核心原则和路由来自人工映射,不由脚本猜测。
  4. 算 A 类指标:固定 tokenizer,离线算出三个版本各自的发现目录载荷、单任务路由载荷上下界和产物文件总量,并保存 tokenizer/文件哈希。半天。
  5. 20 条任务集粗筛:按 §10.2 建 20 条三版本共用任务集,对 A/B/C 三版各跑一次,只测路由命中与能力覆盖两项。1—2 天。
  6. 真实读者交叉试用:按 §10.5 的中性协议,让 3—5 名读者按平衡顺序体验 19-Skill、single 与 compact pack,记录安装、查找、任务完成和偏好原因。它用于发现明显可用性问题,不能单独证明正式默认策略。
  7. 输出基线报告与 §10.6 终止条件的判定结论。

宿主锁定:Phase 0 的全部任务评测和读者交叉试用必须在同一宿主、同一版本上进行并记录(宿主名 + 版本号写进报告);结论标注 host-specific。触发与路由行为是宿主相关的(见 §15.18),不锁定会把宿主差异混进 A/B/C 差异。跨宿主验证属于 §13A 的兼容矩阵,Phase 0 不做。

compact pack 原型的产出方式Phase 0 不实现 compile_pack.py。路由入口可复用 compile_single.py 的编译逻辑(同一份能力映射的另一种 frontmatter/路由视图),晋级 Skill 目录直接复制现有产物,capability-destinations.json 手工编写。是否值得做正式 pack 编译器,由 Phase 0 结论决定。

不做:不建 .cangjie/ 侧车、不建 SourceDocument、不建缓存、不建依赖图、不接任何解析器、不写 CLI。这些都要等 Phase 0 的结论出来才知道值不值得做。

退出条件:能用探索性数据回答两个问题——“19 个压成 1 个后,具体丢了什么、省了什么”,以及“交叉试用中读者在哪种模式下更顺利、为什么”。不得在 20 条任务和 3—5 名读者上宣称统计非劣;只能据此做出继续扩大验证 / 调整 / 终止的明确决定。

Phase 1:双输出正式化 + Registry 联动(7—10 个工作日)

前置条件:Phase 0 的结论支持继续(未触发 §10.6 任何终止条件)。

交付:

  • --output auto|single|pack 与可解释的 output decision report
  • 稳定 capability_id 生命周期、capability.schema.jsoncapability-bundle.schema.json
  • 最小 .cangjie/capabilities/verified.yamldestinations.json;Phase 1 只引入这一小段编译事实源,不提前建设完整侧车;
  • 改写根 SKILL.mdmethodology/ 的阶段 2—5,使 Agent 蒸馏产出 Capability Bundleverified.yaml + destinations.json)而非直接写最终 Skill 目录——这是对一个已公开元 Skill 的破坏性契约变更,也很可能是 Phase 1 单项最大的工作量,必须附旧流程兼容与迁移说明;
  • single 模板、能力卡、主题/章节路由;阶段 1.6 晋级门,以及“来源路由入口 + 晋级 Skill”的 compact pack 编译器;
  • 正式编译器使用 per-run workdir、目标包 writer lock、staging 校验与原子发布,避免并发编译串写或半发布;
  • 生成模板的 references/ 分层;
  • Agent Skills 格式和相对引用校验(validate_skill_pack.py);
  • §11.5 的 Registry schema v2、官网展示调整与 CI 扩展
  • Naval 三版本 A/B/C 报告(任务集扩到 50 条)。

退出条件:Agent 能把同一来源蒸馏为一份已验证 Capability BundleCLI 能用一条命令从同一份 Bundle分别编译出 single 与 compact pack;两者通过 §10.4 第一级硬门;并发编译不串写,中断不覆盖旧发布;registry 与官网能正确表达两种输出模式。不得把这一条件缩写成“纯 CLI 从原始书籍一键蒸馏”。

注意本阶段只包含最小 .cangjie/capabilities/,不包含 manifest、normalized、SourceDocument、chunks、cache key、FTS5 索引和依赖图——这些是 Token 与增量能力的完整底座,移到 Phase 2A—2B。Phase 1 只做输出粒度这一件事,保证它能独立交付用户价值。

Phase 2A:统一底座与低成本上下文(6—9 个工作日)

交付:

  • .cangjie/manifest.yaml 与来源版本清单;
  • 核心共享的 SourceDocument / Chunk 最小 schema(先覆盖原生 Markdown/TXT,不接重型解析器);
  • 结构感知 chunks 与内容寻址缓存;
  • SQLite FTS5 索引;
  • 按 §2.2 缺口 B 的分类策略改造 extractor 上下文(framework/principle 保持全量扫描);
  • 确定性缓存键、可选 host_fingerprint、阶段代理指标与路由 Trace
  • 在 Phase 1 运行隔离基础上补齐缓存原子写入、Agent 阶段失败标记和恢复;
  • 阶段 1 覆盖率回归基线。

退出条件:同一输入重复运行确定性阶段时结果字节一致且可命中缓存;并发 run 不串写;中断后可安全续跑或清理;阶段 1 覆盖率相对全量扫描基线漏检数为 0。

Phase 2B:增量 update6—9 个工作日)

前置条件:Phase 2A 的契约、缓存与基线稳定。

交付:

  • source diff、块去重、change-set
  • 依赖图与影响分析;
  • 新增/纠错/冲突/删除处理;
  • 局部补丁、回滚和变更报告;
  • 三组增量验收用例。

退出条件:添加一篇补充材料时,未受影响 Skill 保持字节不变,相关 Skill 更新后全部回归通过;合并、拆分、纠错与删除均保留 Capability 生命周期和回滚证据。

Phase 3:定向 repair 与新评测(5—8 个工作日)

交付:

  • 失败案例 schema
  • 诊断分类;
  • trigger train/validation
  • old/new/without output eval
  • 多次运行、盲评、静态路由载荷/可观测时延对比;
  • repair 事务和回滚。

退出条件:可以用一个真实失败案例只修一个 Skill,并证明没有破坏邻居能力。

Phase 4:CI、文档与发布(3—5 个工作日)

交付:

  • 核心流水线 CI,不再只校验网站 Registry
  • schema、引用、单元、golden、集成测试;
  • 迁移指南和回滚指南;
  • 版本化 benchmark
  • 发布候选与 changelog。

移出主线:文档预处理与视频多模态

§8 与 §9 的完整设计保留在本文中,但不进入上述排期。它们作为独立仓库 / 独立 Skill 推进,理由见 §1:

  • 两者合计 14—24 个工作日,占 v1.1 主线的三分之一以上;
  • 引入 DoclingGB 级模型)、MinerU、WhisperX、PySceneDetect、VLM 等重依赖,会显著抬高普通读者的安装门槛——与本方案“降低安装与理解成本”的核心目标直接冲突;
  • 它们的产出对主线只有一个接口:SourceDocument。只要契约稳定,两边可以完全并行、独立发版。

主线与它们的耦合点只有一处:Phase 2A 定义 SourceDocument / Chunk 最小 contracts 时,必须保证外部解析器可以通过版本化契约填充,且主线自身在只有原生 Markdown/TXT 的情况下也能完整跑通。

推进顺序建议:主线 Phase 0—4 全部完成、single/pack 得到真实用户验证之后,再启动预处理仓库。在此之前,PDF / 扫描件 / 视频一律要求用户自备转写文本——这正是当前 SKILL.md 已经采用的做法,且运行良好。


13A. 架构决策记录(ADR)与非功能要求

以下决策已在本方案中接受。实施中如果要改变,必须新增 superseding ADR,并同步修改受影响的验收、schema 和迁移说明,不能只改一处代码。

ADR-001:保留 Agent Skill 形态,采用路线 C 混合执行

  • 状态Accepted
  • 背景:自建 harness 能拿到真实调用 Token,但会抬高安装、权限和运维成本;纯 Prompt 又无法支撑确定性增量与校验。
  • 决策:Agent 负责语义蒸馏与判断;CLI 负责哈希、切块、索引、编译、校验、diff、回滚等确定性操作。真实 per-call Token 不作为路线 C 承诺。
  • 代价:只能报告文件计数、静态路由载荷与过程代理指标;Agent 生成物默认不能跨未知宿主安全复用。
  • 备选:路线 A 自建 harness 暂缓;路线 B 纯 Skill 无法满足增量与可复现工程目标。

ADR-002:以 Capability Bundle 为唯一编译事实源

  • 状态Accepted
  • 背景:如果 single 与 pack 分别蒸馏,会产生两套能力、证据和评测,无法比较也无法增量维护。
  • 决策:原始来源先经 Agent/RIA-TV++ 形成已验证 Capability Bundlesingle 与 pack 只做确定性编译。compact pack 固定包含 1 个来源路由入口,保证未晋级能力运行时可达。
  • 代价:Phase 1 必须先定义能力生命周期、owner 和去向映射;编译前多一道 schema 校验。
  • 备选:纯 one-to-one 原子 Pack 保留为 legacy-pack;“隐藏能力卡但无入口”的方案拒绝。

ADR-003:核心拥有内容契约,外部仓库拥有重型适配器

  • 状态Accepted
  • 背景:核心增量流程依赖 SourceDocument / Chunk,但 PDF/OCR/ASR 重依赖不适合进入核心安装链路。
  • 决策:带版本的 contracts 留在核心;原生 Markdown/TXT 由核心处理;Docling、MinerU、音视频等适配器在独立预处理仓库实现,并运行契约兼容测试。
  • 代价:contracts 的破坏性变化需要迁移期;核心与预处理仓库要维护一组共享 golden fixtures。
  • 备选:把 schema 一起移出会让核心依赖外部仓库才能运行;把重依赖全部放入核心则安装成本过高。

ADR-004Registry 使用 v1/v2 schema 分发,不原地重定义 v1

  • 状态Accepted
  • 背景:当前 schema_versionconst: 1,直接替换为 v2 会让 22 个存量条目失效。
  • 决策:顶层 schema 使用 oneOf 分发 v1/v2;v1 永久保持可读,读取时规范化但不回写;新输出使用 v2 的 entrypoint_countcapability_count 和 router 字段。
  • 代价:校验与网站读取层要同时支持两版;移除兼容字段只能在未来主版本进行。
  • 备选:一次性迁移第三方条目成本和风险不可接受。

非功能验收矩阵

类别 首版要求 验证方式
并发隔离 每次运行独立 workdir;同一目标 pack 同时只允许一个 writer 两个并发 run 写同一目标,第二个明确等待或失败,文件不得串写
崩溃一致性 先写 staging,全部校验通过后原子替换发布目录;缓存使用临时文件 + 原子 rename 在编译、缓存和发布中点注入中断,旧版本仍完整,新 staging 可识别和清理/恢复
可恢复性 已发布产物 RPO=0;失败 run 不覆盖已发布版本;目标 RTO 为 15 分钟内用一条命令恢复最近快照 rollback 集成测试 + 快照哈希核对
幂等性 相同输入、脚本版本和参数的确定性阶段输出字节一致 连续运行两次并比较哈希
宿主兼容 Claude Code、Cursor、Codex/Agent Skills 的 frontmatter、发现、相对引用、可选 scripts 行为有兼容矩阵 每次发布跑静态 host lens;至少在 2 个可用目标宿主上做真实安装与触发冒烟测试,并记录未验证项
性能预算 首版只预注册静态文件/路由载荷和确定性阶段墙钟预算,不承诺真实模型 Token 固定机器与 fixture 的 benchmark;报告 tokenizer、文件哈希和环境
安全与隐私 来源视为不可信数据;默认无远程遥测;本地路由日志默认关闭且可删除;路径不得逃逸目标工作区 提示注入 fixture、路径穿越测试、日志字段审计
可维护性 schema、模板、脚本和 host lens 均有版本;破坏性变更有迁移与回滚说明 CI schema/golden/compatibility 测试
运维与成本 默认本地文件 + SQLite,不引入常驻服务和云数据库 doctor 在无网络、无重型解析依赖环境中通过核心检查

发布时必须附一份 compatibility-report.md,至少列出宿主版本、验证日期、发现行为、相对引用、脚本权限、single router 与 pack router 结果。未验证不等于不支持,但必须显式写成 not-tested,不能留空让读者误以为已通过。


14. 版本路线建议

14.1 先统一版本口径

当前项目存在四套互不相干的版本表述,动手前必须统一,否则 changelog、官网与 README 会互相矛盾:

位置 当前值
README.md 标题 无版本号
本地目录名 cangjie-skill-2.0
website/package.json 0.1.0
registry entry / 官网 UI schema_version: 1 / “Registry v1”
本方案(v1.1 规划 v2.1 → v3.0
口头表述 “仓颉 Skill 3.0”

建议方案:以核心 Skill 自身的版本为唯一对外口径,在 SKILL.md frontmatter 的 metadata.cangjie.version 中声明,并写进 README 标题。官网与 registry schema 各自保留独立版本号(它们是不同的产物,本就不必对齐),但官网需显示它当前展示的核心版本。

按这个口径,当前实际状态是 v2.0RIA-TV++ 七阶段 + Skill Pack 输出 + Registry),本方案的目标是 v3.0。

14.2 路线

版本 主题 核心能力 对应 Phase
v2.0 现状 RIA-TV++ 七阶段、Skill Pack 输出、Registry 与官网
v2.1 Dual Output single/pack 双输出、auto 决策、晋级门、Registry schema v2 与官网联动 Phase 0—1
v2.2 Incremental & Lean 统一 IR、内容寻址缓存、检索式上下文、来源版本、change-set、impact analysis、update Phase 2A—2B
v2.3 Repairable 失败诊断、最小补丁、old/new 回归评测 Phase 3
v3.0 Stable 完整迁移、兼容性、核心流水线 CI、公开基准与稳定接口 Phase 4

文档预处理与视频多模态作为独立产品线单独版本化(例如 content-preprocessor v0.1),不占用主线版本号。

不建议一口气标记 v3.0。先让每一阶段都能独立产生用户价值和可验证数据;尤其 v2.1 必须能单独发布——如果只做到这一步就停了,用户拿到的仍然是一个完整可用的改进。


15. 风险与应对

15.1 解析器更新导致输出漂移

应对:锁定解析器/模型版本;将版本写入 run;golden set 发现漂移后再升级。

15.2 语义去重误删真正的新知识

应对:精确重复可以自动跳过;near duplicate 只提出合并建议,保留来源;低置信度不自动删除。

15.3 增量更新产生局部一致、全局冲突

应对:依赖图必须把邻居 Skill 纳入回归;核心结论纠错和删除要求人工确认。

15.4 为降 Token 过度压缩证据

应对:证据不删除,只从主上下文迁移到 references;质量门比较覆盖率和输出能力。

15.5 Prompt 缓存命中不稳定

应对:本地阶段缓存是主机制;API 缓存仅作为可观测加速层,不写进正确性假设。

15.6 LLM judge 偏差

应对:机械断言优先;A/B 隐藏版本;多个运行;人类复核分歧和关键样本。

15.7 视频成本失控

应对:先去重和 OCR/视觉变化检测,只升级高信息帧;对 VLM 调用设每分钟上限和预算。

15.8 视频号来源不稳定或越权

应对:来源 connector 与处理管线分离;只处理授权媒体;遇到访问控制立即停止并说明替代输入。

15.9 外部内容中的提示注入

应对:把来源内容视为不可信数据,不执行其中命令;预处理与分析阶段使用最小权限;脚本、URL、凭证和外部动作单独审批;来源文本不能覆盖系统/Skill 指令。

15.10 许可证和版权

应对:manifest 记录 rights/license;默认不提交原始受版权保护材料;公开 Skill 只保留必要短引用、来源定位和改写后的方法,不发布整书/整段转写。

15.11 单 Skill 变成“巨型提示词”

应对:主 SKILL.md 设体积门;能力卡、章节、证据分层按需读取;增加 routing eval,并机械检查是否一次性加载全部 references。Single 的“一个”指一个发现入口,不是一个文件塞下所有内容。

15.12 Pack 为控数量而错误合并

应对:软预算不能覆盖独立输出契约;候选若不能合并又超过预算,默认降为能力卡并说明原因,用户可显式选择 exhaustive。任何合并都要重跑近邻触发和输出评测。

15.13 自动模式在更新时改变产物形态

应对:输出策略写入 manifest 并默认锁定;update/repair 不重新选型;--replan-output 只生成 side-by-side 预览,得到明确确认后才迁移,不自动删除旧 Skill。

15.14 执行模型未决导致目标不可验证

这是本方案最高优先级的风险,见 §0.1 与缺口 G。若在未拍板路线 A/B/C 的情况下开工,会出现两种失败:要么按路线 A 的假设写了一堆 token 采集代码,最后发现宿主根本不给数据;要么口头承诺了 30% 降幅,交付时无法证明也无法证伪。

应对:路线选择是 Phase 0 的准入条件,不是交付物。本版已选定路线 C 并据此改写了 §5 全章。若将来改选路线 A,必须同步重写 §5.1、§5.2 第五级与 §5.3,不能只改数字。

15.15 范围蔓延超出实际带宽

v1.1 的 7 个 Phase 合计 41—64 个全职工作日,而项目当前的工程底座是:无 pyproject.toml、无根 package.json、无 Makefile、流水线零测试、CI 只覆盖官网。从这个起点直接建设 9 schema + 16 脚本 + 5 个外部重依赖,实际风险不是做得慢,而是做到一半停在一个比现在更难维护的中间态。

应对:预处理与视频移出;Phase 2 拆成可分别退出的 2A / 2B,主线按 30—46 个工作日现实估算;每个 Phase 必须能独立发布并单独产生用户价值;Phase 0 设 8 个工作日的硬性超时(见 §10.6)。宁可少做,不可半途。

15.16 检索式上下文导致阶段 1 覆盖率回退

见缺口 B。阶段 1 的目标是覆盖率而非精度,改成按需检索会直接损害这个目标,而覆盖率损失在最终产物上不可见——只表现为“某个好方法没被提取出来”,没有任何报错。

应对:framework 与 principle 两类 extractor 保持全量扫描;把“最终通过三重验证的候选漏检数为 0”设为硬门;每次改动检索策略都要对基准集重跑覆盖率对比。若做不到,放弃这部分 Token 收益。

15.17 并发运行和中断导致产物串写或半发布

本地 CLI 同样存在并发与崩溃一致性风险;book-to-skill 的近期修复已经证明,共用固定工作目录会让两个任务互相污染。单纯依赖“通常一次只跑一个”不是安全设计。

应对:每次运行独立 workdir;同一目标包使用 writer lock;所有产物先进入 staging;校验通过后原子替换;缓存临时写入后 rename;启动时扫描未完成 run 并给出 resume/cleanup,不静默覆盖。

15.18 宿主差异导致“格式合法但不可发现/不可路由”

Agent Skills 规范兼容不等于每个宿主的发现、frontmatter 容忍度、相对引用和脚本权限完全一致。来源路由入口尤其可能与晋级 Skill 发生宿主相关的触发竞争。

应对:维护 §13A 的宿主兼容矩阵和固定触发 fixture;发布前至少做两个实际宿主的安装/触发冒烟测试;未测试宿主明确标记 not-testedrouter 与晋级 Skill 必须互有近邻负例。


16. 明确不建议的方案

  1. 每次新增资料都全量重蒸馏:成本高、不可解释,也容易引入回归。
  2. 把所有材料直接塞进超长上下文:上下文大不等于信息利用率高,且无法做增量复用。
  3. 只做向量数据库:向量检索解决召回,不解决来源版本、冲突、补丁、回归和交付。
  4. 只换更便宜模型:没有基线和质量门,成本下降可能来自能力下降。
  5. 只压缩 SKILL.md:会损失证据;正确做法是渐进式披露和按需引用。
  6. 用同一个 LLM 自己生成、自己判分、单次 100% 就通过:缺少独立性和波动评估。
  7. 把某一个 PDF 解析器写死成永远最优:不同材料类型表现差异大,必须用质量路由和自己的基准。
  8. 每秒所有视频帧都送 VLM:成本高、重复多,仍可能遗漏快动作的因果步骤。
  9. 自动覆盖冲突知识:应保留来源和适用条件,让高风险冲突进入人工决策。
  10. 现在就建设云端账号、数据库和复杂后台:核心正确性尚未跑通,本地文件 + SQLite 已足够完成第一阶段验证。
  11. 把所有书都强制改成一个 Skill:操作手册、SOP 和多工作流技术资料会失去独立触发、权限和复用价值。
  12. 继续把每个通过验证的知识点都变成独立 Skill:知识价值不等于产品化价值,会继续制造安装负担和触发竞争。
  13. 同时安装同一本书的 single 和完整 pack:两套 description 会重复覆盖意图;双模式是两种编译/发布目标,默认应二选一安装。
  14. 在没有基线的情况下设定百分比目标并把它设为发布门:会导致要么回头调门槛,要么拿质量换数字。所有阈值必须在基线之后、查看 validation 结果之前按产品风险预注册;基线数据只用于估计波动和样本量,不得用事后分布挑最容易通过的门槛(与 §5.3 同一规则)。
  15. 在执行模型未拍板时承诺 Token 降幅:见 §0.1。作为纯 Agent Skill 运行时拿不到 per-call token,任何百分比承诺都无法证明也无法证伪。
  16. 把预处理与视频的重依赖塞进核心 Skill:目标用户是想少装点东西的普通读者,给核心链路加 GB 级模型依赖会同时损害安装率和可维护性。它们应当是独立、可选、按需安装的产品线。
  17. 1/n 当成统计显著性或非劣门槛:它只是一个计数对应的百分比粒度;正式结论必须使用预注册界值与配对统计方法,Phase 0 只报告原始配对结果。
  18. 把未晋级能力只藏进 references 而不给运行时入口:文件存在不等于宿主能发现;compact pack 必须有来源路由入口和完整去向映射。
  19. 多个运行共用固定工作目录或直接覆盖发布目录:会产生串写和半发布;必须 per-run workdir + writer lock + staging + 原子替换。

17. 第一批开发任务拆解

Epic A:Phase 0 低成本证伪(主线,最先做)

  • A0 从最新 origin/main 建干净 worktree,复制并校验 Naval 基线后再选择 tag 或 tarball + SHA-256(禁止在当前脏工作区直接提交)
  • A1 count_tokens.py:算出 A 类四个产物指标
  • A2 人工建立 capability-map.yaml:19 个稳定 ID、owner、路由意图、重要度与去向;再用 compile_single.py 编译 single 原型
  • A3 人工评审晋级门 → “1 个来源路由入口 + 晋级 Skill”的 compact pack 原型(总入口软预算 ≤8)
  • A4 建立 Naval 19 个能力的稳定 ID、重要度和 20 条三版本共用任务集
  • A5 A/B/C 三版跑一轮,输出基线报告
  • A6 找 3—5 个真实读者按平衡顺序交叉试用 19-Skill / single / compact pack,并按中性协议记录任务证据
  • A7 对照 §10.6 做出继续 / 调整 / 终止的决定

Epic B:双输出正式化与 Registry 联动(主线,Phase 1

  • B1 定义 capability 生命周期、Capability Bundle schema 与阶段 1.6 独立 Skill 晋级门
  • B2 --output auto|single|pack 与 decision report
  • B3 single 路由入口、RIA 能力卡和 references 模板
  • B4 compact pack 编译器、来源路由入口、capability-destinations.json 与默认总入口软预算
  • B5 渐进式原子 Skill 模板(references 分层)
  • B6 validate_skill_pack.py 格式与相对引用校验
  • B7 Registry v1/v2 dispatcheroneOf + entrypoint_count + capability_count + router 不变量
  • B8 官网展示与 install.ts 按输出模式分支
  • B9 registry-check.yml 扩展 + 新增 books/ 产物校验 workflow
  • B10 任务集扩到 50 条,重跑 A/B/C benchmark
  • B11 per-run workdir、目标 writer lock、staging 校验与原子发布
  • B12 改写根 SKILL.md / methodology/ 阶段 2—5 以产出 Capability Bundle,附旧流程兼容与迁移说明
  • B13 生成文件发布哈希登记与本地手改检测(update 三选一保护)

Epic C:统一 IR、缓存与低 Token 蒸馏(主线,Phase 2A

  • C1 manifest.yaml
  • C2 核心共享 SourceDocument / Chunk contracts(首版仅原生 Markdown/TXT
  • C3 结构感知 chunks
  • C4 内容寻址缓存
  • C5 SQLite FTS5
  • C6 按类型分化的 extractor 上下文framework/principle 全量扫描,其余检索式)
  • C7 覆盖率回归门:通过三重验证的候选漏检数为 0
  • C8 早停与候选去重
  • C9 保持 extractors/methodology/ 文件内容稳定,不注入运行时变量
  • C10 在 Phase 1 运行隔离基础上补齐缓存原子写入、Agent 阶段中断恢复和故障注入测试
  • C11 固定 tokenizer 的文件计数、静态路由载荷模型与可选 host_fingerprint

Epic D:增量 update(主线,Phase 2B

  • D1 source/chunk diff
  • D2 change-set
  • D3 dependency graph
  • D4 impact analysis
  • D5 patch/rollback
  • D6 冲突确认

Epic E:定向 repair

  • E1 failure-case schema
  • E2 诊断分类
  • E3 old/new/without runner
  • E4 trigger train/validation
  • E5 邻居 Skill 回归

Epic F:文档预处理(移出主线,独立仓库)

  • F0 确认 MinerU 等依赖的许可证与 AGPL-3.0 兼容性
  • F1 Docling adapter
  • F2 MinerU adapter
  • F3 quality probe/router
  • F4 provenance 和 assets
  • F5 文档基准报告

Epic G:视频多模态(移出主线,独立仓库)

  • G1 媒体探针和 ASR
  • G2 双路抽帧
  • G3 OCR/重复帧过滤
  • G4 VLM provider adapter
  • G5 音画时间轴
  • G6 视频号 connector 边界
  • G7 视频基准报告

Epic H:版本与文档口径(贯穿)

  • H1 统一版本口径(见 §14.1),README 标题标注核心版本
  • H2 README「仓库结构」段补齐 books/registry/website/schemas/scripts/docs/(当前只列了 6 项,与实际不符)
  • H3 迁移指南与回滚指南
  • H4 固化 ADR-001—004,并为被替代决策使用 superseding ADR
  • H5 维护 Claude Code / Cursor / Codex 宿主兼容矩阵与 compatibility-report.md

18. 推荐的第一步

下一步不要立刻写 5 个功能,也不要按 v1.1 那样在 Phase 0 就建 IR、缓存和 50 条评测集。先做一个 3—5 天、不建设平台基础设施的证伪;其中 3 个小工具是否成为长期 API,要等结论出来再决定:

第 0 天(半天):拍板前置决策

  • 确认 §0.1 的执行模型路线(默认 C);
  • 重新读取 origin/main,建立干净 worktree;只复制 Naval 包,生成文件清单与 SHA-256,校验后再选择 tag 或 tarball 归档。它现在是 untracked,基线不可复现则后续一切对比无效;当前脏工作区不得直接提交。

第 1 天:静态编译两个原型

  • 先人工填写 19 个能力的稳定 ID、owner、路由意图、重要度和去向,再编译 1 个入口 + 19 张能力卡的 single 原型;
  • 人工过一遍晋级门,产出“1 个来源路由入口 + 少量晋级 Skill”的 compact pack,总可发现入口软预算 ≤8;
  • 不重新蒸馏原书

第 2 天上午:算清楚四项静态指标

  • 用固定 tokenizer 离线算出三版各自的发现目录载荷、单任务路由载荷上下界、产物文件总量,并保存文件哈希与路由规则;
  • 这一步会直接验证或推翻 §0 的判断——single 最确定的静态收益主要在发现目录载荷,且绝对值未必大。

第 2—3 天:20 条任务集粗筛

  • 三版各跑一轮,只测路由命中与能力覆盖;
  • 记录 single 丢失或降级的能力清单。

第 3—5 天:真实读者反馈

  • 找 3—5 个真实读者按平衡顺序分别试用 19-Skill、single 与 compact pack,不告诉哪一版是优化版;
  • 用 §10.5 的中性问题记录安装、查找、任务完成、信心和最终偏好,不使用“比 19 个更好用吗”这种引导问法;
  • 把结果视为可用性发现,不在小样本上宣称正式非劣。

收尾:对照 §10.6 做决定 —— 继续、调整,还是终止。

Phase 0 要回答的问题

v1.1 列了五个问题,其中三个(Token 分布、缓存收益、增量粒度)在没有执行模型和真实使用之前根本问不出答案,属于过早提问。本版收敛为三个真正能回答、且能决定后续方向的问题:

  1. 19 个压成 1 个后,具体丢了什么、省了什么?(覆盖率清单 + 四项固定 tokenizer 文件/路由载荷指标)
  2. 交叉试用中,读者在哪个版本更容易安装、找到能力并完成任务,为什么?(定性发现,直接对应“Skill 太多”这条原始反馈;不在 3—5 人上宣称统计非劣)
  3. 19 个候选里,哪些真的值得独立成 Skill?(晋级门的第一次实战,也是 skill_budget: 8 这个假设的第一次校准)

至于“最大上下文准备量在哪个阶段”“确定性缓存能省多少”“增量该精确到章节还是 chunk”,等 Phase 2A—2B 有了统一底座和真实运行数据再问。现在问,只会得到猜测。


19. 参考资料

Agent Skills

单 Skill 编译参考

增量与内容处理

视频与音频

Token 与缓存