设计理念 · 难度:高级

设计理念

贯穿每个技能、每份参考资料、每个转换器的共性规则。读一次;当任何发现看起来奇怪时翻一翻。

AGENTS.md(规范的仓库指令文件)

无论技能是否被调用都成立的三条规则:

  1. 陈述条件,而非流程或情形。当一段文字在不断吸收「把我们刚发现的 case 也加上」时 — 无论是在编写、评审回合还是你为一条发现所做的修复 — 这种表述就是错的。删掉那些补充并重新陈述目标,然后针对原表述服务的每条路径重新验证;一次无法再命名任何路径的重述是一个新的缺陷,而不是简化。
  2. 仅在你拥有的层级规定机制。委托型技能陈述条件、安全失败方向以及不可推导的被调用者事实,绝不复述被调用者的命令。
  3. 把你触碰的段落提升到标准;保留未触动的段落不动,并把那些段落记为后续工作。技能早于标准存在,会逐步演进到该标准。

十条贯穿主题

这些主题来自对 105 份参考文件的完整阅读。它们与版本无关 — 新技能加入时,同样的形态会再次出现。

十条贯穿主题 — 每个技能都遵循的 ID/出处/三层模型/跨模型/收敛/docs_root/原子写/wave/输出契约/信心锚 every skill honors these Stable IDs R / U / KTD / A / F / AE session-settled provenance user-directed | user-approved Three-tier models extract · gen · ceiling Cross-model peer independence_verified Anti-cry-wolf convergence via trajectory docs_root discipline config.yaml only Atomic write create dir before file Wave contract 5 holds + disjoint files Per-idea contract title/summary/axis/why Confidence anchors 0 / 25 / 50 / 75 / 100 — never continuous floats + 3 always-loaded rules conditions not cases · own the mechanism · bring block to standard
十条主题 + 三条始终加载的规则。每个技能都遵循所有主题。

1. 稳定的 ID 契约

统一计划格式使用一套小巧、固定的稳定标识符,下游消费者据此索引:

R-ID(需求)
产品需求的稳定 ID。会被实现单元和测试场景引用。
U-ID(实现单元)
工作单元的稳定 ID。实现提交可在标题后追加 (U3)
KTD(关键技术决策)
规划阶段做出的决策,当由用户指示或用户批准时,标注 session-settled: 来源类别。
A / F / AE
锚点:Assumption(假设) / Fact(事实) / Architectural Element(架构元素)。计划章节的引用标签。

这些 ID 永不重写、永不重新编号。消费者可以放心地认为 (U3) 在跨会话和提交中指向同一个单元。

2. session-settled: 来源

计划中的决策分三类来源:

类别含义示例
session-settled: user-directed用户在规划对话中明确指示了该决策。「用 SQLite,因为我们生产里已经在跑它。」
session-settled: user-approved用户批准了规划者抛出的某个选项。「在规划者提出 3 次重试后,用户表示同意。」
(未标注)Agent 自身的建议。不能约束用户。规划者基于证据的最佳猜测。

只有前两类可以钉住后续决策。Agent 绝不自己把自己的建议定为定论。

3. 三层模型架构

每个调度型技能都使用三层能力阶梯。选择按任务形态,而非模型名称。

抽取层
能完成工作的最便宜模型。用于检索-引用类任务:work-recap-scoutpr-snapshot 快照器、learnings-researcher
生成层
用于起草的能力型模型:ce-code-review 的人格、调度工作者、构思框架。
顶层
编排器的主上下文。绝不调度。负责判断、综合、调和与最终成稿。

4. 带 independence_verified 的跨模型同行

当改动风险足够大时,ce-code-reviewce-doc-review 会在同一份产物上调用一个同行模型。同行的发现只在「如果让一个独立评审者重新看也会得出相同结论」时才会被合入;综合阶段会在每条合格发现上盖上 independence_verified: true 的戳。

何时把一条发现升格为「已达成共识」

只用锚定式评分。只有 0 / 25 / 50 / 75 / 100 这四个级别。连续的浮点数会引入虚假的精度;请使用锚。

5. 防「狼来了」收敛(ce-babysit-pr)

babysit 循环是「看门狗喊狼来了」最容易发生的地方。设计编码了三条防护:

  1. 看轨迹,不看断言。快照会输出 check_recur_maxrecurring_checksunresolved_trendnew_threads_this_tickheads_since_progress。委托的叶子节点据此判断是否真的收敛。
  2. 触发条件透传给叶子。invariant_rounds[].rounds >= 2 或其他触发条件被跨越时,编排器必须把轨迹透传给 ce-resolve-pr-feedbackce-debug — 绝不自己宣告不收敛。
  3. 有界停止。max-runtime 限定运行;「看起来就绪」闸门检查 7 个条件;未解决的残留会阻塞「就绪」声明但不会停止循环。

6. docs_root 纪律

docs_root.compound-engineering/config.yaml唯一只从 config.yaml 读取的键 — 永远不会从 config.local.yaml 读取。原因:docs_root 是一条物理机器路径;本地覆盖会把用户的机器路径泄漏到 CI。完整的分层规则见 配置系统

7. 通过建目录实现原子写

多步写入采用「先建目录,再写文件」的模式,避免半写状态。父层写入器先调用 ensureDir(path);文件随后写入已存在的目录。代价是多一次 syscall;收益是中途崩溃时不会留下孤立文件。src/utils/files.ts 中的 writeTextSecure / writeJsonSecure 变体实现了该模式。

8. 共享工作区的 wave 契约

当多个子 Agent 需要写入同一份检出(ce-work 中的常见情况),它们共享工作区但通过文件所有权来协调:

约束规则
1按不相交的文件所有权进行扇出,而非按条目。
2条目会跨文件;共享同一文件的 Agent 会丢失彼此的改动。
3class 条目要预先枚举每个具体位置。
4工作者集成是规范的;由编排器提交。
5工作区隔离是升级手段,而非入门券。

9. 每条想法的输出契约(ce-ideate)

ce-ideate 的发散阶段生成的每条想法都必须携带一份固定契约:

title
短名称;在本次运行内唯一。
summary
一段话 — 这条想法是什么意思。
axis
它针对的是分解出的 3–5 个维度中的哪一个。
basis
想法的依据 — 仓库 / 外部 / 非软件。
why_it_matters
它所交换的价值或风险。
meeting_test
能证实这条想法值得推进的单一可观测事实。

存活下来的想法必须解释每个字段;被拒绝的候选只需要一行拒绝理由。这就是大量生成、全部批判、只解释存活者

10. 信心锚(0 / 25 / 50 / 75 / 100)

发现、决策和评分使用 5 个锚定等级,而非连续浮点数。原因如下:

为什么连续浮点会失败

「信心 0.73」看起来精确但毫无意义 — 发出该评分的模型也无法为 0.71 与 0.75 之间的取舍辩护。而 Confidence 75 (cross-persona agreement noted in the report) 则把闸门需要的信息讲清楚了。

AGENTS.md 三条规则的实践

陈述条件,而非流程

当你发现自己往规则里加「并且在 X 时也这样」时,请说出 X 所代理的那个条件并直接陈述它。一条必须枚举情形的规则,本身就陈述错了。

具体地说:ce-babysit-pr 的「看起来可以合并」闸门并不是说「没有失败检查时就绪」。它说的是「mergeability_certain + MERGEABLE + CLEAN + 没有 base_ref_blocker + checks_terminal + 积压为零 + branch_currency_blocker == null + open_needs_human == 0 + settle 已过 + review-still-coming 干净 时就绪」。情形由合取涌现;条件就是这个合取,不是「情形 X:就绪」。

仅在拥有的层级规定机制

委托型技能陈述条件、安全方向以及不可推导的被调用者事实。它不复述被调用者的命令。

具体地说:ce-lfg 第 5 步说「应用并持久化评审修复」 — 并指向 references/review-followup.md 中的四项条件过滤。ce-lfg 不会说「对每条发现,检查 suggested_fix 是否存在,再检查 confidence」。那是 ce-code-review 的机制。lfg 陈述策略(「仅当…时在工作区中应用一条发现」),由参考资料拥有该规则。

把你触碰的段落提升到标准

如果你在编辑段落 X,就把 X 修到符合标准。段落 Y 留着不动 — 并把 Y 列为后续工作。

具体地说:当 ce-skill-work 的评审模式发现一个缺口时,修复应当是重写该段,而不是再添一个 case。如果同一段在第二轮又拿到发现,把所有内容合并成一次重述,永远不要再二次修补情形列表。

编码了这些规则的 15 份技能设计解决方案

docs/solutions/skill-design/ 收录了 44 份沉淀的学习。上面 10 条主题是元规则;这 44 份文件是逐个 case 的编码。以下这些反复出现于评审发现:

解决方案文档重复出现的模式
skill-gates-state-conditions-not-prescribed-git-commands.md同一发布闸门改了六版;修复是陈述条件。
state-the-condition-not-a-placement-absolute.md代理规则(条件 + 放置绝对项)一旦重复就会开始禁止其条件所要求的做法。
subordinate-the-failing-shape-to-the-condition.md在无法实例化条件的宿主上如何保持条件可读。
strong-models-mask-defensive-skill-fixes.md带技能 vs 基线的平局并不能证明修复有效。
size-driven-skill-restructure.mdce-babysit-pr 从 90KB → 8KB;如何在不丢失不变量的情况下瘦身。
bound-contradiction-checks-to-named-guidance.mdce-compound-refresh 与学习命名的指导文件作对比。
dispatch-script-failure-degrade-outcome-not-boundary.md脚本守住边界;失败时退化的是结果,不是边界。
liveness-judgment-belongs-to-the-agent.mdce-babysit-pr 在收尾后多挂了 15–30 分钟,因为活性检测器把评审状态建错了模。
watch-loops-need-a-blocked-external-terminal-state.mdwatch 循环需要第三个终态:blocked-external。
named-frameworks-with-detection-conditions-for-review-personas.md引用 OWASP / Fowler smells / Release It!;而不是「以 X 视角评审」。
context-absent-skill-handoff-needs-pinned-invocation.md为什么 Skill 工具在跨技能交接时胜过散文。
invocation-opt-out-flags-block-sibling-skill-invocation.mddisable-model-invocation 会在宿主之间阻断兄弟技能调用。
inline-callee-side-channel-must-name-where-it-may-not-land.md调用方的侧信道规则必须说明它「不能」落在哪里。
workspace-isolation-is-escalation-not-entry-fee.md隔离是给必须提交的工作者用的;不是并行的默认项。
post-menu-routing-belongs-inline.md不要把菜单路由放在模型不会打开的参考资料里。

每一条都在 解决方案库 中有专属页面;本表只是一个主索引。