架构漂移治理:当代码和架构图开始互相说谎
【免费下载链接】archifyTurn any idea, plan, or codebase into a beautiful interactive diagram. An agent skill for Claude Code, Codex, and more.项目地址: https://gitcode.com/GitHub_Trending/arch/archify
几乎每个经历过一年以上迭代的团队,都见过这种场景:PR 里改动的代码越来越复杂,而画在文档里的架构图还停留在"上线第一周"的版本。新人照着图理解系统,被误导;老人知道图不对,但没人有空改。等到某次事故复盘,所有人盯着那张优雅的架构图,才意识到它和线上真实行为已经毫无关系——这就是架构漂移(Architecture Drift):文档债务里最贵的一种。它不产生任何功能缺陷,却让每一次维护、排障和评审都支付隐形成本。
而最近 AI 编程工具的爆发让这个问题变得更有意思:模型能几秒生成漂亮的架构图,但图里的组件、依赖、边界有多少是真实代码里存在的?GitHub Trending 上连续数周霸榜的 Archify(v3.0.1,社区报道累计超过 2.8 万星)给出了一个反直觉的答案——让 AI 生成图,但用确定性程序去校验图。本文不聊口号,直接从仓库源码拆解它的"双向依赖比对"到底在比什么、怎么比、以及如何把漂移检测变成日常研发流程的一部分。
一、漂移是怎么发生的:需求迭代中的文档债务
架构图失效从来不是单次事件,而是一条平滑的滑坡。需求迭代时,开发者的注意力天然集中在"让功能跑通":加一个缓存、引入消息队列、把某条调用链改异步——每一次都在改变系统的真实拓扑。而架构图维护是典型的"低优先级高成本"工作,于是它被无限推迟。结果是:
- 拓扑失真:图上没有的组件(新引入的服务)和图上还在的组件(已被替换的中间件)并存;
- 边界失真:安全组、信任区域、数据库私有边界在图上维持原样,代码里的跨边界访问早已蔓延;
- 依赖失真:调用方向、通信协议、同步/异步语义被悄悄改写,图却纹丝不动。
社区对这一问题的关注度正在肉眼可见地上升:2026 年 9 月的多篇技术周刊都把"架构图可核验"列为 AI 编程工具链的关键趋势,观点高度一致——AI 进入生产流程后,结果的可验证性比生成速度更重要。而 Archify 恰好踩中了这个交叉点:它的核心机制是"AI 生成结构化 JSON,再由确定性程序渲染与校验",把"AI 会一本正经地编造"这个最大风险,从根上按住。
二、Archify 的双向依赖比对原理,一次讲透
"双向依赖比对"听起来玄,拆开其实是一套非常克制的工程方案。它的全部核心逻辑都在一个文件里:archify/delta/architecture-delta.mjs(1313 行,无外部依赖)。理解它只需抓住四个环节。
1. 先让两份快照"有身份"
漂移检测的前提,是能回答"这份图和那份图描述的是不是同一个系统"。Archify 要求每个组件有稳定的id、每条连接有id、每个边界用kind + label作为派生身份。比较前,stableIndex 会先做完整性检查:缺 id、有重复 id 都会直接以delta/stable-id-required、delta/duplicate-stable-id这类机器可读错误码拒绝比较,并给出supportedFixes。
更关键的是防错配逻辑:如果两份快照没有任何共享组件 id,比较器直接失败——"Archify cannot prove that they describe the same system"(delta/no-shared-component-id)。如果两侧都写了meta.repository且指向不同仓库,同样拒绝(delta/repository-mismatch)。先证明可比,再谈差异,这是它与普通 diff 工具的本质区别。
2. 用 canonical 序列化做"深度相等"
架构 JSON 里字段顺序无关紧要,直接字符串比较会产生大量误报。architecture-delta.mjs第 18 行起实现了一个canonical()函数:递归地对对象键排序、对数组元素排序,然后序列化成字符串比较。组件里的sources、边界里的wraps都会被先行规范化。这份 canonical 化的结果还会产出semanticSha256——两份快照的"语义指纹",让"内容变了没有"可以被哈希化、可被机器审计。
3. 分类引擎:语义、拓扑、证据、几何分层判定
这是整个比较器最精巧的部分。它把每个实体的字段按"类别"分组(COMPONENT_FIELDS / CONNECTION_FIELDS / BOUNDARY_FIELDS):
- semantic(语义):type、label、sublabel、tag 等——"它是什么";
- topology(拓扑):from、to——"它连向谁";
- scope(范围):wraps——"边界圈住谁";
- evidence(证据):sources——"它有没有源码依据";
- geometry(几何):pos、route、via 等——"它画在哪、怎么画"。
statusFor()据此给出六种状态,优先级从高到低:语义/拓扑/范围变化 →changed;仅证据变化 →evidence-changed;仅几何变化 → 组件是moved、连接是rerouted。同一个实体的变更会被精确归类,而不是笼统地标一个"modified"。
4. 输出带证明层次的机器回执
compareArchitecture()的返回值非常"工程化":summary里按 added / changed / removed / moved / rerouted 分组计数,changes里列出每一个变化实体的changedFields(精确到/sublabel、/from、/wraps这种 JSON 路径),identity说明身份规则,limitations声明边界。最值得注意的是proofLevel:
- 两份快照都带 40 位十六进制 commit revision,且源码证据通过 Git 校验时 →
revision-pinned(钉死到真实 commit); - 否则 →
authored(只代表作者写入的内容)。
也就是说,这份比对报告自报可信等级,绝不假装自己比实际证据更权威。
仓库里有一个现成的完整案例,可以直接感受输出质量:
- 基线快照 checkout-platform.base.architecture.json:8 个组件,Checkout API v1 + Redis 会话缓存;
- 变更后快照 checkout-platform.head.architecture.json:引入 Fraud Gate(新增组件)、移除 Session Cache、授权调用从 orders 改由 fraud 发起。
运行compare后,校验回执 精确报告:组件 +1 / -1 / 变更 1 / 移动 1,连接 +1 / -1 / 变更 2 / 重路由 1,边界范围变更 2 处——连session-read连接被删除、authorize-payment的from从orders变为fraud这种拓扑级变化都逐一列出,28 项校验全部通过。渲染出的可视化结果对每个节点打上标记:+新增、−移除、~变更、↔移动或重路由、E证据变更:
必须强调的是,这份"双向依赖比对"在语义上极其克制。回执的limitations写得明明白白:只比较作者写入的 Architecture IR,不推断运行时影响、因果关系、风险或合并安全性。图上可达不等于运行时真的会调用,这一点 Archify 不越界。这种"知道自己不知道什么"的克制,恰恰是它能在工程场景立足的原因。
三、治理落地:漂移检测放进日常研发流程
原理讲完,最实际的问题是:怎么让漂移检测不变成又一次"忘了维护的文档"?Archify 的答案是把校验做进工具链,而不是靠人自律。
1. 一行命令,进 PR 评审
完整的比对命令定义在 bin/archify.mjs 的 usage 中:
node bin/archify.mjs compare architecture base.json head.json architecture-delta.html --json--json输出机器可读回执,--receipt可指定回执落盘位置,--quality standard|showcase控制校验强度。设计评审时,把"上次发布时的快照"和"本次 PR 后的快照"丢给这条命令,几分钟内就能得到一份钉在 commit 上的差异报告——漂移检测终于可以从"人工对照两张图找不同"变成"机器读 JSON"。
2. 门禁链:不是"生成了图",而是"图通过了五道校验"
社区情报里流传的"交图前过五道校验"并非夸张。查看 SKILL.md 中的工作流定义,finalize是一条完整的门禁链:validate(Schema + 布局规则校验)→deliver(在目标同目录生成候选)→check(严格 provenance 校验)→browser-check(真实浏览器渲染检查)。只有全部通过,候选才会通过原子输出替换上一份可信结果——半写入或校验失败的中间状态永远不会成为最终交付物。失败时,validate --json/deliver --json仍然只输出一个 JSON 对象,返回稳定规则码、精确到对象的subject和真正支持的修复旋钮supportedFixes,并限制最多两轮聚焦修复,杜绝"整图重写"式打补丁。
这套设计把"图错了"从一次性的、不可复现的模糊反馈,变成了可审计、可修复、可回归的工程事件。
3. 让图"长"在代码上:revision-pinned 证据链
漂移检测最怕的是"比对的两份快照都是编的"。Archify 的防线是源码证据:带证据的 Architecture 节点会显示SRC n标记,可打开由 Git 校验、固定到公开 commit 的文件与行号。配合--repo-root参数,finalize会在首版草稿时就校验真实仓库中的引用。结合上一节的proofLevel,这就构成一条完整的证据链:快照 → commit → 真实源码。图的拓扑不再只存在于 JSON 里,而是可以被追溯回具体代码行。
整体管线可以浓缩为这样一张图——从想法/仓库出发,经 Typed JSON IR、确定性校验、原子交付,最终产出可交互 HTML 成品:
4. 落地的现实建议
基于仓库的实际机制,把漂移治理嵌入日常流程时有三条可操作路径:
- 设计评审挂 compare:每个涉及架构变动的 PR,附上 base/head 快照的 compare 回执,让"加了什么、移了什么、边界圈住谁变了"成为评审的必备输入;
- 发布前跑 finalize 门禁:把
finalize --quality showcase接进 CI 或发布前置检查,让"校验失败 = 不允许交付"成为硬规则,而不是口头约定; - 用 receipts 攒历史:每一次成功的 compare / deliver 都会留下机器可读回执(含 SHA256 指纹与校验统计),这些回执本身就是一份"架构演化日志"——比任何人工维护的变更记录都可靠。
结语
回到标题的问题:代码和架构图为什么开始互相说谎?因为架构图长期被当作"静态产物"维护,而代码是"动态过程"的载体,两者之间缺少一条自动对账的链路。Archify 的启示在于:它没有试图让 AI 变得更"聪明"来消除谎言,而是用确定性程序、稳定身份、分层分类和证明等级,把"比对"这件事变成了可验证、可审计、可进 CI 的工程能力。架构漂移也许永远无法被彻底消灭——但只要每次漂移都能被机器精确地、低成本地捕捉到,它就从"团队内耗"降级为"常规治理项"。这或许才是 AI 时代架构治理最务实的答案。
【免费下载链接】archifyTurn any idea, plan, or codebase into a beautiful interactive diagram. An agent skill for Claude Code, Codex, and more.项目地址: https://gitcode.com/GitHub_Trending/arch/archify
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考