
agent-skills /code-simplify 命令实战行为保持不变的代码简化工作流、Skill 底层原理与 Hook 保护机制【免费下载链接】agent-skillsProduction-grade engineering skills for AI coding agents.项目地址: https://gitcode.com/GitHub_Trending/agentskill/agent-skills本文围绕 agent-skills 仓库中的/code-simplify斜杠命令展开完整解析它的 6 步简化流程、所调用的 code-simplification 技能的五条原则与信号模式表并结合simplify-ignoreHook 的块级保护机制和仓库自带评测用例讲清楚如何在不改变行为的前提下降低代码复杂度这一完整工程方案。读完你可以直接在自己的项目里复现这套流程理解保护块原理并掌握简化的验收标准。命令定位一条指向 Skill 的瘦身入口在 agent-skills 中/code-simplify是 9 个覆盖开发生命周期的斜杠命令之一README 的命令总表将其定位为 Simplify the code核心原则是 Clarity over cleverness清晰优于聪明。该命令在 .claude/commands/code-simplify.md 中定义其 frontmatter 声明了命令用途description: Simplify code for clarity and maintainability — reduce complexity without changing behavior命令体本身非常精简——它的本质是一次技能调用Invoke the agent-skills:code-simplification skill然后把执行约束压缩成一条标准工作流。值得注意的是仓库里同时存在两份等价实现.claude/commands/code-simplify.mdClaude Code 原生命令格式约定读取CLAUDE.md了解项目规范commands/code-simplify.toml供其他 Agent 平台使用的 TOML 版本约定读取AGENTS.md。两者 prompt 内容完全对应仅项目约定文件不同。这意味着无论宿主 Agent 是 Claude Code 还是其他支持 AGENTS.md 的工具简化流程的执行标准是一致的。命令的 6 步工作流完整继承命令原文给出的执行序列如下步骤 4 的扫描清单逐条列出读取项目约定Read CLAUDE.md and study project conventions读 CLAUDE.md研究项目规范确定目标范围Identify the target code — recent changes unless a broader scope is specified默认只处理近期改动的代码除非显式指定更大范围先理解再动手Understand the codes purpose, callers, edge cases, and test coverage before touching it动手前搞清代码用途、调用方、边界情况和测试覆盖扫描简化机会六类信号Deep nesting → guard clauses or extracted helpers深嵌套 → 卫语句或抽取辅助函数Long functions → split by responsibility长函数 → 按职责拆分;Nested ternaries → if/else or switch嵌套三元 → if/else 或 switchGeneric names → descriptive names泛化命名 → 描述性命名Duplicated logic → shared functions重复逻辑 → 共享函数Dead code → remove after confirming死代码 → 确认后再删除增量应用Apply each simplification incrementally — run tests after each change每做一处简化就跑一次测试验证结果Verify all tests pass, the build succeeds, and the diff is clean确认全部测试通过、构建成功、diff 干净。命令末尾还给出两条兜底规则简化后测试失败回滚该处改动并重新评估用code-review-and-quality技能对结果做复查。这与 skills/code-review-and-quality/SKILL.md 形成先简化、后审查的组合闭环。底层 Skillcode-simplification 的五条原则命令所调用的 skills/code-simplification/SKILL.md 是该命令的真正知识载体。它开宗明义简化的目标不是减少行数而是让代码更易读、易理解、易修改、易调试。每个简化必须通过一个简单测试——新成员是否能比看原版更快地理解这段代码五条原则如下1. 精确保持行为Preserve Behavior Exactly只改表达方式不改做什么。所有输入、输出、副作用、错误行为和边界情况必须保持一致。每次改动前自问四个问题ASK BEFORE EVERY CHANGE: → Does this produce the same output for every input? → Does this maintain the same error behavior? → Does this preserve the same side effects and ordering? → Do all existing tests still pass without modification?2. 遵循项目约定Follow Project Conventions简化是让代码与代码库更一致而不是强加外部偏好。顺序是读 CLAUDE.md / 项目约定 → 研究邻近代码如何处理同类模式 → 在导入顺序、函数声明风格、命名习惯、错误处理模式、类型标注深度上匹配项目风格。技能原文的判断很犀利Simplification that breaks project consistency is not simplification — its churn.破坏项目一致性的简化不是简化是折腾。3. 清晰优于聪明Prefer Clarity Over Cleverness当紧凑写法需要停下来想一想才能读懂时显式写法更好。SKILL.md 给出两组对比// 不清晰密集三元链 const label isNew ? New : isUpdated ? Updated : isArchived ? Archived : Active; // 清晰可读映射 function getStatusLabel(item: Item): string { if (item.isNew) return New; if (item.isUpdated) return Updated; if (item.isArchived) return Archived; return Active; }// 不清晰链式 reduce 内联逻辑 const result items.reduce((acc, item) ({ ...acc, [item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) 1 } }), {}); // 清晰具名中间步骤 const countById new Mapstring, number(); for (const item of items) { countById.set(item.id, (countById.get(item.id) ?? 0) 1); }4. 保持平衡Maintain Balance简化存在过度简化的失效模式要警惕四个陷阱过度内联删掉了给概念命名的辅助函数、合并无关逻辑两个简单函数合成一个复杂函数不是简化、删除看似多余的抽象有些抽象服务于可扩展性或可测试性、以行数为优化目标行数少不是目标理解容易才是。5. 范围限定在改动处Scope to What Changed默认只简化近期修改的代码除非显式要求扩大范围否则不做顺手重构。无界简化会在 diff 中制造噪音并引入非预期回归。简化信号模式表从模糊味道到具体信号SKILL.md 的 Step 2 把命令里的六类扫描信号扩展成三张可操作的检查表每条都是模式 → 信号 → 简化手段结构复杂度模式信号简化手段深嵌套3 层以上控制流难以跟踪把条件提取为卫语句或辅助函数长函数50 行以上承担多个职责拆分为职责单一的函数并给出描述性命名嵌套三元表达式需要心理压栈才能解析换成 if/else 链、switch 或查找对象布尔参数标志位doThing(true, false, true)换成 options 对象或拆成独立函数重复条件判断同一if检查出现在多处提取为命名良好的谓词函数命名与可读性模式信号简化手段泛化命名data、result、temp、val、item改名为描述内容的名字userProfile、validationErrors缩写命名usr、cfg、btn、evt用完整词除非缩写是通用的id、url、api误导性命名名为get的函数却修改状态改名以反映真实行为解释是什么的注释// increment counter上面写着count删除注释——代码已经够清楚解释为什么的注释// Retry because the API is flaky under load保留——它们承载代码无法表达的意图冗余模式信号简化手段重复逻辑相同的 5 行以上代码出现在多处提取为共享函数死代码不可达分支、未用变量、注释掉的代码块确认确已无用后删除无价值抽象没有增加任何价值的包装层内联包装直接调用底层函数过度设计模式工厂的工厂、只有一个实现的策略换成简单直接的写法多余类型断言断言到已被推断出的类型删除断言执行过程Chestertons Fence 到 500 行法则Step 1先理解再触碰Chestertons Fence切斯特顿栅栏改任何东西之前先弄清它为什么存在——如果在路上看到一道栅栏而不知道它为何立在那儿先别拆先理解原因再判断原因是否仍然成立。动手前必须能回答这段代码的职责是什么谁调用它、它调用谁边界情况和错误路径有哪些有没有测试定义了预期行为为什么当年写成这样性能平台限制历史原因git blame给出的原始上下文是什么答不上来说明还没准备好简化。Step 3增量应用与 500 行法则一次只做一处简化每改一处跑一次测试FOR EACH SIMPLIFICATION: 1. Make the change 2. Run the test suite 3. If tests pass → commit (or continue to next simplification) 4. If tests fail → revert and reconsider重构改动要与功能/修 bug 改动分开提交——一个既重构又加功能的 PR 其实是两个 PR拆开来。技能还给出了Rule of 500如果一次重构要动 500 行以上应投资自动化手段codemods、sed 脚本、AST 转换而不是手工改——那个规模下手改既易错又让评审者疲惫。Step 4整体验证全部简化完成后退后一步对比前后简化版是否真的更易理解是否引入了与代码库不一致的新模式diff 是否干净可评审同事是否会给这次改动点赞如果简化后反而更难读或更难评审——回滚。不是每次简化尝试都能成功。语言级简化案例SKILL.md 附带了 TypeScript/JavaScript、Python、React/JSX 三组Before/After对照覆盖最典型的简化场景TypeScript / JavaScript四个场景// 无必要的 async 包装去掉 async/await 直接返回 Promise async function getUser(id: string): PromiseUser { return await userService.findById(id); } // → function getUser(id: string): PromiseUser { return userService.findById(id); } // 啰嗦的条件赋值 let displayName: string; if (user.nickname) { displayName user.nickname; } else { displayName user.fullName; } // → const displayName user.nickname || user.fullName; // 手工构建数组 const activeUsers: User[] []; for (const user of users) { if (user.isActive) { activeUsers.push(user); } } // → const activeUsers users.filter((user) user.isActive); // 冗余的布尔返回 function isValid(input: string): boolean { if (input.length 0 input.length 100) { return true; } return false; } // → function isValid(input: string): boolean { return input.length 0 input.length 100; }Python两个场景字典推导替代手工建字典三层嵌套条件改为卫语句 提前抛错# Before嵌套条件 def process(data): if data is not None: if data.is_valid(): if data.has_permission(): return do_work(data) else: raise PermissionError(No permission) else: raise ValueError(Invalid data) else: raise TypeError(Data is None) # After卫语句 def process(data): if data is None: raise TypeError(Data is None) if not data.is_valid(): raise ValueError(Invalid data) if not data.has_permission(): raise PermissionError(No permission) return do_work(data)React / JSX条件渲染提炼出variant/label局部变量// After function UserBadge({ user }: Props) { const variant user.isAdmin ? admin : default; const label user.isAdmin ? Admin : User; return Badge variant{variant}{label}/Badge; }对于 prop drilling 这类判断题技能明确要求标记它、交给人判断不要自动重构。实战增强simplify-ignore Hook 的块级保护机制命令工作流默认近期改动范围但仓库还提供了一层更硬核的保护机制hooks/simplify-ignore.sh hooks/SIMPLIFY-IGNORE.md。它的思路是让受保护代码块对模型完全不可见——不是靠提示词劝说模型别动而是从数据层面把代码藏起来。标注语法用一对标记包裹不允许被简化的代码块可以带理由会出现在占位符里/* simplify-ignore-start: perf-critical */ // manually unrolled XOR — 3x faster than a loop result[0] buf[0] ^ key[0]; result[1] buf[1] ^ key[1]; result[2] buf[2] ^ key[2]; result[3] buf[3] ^ key[3]; /* simplify-ignore-end */任意注释风格都支持//、/*、#、!--占位符会保留原注释语法Python 里是# BLOCK_xxxHTML 里是!-- BLOCK_xxx --。Hook 注册在.claude/settings.json中把同一脚本挂到三个事件上{ hooks: { PreToolUse: [ { matcher: Read, hooks: [{ type: command, command: bash \${CLAUDE_PROJECT_DIR}/hooks/simplify-ignore.sh\ }] } ], PostToolUse: [ { matcher: Edit|Write, hooks: [{ type: command, command: bash \${CLAUDE_PROJECT_DIR}/hooks/simplify-ignore.sh\ }] } ], Stop: [ { hooks: [{ type: command, command: bash \${CLAUDE_PROJECT_DIR}/hooks/simplify-ignore.sh\ }] } ] } }三个事件各做什么事件动作PreToolUse Read备份文件把保护块原地替换为BLOCK_hash占位符PostToolUse Edit\|Write把占位符展开回真实代码、保存模型改动、再重新过滤Stop会话结束时从备份恢复所有文件从源码结构看hooks/simplify-ignore.sh关键实现细节有三点filter_file函数第 59–142 行逐行扫描simplify-ignore-start/-end标记把块内容按 8 位十六进制哈希shasum/sha1sum自动检测block_hash函数取前 8 位存入.claude/.simplify-ignore-cache/磁盘文件里只留下形如/* BLOCK_de115a1d: perf-critical */的占位符。每个块的内容哈希保证了即使模型复制或重排占位符往返展开也是无歧义的脚本用mkdir实现原子锁防止并发会话竞争第 189–199 行并用cat file写回以保留 inode 与权限第 205–209 行PostToolUse 阶段的展开是渐进式回退匹配完整占位符 → 前缀哈希后缀 → 仅哈希。若模型改动了占位符格式会打印警告并使用模糊匹配第 246–261 行如果模型把受保护块整个删掉脚本会输出Warning: protected block BLOCK_xxx was deleted by model第 282 行。依赖与已知限制需要jq、shasum/sha1sum、Bash 3.2。文档列出的限制值得注意单行块会隐藏整行注释闭合符识别只覆盖*/和--ERB/Blade 等非标准注释可能产生不平衡占位符模型通过 shell 命令重命名文件时新文件会残留占位符原始代码会存为old-filename.recovered需要手工恢复。缓存目录.claude/.simplify-ignore-cache/应加入.gitignore。若会话崩溃导致 Stop hook 未触发可用一条命令手动恢复echo {} | bash hooks/simplify-ignore.sh这套机制与命令流程的Dead code → remove after confirming形成互补确认过不该动的代码直接交给 Hook 做硬隔离。评测体系触发边界与验收标准仓库为这个技能配了自动化评测 evals/cases/code-simplification.json可以从中看到/code-simplify的触发边界和输出验收标准触发判定——三条正向 prompt 都应该命中该技能This function works but it is way too clever, simplify it without changing behaviorReduce the complexity of this module so juniors can maintain itClean up this working code, it has grown hard to follow两条负向 prompt 不应命中Add a feature flag system to the app新功能需求以及 Diagnose why the build broke overnight该归debugging-and-error-recovery技能所有。行为评测——针对一个 80 行的配置解析函数要求保持精确行为地简化期望输出是行为完全一致的更简实现 删除了什么及为何安全的说明验收点有四条Behavior is preserved测试不改仍通过或给出具体的等价性论证Complexity is reduced rather than relocated复杂度被消除而非被搬走回复解释了删除了什么、为什么安全简化过程中不引入任何新功能。评测用的真实夹具就是 evals/fixtures/code-simplification/config-parser.js——一个 46 行的parseConfig典型地呈现了命令要处理的症状for循环里 5–6 层嵌套空行 → 注释 → 节头 → 键值分离 → 类型推断值类型推断用了一长串if/else if链。配套的 config-parser.test.js 用node:testnode:assert/strict锁定了节解析、注释忽略、默认节和字符串/布尔/数值类型推断等行为。对照信号表可以直接规划简化路径把行前过滤跳过空行/注释和值类型推断提取为辅助函数、用卫语句压平嵌套——同时因为行为契约被测试钉死每一步都能立刻验证。常见借口反驳与红旗清单SKILL.md 用一张借口 vs 现实表拆掉了七种最常见的自我开脱值得在评审时直接引用借口现实能跑就不用动难读的代码在坏掉时同样难修现在简化是在给未来每次改动省时间行数少一定更简单1 行嵌套三元不比 5 行 if/else 简单简单关乎理解速度而非行数顺手把这段无关代码也简化了无界简化制造噪音 diff 并带来回归风险聚焦当前范围有类型就不用文档化了类型描述结构而非意图命名良好的函数比类型签名更能解释为什么这个抽象以后可能有用别保留投机性抽象现在没用就是无价值复杂度删了需要时再加原作者一定有他的理由也许。查 git blame、套切斯特顿栅栏但累积复杂度往往没理由只是时间压力下迭代的残留加功能的时候顺手重构重构与功能工作分离混合变更更难评审、回滚和理解与命令测试失败就回滚对应的红旗清单出现即说明简化出了错简化后需要修改测试才能通过很可能改了行为简化后的代码比原版更长更难跟按个人口味而非项目约定改名以更干净为由删除错误处理;简化自己并不完全理解的代码把大量简化塞进一个难以评审的大 commit未经要求重构任务范围之外的代码。验收清单一次简化收尾时逐项核对把 SKILL.md 的 Verification 清单作为/code-simplify的最终门禁与命令第 6 步verify对应所有既有测试无需修改即通过构建成功且无新警告Linter/Formatter 通过无风格回归每处简化都是可评审的增量改动diff 干净——没有混入无关变更简化后的代码符合项目约定对照 CLAUDE.md 或等价文件没有删除或削弱错误处理没有遗留死代码未用导入、不可达分支团队成员或评审 Agent 会认可这是一个净改进小结这套方案的三层结构/code-simplify的完整能力可以归纳为三层流程层.claude/commands/code-simplify.md6 步约束——读约定、定范围、先理解、扫信号、增量改、验结果失败即回滚知识层skills/code-simplification/SKILL.md五条原则 三张信号表 语言级案例 借口反驳保证简化有统一判据而非凭感觉保护层与验证层hooks/simplify-ignore.sh、evals/cases/code-simplification.jsonsimplify-ignore标注块让性能敏感等禁止简化代码对模型不可见评测用例则把触发边界和行为保持验收标准自动化。复用到自己的项目时最小路径是安装 skill 与命令 → 在CLAUDE.md/AGENTS.md写清风格约定命令第 1 步依赖它→ 对确实不能动的代码块加simplify-ignore标注并配置三个 Hook 事件 → 把.claude/.simplify-ignore-cache/加入.gitignore。之后每次/code-simplify都会在行为不变的硬约束下把复杂度降下来并用测试作为每一步的保险丝。【免费下载链接】agent-skillsProduction-grade engineering skills for AI coding agents.项目地址: https://gitcode.com/GitHub_Trending/agentskill/agent-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考