mcpField
R
review-a-design

review-a-design

github.com/inkeep开发14230 次安装1 天前更新
代码仓库

关于 review-a-design

review-a-design 是一项技能,用于判断软件设计是否由其目标和约束推导而来,而非仅检查完整性或事实准确性。它面向设计作者和评审者,输出有证据支撑的发现,而不直接修改待评审文档。

主要功能

  1. 01梳理目标、约束与设计依据
  2. 02检查相关既有决策和事后复盘
  3. 03按需运用设计合理性评审视角
  4. 04给出排序、含证据和解决方案的发现
  5. 05校准置信度并检验评审结论

适用场景

  1. 01在 RFC 接受前评审设计
  2. 02检查提案是否符合既有决策
  3. 03发现假设边界处的风险
  4. 04提供可行动反馈而不重写设计

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/inkeep/open-knowledge-skills --skill review-a-design

安装后在 Claude Code 中输入/review-a-design确认已加载。

详细介绍

评审设计——判断它是否合理,而不只是完整

此处的所有 Markdown 操作仍受平台 /open-knowledge 技能约束(通过 exec 读取,通过 write/edit 写入,链接使用普通相对 Markdown,范围内的 .md 由 MCP 管理);本技能在此基础上增加设计评审方面的实践。

三种评审并不相同,而只有一种属于本技能的职责。

  • 完整性评审会问:每个章节都填了吗?(缺点和替代方案是否非空?)
  • 正确性评审会问:各项说法是否属实?(基准测试中说的真是 40ms 吗?该 API 已弃用了吗?)
  • 合理性评审会问:这项功能到底该不该构建?根据所述目标和约束,是否应当采用这个设计?

你要做的是第三种。提案可能完整无缺、事实准确,但设计仍然不对——它解决的是症状,在明确目标之前就选定方案,对替代方案的探讨也只涉及稻草人。完整性和正确性检查成本低,而且应该由其他人负责。如果用户想要哪种评审并不明确,就先向用户说明这一点,再进行合理性评审。

你要给出评审发现,而不是修改内容。由作者决定要改什么。除非用户明确要求,否则绝不要重写正在评审的文档。


步骤 0:识别文档并完整阅读——以及它继承的内容

硬性要求:绝不评审自己没有从头到尾读过的设计,也绝不脱离其所继承的决策进行评审。 只评审前半部分比不评审更糟糕——这会让作者把信任浪费在不完整的理解上。

  1. 识别文档类型。它属于以下一种:
    • 提案(proposals/NNNN-name.md——动机 / 设计 / 缺点 / 替代方案 / 未决问题),
    • 规范(specs/NNN-name/spec.md——目标 / 非目标 / 设计 / 迁移 / 测试计划,包含 parent_proposal:),
    • 决策(decisions/NNNN-title.md——背景 / 决策 / 后果,包含 supersedes: 链),或
    • 尚无文档的待定选择(用户正在对话中做决定)。这也是有效的评审对象——见步骤 1。
  2. 完整阅读:exec("cat proposals/0003-feature.md")。
  3. 阅读它依赖的内容。设计的合理性取决于其依据:
    • 规范通过 parent_proposal: 关联的上级提案,以及决策所落实的任何提案;
    • 它所依赖的决策——exec("grep -rln <subsystem-keyword> decisions/"),然后 cat 相关内容。设计若与已接受的 ADR 矛盾却未说明,这本身就是一项评审发现。
    • 同一子系统中此前的事后复盘——exec("ls -A postmortems/") 和 search({ query: "<subsystem> failure" })。事后复盘会指出故障模式;设计若让这种故障再次出现,这是最有价值的发现。
    • 它取代或与之重叠的同级提案/决策——沿 supersedes: 链正向和反向追溯。
  4. 如果设计引用了源代码,请使用宿主的原生工具(Read、Grep)阅读代码——源代码不属于知识库。范围内的 Markdown 仍通过 exec/search 处理。

在你能够说清目标、约束以及该设计所依据的既有决策之前,不要继续。

步骤 1:重构设计自身的论证,并展示给用户

在提出任何批评之前,先用自己的话说明设计的论证:它服务的目标、接受的约束,以及为何这些因素会导出这一设计。 在步骤 2 之前展示给用户。

设置这一关的原因:

  • 如果你能清晰地重构论证,作者就能免费确认预期读者是否理解了设计——这往往是评审最有用的成果。
  • 如果你无法说明目标、约束以及为何这些因素会导出这一设计,那么可供评审的对象就还不存在——这本身就是发现。 停下来并报告:“我无法重构这一设计为何符合其目标;以下是论证链条断裂之处。” 如果连设计的论证都说不清,却去评审设计的表面内容,只会产生自信却空洞的噪声。先把它交还给编写技能,让论证变得清晰易懂。

对于没有文档、仍在进行中的选择,这一步是首次将论证明确表达出来的地方。很多时候,仅仅重构论证就能解决问题,无需使用任何分析视角。


步骤 2:运用合理性分析视角

用下方的每个视角审视设计。每个视角都是一个明确的问题,以及它能发现的失败——针对这一产物,运用切中要害的视角,跳过显然不适用的视角,也可补充任何值得采用的视角。不要机械地填满全部九个视角;如果评审只是把同一个浅显观点重复九遍,就毫无价值。

  • 问题视角 — 所述问题是真正的问题,还是某个上游问题的症状? 这是给谁带来的问题?有什么证据表明它现在确实造成了困扰(而不是假设如此)?针对症状的设计无论多么精妙,都站不住脚。它能发现的失误:漂亮地解决了错误的问题。
  • 目标推导视角 — 设计是否源于既定目标,还是先选定设计,再反向编造目标为其辩护? 先读目标,再不带预设地读设计:你能否从这些目标推导出这个设计?如果设计包含任何目标未要求的功能,要么目标没有明说,要么该功能超出了范围。它能发现的失误:先有解决方案,再进行合理化。
  • 替代方案视角 — 替代方案是真正的选项,还是稻草人? 选出被否决方案最有力的版本——尽可能为它据理力争——再检查文档是在回应这个版本,还是在回应一个软弱的 caricature。替代方案一节若用一句轻蔑的话就否决每个选项,这是一个警讯。它能发现的失误:把预设结论伪装成比较。
  • 约束视角 — 哪些约束是硬性条件,哪些只是沿袭的习惯? 硬约束:物理规律、合规要求、已经走过的一次性决策、与下游团队签订的合同。软约束:“我们一直都是这么做的”、当前工具的限制、可以调整的截止日期。把软约束当成硬约束的设计,想象力不足,而且很可能比实际所需更庞大。它能发现的失误:用虚构的壁垒为不必要的复杂性辩护。
  • 成本视角 — 这种设计会排除哪些可能性?未来三年里,它每周都会给团队带来什么? 明确指出持续性的义务:无法撤销的迁移、从此需要永久回填的模式、值班负担。影响范围不只涉及上线,还包括后续维护的长期负担。它能发现的失误:看似便宜,后续代价高昂的设计。
  • 可逆性视角 — 这是一扇单向门,还是双向门? 双向门(容易回退)应该直接通过,不必交给委员会审议——如果设计撤销成本很低,过度评审只会浪费大家的时间,结论应当是“直接发布并从中学习”。单向门(数据迁移、公共 API、外部合同)则值得接受双向门不需要的严格审查。它能发现的失误:把严谨用错地方——对可逆选择走繁重流程,对不可逆选择却轻描淡写。
  • 失效视角 — 要让它奏效,哪些条件必须成立?每个假设到了边界会怎样? 列出所有关键假设,再逐一推到极限:负载增至 10 倍时、网络中断时、输入带有恶意时、第二个写入者并发操作时会怎样?**与步骤 0 中的过往复盘交叉检查:这个设计是否会重现某个曾被点名的失败?**它能发现的失误:设计在理想路径上无懈可击,却在每个边界条件下都会出问题。
  • 简化视角 — 是否存在一个明显更小、同时满足既定目标的设计? 请具体说明——“移除队列,改为同步调用;目标从未提及吞吐量”——而不是“简化设计”,后者并不算一个发现。YAGNI 是健全性论据,不是风格建议:推测性的泛化并不健全,因为它为没人提出过的目标付出了成本。它能发现的失误:设计解决了尚未出现的问题。
  • 范围视角 — 非目标是否只是暂缓处理且理由充分,还是有人暗中把关键范围从后门排除? 好的非目标会说:“目前先不做,因为 X;而且这里留有接口,之后可以添加。”糟糕的非目标会悄悄排除实际问题中最难的部分,让设计看起来更容易实现。逐条阅读非目标,并问自己:即使不包含这些内容,设计是否仍然解决了真正的问题?它能发现的失误:为缩水后的问题设计出一个看似可行的方案。

步骤 3:撰写发现

每条发现包含四个部分,缺少第二部分的发现只是意见——应予删除:

  1. 主张 — 用一句话说明哪里站不住脚。
  2. 证据 — 引用相关段落或链接到它:the Design section says "[quoted text]" 或 [the Migration plan](./specs/012-sync/spec.md) 假设了 X。没有证据指针的发现就是意见;请删除。 这条原则是区分作者会采纳的评审和令作者反感的评审的关键。
  3. 严重性 — 以下之一:
    • 阻断性 — 不应按当前写法推进设计;关键假设有误、重新引入了已知故障,或解决的是错误的问题。
    • 实质性 — 设计可以推进,但这会明显削弱设计,应在接受前得到回应。
    • 轻微 — 值得指出,但可以安全地延后处理或不予采纳。
  4. 解决方案 — 提供具体替代方案,或提出能够厘清问题的问题。“这样更糟”不可执行;“可以考虑采用双向门方案来实现 X,这样就无需迁移了”,或“两个 Agent 同时写入同一文档时会发生什么——设计是否考虑了这种情况?”则是可执行的。

按严重性排序,而非按阅读顺序。 把阻断性发现放在最前面;作者读完评审开头、了解大意后可能就会停下。把唯一一条阻断性发现埋在六条轻微发现下面,等于浪费了它。


步骤 4:校准——以对抗性视角重新审视自己的发现

提交前,把这些审视标准用在自己身上。把所有问题都标出来的评审会让作者学会忽略评审——只要你的评审里有一条经不起辩护的发现,作者就会降低对所有发现的重视。

  • 像作者那样重新审视每条发现,并试着推翻它。如果证据经不起质疑,就删掉。
  • 说明每条发现的置信度,以及什么情况会改变你的看法:“阻断性,高置信度——除非上级提案中的负载数字有误,否则这条发现应降为轻微。” 如果一条发现无法附上可证伪条件,它很可能只是偏好,而非真正的发现。
  • 合并重复项。三个根源相同的发现应合并为一条,并列出三个症状。
  • 如果校准后没有阻断性或实质性发现,就直说——“这份设计站得住脚;以下是两条轻微意见”就是一份完整且有价值的评审。不要为了显得全面而凭空夸大严重性。

步骤 5:提交

默认在对话中提交。 大多数评审只需作为一条消息:重构后的论证(步骤 1)、按严重性排序的发现(步骤 3)以及校准说明(步骤 4)。

仅在以下情况下将评审保存为文档: 用户提出要求,或评审内容足够重要,值得日后引用(例如,一份针对即将进入接受/拒绝阶段的提案所做的阻断性评审)。此时:

  • 将文档写在所评审材料旁边:write({ document: { path: "proposals/0003-feature-review.md" } })。
  • 使用 edit 在该材料的 Unresolved questions(提案)或 Open questions(规范)部分添加指向评审的链接——使用普通 Markdown 链接 [design review](./0003-feature-review.md),不要加反引号,也不要使用 HTML 锚点。
  • 在文档自身的 frontmatter 或开篇行中标明其为建议性内容:这是提供给作者的参考,不是裁决。材料由作者负责,并由作者决定采纳哪些内容。

绝不要为了“应用”某条发现而直接编辑正在评审的设计。你负责提出发现;应用这些发现由编写该材料的技能负责。

步骤 6:移交

将阻塞性和实质性发现反馈给负责修复的人:

  • 关于提案的发现 → /frame-a-proposal(论证、备选方案或动机需要返工)。
  • 关于规范的发现 → /write-a-spec(目标、非目标、迁移或测试计划需要返工)。
  • 某项发现已落实为既定选择(“我们讨论过了;我们决定采用同步版本”)→ /record-a-decision,以便将选择及其理由记录到 decisions/ 中;如果该选择推翻了先前的 ADR,还要添加 supersedes: 链接。
  • 发现过去的失败正在被重新引入 → 将作者引向具体的 postmortems/YYYY-MM-DD-name.md,让设计明确考虑这一问题。

在移交时说明技能名称和原因,让作者清楚该去哪里。


非目标

  • 不是完整性检查清单。“X 章节是空的”只有在空缺会导致设计站不住脚时才算发现(没有 Alternatives 意味着没有证据表明曾探索过选项空间——这才是发现,而不是标题为空)。
  • **不是事实核查。**单项主张是否属实属于正确性审查,是另一项工作。你要假定这些主张成立,并检验建立在其上的设计是否站得住脚。只有在某项主张是关键依据且你有具体理由怀疑它时,才标记该主张;否则,应将事实核查单独移交。
  • **不是代码审查。**审查差异以查找错误、风格或实现质量问题不在范围内。此技能审查的是设计,而非代码。
  • **不是重写。**未经请求,绝不修改正在审查的文档。你负责提出发现;由作者修改设计。
  • **绝不是最终裁决。**审查意见是给作者的建议,由作者负责决策。写成裁决口吻的审查——“拒绝”——就是越权;写成“以下是如何改进设计的建议,以及我认为需要阻止推进的事项和原因”,才是尽职履责。

评论

支持 Markdown