AI 改完代码,人却不知道它改了什么:架构漂移才是真正的成本

一个很典型的场景:我让 Agent 做一个看起来很小的需求------给取消订单加审计。

它改了十几个文件,测试也过了。我打开 diff,看了二十分钟,最后只确定一件事: 它能跑。 但它到底把系统结构改成了什么样,我说不上来。

这不是某一次翻车,而是 AI 编程里越来越常见的一种状态:

代码 diff 越来越长,架构变化越来越隐蔽。

以前一个人改代码,review 时还能从文件名和调用关系里还原意图。现在 Agent 一次 改十几个文件,每个改动单看都合理,合起来却可能是一次结构迁移。你看到的是一堆 行级变化,不是"系统从 A 变成了 B"。

这就是我说的架构漂移。

一、代码 diff 看不见结构

代码 diff 回答的是"哪几行变了"。但人真正想知道的是:

  • 有没有新增模块?
  • 有没有新的跨层依赖?
  • 某个实体是不是从订单模块挪到了支付模块?
  • 公开接口有没有变大?
  • 这个改动是临时补丁,还是长期结构?

这些问题,行级 diff 很难回答。

举个很小的例子。Agent 为了让取消订单能写审计日志,可能会做三件事:

  1. 在订单模块里直接 import 审计模块;
  2. 把审计实体放在订单模块下;
  3. 顺手把"发送审计事件"的逻辑塞进订单服务。

每一行都能跑,测试也可能过。但结构上,订单模块多了一条对审计模块的直接依赖, 审计实体放错了位置,订单服务的职责也变大了。

下一次有人想在别的模块复用审计能力,发现它和订单绑死了;再下一次有人想拆模块, 发现依赖已经绕成一团。

AI 不是故意乱写。 它是在局部做最合理的决策:当前文件里有什么,就近用什么。 问题是它没有一个稳定的全局结构参照,所以每个局部最优加起来,就变成了整体漂移。

二、架构漂移有三种常见样子

1. 依赖漂移

本来 orders 只应该依赖 domain,结果为了省事直接依赖了 payment。 代码能跑,但分层被穿透了。

2. 边界漂移

一个工具函数在三个模块里各复制了一份;一个本该 internal 的实体被跨模块引用; 一个新模块没有正式登记,只存在于某个目录里。

3. 语义漂移

模块名字没变,职责变了。orders 里开始处理通知,notifications 里开始拼订单 查询。名字还是那个名字,系统已经不是那个系统。

这三种漂移有一个共同点:测试不一定报错,代码 review 也未必看得见。

三、为什么提示词管不住漂移

我们通常会在提示词里写:

不要改支付模块。 不要引入新依赖。 保持现有架构。

这些话不是没用,但它们是软约束。

Agent 的上下文一长,早期约束会被稀释;遇到一个"顺便"的调用,它可能觉得改了更 合理;更常见的是,它根本不觉得那叫"改架构"------它只是在让代码跑通。

提示词能表达意图,但不能形成可检查的结构事实。

四、Jin 的做法:把结构变成可检查的事实

Jin 让项目维护两层小型架构:

  • L0:系统、包、模块、分层、外部依赖、约束;
  • L1:每个模块里的实体、位置、字段、方法、关系。

Agent 要改结构,不是直接改正式架构,而是创建一个提案,编辑目标快照。校验会检查 目标架构里的引用、公开实体和分层约束;应用后的漂移检查再对照真实代码:

  • 模块路径是否存在;
  • 实体位置和符号是否真实存在;
  • 公开实体是否登记;
  • 跨层依赖是否违反约束;
  • 代码里是否出现了未登记的公开符号。

校验通过后,用户审批,目标才写入正式 arch/。

这并没有让 Agent 变慢,而是让"结构变化"从隐性变成显性:

  • 它想新增模块,提案里会出现新模块;
  • 它想加依赖,差异里会出现依赖边;
  • 它想把实体挪走,位置变化会被标出来;
  • 它写了未登记的公开符号,漂移检查会警告。

人不需要从十几个文件的 diff 里猜结构,而是先看结构有没有变。

五、漂移检查不是万能的

要说清楚:Jin 的漂移检查是声明级的,不是完整编译器。

它能发现:

  • 声明的文件或符号不存在;
  • 模块路径不存在;
  • 代码里有未登记的公开符号;
  • 实体位置跑到模块目录外;
  • planned 实体已经提前存在。

它不能证明:

  • 代码实现符合业务意图;
  • 没有性能问题;
  • 没有安全漏洞;
  • 测试覆盖足够。

所以它不是"架构正确性证明器",也不是代码 review 的替代品。它解决的是一个更窄、 但很烦的问题:结构变化不可见。

六、我真正想要的不是"更快的 AI"

我不需要 Agent 再快一点。我需要它在改结构的时候,留下一个我能看懂的东西:

  • 改之前是什么;
  • 改之后是什么;
  • 为什么改;
  • 哪些模块和依赖被动了;
  • 我有没有批准过这个版本。

这也是我做 Jin 的起点。不是让 AI 少写代码,而是让它写完之后,人还能说清楚 系统发生了什么。

项目地址:

github.com/ZYF93/openc...

v2.0.32-jin.1 下载(macOS / Windows / Linux):

github.com/ZYF93/openc...

中文完整指南:

github.com/ZYF93/openc...

Jin 是 OpenCode 的社区分支,不是 OpenCode 官方产品。项目还很早期,欢迎拍砖。

相关推荐
狂潮lister1 小时前
狂潮 · 元理论v1.0-原创架构设计-AI 网关 | 第9篇:KC-AI‑Gateway(一套可审计的大模型网关完整架构实践)|【完整版】
人工智能·后端
sycmancia1 小时前
Qml——Text元素
java·前端·html
鶴哥只手遮天1 小时前
雷达系统与成像仿真:从电磁散射到工程实现-第 2 章 雷达方程、链路预算与探测边界
后端
DevChronosands_1 小时前
浅谈感受之 React 与 Vue 😒
前端
代码猎人1 小时前
前端怎么掌握模块化
前端
天才熊猫君1 小时前
前端队列,我是怎么从 `push + shift` 换成游标的
前端·javascript
ZhengEnCi1 小时前
AI时代什么样的程序员不会被淘汰:三种代码组织方式的改动成本实测
后端
星_离1 小时前
《Ajax - 实战基础篇》
前端·ajax
对象存储与RustFS1 小时前
GPU 在空转等数据?PyTorch 训练集进 RustFS 的三种接法
后端·docker·云原生