一个很典型的场景:我让 Agent 做一个看起来很小的需求------给取消订单加审计。
它改了十几个文件,测试也过了。我打开 diff,看了二十分钟,最后只确定一件事: 它能跑。 但它到底把系统结构改成了什么样,我说不上来。
这不是某一次翻车,而是 AI 编程里越来越常见的一种状态:
代码 diff 越来越长,架构变化越来越隐蔽。
以前一个人改代码,review 时还能从文件名和调用关系里还原意图。现在 Agent 一次 改十几个文件,每个改动单看都合理,合起来却可能是一次结构迁移。你看到的是一堆 行级变化,不是"系统从 A 变成了 B"。
这就是我说的架构漂移。
一、代码 diff 看不见结构
代码 diff 回答的是"哪几行变了"。但人真正想知道的是:
- 有没有新增模块?
- 有没有新的跨层依赖?
- 某个实体是不是从订单模块挪到了支付模块?
- 公开接口有没有变大?
- 这个改动是临时补丁,还是长期结构?
这些问题,行级 diff 很难回答。
举个很小的例子。Agent 为了让取消订单能写审计日志,可能会做三件事:
- 在订单模块里直接 import 审计模块;
- 把审计实体放在订单模块下;
- 顺手把"发送审计事件"的逻辑塞进订单服务。
每一行都能跑,测试也可能过。但结构上,订单模块多了一条对审计模块的直接依赖, 审计实体放错了位置,订单服务的职责也变大了。
下一次有人想在别的模块复用审计能力,发现它和订单绑死了;再下一次有人想拆模块, 发现依赖已经绕成一团。
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 少写代码,而是让它写完之后,人还能说清楚 系统发生了什么。
项目地址:
v2.0.32-jin.1 下载(macOS / Windows / Linux):
中文完整指南:
Jin 是 OpenCode 的社区分支,不是 OpenCode 官方产品。项目还很早期,欢迎拍砖。