YAOTU INSIGHTS

用SKILL编排给存量代码做微创手术:AI辅助开发的工程化实践

用SKILL编排给存量代码做微创手术:AI辅助开发的工程化实践
1. 先把“散装 AI”这事说透这两年我接触过不少团队聊到 AI 辅助开发大家的普遍状态是手里有一堆脚本、一堆提示词、一堆零散的自动化工具每个跑起来都能干点事但合在一起就是拧不成一股绳。今天用 A 工具生成一段代码明天用 B 工具补一个注释后天再手动把结果贴回仓库。工具之间没有上下文没有交接没有统一的规范。这种状态我管它叫“散装 AI”。散装 AI 最大的问题不是单点能力弱而是流程断裂。你让 AI 帮你分析一段存量代码它给了结论你再让它按结论改代码它又把上下文丢了改出来的东西跟前面的分析对不上。更麻烦的是每个人手里的“AI 助手”都是私房配置张三的提示词和李四的提示词可能互相矛盾最后沉淀不到团队里换个人就一切重来。后来我开始尝试用 SKILL 这套思路来解决这个问题。SKILL 不是一个具体的软件它更像是一种“可复用的能力包”把一个特定任务的理解、步骤、工具调用方式、甚至输出格式打包成一个结构化的模块。配合 workflow 编排把这些 SKILL 串成一条流水线让 AI 从一个“偶尔灵光一现的助手”变成“按流程办事的施工队”。这篇文章就用我踩过坑的实际经验聊聊怎么用 SKILL 编排对存量代码做“微创手术”。所谓微创手术不是推倒重来而是在尽可能不破坏现有结构的前提下精准修复、渐进改造。这套方法适合谁适合那些手里有老项目、老代码库想用 AI 帮忙但不希望被 AI 带偏的开发者、技术负责人和独立开发者。2. 为什么存量代码需要“微创手术”而不是“开颅重建”2.1 存量代码的三个残酷真相老代码之所以是“存量”是因为它还在线上跑着、还在给公司赚钱。它不是不想重构而是动它的风险太高。存量代码有三个特点经历过的人都懂。第一没有完整测试覆盖。很多系统是十年前甚至更早写的当时压根没有自动化测试的概念。你改一个函数不知道会影响哪条调用链。第二文档和实现脱节。注释写得天花乱坠代码却早已面目全非。你问 AI“这个模块是干嘛的”AI 读代码能读明白但文档已经不可信了。第三多处重复逻辑牵一发动全身。同一个权限判断可能散落在十几个文件里改了一处另外十几处可能还在用旧逻辑。这种情况下如果有人建议“用 AI 重写一遍”我一般都会劝退。大模型生成新代码的能力很强但让它从零理解一个跑了十年的业务系统的所有隐式规则几乎不可能。AI 重写的代码表面光鲜实际上可能丢掉大量没写在任何文档里的边界处理。所以对存量代码更务实的态度是“尊重现状局部优化”。像做手术一样能微创就不开刀能局部麻醉就不全麻。这正好是 SKILL 编排的用武之地。2.2 SKILL 给 AI 装上一本“操作手册”你直接让 AI“帮我重构一下这个模块”它多半会给你一个天马行空的方案。但你给 AI 装上一个 SKILL比如“存量模块安全改造”这个技能包它的行为会立刻变得可控。SKILL 的本质是把经验固化成流程。一个合格的 SKILL 通常包含以下内容这个技能是干什么的、适用于什么场景、不能用于什么场景、需要哪些输入参数、执行步骤是什么、输出格式是什么、有哪些红线不能碰。举个生活化的例子。你教一个实习生写周报如果说“你写一下这周工作”他可能写得乱七八糟。但你给他一份周报模板加填写说明告诉他必须包含 “本周成果、问题、下周计划” 三部分每部分不能超过多少字他就会交出符合预期的文档。SKILL 就是给 AI 的“周报模板和填写说明”。当 SKILL 被 workflow 编排起来后就更像一个完整的手术方案先由“诊断 SKILL”做全量扫描再由“风险分析 SKILL”评估改动的影响面最后由“代码修改 SKILL”按照评估结果进行精准编辑。每一步的输入输出都是结构化的上下文不丢责任边界清晰。2.3 编排解决的是“多个技能如何配合”的问题单个 SKILL 解决的是“单点任务怎么做”workflow 编排解决的是“多个任务怎么串”。这两个层面缺一不可。我见过一些团队也做了 SKILL但只是把一堆技能包堆在那里没有编排。结果 AI 在处理一个复杂任务时不知道该在什么阶段调用哪个 SKILL最后还是凭“自由发挥”做完。这就像手术室里工具齐全但没人排手术顺序——先消毒还是先切皮先止血还是先缝合顺序错了工具再好也白搭。workflow 编排的价值就是把这些 SKILL 的前置条件、后置结果、异常处理路径都定义清楚。比如“风险分析 SKILL”必须在“代码修改 SKILL”之前执行如果风险评分超过阈值就进入人工审批分支而不是继续往下走。这样一来AI 的每次执行都是可预测的出了问题也知道是卡在哪一步。3. 开始动手设计一套“存量代码微创手术”的 SKILL 编排方案3.1 从问诊到复查一个五步流程设计我实际用的流程是从医疗流程借鉴来的分五个阶段问诊、检查、评估、手术、复查。每个阶段对应一个或一组 SKILL阶段之间通过 workflow 衔接。问诊阶段核心是“把需求描述清楚”。用户提出一个改造目标比如“给订单模块加一个幂等校验”这个目标要先被结构化。我用一个“需求澄清 SKILL”让 AI 自动列举出目标涉及的模块、可能的改动点、验收标准并生成一份《改造需求确认单》。检查阶段核心是“把存量代码摸透”。这里的 SKILL 不是单纯读代码而是做静态分析。比如扫描指定目录下的文件统计函数调用关系标注 TODO、FIXME、魔法数、重复代码块。这个阶段我一般会让 AI 输出一张“影响面地图”。评估阶段核心是“判断哪里能动、哪里不能动”。根据影响面地图和需求确认单用“风险评估 SKILL”对每个改动点打分改动量、依赖数、是否有测试覆盖、是否在关键链路上。评估结果决定后续手术的力度。手术阶段才是真正改代码。但不是让 AI 直接改而是先让“方案生成 SKILL”输出一份改动方案具体到文件、函数、改动前后对比经过确认后再由“代码编辑 SKILL”执行改动。执行时还绑定了一个“红线检查 SKILL”比如禁止删除公共函数、禁止修改未评估过的文件。复查阶段负责验证。先跑测试再做 diff 审查最后生成一份《手术报告》说明改了哪些地方、为什么改、验证结果如何。整个过程不留模糊地带。3.2 SKILL 的目录结构与元信息怎么写下面是我在项目里常用的 SKILL 目录结构你可以直接抄skills/ legacy-microsurgery/ SKILL.md workflows/ main.yaml prompts/ diagnose.md assess.md plan.md edit.md verify.md scripts/ analyze.py schemas/ requirement.json risk-report.jsonSKILL.md 是这个技能包的入口它的元信息写得好不好直接决定了 AI 能不能正确使用它。我习惯在文件开头用 YAML 格式写 metadata包含 name、description、when_to_use、when_not_to_use、parameters 这几个字段。特别注意两个容易被忽略的字段。一个是 when_not_to_use明确告诉 AI“什么情况下别用这个技能”。比如存量微创手术这个 SKILL如果用户想对整个系统做架构级重构就不该用它而应该走独立的架构升级流程。另一个是 parameters要写明每个参数的格式和默认值否则 AI 会在运行过程中不断追问。SKILL.md 里还要写一段“执行原则”比如“只做最小必要改动”、“不修改未列入计划的文件”、“所有改动必须可回滚”。这些原则会在后续每个 prompt 中被引用确保 AI 的行为一致性。3.3 用 YAML 定义 workflow 编排workflow 编排我用 YAML 定义结构清晰也方便版本管理。下面是一个简化版的 main.yaml你大概感受一下这个思路id: legacy-microsurgery name: 存量代码微创手术 version: 1.0.0 steps: - id: clarify skill: requirement-clarify output: requirement.json - id: diagnose skill: code-diagnose input: requirement.json output: impact-map.json - id: assess skill: risk-assess input: impact-map.json output: risk-report.json on_threshold_exceeded: human_review - id: plan skill: change-plan input: [risk-report.json, requirement.json] output: change-plan.json guard: red-line-check - id: edit skill: code-edit input: change-plan.json output: commit-candidate - id: verify skill: verify input: commit-candidate output: surgery-report.md rollback: strategy: git-revert trigger: verify_failed看到没有每个 step 都定义了输入输出后一个步骤拿前一个步骤的结果继续跑上下文不会丢。on_threshold_exceeded 表示风险评估超过阈值时流程会转向人工评审而不是继续机械执行。4. 实操案例给一个老旧的订单模块加幂等校验理论说再多不如一个完整案例来得直接。下面我拿一个实际做过的场景完整走一遍这套流程。背景是一个运行多年的订单系统最近因为用户重复点击产生了不少重复订单产品要求“在订单创建入口加一个幂等校验”。4.1 需求澄清让 AI 先别急着写代码大多数人遇到这个需求第一反应就是“在 controller 里加个判断”。但存量代码的问题在于你根本不知道订单创建入口有多少个是只有一个 controller 还是有好几个 MQ 消费者也在创建订单。所以我先运行“需求澄清 SKILL”它会自动做三件事读取需求描述、扫描代码中所有“创建订单”相关的方法、生成一份需求确认单。确认单里会列出一组问题比如“幂等键用什么字段生成”“重复请求是返回旧订单还是报错”“是否需要处理并发场景”。这个阶段 AI 不需要写任何代码只是做信息收集和结构化。输出是一份 JSON后续所有 SKILL 都会拿它作为输入。这一步特别重要因为它避免了“AI 拿到一句话需求就埋头改代码”的灾难。4.2 影响面分析用代码扫描代替人肉翻找接下来运行“代码诊断 SKILL”。它会结合需求确认单对订单模块所在的目录做一次静态扫描。我让这个 SKILL 重点输出三类信息创建订单的入口列表、每个入口的函数调用链、是否存在已有的唯一性约束或幂等逻辑。扫描结果会生成一张“影响面地图”包含每个入口的风险等级。比如某个 RPC 接口和某个 MQ 消费者都调用了同一个订单创建服务那么它们的风险等级就高因为改动一个地方会同时影响两条链路。这个环节我要特别强调一点存量代码的入口往往比你想的多。你以为只有一个接口实际上还有定时任务、补偿脚本、管理后台手动触发等路径。如果 AI 没有做全量扫描就动手改结果一定是漏掉关键入口。所以“代码诊断 SKILL”里我强制要求扫描结果必须包含“搜索关键词结果数”和“未覆盖文件列表”让开发者能一眼看到分析是否全面。4.3 风险评估用数据决定“要不要人工介入”拿到影响面地图后“风险评估 SKILL”会对每个候选改动点打分。打分维度包括改动行数、调用方数量、有无测试保护、是否在事务边界内、与外部系统是否有交互。这里我给一个实际算过的例子。订单创建入口有 3 个HTTP controller、MQ consumer、Admin 手动创建。HTTP controller 改动点约 10 行调用方 2 个无单元测试风险分 68MQ consumer 改动点约 15 行调用方 1 个但是触发频率高风险分 82Admin 手动创建入口改动点约 8 行调用方 1 个低频操作风险分 35。我在 workflow 里把风险阈值设为 80超过就进入人工评审。所以 MQ consumer 这个入口不会直接自动改而是先生成一个评审单由我确认后再继续。其他两个入口风险低于阈值可以走自动手术流程。这一步的价值在于它把“改动风险”变成了一组可量化的数据而不是凭感觉决定。我在实践中发现很多程序员对存量代码的恐惧其实来自“不知道改了会炸哪里”而风险评估 SKILL 正好把这种不确定性摊开放在桌面上。4.4 手术执行先出方案再改代码风险确认后进入“方案生成 SKILL”。它要根据前面的所有信息生成一个具体的修改方案。注意这个阶段依然不直接改文件而是输出一份包含“文件路径、原代码片段、新代码片段、修改理由”的 JSON 方案。在这个案例里AI 给出的方案是在订单创建服务层新增一个 createOrderWithIdempotency 方法内部先查幂等表再执行原有逻辑HTTP controller 和 Admin 入口改为调用新方法MQ consumer 则因为需要幂等键但消息体里没有方案会先返回“消息体改造建议”让人工决定是否调整上游。方案确认后才轮到“代码编辑 SKILL”执行。执行时我挂了一个“红线检查”不允许 AI 修改方案之外的文件不允许删除任何导出的公共方法不允许改变数据库表结构。这样即便 AI 在执行中产生“灵感”也不会跑偏。4.5 复查与回滚留好退路再收工改了代码不是结束还要验证。“验证 SKILL”会依次做编译检查、运行已有测试、执行一个简单的静态 diff 审查然后生成手术报告。报告内容包括改动文件的 diff 摘要、是否有新增的未覆盖分支、是否需要补充哪些测试。我在案例中遇到的一个典型情况是HTTP controller 改动跑通了测试但 MQ consumer 的改动因为没有现成测试环境验证 SKILL 主动标记为“建议人工验证”而不是强行通过。这个“主动承认不确定性”的行为正是编排设计出来的效果。万一验证失败workflow 会触发回滚策略。我的建议是所有手术步骤都基于 git 分支执行主分支不动。手术分支验证通过后再通过 MR 合入。这样即使中途出了问题git revert 一条命令就能回到手术前的状态真正做到了“微创可逆”。5. 常见问题与排查技巧实录5.1 SKILL 没生效AI 仍然在自由发挥我见过最常见的问题是明明配置了 SKILL但 AI 行为却跟没配一样。大部分原因是描述写得不够清晰AI 根本不知道“现在该用这个技能”。排查思路就三步。第一步检查 SKILL.md 里的 when_to_use 是否足够具体。不要写“当用户需要修改代码时”而要写“当用户提到幂等、校验、日志埋点等关键词并且涉及存量模块时”。第二步查看 workflow 是否有明确的入口提示比如用户消息里需要带上固定的触发词。第三步确认 AI 工具本身支持自定义 SKILL 加载有些平台需要在配置里手动启用。5.2 编排顺序乱了AI 跳过中间步骤直接改代码另一个高频问题是 AI 在执行复杂任务时省略了中间的评估步骤直接跳到代码修改。这通常是因为 workflow 定义中“前后依赖表达得太弱”。解决办法有两个。一个是在每个步骤的 prompt 里明确写上“上一步输出文件的路径”让 AI 必须先读取上一步的结果才能继续。另一个是把工作流拆成多次独立的 AI 调用每调用完一个 SKILL就把结果保存到磁盘下一次调用时强制读取。我在实践中倾向于后者虽然多了一点 IO 开销但可靠性大幅提升。5.3 提示词漂移同样的 SKILL 每次输出不一样大模型生成本身就带有随机性这是没法完全消除的。但可以把它控制在一个可接受的范围。我常用的一套做法是在 SKILL 的 prompt 模板里强制要求输出 JSON 格式并为每个字段写 examples正例和反例。AI 一旦输出了非预期格式就通过一个“格式校验脚本”自动拦截要求重新生成。这里给大家推荐一个低成本技巧把每次 AI 执行的结果记录下来定期打开看一遍。你会发现某些 SKILL 的输出质量在变差这时候就该回头检查 prompt 是不是被改复杂了或者模型版本是否发生了变化。AI 工具迭代快不能配完就不管。5.4 SKILL 太死板遇到没见过的场景就卡住给 SKILL 写太多硬性规则AI 会变得机械化遇到规则之外的场景就不知道怎么办。我处理这个问题的方法是在每个 SKILL 里加一个“特殊情况处理”小节告诉 AI “如果遇到未覆盖的场景输出一个 UNKNOWN_RISK 标记并暂停流程请求人工介入”。这样既保留了规则的可控性又给了 AI 面对未知情况的出口。因为我们在做存量代码手术的时候最怕的不是 AI 说“我不知道”而是 AI 在不知道的情况下强行给出一个看起来合理的方案。5.5 集成到现有开发流程别搞成另一套孤岛最后一个常见问题是 SKILL 编排系统本身又变成了一个新的“散装工具”。开发团队不想为了跑一条 AI 流水线特地去装一个陌生平台。我的经验是优先选择支持 Git 工作流的工具链。所有 SKILL 的配置、workflow 定义、模板文件都作为代码放在仓库里管理。这样团队可以用 Git 做 review、回滚、版本对比。执行结果也尽量落地成普通文件比如报告输出成 Markdown改动输出成 diff patch让现有工具链可以直接消费而不是关在一个私有系统里。6. 我的经验体会与下一步想做的事这套“SKILL 编排 存量代码微创手术”的思路我实际跑了几个月最大的感受是它没有让 AI 变得“更聪明”而是让 AI 变得“更靠谱”。聪明是模型的事靠谱是流程的事。当你把每一个步骤的输入输出都定义清楚把风险控制点前置AI 就不再是一个有想法的“实习生”而是一个严格执行 SOP 的“老师傅”。如果你也想尝试我建议不要一上来就搭一个庞大的编排平台。从一个具体的改造目标开始比如“给某模块加日志”或者“修掉某类代码异味”先冻结一个小 SKILL手动执行一遍再慢慢加编排。第一版无论多简陋都可以重点是跑通闭环。我个人下一步想做的是把这个流程从“代码修改”扩展到“测试补全”和“文档更新”上。存量代码最大的隐患是测试缺失和文档脱节这两块如果也能用 SKILL 编排的方式做“微创补强”老项目的健康度会提升一大截。这个方向我还在琢磨有进展了再来分享。