Skip to content

【AI 实践】 AI 时代下重构旧时代系统

背景

重构的系统是一个企业级的管理系统,有多个客户对其进行了定制化开发,导致系统功能复杂、代码质量参差不齐,维护成本高。

业务诉求

最近遇到了一个需求,因新的客户需求与旧系统功能有部分重合,但又有一些新的功能诉求,其视图交互完全不同,但这些功能未来需要同步到其他客户。

因此需要在不破坏现有功能的前提下,对系统进行重构,以满足新的客户需求,同时方便后续客户的复用和维护。

当前的系统设计不清晰无法满足 AI 时代的需求

当前的系统的架构设计不清晰,缺乏明确的分层和职责划分,在 AI 高增益放大器下,大量冗余的代码会将系统的无序性会进一步放大,导致 AI 生成的代码质量低、采纳率低,在 Code Review 时的修改意见也大大增加了,整体的开发效率反而降低了。

image.png

因此,需要匹配更强的阻尼机制(例如严格的测试、Review、Linting、架构设计),让 AI 在面对无序的需求时,生成有序代码。

接下来,在下将以 重构旧时代系统 为例,去思考在 AI 时代下,我们应该如何去构建一个系统,来对抗熵增,让系统保持有序。

阻尼机制1: SDD (Specification Driven Development,规范驱动开发)驱动重构系统

SDD 典型工作流示例

1. explore(调研,脑暴);
   ⬇️
2. propose "..."(生成设计文档);
   ⬇️
3. apply-change(写代码);
   ⬇️
4. verify-change(自测,校验代码与 SDD 文档是否对应);
   ⬇️
5. archive-change(收尾,归档)
1. explore(调研,脑暴);
   ⬇️
2. propose "..."(生成设计文档);
   ⬇️
3. apply-change(写代码);
   ⬇️
4. verify-change(自测,校验代码与 SDD 文档是否对应);
   ⬇️
5. archive-change(收尾,归档)

重构系统不同于功能开发,重构是「在活体系统上动手术」:这种高风险对 AI 执行提出了截然不同的要求——不仅要知道改什么,更要知道不能改什么,以及按什么顺序改。

而 SDD 的价值正在于此:在动代码之前,把这三件事全部写清楚。

  1. 明确要改什么
  2. 不能改什么
  3. 按什么顺序改

明确要改什么

例如在这次重构事件中,核心诉求是满足新的客户需求,将功能也同步到其他客户(UI 交互差异大),以及让 AI 生成的代码更加有序,方便后续的维护和扩展。

因此在下先对现有的系统进行分析,判断当前的系统是否满足新的客户需求,如果不满足,明确需要如何修改系统的哪些部分,才能满足新的客户需求。

以下是系统模块依赖的分析图:

null

从上面的分析图中,不难发现:

  • 依赖方向混乱:例如 pages 同时依赖 store(51处) + api(55处) + hooks(37处) + components(163处) — 四向依赖,不利于不同客户之前的功能复用和维护
  • store 层存在,且被大量依赖(51处),但其职责不清晰,且存在大量冗余代码(287 行 reducers),不利于维护和复用
  • API 层被大量直接调用(例如 pages 直接调用 API 55处,components 直接调用 API 15处,hooks 直接调用 API 3处,services 直接调用 API 3处),导致系统的依赖关系混乱,难以维护和复用
  • hooks 同时依赖 store(11处) + api(3处) — 混合了状态管理和网络请求

基于此,技术痛点在于系统的依赖关系混乱,职责划分不清晰,导致系统的维护成本高,复用率低,无法比较好的满足新客户的诉求,在加之系统的架构设计不清晰,缺乏明确的分层和职责划分,在 AI 高增益放大器下,大量冗余的代码会将系统的无序性会进一步放大,导致 AI 生成的代码质量低、采纳率低,在 Code Review 时的修改意见也大大增加了,整体的开发效率反而降低了。

因此在重构系统时,我们需要对系统的架构进行重新设计,明确每一层的职责和边界,规范系统的依赖关系,从而提高AI 采纳率和功能复用率。

在这次重构事件中,在下参考了类似于 Vue 的类 MVVM 设计实践,在 Vue 中 temple 模版是 View 视图,Data 相当于是模型,在 Vue 初始化过程中,通过 Object.defineProperty or Proxy 进行数据劫持,当模板渲染时,会触发 getter,Vue 会收集「依赖」,当数据修改时会触发 setter ,Vue 会通知依赖的视图节点重新渲染,实现 Model → View 的自动同步,这个阶段就是 视图模型层,是连接 Model 和 View 的桥梁,负责 数据绑定 和 事件监听,实现数据和视图的双向同步。

回到业务场景,在下针对现有的业务系统,也划分了 3 层:

  • Model 层:负责数据模型的定义和数据访问
  • ViewModel 层:负责业务逻辑的处理和数据的转换
  • View 层:负责 UI 的展示和用户交互

通过明确的分层架构,AI 在生成代码时就有了清晰的职责划分,知道每一层应该做什么,从而生成符合架构规范的代码,同时也方便了后续的复用。

架构图

不能改什么

在重构系统时,除了明确要改什么之外,还需要明确不能改什么,例如在这次重构事件中,原有客户的样式、交互、接口需保持不变,避免破坏现有功能。

按什么顺序改

在重构系统时,还需要明确按什么顺序改,在方案设计过程中,在下自上而下确认了业务痛点,围绕业务痛点进行架构设计,但在实践过程中,应自下而上修改,优先改 Model 层,确保数据模型的定义和数据访问的正确性,然后改 ViewModel 层,确保业务逻辑的处理和数据的转换的正确性,最后改 View 层,确保 UI 的展示和用户交互的正确性。

总结

image.png

这个阶段是核心 Spec,即基于需求的核心痛点,明确了要改什么、不能改什么、按什么顺序改,为重构提供了基础指导,也为后续的规则约束和提示词构建、代码生成打下了基础。

这也意味着,在面对复杂的需求时,先规划后编码,明确任务,可以更好的对抗熵增,让系统保持有序。

阻尼机制2: 规则约束

为什么需要规则约束

AI 模型具备"通识能力",给它一个需求描述,它确实能生成可运行的代码。

但问题在于,这些代码往往是"不符合项目规范的代码":

  • 风格不一致(命名规范、目录结构、分层方式与项目现有代码不同)
  • 复用率低(没有利用项目已有的公共组件、工具函数、请求封装、生成的代码杂糅在一团像一坨 "💩山")
  • 采纳率低(Code Review 时研发同学看到"外来风格"的代码,会产生大量修改意见)

结果就是:AI 生成了代码,但 Review 成本和返工成本反而更高了。

这时候可能有同学会说: "是用的 AI 模型太垃圾啦,换一个牛一点的模型就好了!",诚然,模型的能力是一个重要因素,但除了模型能力之外,规则约束也是另一个重要因素。

规则约束可以给 AI 一个已有的实现作为参照,限定 AI 的能力边界,让它照着复刻一份,而不是凭空创造,这就像给一个新入职的工程师说"你照着这个模块的风格,写一个类似的",而不是"你自由发挥"——前者往往能更快产出符合团队规范的代码。

【实践】规则约束

在这次 AI 重构系统的实践中,在下给系统划分了 4 层规则约束 (架构层、示范层、视觉层、约束层)

  • 架构层:定义系统的分层架构,明确每一层的职责和边界,让 AI 「对系统有一个整体的认知」
  • 示范层:提供已有的实现作为示范,Good Case 与 Bad Case,告诉 AI「标准产出长什么样」
  • 视觉层:提供系统的目录结构、文件结构等视觉信息,告诉 AI「页面应该长什么样」
  • 约束层:提供一些具体的规则约束,例如命名规范、函数长度、注释规范等,告诉 AI「禁止什么、必须怎样」

image.png

image.png

约束层

在约束层面,在下提供了一些具体的规则约束,例如命名规范、函数长度、注释规范等,告诉 AI「禁止什么、必须怎样」,让 AI 在生成代码时有明确的规则可遵循,从而提高代码的质量和一致性。

image.png

视觉层

在视觉层面,在下提供设计系统(主题色、UI库、图标、字体等)、布局系统(Grid 布局、Flex 布局等)、样式开发规范、响应策略等视觉信息,告诉 AI「页面应该长什么样」

image.png

示范层

在这次实践中,在下从 组件编写规范、组件复用规范、API 接口设计规范、项目整体结构 维度提供了一个已有的实现作为示范,告诉 AI「标准产出长什么样」,同时也提供了一些 Bad Case,告诉 AI「不符合规范的产出长什么样」,让 AI 知道什么是好的代码,什么是不好的代码,从而提高生成代码的质量和采纳率。

架构层

在架构层面,我们定义了系统的分层架构,明确了每一层的职责和边界,让 AI 对系统有一个整体的认知。例如在这次重构事件中,划分了 3 层:

  • Model 层:负责数据模型的定义和数据访问
  • ViewModel 层:负责业务逻辑的处理和数据的转换
  • View 层:负责 UI 的展示和用户交互

通过明确的分层架构,AI 在生成代码时就有了清晰的职责划分,知道每一层应该做什么,从而生成符合架构规范的代码,同时也方便了后续的复用。

API 层 (client/src/api/)               → 定义 MethodsAPI 常量 + callAPI 调用函数
Model 层 (client/src/models/)           → MobX 业务状态模型(makeAutoObservable 单例)
ViewModel 层 (client/src/view-models/)  → 页面级 UI 交互逻辑 (可选)
View 层 (client/src/pages/)             → React 组件(observer + memo)
API 层 (client/src/api/)               → 定义 MethodsAPI 常量 + callAPI 调用函数
Model 层 (client/src/models/)           → MobX 业务状态模型(makeAutoObservable 单例)
ViewModel 层 (client/src/view-models/)  → 页面级 UI 交互逻辑 (可选)
View 层 (client/src/pages/)             → React 组件(observer + memo)

实践中,Model 层尽量保持单一职责,如有数据聚合、数据转化等诉求,优先放在 ViewModel 层去实现,避免 Model 层过于臃肿,AI 也可以尽可能的复用 Model 层的代码,减少重复代码的生成。

生成效果

image.png

通过以上的规则约束,AI 生成的代码质量和采纳率得到了显著提升,研发同学在 Code Review 时的修改意见也大大减少了,整体的开发效率得到了提升。

注意事项

1. 过大、过多的规则文件会占用更多上下文窗口、降低 Agent 对规则的遵循度,增加冲突概率。

在这次实践中,在下对规则进行了分层,拆分为多个 Markdown 文件,使用或导入机制(例如 @path/to/file)或路径匹配规则来进行引用,既保证了规则的完整性,又避免了单个规则文件过大导致的问题。

image.png

image.png

2. 如何查看规则是否被命中

常见可以通过询问大模型、观察日志输出的记录,也可以通过运行 /memory(或类似命令)查看当前自动记忆的规则。

阻尼机制3: 提示词构建

提示词构建是 AI 时代下非常重要的一个技能,好的提示词可以让 AI 生成更符合预期的代码,而不好的提示词则可能导致 AI 生成的代码质量低、采纳率低。

在这次实践中,在下构建了一个包含 4 个层级的提示词体系:

  • 场景层:描述当前的业务场景和痛点,让 AI 对当前的业务背景有一个整体的认知
  • 目标层:明确当前的目标和预期,让 AI 知道当前的任务是什么,预期的结果是什么
  • 规则层:提供一些具体的规则约束,例如命名规范、函数长度、注释规范等,告诉 AI「禁止什么、必须怎样」
  • 反馈层:提供一些具体的反馈机制,例如 Code Review 机制、UI 视觉验证机制、测试用例验证机制等,让 AI 生成的代码能够被验证,从而提高代码的质量和可靠性

通过以上的提示词构建,AI 在生成代码时就有了明确的指导和约束,从而提高代码的质量和采纳率。

阻尼机制4: 可验证

这是区分 “玩具演示” 和“生产级智能体”的关键。

Anthropic 推荐三种方法:

  1. 基于规则的反馈(测试、代码检查)
  2. 视觉反馈(通过 Playwright 截取 UI 截图)
  3. 大语言模型为裁判 (LLM-as-judge)(由另一个子智能体评估输出)。

Claude Code 的创造者 Boris Cherny 指出,让模型能够验证自己的工作,能让产出质量提升 2 到 3 倍。

基于此,在这次实践中,在下也引入了三层验证机制

  • Code Review 机制
  • UI 视觉验证机制
  • 测试用例验证机制

通过这些机制,让 AI 生成的代码能够被验证,从而提高代码的质量和可靠性。

1. Code Review 机制

在下使用不同的大模型来进行 Code Review,例如使用 Claude 进行编码,使用 GPT 进行代码规范的评审,通过不同模型的评审,让 AI 生成的代码能够得到多维度的验证,从而提高代码的质量和采纳率。

js
// 我常用的提示词
这部分代码是由 Claude 生成的,请你以一个资深前端工程师的身份来进行 Code Review,主要从以下几个维度来评审:
1. 代码风格:命名规范、代码结构、注释规范等
2. 代码质量:是否有重复代码、是否有冗余代码、是否有潜在的 bug 等
3. 代码可读性:代码是否清晰易懂,是否有足够的注释等
4. 代码安全性:是否有安全隐患,例如 XSSSQL 注入等
5. 代码性能:是否有性能问题,例如不必要的循环、过大的数据处理、过高的时间复杂度等

请你给出具体的修改意见,并且给出修改后的代码片段,最后总结一下这段代码是否符合要求,如果不符合,主要是哪些方面不符合。

好好评审,不要让 Claude 瞧不起你!
// 我常用的提示词
这部分代码是由 Claude 生成的,请你以一个资深前端工程师的身份来进行 Code Review,主要从以下几个维度来评审:
1. 代码风格:命名规范、代码结构、注释规范等
2. 代码质量:是否有重复代码、是否有冗余代码、是否有潜在的 bug 等
3. 代码可读性:代码是否清晰易懂,是否有足够的注释等
4. 代码安全性:是否有安全隐患,例如 XSSSQL 注入等
5. 代码性能:是否有性能问题,例如不必要的循环、过大的数据处理、过高的时间复杂度等

请你给出具体的修改意见,并且给出修改后的代码片段,最后总结一下这段代码是否符合要求,如果不符合,主要是哪些方面不符合。

好好评审,不要让 Claude 瞧不起你!

2. UI 视觉验证机制

在重构过程中,对于其他客户的 UI 视觉保持不变是一个重要的约束条件,因此在这次实践中,在下引入了 UI 视觉验证机制。

  1. 分析前端的代码上下文,获取页面的路由信息
  2. 通过 Playwright 访问页面路由并截取重构前的页面的 UI 截图
  3. 通过 Playwright 访问页面路由并截取重构后的页面的 UI 截图
  4. 将重构前后的 UI 截图进行对比,判断是否存在视觉差异,如果存在视觉差异,则说明 AI 生成的代码可能存在问题,需要进行修改。

image.png

举一反三: Figma to Code

在 UI 视觉验证机制的基础上,在下可以实现了 Figma to Code 的功能,例如通过 Playwright 访问 Figma 的设计稿页面并截取设计稿的 UI 截图,然后将设计稿的 UI 截图与 AI 生成的代码的 UI 截图进行对比,判断是否存在视觉差异,如果存在视觉差异,则说明 AI 生成的代码可能存在问题,需要进行修改。

同理,在开发完成后的,设计验收环节也可以通过类似的机制来进行设计验收。

3. 测试用例验证机制

在这次实践中,在下引入了测试用例验证机制,基于 Figma + 代码上下文 + 线上的运营数据(用户行为数据、接口调用数据)编写测试用例,让 AI 生成的代码能够被验证,从而提高代码的质量和可靠性。

阻尼机制5: 护栏与安全

在 AI 时代下,护栏与安全机制是非常重要的,尤其是在涉及到敏感数据、用户隐私、系统安全等方面。

在这次实践中,在下也引入了护栏与安全机制,例如在 API 层面,增加了权限校验和输入校验,避免 AI 生成的代码存在安全隐患;在数据处理方面,增加了数据脱敏和加密机制,保护用户隐私;在系统安全方面,增加了安全审计和监控机制,及时发现和应对安全威胁。

阻尼机制6: 编码实践的编排循环

在这次的实践中,编码实践的编排循环整合了前面上述的规则约束、提示词构建、验证机制等。这 个循环不停运转:提示词 -> 编码 -> 验证 -> 重复。 通过不断地迭代这个循环,让 AI 生成的代码能够不断地被验证和改进,从而提高代码的质量和可靠性。

阻尼机制7: 多智能体编排

在讲述这块的实践之前,在下 想先讲述下什么情况下适合使用多智能体编排:

1. 上下文管理开始失控

如果多个领域/模块的知识无法舒适地塞进同一个 Prompt,必须按角色或任务分发上下文,而不是全部堆给一个 Agent,那么就说明单 Agent 已经接近边界了。

2. 需要分布式维护能力

如果不同团队需要独立维护自己的 Agent 能力,比如:

  • 安全团队维护审计 Agent
  • 测试团队维护测试 Agent
  • 开发团队维护开发 Agent

那么你面对的已经不只是一个 Prompt 优化问题,而是一个跨团队能力协作问题。这时多 Agent 架构才真正有意义。

在这次的重构实践中,在下针对不同的领域/模块,因多智能体会带来额外的开销和信息损耗 加之 当前的重构活动只是为了避免上下文管理失控稀释了大模型的注意力和遵循程度,因此目前只是简单地对不同的模块开启相对应的窗口唤醒 Agent 对不同模块进行重构/开发

虽然没有真正意义上的多智能体编排,但也算是一个初级的分工协作了。

image.png

收益

null

维度一:架构指标(全部可测量)

指标重构前(eab9d50)重构后(当前)变化
页面直调 API55 处 ❌0 处 ✅-100%
页面直调 store/services97 处0 处(遗留 25 处在 components/global)-74%
store/ 目录10 文件 / 287 行已删除-100%
Services 耦合pages + components 直接引用仅 components/global 遗留 25 处(待迁移)-98%
Model 层0 文件32 文件 / 2,709 行从 0 到有
ViewModel 层0 文件5 文件 / 585 行从 0 到有
API 层12 文件 / 1,367 行16 文件 / 1,622 行+33%
页面组件数91 个 .tsx127 个 .tsx+40%(新功能增长)
依赖方向四向交叉单向下行 View→VM→Model→API拓扑收敛

维度二:代码交付速度

指标传统流程(推算)AI 辅助后(git 实测)
4 个新页面骨架(51 文件 / 3,141 行)~12d¹1d(2026-04-16 单次 commit)
68 文件组件库全量迁移~15d¹5d(2026-03-18 → 2026-03-23)
状态管理架构迁移(14 文件 / +1,348 行)~5d¹同日完成(2026-03-23)

¹ 推算依据:按 200-250 行/天的前端典型效率,含理解设计、手写样式、联调状态。

维度三:视觉验收效率(实测)

指标传统人工验收AI 自动化验收(实测)
单次验收耗时~3.5h(14 页面 × 15min/页,含截图+对比+记录)< 10 min(全自动,生成 HTML 报告)
覆盖测试点仅静态页面,依赖 reviewer 记忆29 个点(14 静态 + 15 交互态)
问题定位人工描述diff 图 + 区域坐标 + 像素计数
可重复性每次结果不同确定性输出

研发流程总图

null

总结与展望

这次的 AI 重构实践,本质是一场通过 Harness 的工程实践来「对抗熵增」,我们通过 SDD 规范驱动开发、规则约束、验证循环等阻尼机制,让 AI 在面对无序的需求时,生成有序的代码,从而提升了系统的可维护性和复用率。

本文的实践只是 Harness 的冰山一角,回顾 AI 时代下的系统构建,我们可以将其分为三个层次:

  • 提示词工程 (Prompt engineering):精心设计模型接收到的指令和输出格式
  • 上下文工程 (Context engineering):管理模型渐进式披露上下文。
  • Harness 工程 (Harness engineering):涵盖了上述两者,再加上整个应用架构:包括工具编排、状态持久化、错误恢复、验证循环、安全执行以及生命周期管理。

image.png

而一个生产级的智能体 Harness 工程化应包含 12 个核心组件 (编排循环、提示词构建、输出解析、错误处理、工具、记忆、上下文管理、状态管理、护栏与安全、验证循环、子智能体编排、大模型)

image.png

基于此,我们可以生成一个类似于 Claude Design 的 Coding Agent,传送门: https://github.com/enson0131/mini-claude-design

参考