名称: reduce 描述: 解构高成本抽象,并推荐减少工具层、间接性和隐藏步骤的低级原语。当请求要求减少层数时使用(例如“太多层”、“移除这个框架/插件/依赖注入”、“抛弃代码生成/任务运行器”、“用普通脚本/配置/SQL替换”),或要求进行抽象审计,包括优先削减列表和带回滚的分阶段迁移(除非明确要求,否则仅进行分析)。
Reduce(代理的去抽象化)
概述
诊断抽象成本与价值,并推荐低级原语,采用外科手术式、最小切口的心态。
默认:
- 优化代理可编辑性(少层、显式配置、确定性命令)。
- 激进策略:即使增加短期重复或迁移工作,也倾向于使用原语。
- 保留可观察行为,除非用户明确请求语义更改。
- 仅进行分析/推荐;除非明确要求,否则不实施。
双钻石模型适配
Reduce 是一个侧重于发现/定义的技能,生成具体的削减列表和迁移计划,而不编写代码。
- 发现:盘点抽象堆栈并定位间接点。
- 定义:为每个抽象评分(代理税 vs 价值)并决定保留/削减。
- 开发:选择下一个低级替换层次和最小的可逆迁移。
- 交付:报告审计表 + 优先削减列表 + 迁移计划 + 最小切口补丁建议。
进入条件
仅在至少一个条件成立时使用此技能:
- 变更延迟主要由抽象/工具跳转而非本地可读性主导。
- 行为由框架钩子、插件、代码生成或配置间接控制。
- 目标是在保留可观察行为的同时移除或降级层。
分类门限
- 对于架构/工具去抽象化和依赖削减,首选
$reduce。 - 对于当前堆栈内的本地可读性或控制流简化,首选
$complexity-mitigator。 - 如果两者都适用,先运行
$reduce以删除层,然后简化剩余部分。
核心原则
- 最小切口,最大简化:针对删除最多间接性的最小变更。
- 代理友好原语胜出:普通文件、显式配置、简单CLI、无隐藏生成器、无交互提示。
- 当行为未使用或冗余时,优先删除而非替换(通过仓库证据证明未使用)。
- 优先一个明显路径而非灵活多路复用(插件、适配器、依赖注入容器),除非价值得到证明。
护栏
- 默认基于仓库本地证据;不要猜测使用/价值。
- 不推荐大爆炸重写;要求接缝、阶段、证明信号和回滚杠杆。
- 不要提出破坏外部接口的变更,除非有兼容性包装或用户明确要求。
- 除非明确要求,否则不要添加工具/依赖项。
- 如果要求实施,转交给
$tk或$code。
“代理可编辑性”的含义(实际)
代理可以:
- 找到行为所在的位置(少跳转;少约定;最小魔法)。
- 用小差异进行更改(无仓库级连锁编辑)。
- 快速运行/验证(一个确定性命令;最小环境)。
非目标(除非明确要求):
- 美化重构。
- 为自身而重新平台化。
- 调优性能/规模超出现有合同要求。
工作流程
1. 发现:映射抽象堆栈
盘点使变更困难的因素。
必需扫描(仓库本地):
- 工具链:构建/测试命令、任务运行器、代码生成、格式化器/linter、单仓库工具。
- 运行时:框架/元框架、插件系统、依赖注入、反射、中间件层。
- 数据:ORM/查询构建器/迁移、缓存、队列、服务网格。
- 前端:SPA框架、捆绑器、状态库。
- 基础设施/部署:k8s、Helm、Terraform层、定制管道。
证据收集默认:
- 优先直接证据:
package.json脚本、Makefile/justfile、CI配置、Dockerfile、部署清单。 - 追踪一个真实请求路径:输入 -> 验证 -> 核心规则 -> 持久化 -> 输出。
- 记录每个间接点(代码生成边界、框架钩子、配置间接、适配器层)。
2. 定义:决定抽象成本是否过高
将每个抽象分类为:保留 | 包装 | 切片 | 替换 | 删除。
成本信号(代理税):
- 隐藏步骤:代码生成、隐式约定、运行时魔法、反射、装饰器。
- 间接性:行为存在于钩子/中间件/配置而非可编辑代码中。
- 工具重量:慢速安装/构建/测试;大依赖图;多工具编排。
- 非确定性:环境敏感行为、不稳定测试、需要网络的开发循环。
- 变更风险:升级频繁中断;生成差异;脆弱集成。
价值信号(正当理由):
- 硬约束:合规性、多租户隔离、真实规模需求、审计变更控制。
- 已证明重用:多个独立消费者、稳定共享领域规则。
- 操作杠杆:实质性减少值班风险(有证据)。
评分标准(使削减决策机械化):
- 代理税评分(T):0-3
- 0 = 可忽略(直接代码;明显入口点;无额外工具)
- 1 = 轻微(一个额外层;仍可搜索;确定性命令)
- 2 = 高(代码生成/间接性;慢循环;多工具编排)
- 3 = 严重(隐藏魔法;多个生成器;交互/手动步骤;不稳定循环)
- 价值评分(V):0-3(如果无法引用证据,评分0)
- 0 = 未证明/可选(无测试/文档/调用站点/操作证据)
- 1 = 便利性(小DX优势;可以替换而不更改合同)
- 2 = 已证明杠杆(多个消费者;减少错误类;真实操作利益)
- 3 = 强制(合规/法律要求;SLO关键;审计变更控制)
- 差值(D)= T - V
默认裁决映射(激进但不鲁莽):
- D >= 2:替换或删除(如果未使用,优先删除)
- D == 1:现在切片,下次替换(或先包装以隔离)
- D == 0:包装或切片(减少表面积并移除尖锐边缘)
- D == -1:保留,但简化接口/入口点
- D <= -2:保留
定义(裁决):
- 保留:保留抽象;减少附带摩擦(文档、脚本、入口点)。
- 包装:内部保留,但在前面放置稳定适配器以局部化未来移除。
- 切片:移除可选灵活性(插件、多变量配置)到已证明的一个路径。
- 替换:换为较低级原语,带有迁移接缝。
- 删除:完全移除。
激进默认策略:
- 如果价值未证明(测试/文档/调用站点/操作证据),视为可选并推荐减少。
- 如果抽象“为灵活性而存在”但仅使用一个变体,内联到该变体。
- 如果抽象为防重复但增加跳转/工具,优先重复。
3. 开发:提出低级替换
选择替换梯子的下一个较低层次(避免大爆炸重写)。
替换梯子(常见移动):
- 元框架 -> 框架 -> 标准库原语。
- 代码生成 -> 签入工件 + 小确定性生成器(或完全删除)。
- ORM -> 查询构建器 -> 参数化SQL。
- GraphQL -> REST/JSON -> RPC -> 直接函数调用(仅内部)。
- SPA -> 服务器渲染页面 -> 静态HTML/CSS/JS。
- k8s -> Docker Compose -> 单进程 + systemd(或平台原生)。
- 单仓库工具 -> 包管理器工作空间 -> 普通脚本。
- 依赖注入容器 -> 显式构造函数/连线。
- 自定义DSL -> JSON/YAML/TOML 带小解析器 + 模式。
解构模式(代理中心):
- “使不可见可见”:用显式入口点和连线替换约定。
- “折叠配置”:多层 -> 一个规范配置文件(仅在不可避免时添加注释)。
- “删除编排器”:用单个
scripts/dev和scripts/test(或make dev/test)替换工具链。 - “绞杀接缝”:引入稳定适配器边界;在其后实现原语;逐步迁移调用者。
4. 交付:报告发现和建议
默认输出必须包括:
- 抽象审计(表)。
- 削减列表(优先)。
- 迁移计划(分阶段 + 证明信号 + 回滚)。
- 补丁建议(最小切口;文件/命令级别;无实施)。
输出格式(默认)
按顺序使用这些确切章节标题。如果证据缺失,保留标题并写“尚无足够仓库证据。”而非省略章节。
0) 范围 + 假设
- 在范围内表面:…
- 范围外:…
- 发现的约束:…
1) 抽象审计(表) 每抽象一行。
| 抽象 | 位置 | 存在原因(假设) | 代理税(T:0-3 + 原因) | 价值(V:0-3 + 证据) | 差值(D=T-V) | 裁决 | 替换 |
|---|---|---|---|---|---|---|---|
| … | … | … | T:2 - … | V:1 - … | +1 | 保留/包装/切片/替换/删除 | … |
注释:
- “价值”必须引用仓库本地证明:测试/文档/调用站点/操作配置。
- 如果无法引用证据,评分 V:0。
- “裁决”必须是:保留 | 包装 | 切片 | 替换 | 删除 之一。
2) 削减列表(优先)
- P0(先删除):…
- P1:…
- P2:…
每个项目必须包括:预期简化、影响范围、最快证明信号。
3) 迁移计划(每削减项目) 对于每个 P0/P1 项目:
- 接缝/边界:…
- 阶段1(可逆):…
- 阶段2(切换流量/调用者):…
- 阶段3(删除旧路径):…
- 证明信号:…(测试/构建/运行)
- 回滚杠杆:…
4) 补丁建议(最小切口;无代码) 列出具体、可审查的编辑:
- 要添加/修改/删除的文件:…
- 要运行的命令(确定性):…
- “完成”是什么样子(信号):…
5) 风险/限制
- …
替换模式(示例)
- React/SPA 用于小型静态网站 -> HTML/CSS/JS,无构建步骤。
- 无头CMS 用于小型文档/营销 -> Git + Markdown(+ 静态网站生成器,如果确实需要)。
- ORM 用于简单CRUD -> 参数化SQL查询。
- GraphQL 用于单个客户端 -> REST/JSON 端点。
- 状态管理框架 用于小型UI -> 带显式事件处理程序的本地状态。
- 重量级任务运行器 ->
scripts/*或Makefile带 3-5 个规范命令。 - 多层配置系统 -> 一个配置文件 + 小加载器。
问题(仅判断调用)
- 先研究;不要询问可发现事实。
- 仅询问判断调用,优先1个问题,最多3个。
- 可用时使用
request_user_input;否则在短编号块中询问。
好问题(示例):
- “我们可以接受一些短期重复以删除此框架吗(推荐:是)?”
- “添加兼容性包装是否可接受,以便外部调用者保持稳定(推荐:是)?”
- “是否允许更改基础设施,或这严格限于代码级别(推荐:仅代码级别)?”
移交
- 如果权衡仍不清晰,调用
$creative-problem-solver。 - 如果要求实施,转交给
$tk或$code。
陷阱
- 通用建议而无位置/证据。
- 无接缝、证明信号和回滚杠杆的大爆炸重写。
- 移除携带合规/操作义务的抽象(无替换计划)。