告别“散装 AI ”:用 SKILL 编排对存量代码做“微创手术”

作者:vivo IT 技术团队- Liu Heng
面对涉及存量代码变更的需求,挑战不在于编码,而在于如何安全、精准地修改。本文通过构建一个由1个编排器和多个单职责Skill组成的AI协作流水线,将影响分析、规则沉淀、埋点和回归检查等隐性工作流程化,确保在实现功能的同时,对存量代码实现最小侵入式改造。

1分钟看图掌握核心要点👇

一、典型场景:一个看似简单的存量代码变更

某业务上报模块需要新增"图片上传前压缩"功能。需求本身简单,但作为存量修改,真正的复杂性在于:

  • **影响范围不确定:**报量中涉及上传图片的场景不止一处,具体要改哪一处?同一个上传组件被多个父组件共用,改了这一处,其他调用方会不会受影响?
  • **逻辑分支复杂:**单文件上传和批量上传两条路径,压缩逻辑要插入哪个分支、插到哪一层,会不会有副作用?
  • **降级策略未定义:**压缩失败时是折回调用方、静默降级上传原文件,还是提示用户?会不会导致上传功能不可用导致稳定性风险?边界值等于 3MB 或 10MB 时算哪边?
  • **效果难以量化:**压缩功能上线后,没有埋点就无法证明它在起作用。压缩阶段耗时和上传阶段省下来的时间对比,是否实现正向收益?需要数据支撑以验证优化效果。

核心矛盾: 改存量代码,最怕的不是"不会改",而是改完不知道哪里会炸。传统的"打开文件直接改"模式,极易遗漏代码之外的隐性工作:影响面没分析、处理规则没定义、埋点没集成、回归用例没覆盖------任何一个环节的遗漏都可能导致线上事故。

二、解决方案:从"散装AI"到"编排流水线"

为解决上述问题,我们不再依赖零散的AI问答,而是构建了一条可复用的AI辅助开发流水线。其核心思想是:将开发过程中那些"每次都要做、但容易忘"的环节,沉淀为独立的、单职责的AI Skill,并通过一个智能编排器按需串联执行

这就像为存量代码修改制定了一份标准的"外科手术SOP",让AI作为助手,严格遵循流程,确保每一步都精准、可控。

三、架构设计

整个系统由 1个中央编排器 (dev-workflow) 和 多个独立Skill 构成。编排器负责根据需求类型,智能调度并串联Skill;每个Skill则像流水线上的专用工具,只完成一项特定任务。

3.1 流程编排:两条路径,按需组装

复制代码
dev-workflow(编排器)
│
├── 判断需求类型(增量 / 存量)
│
├── 增量需求 → 流程 A
│   │
│   ├── Phase 1 --- 搭建骨架
│   │   ├── scaffold-generator   → 生成模块目录结构
│   │   ├── api-definition       → 生成 API 请求函数
│   │   └── i18n-integration     → 生成国际化文案
│   │
│   ├── Phase 2 --- 编写业务代码
│   │   ├── [编写或生成业务逻辑]
│   │   └── monitor-integration  → 埋点集成(如需要)
│   │
│   └── Phase 3 --- 验证提交
│       ├── regression-cases     → 回归用例生成
│       └── cr-self-check        → CR 自查
│
└── 存量修改 → 流程 B
    │
    ├── Phase 1 --- 分析评估
    │   ├── impact-analysis        → 影响面分析
    │   ├── processing-principles  → 处理原则提取
    │   └── minimal-invasion       → 最小侵入分析
    │
    ├── Phase 2 --- 编写代码
    │   ├── [实施代码修改]
    │   ├── monitor-integration    → 埋点集成
    │   └── i18n-integration       → 国际化文案
    │
    └── Phase 3 --- 验证提交
        ├── regression-cases       → 回归用例生成
        └── cr-self-check          → CR 自查

编排器并非机械地运行所有Skill,而是根据需求类型(增量、存量),选择不同的Skill组合与执行顺序,形成两条优化流程:

以流程B为例,下面的状态机图展示了完整的动态执行流转------包括 Phase 内部的 Skill 串行顺序、两个并行分支,以及每个 Phase 结束后的关门确认点:

3.2 技能矩阵:每个Skill的职责与产出

每个 Skill 好比流水线上的每台"机器"。多个 Skill,每个只做一件事 。 它们之间通过"产出物"传递数据------上游 Skill 的输出,就是下游 Skill 的输入

**设计思路:**每个 Skill 都是独立的 Markdown 文件,既能被编排器调度,也能单独使用------例如:只想分析影响面?直接调 impact-analysis;紧急 hotfix 可以跳过 Phase 1,直接进 Phase 2。

3.3 编排机制:三个机制让流水线不僵化

编排器通过三个核心机制确保流水线灵活可控:

  • **智能跳过:**不是每个 Skill 都要跑。编排器根据需求特征自动判断,跳过不适用的 Skill。本次实战中 9 个 Skill 执行了 7 个,跳过了 2 个(scaffold-generator、api-definition)。
  • **Phase 关门:**每个 Phase 完成后暂停确认,输出摘要并询问是否继续,让人类保留纠偏的权力。
  • **独立可拆卸:**每个 Skill 可独立使用,编排器只是"推荐的串联方式",不是"唯一的使用方式"。

三个机制的设计动机、实现细节和实战效果,详见第四、五章。

3.4 数据流转:Skill 间的接力赛模式

整个流程中最值得关注的,是 Skill 之间怎么传递数据

这不是通过 API 或数据库,而是通过自然语言形式的产出物在对话上下文中流转:

复制代码
impact-analysis
    │ 输出:"影响面极小,修改封闭在 uploadComponent.vue 内部"
    ▼
processing-principles
    │ 输入:上游结论 → 跳过"跨组件兼容性"检查项
    │ 输出:6 条编码规则(含阈值、降级策略、埋点要求)
    ▼
minimal-invasion
    │ 输入:6 条规则 → 确定需要"条件守卫 + 前置处理"两种模式
    │ 输出:具体的代码插入方案
    ▼
[代码实施]
    │ 输入:插入方案 → 机械化编写代码
    ├──▶ monitor-integration(规则第 5 条触发)
    ├──▶ i18n-integration(Toast 文案触发)
    ▼
regression-cases
    │ 输入:变更的文件和函数 → 生成回归清单
    ▼
cr-self-check
    │ 输入:所有修改的文件 → 逐项检查
    │ 输出:CR 自查报告

上游 Skill 的结论会直接影响下游 Skill 的行为。 比如:

  • impact-analysis 判定"影响面小"→ processing-principles 跳过了"跨组件兼容"和"回滚策略"检查项
  • processing-principles 明确了"需要埋点"→ 编排器在 Phase 2 自动激活了 monitor-integration
  • processing-principles 没提到"新建模块"→ 编排器跳过了 scaffold-generator

四、实战推演:以"图片压缩"需求跑通流程B

以下以"某业务上报图片压缩"这一典型存量需求,演示流程B如何运行。

开发者输入需求描述后,编排器 dev-workflow 自动分析需求特征。本次"图片上传前压缩"涉及对现有 uploadComponent.vue 组件的修改,编排器判定为存量变更 ,自动路由至流程B,并规划出 Phase 1(分析评估)→ Phase 2(编写代码)→ Phase 3(验证提交)的执行路径。

Agent执行过程

以下按 Phase 逐步拆解,看每个 Skill 具体干了什么、产出了什么。

4.1 Phase 1:分析评估(三个 Skill 严格串行)

Phase 1 的三个 Skill 是有依赖关系的------后者需要前者的输出。所以必须串行执行。

Skill 1: impact-analysis --- 影响面分析

**输入:**需求描述 + 目标文件路径(uploadComponent.vue)

AI 自动扫描了调用链------向上追溯(谁在调用我)、向下追溯(我依赖了谁)、横向扫描(谁和我用同一个 API),最终输出:

结论:影响面极小,修改完全封闭在 uploadComponent.vue 内部。 这一步给了我们动手的信心。

这个结论被传递给下一个 Skill------processing-principles 因此知道不需要考虑"跨组件兼容"的问题。

Agent执行过程

Skill 2: processing-principles --- 处理原则提取

**输入:**需求描述 + impact-analysis 的结论(影响面小,无跨组件变更)

它拿着结构化 Checklist(边界阈值、失败处理、兼容性、并发与顺序、可观测性、回滚策略六大维度)逐项引导确认。中间抛出了两个关键问题:

  • "等于 3MB 时算哪边?" → 用户选择:不压缩
  • "压缩失败要不要提示用户?" → 用户选择:不提示

最终沉淀出 6 条编码级规则:

亮点:等于 3MB 时不压缩,等于 10MB 时允许上传------这种边界值的决策,如果没提前想清楚,写到一半才发现又得改。

这 6 条规则被传递给下一个 Skill------minimal-invasion 据此决定代码怎么插入。

Agent执行过程

Skill 3: minimal-invasion --- 最小侵入分析

**输入:**目标函数源码 + processing-principles 的 6 条规则

它读取 uploadFileToServer 方法,画出分支结构:

复制代码
uploadFileToServer(file)
├── if (Array) ──── 批量上传
│   └── forEach → FormData.append → 调用接口
└── else ─────────── 单文件上传
    └── FormData.append → 调用接口

然后从 5 种集成策略中选择了两种的组合:

  • 条件守卫(规则 2):入口处 10MB 拦截,快速失败
  • 前置处理(规则 1/3):FormData.append 之前插入压缩,失败降级返回原文件

输出了具体的代码变更方案:

复制代码
// 原来
formData.append("file", item.file);

// 改为
const processedFile = await this.processFileWithCompress(item.file);
formData.append("file", processedFile);

只改一个变量名,原有的上传、回调、状态管理全部不动。 这就是"最小侵入"的精髓。

Agent执行过程

**Phase 1 小结:**三个 Skill 像接力赛一样------impact-analysis 递出"影响面",processing-principles 接棒递出"规则",minimal-invasion 再接棒递出"插入方案"。上游的结论直接影响下游的行为:

  • impact-analysis 判定"影响面小"
  • processing-principles 就跳过了"跨组件兼容"检查项
  • processing-principles 明确了"需要埋点"

编排器就在 Phase 2 自动激活 monitor-integration;没提到"新建模块",编排器就跳过了 scaffold-generator。此时编排器暂停,输出摘要并询问是否继续------这是关门机制的第一道确认门。

4.2 Phase 2:编写代码(实施 + 两个辅助 Skill)

拿到 Phase 1 的三份产出,写代码就变得非常机械化。

代码实施:三个文件,一套设计

文件 1:压缩工具函数fileCompress.js

核心设计是 Promise + 回调双通道

复制代码
export function compressImage(file, callbacks = {}){
  return new Promise((resolve) => {
    // ...
    new Compressor(file, {
      quality: 0.8,
      success(result) {
        callbacks.onSuccess?.({ duration, originalSize, compressedSize, savedRatio });
        resolve(compressedFile);  // Promise 通道:返回压缩结果
      },
      error(err) {
        callbacks.onFail?.({ duration, error: err.message });
        resolve(file);  // 关键:失败也 resolve,不 reject!
      }
    });
  });
}

设计亮点:永远 resolve,永不 reject。 压缩失败时返回原文件,调用方完全不需要 try/catch。这保证了:

  • 压缩成功 → 上传压缩后的文件
  • 压缩失败 → 上传原文件
  • 调用方代码完全一致,零分支

文件 2:集成到 uploadComponent.vue

核心文件 uploadComponent.vue 只改了三处:

原有的 loading 管理、save 触发、错误处理------一行没动

Agent执行过程

Skill 4: monitor-integration --- 埋点集成

因为处理原则第 5 条要求"埋点监控",编排器自动触发了 monitor-integration Skill。它扫描了 monitorReporter.js 现有的 20+ 个埋点函数,识别出命名模式(report_ 前缀)和公共上报字段(运行环境、用户标识、页面地址),然后在文件末尾追加了 report_imageCompress 函数------风格和已有函数完全一致。

上报字段包括:

复制代码
status(success/fail)| duration(耗时ms)| originalSize | compressedSize | savedRatio | fileName

**埋点与压缩逻辑的解耦:**压缩工具函数不依赖任何埋点库,通过 callbacks.onSuccess / onFail 暴露钩子:

复制代码
compressImage(file, {
  onSuccess: (data) => report_imageCompress({ status: 'success', ...data }),
  onFail: (data) => report_imageCompress({ status: 'fail', ...data })
});

fileCompress.js 是纯工具函数,可在任何模块复用;埋点逻辑留在业务层,由调用方决定是否监控、怎么监控。

Agent执行过程

Skill 5: i18n-integration --- 国际化文案

因为代码中有一处 Toast 提示("文件大小不能超过10MB"),编排器触发了 i18n-integration Skill。它在 zhLang.js中加了一条词条,在 common/index.js 中注册了 key。

Agent执行过程

Phase 2 小结:代码实施阶段的核心特征是机械化------Phase 1 已经定好了"在哪改、怎么改、改多少",这一阶段只是按图施工。三个关键设计决策值得注意:

  • fileCompress.js 采用"永远 resolve"模式,压缩失败自动降级,调用方零分支
  • uploadComponent.vue 仅改 3 处,原有 loading/save/错误处理一行未动
  • 埋点通过 callback 钩子与压缩逻辑解耦,工具函数保持纯粹可复用

编排器根据 Phase 1 的结论自动激活了 monitor-integration(处理原则第 5 条要求)和 i18n-integration(检测到硬编码 Toast),跳过了 scaffold-generator 和 api-definition。此时编排器再次暂停------这是关门机制的第二道确认门。

4.3 Phase 3:验证提交(两个 Skill 可并行)

Skill 6: regression-cases --- 回归用例生成

它分析了本次变更涉及的文件和新增逻辑,生成了 13 条回归用例:

Agent执行过程

Skill 7: cr-self-check --- CR自查

它逐项检查了本次修改的所有文件,区分存量修改的专项检查(分支覆盖、接口兼容、loading 状态、新逻辑失败不阻断原流程)和基础检查,输出:

  • 通过项:无 ESLint 错误、无 console.log 残留、所有文案已国际化、所有分支已覆盖、原有接口未变化、新逻辑失败不阻断原流程
  • 需关注:监控规则 ID 为占位符(待监控平台申请后替换)

Agent执行过程

Phase 3 小结: 两个验证 Skill 无依赖关系,可以并行执行。regression-cases 从变更文件和新增逻辑中自动推导出 13 条分级用例(P0/P1/P2),覆盖了核心路径、交叉场景和边界条件;cr-self-check 则从代码规范、存量兼容性、埋点完整性三个维度逐项扫描,输出结构化的自查报告。

两个 Skill 的产出互补:回归用例告诉你"该测什么",CR 自查告诉你"代码本身有没有问题"------一个面向测试,一个面向审查,共同构成提交前的最后一道防线。

4.4 执行数据总览

代码变更统计

3 个 Phase、7 个 Skill 执行(跳过 2 个)、6 条处理原则、13 条回归用例、CR 自查全部通过。

流水线产出清单

五、编排设计原则与决策

从架构设计和实战验证中,我们提炼出六条可复用的编排原则。每条原则不仅说明"做什么",更解释"为什么"------没有它会怎样,以及实战中如何体现。

5.1 六条原则

1. 单一职责------做螺丝刀,不做瑞士军刀

  • **问题:**如果把多个能力塞进一个"万能 Skill",任何小改动都需要重新调试整个 Skill;不同场景无法按需组合。
  • **设计:**每个 Skill 只解决一个问题,独立成 Markdown 文件。编排器负责组合,Skill 只负责执行。
  • **实证:**本次实战中,monitor-integration 和 i18n-integration 各自独立触发------如果合并为"辅助集成 Skill",就无法单独跳过某项能力。

2. 接力模式------上游的输出是下游的输入

  • **问题:**如果每个 Skill 独立获取信息(如各自重新分析代码),不仅浪费 token,还可能产出矛盾的结论。
  • **设计:**Skill 之间通过自然语言"产出物"传递数据,而非 API 或数据库。LLM 天然产出自然语言,无需额外的序列化/反序列化成本。
  • **实证:**impact-analysis 输出"影响面极小" → processing-principles 据此跳过"跨组件兼容"检查项 → minimal-invasion 据此选择"前置处理"而非"逻辑替换"。

3. 串行 vs 并行------有依赖的串行,无依赖的并行

  • **问题:**如果一律串行,浪费时间;如果一律并行,下游 Skill 拿不到上游结论。
  • **设计:**编排器判断 Skill 间是否存在数据依赖。Phase 1 三个分析类 Skill 有严格依赖,必须串行;Phase 3 两个验证类 Skill 无依赖,可以并行。
  • **实证:**如果 processing-principles 和 impact-analysis 并行执行,processing-principles 就无法根据影响面结论跳过不适用的检查项,产出会包含大量无关的"跨组件兼容"分析。

4. 智能跳过------不是每个 Skill 都要跑

  • **问题:**如果 7 个 Skill 每次都跑,增量需求也要走完"影响分析 → 处理原则 → 最小侵入"这条存量路径,"走流程"就变成了"走形式"。

  • **设计:**编排器维护一张跳过规则表,根据需求特征和上游产出自动判断:

  • **实证:**本次实战中 9 个 Skill 执行了 7 个,跳过了 scaffold-generator 和 api-definition------编排器检测到没有"新建模块"和"新增接口"的需求特征。

5. 关门机制------每个阶段都有"确认门"

  • **问题:**AI 一口气写完代码,你发现方向就不对,全部要返工。越晚纠偏,成本越高。

  • **设计:**编排器在每个 Phase 完成后暂停,输出摘要并询问是否继续:

    ✅ Phase 1 完成。摘要:

    • 影响面:修改封闭在 uploadComponent.vue 内部
    • 处理原则:6 条编码规则
    • 插入方案:条件守卫 + 前置处理

    是否进入 Phase 2?或者需要调整什么?

  • **实证:**本次实战中,Phase 1 完成后编排器暂停,确认了影响面和插入方案后才进入 Phase 2。如果 Phase 1 的结论有误(如影响面判断遗漏),可以在此时纠正,而不是等 200 行代码写完再推翻。

6. 可拆可组------流水线是"建议",不是"强制"

  • **问题:**如果编排器是唯一入口,那只想加个埋点就必须走完整个流程,使用门槛过高。
  • **设计:**每个 Skill 可独立调用。编排器是"推荐的串联方式",不是"唯一的使用方式"。
  • **实证:**紧急 hotfix 可以跳过 Phase 1 直接进入 Phase 2;其他项目可以复用单个 Skill(如只用 impact-analysis),不需要搬走整个编排器。

5.2 设计决策对比

编排设计的每个选择背后,都有替代方案。以下对比解释了"为什么选这条路":

六、结语

存量代码如同有人居住的老宅,改造之道在于"微创"。本次实践表明,AI的价值不仅在于生成代码,更在于将散落的能力编排成一条严谨、可复用的"开发流水线"。它通过流程的确定性,对抗存量修改中的不确定性风险,让"做得对"从一种运气,转变为一种习惯和必然。

这条流水线并未增加工作的复杂度,而是将那些原本依赖个人经验、容易遗漏的隐性工作显性化、自动化。最终,我们以最小的切口(改动202行代码),安全地嵌入了一个新功能,同时获得了完整的影响分析、清晰的规则定义、可量化的监控以及全面的测试保障------这正是工程化AI协作带来的深层价值。

AI 写代码的能力已经不稀奇了。真正有价值的,是把 AI 的能力编排成一个可复用的流程------让"做得对"变成一种习惯,而不是一种运气。

相关推荐
VIP_CQCRE1 小时前
用 Ace Data Cloud 快速接入 OpenAI 语音识别:一行 base_url 改造,让音频转文字更简单
ai·openai·api·语音识别·acedatacloud
ai小陈1 小时前
LTX2.5音视频生成任务验收实战:批量记录与音画质量检查
人工智能·python·深度学习·ai·音视频·gpu算力
匠测AI说1 小时前
AI对话管理器 · Edge / Chrome MV3 扩展 · v0.1.0
chrome·ai·edge
玫幽倩2 小时前
2026第二届湾区杯网络安全大赛决赛(AI专项赛道静态题wp)
pytorch·python·ai·agent·ctf·rag·湾区杯
子非鱼eva2 小时前
昇腾开源仓Issue分析解答-CANN精选(二)
人工智能·ai
学习日记5253 小时前
AI PPT生成系统实践:从自由生成到可控生成的工程演进复盘
人工智能·ai·prompt
石小千3 小时前
GPU(单3090 24G) 部署千问模型
ai
子非鱼eva3 小时前
昇腾开源仓Issue分析解答-Ascend精选(一)
人工智能·ai