clean-ai-slop

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AI Slop Cleaner

AI Slop Cleaner

A corrective discipline for cleaning AI-generated code. Runs after code generation — whether from
run-plan
, a manual session, or any other source.
The core problem: LLMs produce code that works but carries distinctive smells. Over-commenting, unnecessary abstractions, defensive paranoia for impossible scenarios, verbose naming. Left unchecked, these accumulate into a codebase that is harder to read and maintain than hand-written code.
This skill removes those smells systematically, one category at a time, without changing behavior.
一套用于清理AI生成代码的修正规范,在代码生成完成后运行,无论代码来自
run-plan
、手动会话还是任何其他来源。
核心问题:LLM生成的代码虽然可以运行,但会带有明显的异味:过度注释、不必要的抽象、对不可能出现的场景做过度防御校验、命名过于冗长。如果放任不管,这些问题会逐步累积,最终导致代码库比手写代码更难阅读和维护。
本工具可以系统性地逐类移除这些代码异味,同时不会改动代码原有行为。

Hard Gates

硬性规则

These rules have no exceptions.
  1. Lock behavior before cleaning. Run existing tests. If coverage is insufficient, add regression tests for the code you're about to touch. No test coverage, no cleanup.
  2. One smell category per pass. Do not mix dead code removal with naming fixes. Complete one pass, verify, then start the next.
  3. Run tests after every pass. If tests fail, revert the pass and investigate. Do not proceed to the next category.
  4. Stay in scope. Only touch files that were generated or modified by AI. Do not expand into "nearby" code that looks like it could use improvement.
  5. Preserve behavior exactly. If a cleanup changes observable behavior — even if you think the new behavior is "better" — revert it. Behavior changes require a separate task.
以下规则没有任何例外:
  1. 清理前先锁定代码行为。运行现有测试,如果测试覆盖度不足,需要先为待清理的代码补充回归测试。没有测试覆盖就不能进行清理。
  2. 每次清理只处理一类代码异味。不要同时清理死代码和修复命名问题,完成一类清理、验证通过后再开始下一类。
  3. 每轮清理后都要运行测试。如果测试失败,回滚本轮改动并排查问题,不要继续处理下一类异味。
  4. 严格限定清理范围。只处理AI生成或修改的文件,不要扩展到看起来也需要优化的「邻近」代码。
  5. 完全保留原有行为。如果某步清理改动了可观测的代码行为——哪怕你认为新行为「更好」——也要回滚改动。行为修改需要走单独的任务流程。

When To Use

适用场景

  • After
    run-plan
    completes and the implementation works but reads like AI wrote it
  • After any significant code generation session
  • When reviewing AI-generated PRs
  • When the user explicitly asks to clean up or deslop code
  • run-plan
    执行完成后,实现功能可用但明显是AI生成的代码风格
  • 任何大型代码生成会话结束后
  • 评审AI生成的PR时
  • 用户明确要求清理或去除代码冗余时

When NOT To Use

不适用场景

  • Code that was written by humans (different smells, different treatment)
  • When tests don't exist and can't be added quickly (lock behavior first)
  • Mid-implementation — finish the feature, then clean
  • 人类手写的代码(异味类型不同,处理方式也不同)
  • 没有测试且无法快速补充测试的代码(先锁定代码行为再清理)
  • 功能实现中途:先完成功能开发,再进行清理

Smell Categories

异味分类

Passes execute in this order. Each pass completes fully before the next begins.
清理按以下顺序执行,每轮清理完全完成后再开始下一轮。

Pass 1: Dead Code

第1轮:死代码

Remove code that serves no purpose.
  • Unused imports
  • Unused variables and parameters
  • Unreachable branches
  • Commented-out code blocks
  • Empty error handlers that swallow exceptions
Detection: compiler warnings, linter output, IDE grayed-out symbols. Trust the tooling.
移除没有任何作用的代码:
  • 未使用的导入
  • 未使用的变量和参数
  • 不可达的分支
  • 注释掉的代码块
  • 吞掉异常的空错误处理函数
识别方式:编译器警告、linter输出、IDE灰显的符号,信任工具的检测结果。

Pass 2: Over-Commenting

第2轮:过度注释

Remove comments that restate what the code already says.
Targets:
  • // Initialize the counter
    above
    let counter = 0
  • // Return the result
    above
    return result
  • JSDoc that repeats the function signature with no additional insight
  • Section dividers that add no information (
    // --- Helper Functions ---
    )
  • File headers that describe what is obvious from the filename
Keep: comments that explain why, not what. Comments about non-obvious constraints. Links to external documentation or issues.
移除只是重复代码本身含义的注释
清理目标:
  • let counter = 0
    上方的
    // 初始化计数器
    注释
  • return result
    上方的
    // 返回结果
    注释
  • 只是重复函数签名、没有额外信息的JSDoc
  • 没有任何信息增量的分割线(比如
    // --- 辅助函数 ---
  • 从文件名就能明显看出含义的文件头注释
保留:解释「为什么这么做」而非「做了什么」的注释、非明显约束的说明、外部文档或Issue的链接。

Pass 3: Unnecessary Abstractions

第3轮:不必要的抽象

Remove indirection that serves no purpose.
Targets:
  • Helper functions called exactly once (inline them)
  • Wrapper classes that delegate everything to one inner object
  • Configuration objects for things that will never be configured
  • Factory functions that always produce the same thing
  • Interface/type definitions used by a single implementation with no plans for more
Test: if removing the abstraction makes the code shorter and equally readable, it was unnecessary.
移除没有任何作用的间接层
清理目标:
  • 只被调用过一次的辅助函数(直接内联)
  • 所有逻辑都委托给单个内部对象的包装类
  • 永远不会被修改的配置对象
  • 永远返回相同结果的工厂函数
  • 只被一个实现使用、且没有扩展计划的接口/类型定义
判断标准:如果移除抽象后代码更短且可读性不变,说明这个抽象是不必要的。

Pass 4: Defensive Paranoia

第4轮:过度防御校验

Remove error handling for scenarios that cannot occur.
Targets:
  • Null checks on values that are guaranteed non-null by the type system
  • Try-catch blocks around code that cannot throw
  • Validation of internal function parameters (validate at system boundaries only)
  • Fallback values for required fields
  • Redundant type assertions
Keep: validation at system boundaries (user input, external APIs, file I/O). Error handling where the runtime genuinely can fail.
移除对不可能出现的场景的错误处理
清理目标:
  • 类型系统已经保证非空的值的空值校验
  • 包裹不可能抛出异常的代码的try-catch块
  • 内部函数参数的校验(只在系统边界做校验即可)
  • 必选字段的兜底值
  • 冗余的类型断言
保留:系统边界的校验(用户输入、外部API、文件I/O)、运行时确实可能失败的场景的错误处理。

Pass 5: Verbose Naming

第5轮:冗长命名

Shorten names that carry redundant information.
Targets:
  • getUserDataFromDatabase
    getUser
    (where else would it come from?)
  • userAccountStatus
    status
    (when used inside a
    User
    class, the prefix is redundant)
  • handleButtonClickEvent
    onClick
  • responseDataObject
    response
  • tempVariableForCalculation
    temp
    or inline it
Rule: a name should be as short as possible while remaining unambiguous in its scope. Longer scope = longer name. Short scope = short name.
简化带有冗余信息的命名
清理目标:
  • getUserDataFromDatabase
    getUser
    (除此之外还能从哪里取?)
  • userAccountStatus
    status
    (在
    User
    类内部使用时,前缀是冗余的)
  • handleButtonClickEvent
    onClick
  • responseDataObject
    response
  • tempVariableForCalculation
    temp
    或者直接内联
规则:命名应该在作用域内无歧义的前提下尽可能短,作用域越长命名可以越长,作用域越短命名越短。

Pass 6: LLM Filler

第6轮:LLM生成冗余内容

Remove artifacts of LLM generation style.
Targets:
  • Emoji in code, comments, or commit messages (unless the project uses them intentionally)
  • Conversational tone in comments ("Let's", "Now we need to", "Great!")
  • Excessive
    console.log
    /
    print
    statements added "for debugging"
  • Redundant type annotations where inference handles it
  • Overly structured code that follows a template pattern rather than the natural shape of the problem
移除LLM生成风格的遗留产物
清理目标:
  • 代码、注释、提交信息里的emoji(除非项目有意规范使用)
  • 口语化的注释(比如「我们来」、「现在我们需要」、「太棒了!」)
  • 「为了调试」添加的过多
    console.log
    /
    print
    语句
  • 类型推断可以覆盖的冗余类型注解
  • 生搬模板模式、不符合问题本身自然结构的过度结构化代码

Process

执行流程

text
1. Identify scope (which files to clean)
2. Run existing tests — all must pass before starting
3. Add regression tests if coverage is thin
4. Execute Pass 1 → verify → commit
5. Execute Pass 2 → verify → commit
6. ... continue through all relevant passes
7. Run full test suite
8. Report summary of changes
Not every pass applies to every codebase. Skip passes that have zero findings. But execute in order — never jump ahead.
text
1. Identify scope (which files to clean)
2. Run existing tests — all must pass before starting
3. Add regression tests if coverage is thin
4. Execute Pass 1 → verify → commit
5. Execute Pass 2 → verify → commit
6. ... continue through all relevant passes
7. Run full test suite
8. Report summary of changes
不是所有轮次都适用于每个代码库,没有对应问题的轮次可以跳过,但必须按顺序执行,不能跳步。

Anti-Patterns

反模式

ImpulseWhy It Fails
"I'll clean everything in one big pass"Mixed changes are impossible to debug when tests break
"This abstraction is bad, let me redesign it"Redesign is a separate task, not cleanup
"Tests pass, so I'll skip the per-pass verification"A later pass may interact with an earlier change
"This code nearby also looks sloppy"Scope creep. Only clean what's in scope
"The behavior is wrong anyway, I'll fix it while cleaning"Behavior changes require their own task with their own tests
"I don't need regression tests, the code is simple"Simple code breaks too. Lock behavior first
错误想法失败原因
「我要一次性把所有问题都清完」混合改动在测试失败时根本无法调试
「这个抽象写得不好,我来重新设计下」重设计是单独的任务,不属于清理范畴
「测试都通过了,我就跳过每轮后的校验吧」后面轮次的改动可能和前面的改动产生冲突
「附近的代码看起来也很乱,顺便清了」范围蔓延,只清理限定范围内的代码
「反正原有行为也是错的,我清理的时候顺便改了」行为修改需要走单独的任务流程,配套单独的测试
「代码很简单,我不需要补充回归测试」简单代码也会出问题,先锁定代码行为

Red Flags

危险信号

Stop and reconsider if you catch yourself thinking:
  • "This is taking too long, let me batch the remaining passes"
  • "I'll just quickly fix this other file too"
  • "The tests are probably fine, I don't need to run them again"
  • "This behavior should be different anyway"
  • "I don't need tests for this — it's just removing comments"
如果你发现自己有以下想法,请停下来重新考量:
  • 「这太慢了,我把剩下的轮次合并处理吧」
  • 「我就顺便快速改下另一个文件」
  • 「测试应该没问题,我不用再跑一遍了」
  • 「反正这个行为本来就应该改」
  • 「我只是删点注释而已,不需要测试」

Completion Standard

完成标准

Cleanup is done when:
  • All applicable passes have been executed in order
  • Tests passed after every individual pass
  • Full test suite passes at the end
  • No behavior has changed
  • Changes are scoped to the identified files only
If any of these are not met, the cleanup is not complete.
满足以下条件时清理才算完成:
  • 所有适用的清理轮次都按顺序执行完毕
  • 每轮清理后测试都通过
  • 最终全量测试套件运行通过
  • 没有改动任何原有行为
  • 改动只限定在指定的文件范围内
只要有任意一条不满足,清理就没有完成。

Minimal Checklist

最简检查清单

During cleanup, verify against this list:
  • Behavior is locked with tests before starting
  • Current pass targets one smell category only
  • Tests passed after the current pass
  • No files outside the defined scope were touched
  • No behavior was changed
清理过程中,请对照以下清单校验:
  • 清理前已经通过测试锁定了代码行为
  • 当前轮次只处理一类代码异味
  • 当前轮次完成后测试运行通过
  • 没有改动限定范围外的任何文件
  • 没有改动任何原有行为

Transition

后续动作

After cleanup is complete:
  • If the code was generated by
    run-plan
    → report results to the user
  • If implementation discipline was lacking during generation → consider applying
    karpathy
    in future sessions to prevent slop at the source
清理完成后:
  • 如果代码是由
    run-plan
    生成的 → 向用户上报清理结果
  • 如果生成过程中缺少实现规范 → 后续会话可以考虑使用
    karpathy
    规范从源头避免生成冗余代码