Claude Code开源:用code-simplifier提示词根治AI生成的屎山代码 刚开始用AI写代码那会儿我确实爽了几天——几句话就能出一套完整接口半天能顶过去一周的活。但三个月之后我开始为自己的天真还债一个订单状态字段要改动顺着调用链翻到凌晨两点每一层都在“好像有用但不知道干嘛”的边缘试探注释永远在撒谎逻辑永远有第三条路。我当时在群里喷了一句“AI不是在帮你写代码是在帮你批量生产屎山。”所以这次Claude Code官方开源的消息出来我比谁都上心。装完之后真正让我留下印象的不是它写代码的能力而是一套配套开源出来的提示词工作流叫code-simplifier。一句话说清楚它的作用它不帮AI写更多代码它逼着AI删掉不该存在的代码专门治AI自己吐出来的那堆屎山。这篇文章不吹不黑把我这几个月实测下来的经验全部拆开——包括完整的提示词文本、Claude Code的环境准备、以及一套我自己验证过的简化流程。你直接复制走就能开工。1. 为什么AI越写代码屎山越高先认清病根再谈解药先别急着拿提示词去删代码我们得先理解AI是怎么把代码写成一坨的。你不看清病根给你再好的工具到了第二天它还是会继续长回来。1.1 AI的努力方向跟人类维护者完全相反人写代码目标函数里天然带着“可维护性”这个权重——因为三个月后你自己要回来改。但AI不一样它在生成代码时真正想优化的是“在当前的对话上下文里让代码看起来能工作、且看起来专业”。这里面有个致命的东西叫局部最优。大模型看到的是你贴给它的这段函数、这个文件它的视野里没有整个系统的历史包袱。于是当它发现“如果用户不是管理员、而且金额超过一万、而且没有审批人、而且重试次数大于零”它最稳妥的做法是再加一个if分支而根本不去想这个分支是不是早就被上层逻辑拦截了。你想想你干过多少次这种事凌晨三点线上出了个偶发bug你看着AI补了一行防御式判断表面上稳了三个月后变成了没人敢删的“历史遗留保护逻辑”。屎山就是这么一层一层叠出来的——不是某一次的重写导致的是每一次“加一点保险”叠出来的。1.2 屎山的三张典型面孔我把AI生成的屎山代码归纳成三类你在公司里随便找个接口都能对号入座重复分派层层转手。一个请求进来先过validate再过normalize再过checkPermission每层都做一次字典拷贝每层都返回一个新类型最后真正的业务逻辑只剩下三行。AI尤其喜欢这么干因为它觉得“分层”就是专业。过度防御处处设防。if config is None: config {}、if not payload.get(x): return None、try: ... except: pass看起来健壮实际上把所有错误都吞掉出了问题你连日志都查不到。预留扩展自作多情。定义了一个AbstractPaymentProvider下面只有唯一一个AlipayProvider实现工厂函数里再套一层映射表——因为AI觉得你“以后可能会接入微信支付”。问题是没有第二家支付通道的时候这套抽象就是纯负债。1.3 屎山的加速度效应最麻烦的不是单段代码脏而是屎山会指数生长。当项目里有30%的代码没人能说清作用时AI每次基于这些混乱代码做增量修改都会吸收混乱并把混乱放大——它不敢删只能叠叠了之后下一轮修改的上下文又被劣化于是越到后面每次改动的成本越高。我见过一个项目一年前还很清爽接入AI辅助之后代码量翻了4倍接口路由从400行涨到6000行但功能几乎没有新增。老板问我为什么效率反而更低了我说因为你们一直在给一栋烂尾楼加装修。所以AI屎山问题的解药不在于换一个更聪明的模型而在于换一套强制简化的工作流。你堵不住AI生产屎山但你可以定期派人去拆。2. code-simplifier是什么它治的不是代码风格而是决策质量如果只是“帮我优化代码”这种提示词市面上早就泛滥了它解决不了问题——因为AI会老老实实地把命名改漂亮、把函数拆得更碎、把注释补得更全整段代码看起来清爽了实际上依然是屎山只是换了层皮。code-simplifier的思路不一样它的核心不是“美化代码”而是逼着AI对每一行代码做存在性论证。2.1 它是一套“带删除权”的重构协议我把它理解成一个协议不太把它当成一段普通提示词。协议包含四层先读后改AI必须先用自然语言复述这段代码的职责证明它真的看懂了而不是上来就动手。遍历审判对每一处可疑代码AI必须做出归类判断——属于“用户需求”“系统约束”“历史遗留”还是“可消除”。有权删除但必须举证删的时候要用表格说明“为什么删、删了之后业务语义哪里变了、哪里没变”。验收建议最后AI必须给出验证方法让你跑测试或命令确认行为没有被偷偷改掉。这听起来都是很简单的步骤但叠加在一起产生了一个很有意思的效果AI终于产生了“沉默成本意识”。普通重构提示词下AI看到前人的代码会觉得“既然写了可能有用”于是保留。但在code-simplifier的压力下它必须先回答“这段代码在当前调用方手里真的会走得到吗”回答不出来就按可消除处理——删除。2.2 跟普通重构提示词的本质区别有一个很直观的对比日常指令“重构这个函数提高可读性。”——AI会改格式、拆函数、改名改动量巨大但逻辑复杂度一点没降。普通优化“去掉重复代码。”——AI会合并几个看起来像的分支但遇到稍微绕一点的逻辑就装看不见。code-simplifier“列出这个函数里三个不需要存在的分支并证明它们在当前调用路径上不可能到达。”看到了吗前两种是让AI“做优化”最后一种是让AI“做审计”。审计姿态下的AI才会暴露它真正的判断力。2.3 它相当于给AI配了一位“不留情面的技术主管”我做过一个类比团队里写代码时最怕什么最怕没有人敢说“这段代码可以删”。开发太多都不敢动别人的逻辑最后堆成屎山。code-simplifier扮演的就是那位刚入职三个月、不知天高地厚、看见冗余代码就下手删的年轻人——而提示词里的种种限制就是防止这个年轻人把核心业务逻辑也一起删掉的缰绳。所以它解决的核心问题不是风格而是决策质量。它要让AI把“我觉得这代码可能有历史原因”这种模糊感觉转变成“这段代码在这里就是冗余”的可查验结论。3. Claude Code环境准备从安装到跑通一次简化会话code-simplifier只是一个提示词它跑在有执行能力的AI编程工具上。我这里用的载体是Claude Code。标题里说了官方开源实际上你在终端里跑起来之后它就是那个能读你项目、改你文件、执行命令的agent。准备环境这一步不算难但有几个坑经常翻车我一并给你排掉。3.1 安装Claude Code的两种方式最主流的是通过npm全局安装npm install -g anthropic-ai/claude-code装完之后在终端里执行claude 101 初始化会引导你走一遍登录流程本质上是帮你拿到访问凭证之后的会话就统一走这个身份。如果你所在团队用的是企业方案走对应的登录入口即可流程上大同小异。 如果你不想全局安装也可以在项目目录里局部安装然后用npx调用 bash npm init -y npm install anthropic-ai/claude-code npx claude局部安装的好处是版本跟项目锁在一起多人协作的时候不会因为版本各不同导致行为不一致。我自己的习惯是全局装一份日常用关键项目再锁一份局部版本。3.2 配合VS Code使用把交互搬进编辑器里很多人不习惯在纯终端里干活其实Claude Code跟VS Code配合起来非常顺。打开VS Code的集成终端直接敲claude它就能以工作目录为上下文开始工作——读取项目结构、查看文件内容、执行测试命令都在同一个窗口里完成。进入之后建议第一时间把这两个配置说清楚不然后面容易乱--model参数可以在启动时指定具体模型版本按你自己订阅的实际权限填不确定就拿默认值。权限设置在我的项目里我会先让它只读、不允许自动改文件claude --permission-mode plan这个模式意味着AI只做分析和规划不会主动改文件。打算用code-simplifier做重构之前我先在plan模式里让它跑一遍全量审判把该删的代码列成清单我看过没问题再切换成全权限模式让它动手。这个习惯大概能帮你躲掉一半的翻车事故。3.3 跑code-simplifier之前的三个项目准备环境装好了还没完。因为简化代码本质上是高危重构你得先把场地清理干净第一先把改动区变干净拉起一条独立分支。别在有未提交改动的工作区里跑重构AI不知道哪些改动是你刚写的新功能它可能顺手把你的新功能当成“历史遗留”删了。第二确保这个模块有测试兜底至少要能编译通过。没有任何测试的项目跑简化AI删错了你也毫无知觉直到线上出问题。没有测试的老模块我建议先在plan模式里让AI根据现有行为把测试骨架补出来再进入正式简化。第三把简化范围限制在一个文件或一个函数。Claude Code虽然能读整个项目但你得防着它“顺手牵羊”。在提示词里明确指定路径比如“只处理src/services/order_service.py中的process_order函数”这能避免AI越改越high最后给你重写了整个架构。4. 附赠提示词我实测三个月的code-simplifier完整版本提示词这东西网上很多版本是抄来抄去没实测过。下面这版是我自己迭代出来的改了很多轮目前在公司内部用了三个月处理过支付模块、订单状态机、权限校验层效果稳定。你可以直接复制走按自己的项目微调。4.1 完整提示词全文你是一名在大型软件团队里干了十年重构的代码审计专家现在的工作是简化指定代码而不是美化代码。 请严格按以下流程执行 第一步通读目标代码用不超过三句话说明它的核心职责。如果无法清晰说明请直接告诉我“这段代码职责混乱需要先补充业务文档”不要强行动手。 第二步逐段审查代码找出以下类型的问题并在回答中逐一列出 - 重复分派多层函数只是把参数转来转去没有新增行为 - 防御式编程为了不存在的异常场景加的 if 判断、空值保护、默认值兜底 - 无效中间变量只赋值一次且只传给下一个函数的变量 - 冗余状态标记被多次重复计算或写入的状态字段 - 伪扩展点只有一种实现却抽象成接口/工厂且没有第二个落地场景 - 死代码没有任何调用链能触达的分支或函数。 第三步在删除任何一行之前必须对这行代码做出归类。归类只能是以下四类之一 - 用户需求业务上明确要求的行为必须保留 - 系统约束框架、协议、依赖库强制的调用方式必须保留 - 历史遗留曾经有用但现在没有触发路径可以删除 - 可消除当前实现方式欠佳可以换一种等价但更简单的写法。 第四步重写代码。重写时遵循三条铁律 1. 保持所有公开函数的签名完全不变 2. 保持所有函数返回值的数据结构语义不变 3. 不得新增任何依赖包不得引入设计模式。 第五步输出一张“改动对照表”包含改动类型、删除/改动位置、归类、删除理由、行为影响。 第六步最后给出三条回归验证建议说明我运行哪些命令或调用哪些函数能确认行为没有被破坏。 禁止的事项 - 禁止为了对称性重排代码 - 禁止给变量批量改名除非变量名在误导人 - 禁止把多个函数合并成一个“更优雅”但更长的函数 - 禁止在回答中使用“可能”“大概”“建议保留”这类含糊表达你必须给出明确判断。4.2 这段提示词每一个段落都在防什么你可能觉得这提示词太长了又是六步又是四个禁止有必要吗有。我给你拆一下**“先复述职责”**是防AI没读懂就瞎改。我实测过去掉这一步AI有30%的概率把核心逻辑理解反。让它先复述、先说人话等于强制它进入思考状态。五个问题类型是界定简化的目标不是笼统的“可读性”而是可落地的六类病灶。AI对大而化之的指令不会抽丝剥茧但给了明确类型清单它就能一项项对号入座。四类存档归类是整个提示词的关键点。这一步是在强制AI做判断无论是if分支还是中间变量必须归档到“用户需求”“系统约束”“历史遗留”“可消除”其中之一。一旦归类必须明确AI就没法用模糊话术蒙混过关。第六步回归建议是防AI甩手不管。很多提示词让AI重构完就完事了它根本不在乎你会不会上线翻车。这里强制它给验证方案你拿到提示词输出后哪怕一条不跑心里也清楚该重点盯哪里。4.3 什么时候用它什么时候千万冷静code-simplifier不是万能药用错场景等于伤筋动骨。我自己的使用边界是这样的适合用老模块重构前期快速摸清底细AI刚生成的一批新代码做上线前清理接手同事离职留下的混乱代码时做地毯式排查。不适合用项目没有任何自动化测试而且编译都过不去——这种情况先补测试别急着简化改了公开接口就等于要动所有调用方——这不是简化是重构SDK公司核心交易链路上正在线上大促的关键模块——你要简化也得避开高峰期一步步来。5. 实测实录把一团乱麻的AI代码简化成能进生产的样子光讲理论没用我拿一段真实风格的后端代码来演示。这段代码是AI生成的订单处理伪代码你第一眼看可能觉得“还能这样写太假了”但实际生产里类似结构到处都是。5.1 一段典型的AI屎山代码def process_order(order, user, inventory, configNone, retry_count0, **kwargs): order_id order.get(id) status pending if not order_id: raise ValueError(missing order id) if user.get(is_admin) and config and config.get(skip_validation): status approved elif not user.get(is_admin): if order.get(amount, 0) 10000: if not order.get(approved_by): raise PermissionError(large order needs approver) if retry_count 0: status pending else: status processing else: status approved if not inventory or inventory.get(stock) is None: stock_info {available: True, source: unknown} else: stock_info {available: inventory[stock] 0, source: db} if status pending and stock_info[available]: status processing try: result _place_order(order_id, status) except Exception as e: if retry_count 3: result process_order(order, user, inventory, config, retry_count 1) else: raise e return {order_id: order_id, status: status, retries: retry_count}这段代码的问题在哪里表层看是逻辑绕深层看是AI在用retry_count实现递归重试——每次重试都会从头再过一遍判定流程而流程里的status计算依赖retry_count这本身就埋了状态错乱的雷。更别提stock_info在库存缺失时给availableTrue这种很要命的默认值直接把库存判断变成形同虚设。5.2 code-simplifier给出的简化结果把上面那段代码喂给Claude Code加上code-simplifier提示词它给出的重写版本是这样的def process_order(order, user, inventory, configNone, retry_count0): if not order.get(id): raise ValueError(missing order id) status _resolve_status(order, user, config) if status pending and _has_available_stock(inventory): status processing return _place_with_retry(order[id], status, retry_count) def _resolve_status(order, user, config): if user.get(is_admin) and config and config.get(skip_validation): return approved if order.get(amount, 0) 10000 and not order.get(approved_by): raise PermissionError(large order needs approver) return processing def _has_available_stock(inventory): if not inventory or inventory.get(stock) is None: return False return inventory[stock] 0 def _place_with_retry(order_id, status, retry_count): try: return _place_order(order_id, status) except Exception as e: if retry_count 3: raise e return _place_with_retry(order_id, status, retry_count 1)你能明显感觉到代码量没有缩小太多但在逻辑上有一个很重要的变化每个子函数只干了它名字说的事。_resolve_status只管判定状态_has_available_stock只管查库存_place_with_retry只管重试状态不再被递归重试过程反复改写。5.3 简化前后的硬指标对比指标简化前简化后说明最大嵌套深度5层2层阅读时的脑负荷大幅下降函数行数34行主函数14行拆分后整体反而更易懂中间变量5个2个少掉的状态字段不再混淆递归条件依赖外部状态依赖明确计数重试逻辑不再改写业务状态库存缺失默认值availableTrueavailableFalse从“假装有货”改成“缺货”最核心的那处改动是“库存缺失时默认有货”修正为“库存缺失时默认无货”。这个坑不修未来一定在早上八点高峰时段爆出超卖事故。当然这不是说简化版就百分之百正确——比如_place_with_retry在重试语义上跟原来的行为还是有一点点差异但差异是显式的、可追踪的你只要跑一遍针对库存缺失和超时重试两个用例的单测就能明确返回值。这就比原版“哪个分支都对但说不清”强太多。6. 绕坑指南提示词好用不代表无脑用到这里你以为复制提示词就完事了天真。我在公司内部推广这套工作流的过程中见到了太多翻车现场这里专门给你写几个高频坑。6.1 最常见的三种翻车第一种AI把必要判断当“历史遗留”删了。这是最危险的。比如库存缺失时availableTrue那个默认值代码审计专家看到的是错的但业务方可能故意希望“下单时不查库存、出库时再校验”——在这种业务语境下默认值就不是bug而是feature。code-simplifier第四步的分类只是给AI一个判断框架框架救不了“业务语义缺失”的项目。对策在跑简化之前先把核心业务约束写进提示词附录里。我现在用的时候都会追加一段“以下是我确认过的必须保留的行为禁止以任何形式修改”。把通配符式的AI裁决变成“业务原则 技术审查”的协同机制。第二种AI一次性改太多改错了没法定位。我见过同事让Claude Code一次简化整个服务目录结果AI把七个文件都改了跑测试挂了三个但AI自己都没法说清哪一段改动导致失败。这种锅根本没法背。对策严格限制范围一次只处理一个函数或一个类改完验证、提交、再继续下一个。慢是慢一点但简化这件事本来就不能图快。第三种AI把测试通过的假象当成“安全”。这是很讽刺的一个坑AI非常喜欢在输出里写“回归测试全部通过”但它可能根本没细想你项目里测试是否真的覆盖到了它改过的分支。没有覆盖测试通过当然无意义。对策在第六步把“给出回归建议”改成“先运行相关测试如果该函数没有测试用例请生成一个针对核心行为的临时测试运行给我看”。强制它用行为差异说话而不是用嘴包票。6.2 让简化结果“可验证”的小技巧我自己的经验code-simplifier跑完之后别急着把它的大段回答看完。先把它的回答滚到第五步的改动对照表只看表格里每个“删除”操作对应的归类。然后做一件事在项目里搜一下被删除代码的调用链人肉确认一下这个调用链是不是真空的。如果空AI对如果不空AI错。这个检查不需要花很多时间但能挡住80%的瞎删。另外强烈建议对比着看改动前和改动后的编译警告数。简化完后如果警告数不降反升大概率AI引入新的隐患了。6.3 从“简化代码”升级到“自动代码评审”code-simplifier这套提示词稍微改一改就是个代码评审机器人。我现在在每个PR的CI阶段加了一步让Claude Code以审查员身份读diff输出“本PR增加的可消除代码清单”然后我人工确认。这样做的好处是屎山不再等长成山之后才清理在PR阶段就能拦住一部分。具体做法就是把刚才那段提示词里的“重写”步骤删掉保留“遍历审判”和“归类存档”最后要求输出请针对本PR的diff逐条列出新增代码中属于“可消除”或“历史遗留”的部分并给出理由。不需要重写代码只需要指出问题。这套流程跑了一个月之后我们PR合并前的代码review意见数量明显少了——因为大部分低级冗余在机器审查阶段就被挑了出来。人只负责看真正有争议的业务逻辑。最后再讲一个我的体会AI写代码的能力越强人类的判断力越值钱。code-simplifier真正帮到我的不是替我做决定而是逼我在每一次简化过后重新回答一个问题“这段代码到底为什么存在”这个问题答不清楚今天不删明天它就在那继续发酵。希望这套提示词和流程能帮你从“被AI代码追着跑”的状态里解脱出来——至少不用再为了改一个字段翻到凌晨两点。