Files
2026-07-13 21:36:19 +08:00

6.4 KiB
Raw Permalink Blame History

name, description
name description
improve-codebase-architecture 查找代码库中可深化的机会,依据 CONTEXT.md 中的领域语言和 docs/adr/ 中的决策记录。当用户希望改进架构、寻找重构机会、整合紧耦合模块,或使代码库更可测试且更易于 AI 导航时使用。

改进代码库架构

暴露架构摩擦并提出深化机会——将浅层模块转变为深层模块的重构。目标是可测试性和 AI 可导航性。

术语表

在每一条建议中精确使用这些术语。统一语言是关键——不要偏离到"组件"、"服务"、"API"或"边界"上。完整定义见 LANGUAGE.md

  • 模块(Module——任何拥有接口和实现的东西(函数、类、包、切片)。
  • 接口(Interface——调用者使用模块所需了解的一切:类型、不变式、错误模式、顺序、配置。不仅仅是类型签名。
  • 实现(Implementation——内部的代码。
  • 深度(Depth——接口处的杠杆效应:一个小接口背后承载的大量行为。深(Deep= 高杠杆。浅(Shallow= 接口的复杂度几乎等同于实现。
  • 接缝(Seam——接口所在之处;可以在不原地修改代码的情况下改变行为的地方。(使用这个词,而不是"边界"。)
  • 适配器(Adapter——在接缝处满足某个接口的具体实现。
  • 杠杆效应(Leverage——调用者从深度中获得的好处。
  • 局部性(Locality——维护者从深度中获得的好处:变更、缺陷、知识集中在一处。

关键原则(完整列表见 LANGUAGE.md):

  • 删除测试:想象删除该模块。如果复杂度消失了,它只是一个透传模块。如果复杂度重新出现在 N 个调用方中,那它物有所值。
  • 接口即测试面。
  • 一个适配器 = 假设性接缝。两个适配器 = 真实的接缝。

本技能受到项目领域模型的启发。领域语言为好的接缝提供了命名;ADR 记录了本技能不应重新争论的决策。

流程

1. 探索

首先阅读项目的领域词汇表以及你将要触及的区域的任何 ADR。

然后使用带有 subagent_type=Explore 的 Agent 工具来遍历代码库。不要遵循僵化的启发式规则——有机地探索,并在你感到摩擦的地方做记录:

  • 在哪里理解一个概念需要在许多小模块之间来回跳转?
  • 哪些模块是浅的——接口的复杂度几乎等同于实现?
  • 哪些纯函数仅仅为了可测试性而被提取出来,但真正的缺陷隐藏在其调用方式中(没有局部性)?
  • 哪些紧耦合的模块跨越了它们的接缝?
  • 代码库的哪些部分未经测试,或者通过当前接口难以测试?

对你怀疑是浅层的任何东西应用删除测试:删除它会集中复杂度,还是仅仅转移它?"是,会集中"就是你要找的信号。

2. 将候选方案呈现为 HTML 报告

编写一个自包含的 HTML 文件到操作系统临时目录,这样不会有任何内容落入代码库。从 $TMPDIR 解析临时目录,回退到 /tmp(在 Windows 上为 %TEMP%),并写入到 <tmpdir>/architecture-review-<timestamp>.html,这样每次运行都会生成一个新文件。为用户打开它——Linux 上使用 xdg-open <path>macOS 上使用 open <path>Windows 上使用 start <path>——并告知他们绝对路径。

报告使用通过 CDN 引入的 Tailwind 进行布局和样式设计,以及通过 CDN 引入的 Mermaid 用于绘制能可靠传达结构的图形/流程图/时序图。将 Mermaid 与手写 CSS/SVG 可视化效果混合使用——当关系呈图形结构(调用图、依赖关系、时序图)时使用 Mermaid,当你想要更具编辑性效果(质量图、截面图、折叠动画)时使用手写 div/SVG。每个候选方案都附带一个前后对比可视化图。要可视化。

每个候选方案使用与之前相同的模板,但以卡片形式呈现:

  • 文件——涉及哪些文件/模块
  • 问题——当前架构为何导致摩擦
  • 解决方案——将发生什么变化的纯英文描述
  • 收益——用局部性和杠杆效应来解释,以及测试将如何改进
  • 前后对比图——并排展示,自定义绘制,说明浅层性和深化效果
  • 推荐强度——强烈推荐值得探索推测性之一,以徽章形式呈现

报告以首要推荐部分结尾:你会优先处理哪个候选方案以及原因。

对领域使用 CONTEXT.md 的词汇,对架构使用 LANGUAGE.md 的词汇。 如果 CONTEXT.md 定义了"订单",那就说"订单接收模块"——不要说"FooBarHandler",也不要说"订单服务"。

ADR 冲突:如果一个候选方案与现有 ADR 相矛盾,只有当摩擦确实足够大、值得重新审视该 ADR 时才将其呈现出来。在卡片中清晰标注(例如警告提示:"与 ADR-0007 冲突——但值得重新讨论,因为……")。不要列出每个被 ADR 禁止的理论性重构。

详见 HTML-REPORT.md 了解完整的 HTML 脚手架、图表模式和样式指南。

暂时不要提出接口。文件写入后,询问用户:"你希望探索其中的哪一个?"

3. 反复质询循环

一旦用户选择了一个候选方案,进入质询对话。与他们一起遍历设计树——约束条件、依赖关系、深化后的模块形态、接缝背后是什么、哪些测试仍然有效。

当决策逐渐明确时,副作用会就地发生:

  • 将一个深化后的模块以 CONTEXT.md 中不存在的概念命名? 将该术语添加到 CONTEXT.md 中——与 /grill-with-docs 相同的规范(见 CONTEXT-FORMAT.md)。如果文件尚不存在,则惰性创建。
  • 在对话过程中明确了某个模糊术语? 立即更新 CONTEXT.md
  • 用户以某个关键理由拒绝了候选方案? 提供一份 ADR,表述为:"想让我将其记录为一条 ADR,这样未来的架构审查就不会再次推荐它了吗?" 只有当该理由确实会被未来的探索者需要以避免重复推荐同一内容时才提出——跳过短暂的理由("现在不值得")和不言自明的理由。详见 ADR-FORMAT.md
  • 想为深化后的模块探索替代接口? 详见 INTERFACE-DESIGN.md