🟢 入门

给一个已成型的项目画结构图:不读一行代码,画出「有哪几块、谁用谁、谁在改同一份数据」

你感觉到的「修 A 出 B、越改越多」,绝大多数不是你不会改,而是同一份东西被好几处同时改。这篇不教你读懂代码——读代码是 AI 的活。它教你把这三张表画出来,再用「改一下、看会怎样」验它准不准。

📅 更新于 2026-09-16

3
要画的表只有三张,第三张最关键
0
需要你读的代码行数
三十几
ai-teach 里同一段程序被逐字复制了这么多份
1
全站样式只有一份,所以它属于「干净的那种」

0030 秒速览:三句话、起手动作、以及你手上必须有什么

如果只记三句话

🎯 记住了,后面都是细节

① 结构图回答的不是「代码怎么写的」,是三个关于关系的问题:有哪几块、谁用谁、谁在改同一份数据。你要判断的是关系对不对,不是代码对不对——这是两个完全不同的活。

② 一个东西被多少处「用」不重要,被多少处「改」才重要。全站样式被三十几个页面用,但它只有一份、只有一个地方能改,所以它从来不给你惹麻烦。反过来,同一份东西存了三十几份、你还得手动让它们保持一致——那才是你「越改越多」的来源。

③ 你不用读懂代码,就能验这张图准不准:改一个小东西,看实际有几处跟着变。变了的地方比图上多,就是图画漏了;比图上少,就是图多画了。你不需要知道为什么变,只需要知道会不会变。

起手动作:读完 60 秒内,你要做的第一件事

打开你手上最小的那个半途项目(烂尾的、你看不懂的,都行),让 AI 编程助手(能读你电脑里文件的那种 AI 工具)读一遍它,然后问一句话(你打给 AI 的那段话,行业里叫「提示词」):

# 这是一段提示词,整段复制,粘给 AI 编程助手
先不要解释任何代码。把这个项目分成 5 到 15 块,每块给我:
1) 一个中文名字,不要用行业词
2) 一句话:它负责什么
3) 它包含哪些文件或目录,列路径
不确定的地方标注「不确定」,不要猜。

但在按下回车之前,先做一个小动作:拿张纸,写下你猜它会列出几块。然后发送,对一下差多少。

为什么要先猜?因为这一猜,就把这件事从「听 AI 汇报」变成了一次实验。你的猜测和它的答案之间的差距,就是这个项目里你还没看见的那部分。第 6 节会把「先猜、再改、后对账」这套动作拆开讲——它是全文最值钱的一段,而你现在做的正是它的第一步。

做这个动作之前,你手上必须有什么

⚠️ 这篇假设你已经有这两样

1. 一个已经存在的项目目录——哪怕烂尾、哪怕你一行代码都看不懂。这篇文章不会教你从零建项目。它的全部前提是「已经有一堆东西在那儿了」。

2. 一个能读你本地文件的 AI 编程助手——注意是「能读文件」的那种(Claude Code、Codex、Cursor 这类装在电脑上、能看见你项目目录的工具),不是网页聊天窗口。只开一个网页对话框没用:它看不见你的文件,只能听你转述,而你转述不出来的恰恰就是你不懂的那部分。

手上没有项目?那这篇文章你照样现在就能练——全篇的例子用的是 ai-teach 这个站本身,也就是你正在读的这个网站。它就在你手上、你天天看、而且它小到你几分钟就能走完一圈(第 5 节)。等拿它练完手,再回去开你那十几个烂尾项目里最小的那一个。

数字先给量级

这篇里会反复出现几个数字,它们都来自这个站自己,而且你随时可以自己数一遍(命令在最后一节):

这个站里有什么数量为什么这个数字值得记住
全站样式(决定所有页面长什么样的一份文件)1 份被三十几个页面同时用,但从不出事——因为只有一处能改它
行为脚本(让按钮能点、目录能开的那份程序)1 份同上。这两个是「一对多」关系里健康的样子
页面顶部那段「先决定用深色还是浅色」的小脚本三十几份同一段文字被逐字抄进了每个页面。改它必须一次改三十几处
校验脚本(一个替你做检查的程序)1 个它不认识你的意图,只核对「几处数字对不对得上」

注意第一行和第二行,跟第三行的差别:都是「一个东西被很多地方用」,但第一二行只有一处能改,第三行有三十几处能改。这个差别就是这篇文章的全部要害。

01先破一个错想:这件事不是「读懂代码」

你可能已经这样想过了

🚫 那个把你挡在门外的想法

「画结构图,那得先看懂代码吧。我看不懂代码,所以这件事我做不了。」

这个想法非常合理,而且它合理得值得说清楚为什么——因为如果它是个明显的蠢念头,你不会被它挡住这么久。

它有三个看起来很硬的理由:

1
你见过的每一张结构图,都是懂代码的人画的

所以你自然推出:画它需要懂代码。但这只说明那些人懂代码,不说明这件事要求懂代码——就像你见过的每份体检报告都是医生写的,不代表你不能自己量个血压。

2
图上的词你不认识

「服务层」「中间件」「解耦」——这些词确实像门槛。但它们不是门槛,是行话。行话可以被替换成人话,门槛不能。这篇文章会证明:换成人话之后,图还是那张图,而且更有用。

3
所有讲这事的材料都在讲「怎么画」,没人讲「怎么问」

那些工具(画图的软件、各种图例规范)都在解决「形状怎么摆」,前提是你已经知道要摆什么。而你的问题在更前面一步:我怎么知道要摆什么?没人回答这个问题,于是你只能猜「大概需要先读懂代码吧」。

真相是:你要画的关系,AI 读代码就能给你

把这件事拆开,其实是两个人的活:

AI 的活:从文本里推出关系

「文件 A 里出现了文件 B 的名字,说明 A 用了 B。」
「这份数据在 C、D、E 三个文件里各存了一份。」

这事它比你快一万倍,而且它不嫌烦。你完全不必自己干。

你的活:判断这些关系对不对

「它说 A 用了 B——那我把 B 改一下,A 真的会跟着变吗?」

这件事 AI 做不了,因为它只能读,不能改。而你能改。

这里有个关键区别,值得单独说一句:AI 是从「写下来的文字」推关系,你是从「改一下之后真的发生了什么」看关系。文字会说谎——某个文件里写着「用到了订单模块」,但那段代码可能从来没被执行过。行为不会说谎。

所以你的位置不是「不如 AI」,而是补上了 AI 唯一缺的那一环:AI 给你一张申请的图,你负责验它。验完,这张图才从「AI 说的」变成「你知道的」。

一个类比:这张图像大楼的消防图

💡 消防图上没有一句话讲墙是怎么砌的

消防图不告诉你墙用什么材料、钢筋多粗、线路怎么走——那是施工队的事。它只告诉你三件事:

1. 有几个房间(对应表一:有哪几块)
2. 哪扇门通向哪个房间(对应表二:谁用谁)
3. 哪条走廊是唯一的出口——堵了就全都出不去(对应表三:谁在改同一份数据)

这三件事,一个不懂建筑的人也能看懂、也能验:指着门问「这扇门真的通那边吗」,走一遍就知道了。

这个类比的边界在哪:消防图不会告诉你「这面墙能不能拆」。同样,本文这张图不回答「这段代码写得好不好」——它只回答一个问题:我要动的这个东西,会牵动什么。你要是拿它去问「我这项目的整体设计优不优雅」,那是我误导了你。

为什么「关系」比「代码」更要紧

回到你真实的那个感受:「修 A 出 B,越改越多」。

这件事几乎不会发生在「代码写错了」的时候。代码写错了,你改那一行,它就对了。它发生在你以为你在改一个地方,其实你同时改动了另一个地方的命根子的时候。

而「另一个地方」在代码里通常长得跟你改的东西毫无关系——它可能是另一个文件、另一个页面,甚至另一份配置(存设置的那份文件)。你从字面上看不出它们连着。这就是为什么你需要一张图:图上画的就是那根看不见的线。

02表一 · 有哪几块:把项目分成 5 到 15 块

这张表长什么样

块的名字(用人话)它负责什么(一句话)它包含哪些文件
读文章的界面把一篇文章显示出来,能滚动、能开目录、能切深浅色所有页面文件本身
全站外观决定每个页面长什么样:字体、颜色、间距样式那份文件
交互行为让按钮能点、目录能开、搜索能用脚本那份文件
首页列表把所有文章排成卡片,让人点进去首页文件
生成器按规矩生成新文章、生成卡片、检查有没有出错生成器那一整个目录

就长这样。没有一行代码,没有一个你听不懂的词,长度不超过一屏。

最容易搞错的一处:文件列表不等于「块」

错:把目录结构当成块

src/ 下面有 components/、utils/ 这些文件夹……照抄一遍目录树,一行一层,画了四十行。

问题:目录结构回答的是「文件放在哪」。可文件会搬家——今天放 utils/ 的下个月挪到 lib/,而「它负责什么」没变。你抄下来的是会过期的信息。

对:块 = 一起变的东西

把「改一个功能时要一起动的那些文件」圈成一块。块的名字来自它负责什么,不是来自它放在哪个文件夹。

判断法:改这个功能的时候,你会同时打开哪几个文件?那几个就是一块。

怎么判断一块划得好不好

✅ 一句话检验

这一块能不能只用一句话说清「它负责什么」,而且这句话里不需要提到别的块的名字?

能 → 这块划得干净。
不能,比如你非得说「它负责给订单那块准备数据」——那它跟「订单那块」要么该合并,要么它们的边界划错了,得重划。

这条检验你完全可以自己做,不需要懂代码。你需要的只是「这句话读起来别扭吗」的语感。

块的数量:5 到 15 块

这里有个来自画图规范的建议,可以直接拿来用:C4 模型(一套公开的软件结构画法)明确说「你不需要画满所有层」——它建议多数团队画到「系统上下文 + 容器」这两层就够了,再往下是给要改代码的人看的。来源见文末。

翻译成你的判据:画到「再往下画就需要懂代码了」那一层,就停。那一层之上的所有内容,都是你该管、也管得动的。

03表二 · 谁用谁:每块被别人从哪几个口子用

这张表长什么样

谁用了谁从哪个口子用(具体到文件或功能名)
首页列表文章页面卡片上的链接,点一下跳过去
文章页面全站外观页面顶部引一下那份样式文件
文章页面交互行为页面底部引一下那份脚本
生成器文章页面直接生成出这些文件
校验脚本首页列表读出每张卡片的日期,跟文章里的日期比

为什么要画这张表:它就是「改动的影响半径」——改了它,波及到哪一圈

这张表回答一个问题:我把 B 改了,谁会跟着疼?

行业里管「A 用了 B」叫 A 依赖 B,管两组东西「一处变了、另一处必须跟着变」这种关系叫耦合。这两个词你以后会一直撞见,现在你知道了:它们说的就是这张表上的箭头。箭头指向你的时候,你就在影响半径里。

这张表最大的用处是看方向:

健康:箭头大致朝一个方向

A 用 B,B 用 C。你要改 C 的时候,知道自己得去看看 A 和 B——数得清,跑得完。

更健康的是「一个东西被很多处用,但只有一处能改它」:这个站的样式文件就是这样。三十几个页面都引它,可它只有一份,改它就等于改全站,不会有「漏改一个」这种事。

麻烦:箭头互相指

A 用 B,B 也回头用 A。这时候你改 A 会影响 B,改 B 又会影响 A——你没法只改一边。

这是「越改越多」最典型的产地:你以为在给 A 打补丁,其实同时在给 B 制造新问题,然后你去修 B,又回头碰 A。

最容易搞错的一处:把「名字出现了」当成「真的用了」

⚠️ 这两件事经常不一样

AI 是从文字找关系的,所以它容易把这两种情况混起来:

「文件 A 里出现了 B 的名字」——这只是文字上的引用。
「A 真的会走到 B 那条路上去」——这才是真的用了。

差别在哪?一个项目里经常有一段代码写着「如果出错,就调用紧急处理流程」——但那个错误从来没发生过,所以那段紧急处理流程一次都没跑过。它在图上画着一条线,实际上那条线是死的。

这正好说明:图上有一条线,不等于那条线活着。这就是为什么你后面必须用「改一下看会怎样」去验(第 6 节)。

所以在要提示词的时候,得逼 AI 把「确定的」和「疑似但没确认的」分开列——第 7 节的第二段提示词就是干这个的。

这张表要画多细

判据:画到「你改之前能一眼看出该去哪几个地方看一眼」就够了。

不要试图画全。你不需要知道 A 里的第 37 行调用了 B 里的第 12 行——你需要知道的是「我要动 B,所以我得先打开 A 看一眼」。

04表三 · 谁在改同一份数据:最关键的一张

如果这三张表你只画一张,画这张。你感觉到的「修 A 出 B」,绝大多数出在这里。

先把这张表要抓的东西说清楚

它抓的不是「数据」这个词的字面意思——不只是数据库里的东西。它抓的是任何「同一份东西,在项目里存在不止一处」的地方。

这种东西长什么样?举几个你项目里几乎一定有的:

它的两种形态,必须分开看(这是最容易混的地方)

「同一份被好几处碰」其实有两种完全不同的情况。它们长得很像,坏的方式却不一样,修法也完全相反。把它们混成一件事,你就会用错药。

形态它长什么样它坏在哪该往哪个方向修
共享
一份东西,好几处在读写
一份数据放在那儿,三个功能都能改它坏在顺序上:谁先改谁后改,结果不一样。单独跑都对,一起跑就错减少能改它的入口——让只有一处能写,其他只能读
复制
一份东西,好几处各存了一份
同一段文字/同一条规则,在 3 个地方各写了一遍坏在漏改上:你改了其中一处,忘了另一处。系统不报错,只是从此两处说的不一样了让一份从另一份自动生成,而不是靠你记得同步

这个区分背后有一条老规矩,出自 1999 年的《程序员修炼之道》(The Pragmatic Programmer),原文是:「每一条知识,在系统里都只能有一份、明确的、有权威的表述。」行业里把它缩写成 DRY 两个字。来源见文末。

但注意——这条规矩说的是「每一条知识」只留一份,不是「每一段长得像的文字」都该合并。这个区别很重要,第 9 节会专门讲它,因为搞反了会把事情弄得更糟。

这张表长什么样

四列,缺一不可。下面这张表举的例子,是这个站自己——下一节会带你把它完整走一遍,这里先看一眼形态:

这份东西是什么(用人话)它总共存了几份谁在写它我改了其中一处、忘了别处,会出什么事
页面顶部那段决定深色浅色的小脚本三十几份(每个页面各一份逐字副本)人手动改不会报错。只有那几篇漏改的页面,打开时会闪一下白——你多半看不到,但访客看得到
首页卡片上显示的更新日期2 份(文章里一份、首页卡片上一份)生成器自动写校验脚本会直接报错:卡片日期 ≠ 文章日期
网站名字2 份(配置里一份、首页上显示一份)人改配置校验脚本会报错,说首页上找不到那个站名
全站外观1 份人改什么都不用担心——改一处,全站自动跟着变

现在回头看这张表,注意一件事:第一行和第二三四行的差别,不是「被多少处用」,而是「有多少处能改它」。

🎯 这张表唯一要你记住的一句

一个东西被多少处「用」不重要;被多少处「改」才重要。

一句话推断出它的用途:看到「被很多地方用」先别紧张,去数「有几处能改它」。数是 1,你可以放心;数出来是三十几,那你每改一次都得把三十几处一起改——下一节就有一个活生生的例子。

为什么这张表的杀伤力最大

回到表一那个「看方向」的说法。共享和复制这两种情况,破坏力之所以大,是因为它们在图上是一条不显眼的线,但在现实里是一整片:

一个判断题:这张表什么时候算画完了

当你能对着项目里任何一处改动,回答出「这份东西还在别处存着吗」的时候。

答不上来,就继续问。答得上来,这张表就够用了——它不需要完整,它需要的是在你要动手的时候站在你手边。

05最小例子:拿 ai-teach 这个站走一遍三张表

为什么用这个站:你正在读它。它小到几分钟能走完一圈,而且每一处结论你都能自己核对——文末给了核对命令。

先看表一:这个站有哪几块

块的名字它负责什么它包含哪些文件
文章页面把一篇文章显示出来,能滚动、能开目录、能切深浅色三十几个页面文件
全站外观决定所有页面长什么样style.css 一份
交互行为主题按钮、手机上能把目录拉出来的那个开关、搜索、排序、复制代码按钮theme.js 一份
首页列表把文章排成卡片、支持搜索和筛选index.html
生成器生成文章、生成卡片、检查有没有出错生成器目录里的说明书、题材表、风格规范、校验脚本
站点配置存站名、副标题、以及「这个站写给谁看」learn.config.json

六块。注意「全站外观」和「交互行为」各只有一份文件——这是好事,先记住,下面会用上。

再看表二:谁用谁

谁用了谁从哪个口子用
首页列表文章页面每张卡片是一个链接,点一下跳过去
文章页面首页列表页面右下那个「返回目录」按钮
文章页面全站外观页面顶部引一下 style.css
文章页面交互行为页面底部引一下 theme.js
首页列表全站外观、交互行为同上,首页也引这两份
交互行为首页列表脚本会读出每张卡片上的标题、简介、日期、难度标签——用来做搜索和排序
生成器文章页面、首页列表、站点配置生成它们,并读配置里的站名和读者画像
校验脚本文章页面、首页列表、站点配置读出几处数字,互相核对

箭头不少。但看方向:它们基本是从上往下的——「生成器」和「校验脚本」站在最上面,读下面所有东西;下面的东西之间只有几条水平线。没有「互相回头指」的死结。

最后看表三:这个站里,谁在改同一份数据

这是全篇的核心。我把这个站里真实存在的三处列出来,按「改一处会牵动几处」从多到少排:

这份东西是什么存了几份谁在写我改一处、忘了别处,会出什么事
页面顶部那段「先决定深浅色」的小脚本三十几份
(每个页面各存一份逐字相同的副本)
人手改什么都不报错。只有你漏改的那几篇,打开时会闪一下白。校验脚本能抓到——但它抓的方式是「拿每篇的那段跟首页那份比」,所以真正的规则是:改它必须一次改三十几处
首页卡片上的更新日期2 份
(文章里一份、卡片上一份)
生成器写校验脚本直接失败,并明确告诉你「卡片上的日期和文章里写的对不上」。这是会喊疼的那种
网站名字2 份
(配置里一份、首页上显示一份)
人改配置校验脚本失败,说首页上找不到配置里的那个站名

然后,把第四行补上——这个站里不属于这张表的东西:

这份东西是什么存了几份谁在写改一处会怎样
全站外观(style.css)1 份人手改改一处,所有页面同时跟着变。不会漏,不会不一致。这是你想要的样子
交互行为(theme.js)1 份人手改同上

现在把这两张表并排看——这就是这篇文章想让你亲眼看到的东西:

🎯 一组对照,看完整篇都值了

样式文件:被三十几个页面用,只有 1 处能改 → 从来不给你惹麻烦。
主题引导脚本:也被每个页面用,但有三十几处能改 → 改一次要改三十几遍,漏了就静默出错。

它们被「用」的规模几乎一样。差别只在能被「改」的地方有几个。

这个站真的栽过一次

2026-09-16,这个站为了在首页加一张卡片,改完发现要回滚(回滚就是把改动退回去、恢复成改之前的样子)。

表面上看,那只是「加一个卡片」。但按上面这两张表拆开看,加一张卡片要动的是:

1
在首页加上那张新卡片

这是你想得到的那一处。

2
改首页顶栏的「共 N 篇」计数

校验脚本会核对这个数字和实际文章数是否一致。忘了改 → 直接失败。这是你没想到的第一处。

3
把卡片插到正确的位置上

卡片是按日期从新到旧排的,插错位置 → 校验脚本报「主页非按日期倒序」。这是你没想到的第二处。

4
保证卡片上的日期,和那篇文章里写的日期一致

两处数字必须相同,校验脚本逐个比。这是第三处。

5
卡片简介不超过 140 个字

超了会把整行卡片撑高,网格散掉。校验脚本按字符数拦。这是第四处。

「加一个卡片」——本来以为是一处,实际是五处。

这正好是那个信号:一个看起来很小的改动,要动的地方超过三处。出现这个信号的时候,你遇到的不是「一个 bug」(bug 就是程序出错的地方),是「结构问题」——继续埋头改只会越改越多,正确动作是停下来回头看结构。

💡 顺便说一句:上表里那个「2 份」的日期,正是「会喊疼」的那种

它之所以好,是因为有一道自动检查盯着它。没有那道检查的话,它就变成第一行那种「静默出错」了。

这一点可以直接搬到你的项目里:对于那些不得不在两处各存一份的东西,至少要留一个能自动对账的检查。没有检查的复制,等于埋雷。

06不懂代码,怎么知道图画对了:预测 → 扰动 → 对账

这是全文最值钱的一段。前面三张表都是「AI 给你的」——这一段才把它变成「你知道的」。

先说清为什么需要这一步

AI 给你的表,是从文字里推出来的。而文字有两个毛病:

所以「AI 给了三张表」不等于「图上是对的」。而好消息是:验证它,恰恰不需要你懂代码。

方法只有三步:预测 → 扰动 → 对账

1
挑一个「确定改得动、改错了能退回来」的小东西

一个字、一个日期、一个颜色、一张卡片——越小越好。所谓「能退回来」,是指这个项目能撤销你的改动、回到上一版(如果你用 git 管着——git 是一种记录每次改动、随时能退回上一版的工具,退回去的命令就是 git checkout;不确定的话,先复制一份整个文件夹,改那份副本)。

这个改动不必你亲自动手。你完全可以告诉 AI:「把首页第三张卡片上那个日期改成 2026-01-01」——它去改,你负责看结果。这个方法里你是观察者,不是操作者;动手那部分可以外包给 AI,只有「预测」和「对账」必须是你。

2
改之前,先写下你的预测

具体到「哪个页面、哪个数字、哪一块」会跟着变。这一步是整个方法的核心,也是唯一需要你动脑的地方——不要跳过它。没有预测,后面就无从对账,你只会得到一句「哦,好像变了」。

3
改,然后看实际变了几处

打开项目、刷新页面、跑一遍那个自动检查——用一切你能用的方式观察。不需要看懂任何代码,只需要看「什么跟着动了」。

对账:三种差,各自说明什么

你的预测实际结果这说明图上哪里错了
预测它会变真的变了图上这条线是对的。你可以信它了
预测它会变没变图上多画了一条线。你以为这两处有关,其实无关——多半是那段代码从来没被执行过
没预测到却变了图上少了一条线。——这就是你要找的东西,也正是你「修 A 出 B」的根源
没预测到变了,而且什么都没报错最危险的一类。它不是图上少了一条线的问题,是「这条线还带着一个静音开关」——它在悄悄让两处说的不一样

这个方法为什么不需要你懂代码

🎯 全文最关键的一句话

你不需要知道「为什么」会变,只需要知道「会不会」变。

「为什么」是因果关系,那需要读懂代码——那是 AI 的活。
「会不会一起变」是共变关系,你改一下、看一眼,就知道了。这是你的活。

这件事在行业里有正式名字,叫影响分析(change impact analysis)。它的标准定义是:「找出一次改动可能带来的后果,或者估计为了完成这次改动还需要改什么。」专业人士用工具做这件事(能自动把所有连线画出来的那种),你用一次真实的改动做。名字一样,问的是同一个问题:改了它,还有什么要跟着改?来源见文末。

把它变成数字:改一处,牵动几处

对账完之后,数一下:为了这一个改动,我一共动了几个地方?

1干净。这个东西只有一个写入的地方——放心改,改完就完事
2–3正常。记住这几处的对应关系,下次改的时候一起动
4+信号。这不是「一处小改」,这是结构在告诉你它有问题。下一节的动作在这里就该启动

「改一个小东西要动三处以上」——这是你能拿到的最有用的一个信号。它不要求你懂代码,只要求你数数。

现在就能做的一次实验(拿这个站)

这个站里有两处「会喊疼」的耦合,都配了自动检查。你可以直接做一次:

# 第 1 步:先数一下,现在有几处存着同一段脚本
# ("ln-theme" 是那段脚本里独有的一个词,用它来把存了副本的文件全找出来)
grep -l "ln-theme" learn/*.html | wc -l
# 你会看到一个三十几的数字 —— 每一份都是一个页面里存的那段副本

# 第 2 步:只改一处(把某一篇文章的那份改坏一个词)
# (cloudflare-overview.html 是这个站里随便一篇文章,换成你看到的任意一篇都行)
sed -i '' 's/prefers-color-scheme: light/prefers-color-scheme: dark/' learn/cloudflare-overview.html

# 第 3 步:让那个自动检查跑一遍,看它会不会告诉你
bash .agents/skills/learn/check.sh learn/cloudflare-overview.html

# 第 4 步:撤回,把项目恢复到改之前
git checkout learn/cloudflare-overview.html
💡 上面这些命令怎么跑

它们是要在终端里跑的(终端就是电脑上那个只能打字的黑色窗口,macOS 上按 Command + 空格 搜「终端」就能打开)。打开后先让终端进到项目目录里,再一条一条粘进去、按回车。

不想碰终端?完全可以。把这些命令直接粘给你的 AI 编程助手,说「帮我在这个项目里跑一下这几条,把结果告诉我」——它替你跑,效果一样。你要的是「改一下、看会怎样」这个动作,不是「学会打命令」。

第 3 步会失败,并且明确告诉你:那段脚本跟首页那份对不上了。

你刚才做的,就是一次完整的「预测 → 扰动 → 对账」:你预测「改这一处会出事」,扰动了一处,检查替你确认了。而你全程没有读一行代码。

⚠️ 但请注意第 4 步

这个实验之所以安全,全靠第 4 步——改完能退回去。

所以这条方法有一条铁律:只扰动你能撤销的东西。《怎么把「批准方案」换成「验收结果」》那篇里有一条判据也是这个意思——判断不了哪个对的时候,选「错了更容易改回来」的那个。用在这里就是:拿能复制、能撤销的部分去试,不要去碰你没法恢复的东西(比如线上的真实数据、别人正在用的东西)。

验到什么程度可以停

不要想验完整张图——那是不可能的,也没有必要。判据是:

✅ 停下来的条件

对于你「这次要动的那个地方」,图上那条线你验过了,就够了。

你不需要验证整个项目。你需要的是——在你要动手之前,那个特定位置的连线是真的。图是为这一次改动服务的,不是为了一次性把项目看透。

07可复制的提示词:三张表各一段,外加一段追问

下面四段话可以整段复制、粘给 AI 编程助手。注意它们的设计意图——这些句子不是客套,每一句都在堵一个具体的漏洞。

第 1 段:要表一(有哪几块)

先不要解释任何代码,也不要贴代码。把这个项目分成 5 到 15 块。
每块给我四样东西:
1) 一个名字,用中文、用日常说法,不许用「服务层」「中间件」这类行业词
2) 一句话说清它负责什么。这句话里如果必须提到别的块才能说清,请直接标注「和 X 块分不开」
3) 它包含哪些文件或目录,列具体路径
4) 改这一块的时候,通常还要同时动哪几个文件
不确定的地方标「不确定」,不要猜。最后用一句话告诉我:哪一块是最大的。

这几句分别在堵什么:「不要贴代码」堵它甩一堆你没用的东西;「不许用行业词」堵它用行话糊弄;「必须提到别的块就标注」就是你第 2 节那条「一句话检验」的自动化;「改这块还要动哪几个文件」是在逼它按「一起变」来分块,而不是按目录分。

第 2 段:要表二(谁用谁)

列出这个项目里「块与块之间的使用关系」,一行一条,格式是:
A 用了 B —— 从 B 的哪个口子用的(具体到文件名或功能名)

只列你确认存在的关系。如果你只是「在 A 里看到了 B 的名字」
但找不到真的会执行到的地方,不要混进来,
单独列一张「疑似、未确认」的清单给我。

最后额外回答一个问题:这些关系里,有没有互相指的(A 用 B,B 也用 A)?
如果有,单独列出来 —— 这是我最关心的一组。

关键在中间那句:把「确定的」和「疑似没确认的」分开。这正是第 3 节说的那个坑——「名字出现了」不等于「真的用了」。最后那句是让它主动把「互相指」的挑出来,因为那是麻烦最集中的地方。

第 3 段:要表三(谁在改同一份数据)——最重要的一段

停。现在只回答一个问题,不要讲别的:
这个项目里,有哪些「同一份东西存在不止一处」或者「同一份东西被不止一处改写」的地方?

不要只找数据库和配置文件。任何一份"被复制过"或"被好几个地方碰过"的东西都算,
包括:同一段代码被抄进好几个文件、同一个数字写在好几个地方、
同一条规则在前后两端各写了一遍、同一个说明文档里的内容和代码对不上。

每一处给我五行:
1) 这份东西是什么 —— 用人能懂的说法,比如「首页上显示的更新日期」
2) 它总共在几个地方各存了一份 —— 给我一个数字
3) 谁负责写它 —— 是自动生成的,还是人手改的
4) 谁读它 —— 哪些文件或功能依赖它
5) 如果我只改了其中一处、忘了别处,会出什么事 ——
   请明确告诉我是「会报错」还是「不报错、但结果已经不对了」

最后按「改一处会牵动几处」从多到少排序,第一行应该是最危险的那个。
如果一处都没有,直接说没有,不要凑。

这段里有三个地方是故意的:

第 4 段:它开始甩代码 / 说行话的时候,用这段

停。不要贴代码,也不要用「解耦」「抽象」「服务层」这类词。
用一句话回答我:这段代码是「谁改了什么」?
如果不能用一句话说清,就告诉我「说不清,因为……」。

这一段你会在整个过程中反复用到。它不是防 AI 犯错,是在防你自己糊弄自己——「我看不懂但好像很专业」这种状态下点下去的那个「好的」,是你后面所有麻烦的起点。允许 AI 说「说不清」,比逼它给一个你听不懂的答案有用得多。

用这些提示词的时候,怎么读它的回答

它给的块太多(超过 15 块),我要不要照单全收?
不要。这说明它在按文件分,不是按职责分。回一句:「请合并成不超过 10 块,合并的理由是它们改的时候会一起动。」
它说的块名我完全不认识,怎么办?
让它换。判据是第 2 节那条:这个名字能不能让我一句话说清它负责什么。说得出就留,说不出就让它用日常词重说一遍。词换不掉,说明它自己也没搞清那块是干什么的。
表三它说「没有」,可我明明觉得有。
缩小范围再问一次,别问整个项目。改成:「只在这个项目里找『同一个数字或同一段文字被写在两个以上地方』的情况,给我具体路径。」范围小了,它就编不动了。

08画完之后怎么用:改之前看图,改完更新图

改之前:三个问题,答完再动手

这就是这张图存在的全部意义。在你要改任何东西之前,先问三个问题——三张表各出一个:

问什么用哪张表答不上来的时候,说明什么
我要改的这东西,属于哪一块?表一你还没找到地方——先别改,先找
有谁在用这一块?表二你不知道改完要检查什么——这正是「修 A 出 B」的入口
这份东西还在别处存着吗?表三最危险的一种。你极可能改了一半、漏了另一半,而且它多半不报错

三个都答得上来,你再动手。答不上来的时候去问 AI——问法就是上一节那四段话。

改完:更新图,而且只改那几行

⚠️ 一张不准的图,比没有图更坏

因为没有图的时候你会小心,有图的时候你会信它。你照着一条早就失效的线去做判断,还不如没有。

所以图要跟着改。但更新图不等于重画——那太重了,重到你第二次就不会做。最小动作是:

把它放成一份文件,放在项目里

不要留在聊天记录里,也不要只存在脑子里。写成一份文件放进项目目录,名字随便(结构图.md、项目地图.md 都行),内容就是那三张表加一个日期。

两个好处,都很实际:

  1. 下次你忘了,能查。你手上有十几个项目,隔两个月回来,你不会记得任何一个的细节。
  2. AI 也能读它。下次你让 AI 改这个项目的时候,它自己会看到这份文件——于是它做的判断会带着这些关系,而不是从零重新猜一遍。
✅ 那个日期是整份文件里最重要的一个字

「更新于 2026-09-16」——它告诉你这张图是什么时候为真的。看到一份没有日期的图,你的正确反应是:不知道它现在还准不准,得当它不准。

09什么时候别做这件事

这一节和前面同等重要。前面教你怎么做,这一节防你做过头——而做过头这件事,会让一张好方法变成新的负担,然后你就再也不会用它了。

四种别做的情况

什么时候为什么别做改做什么
你能一口气讲完这个项目如果你不看任何东西、用五句话就能说清这个项目有哪几块,那这张图对你是零信息——你脑子里已经有了直接改。图是给「说不清」的项目用的
只是修一个已经知道改哪的 bug这是个真 bug,不是结构问题。先画图再修 = 用大炮打蚊子,还容易把自己绕晕直接修。修完如果发现「改了三个地方才修好」,那时候再回头看结构
项目大到你一次画不完贪全的结果是画了三小时、画出一张没人看得懂的图,然后放弃只画你现在要动的那一块,加它周围两三层。图可以一点点长出来
你只是想「了解一下这个项目」没有具体要改的东西时,画出来的图没有验证对象——你没法用「改一下看会怎样」去验它,于是它只是一份好看的文档等你要动手的时候再画。这张图的用途只有一个:回答「我改这个会牵动什么」

别做过头:长得像的文字,不等于同一份知识

这是「谁在改同一份数据」这张表最大的误用,值得单独讲。

你学会表三之后,会很想把「所有重复的东西」都合并掉。但其中有一部分不该合。

错:只要两边长得一样,就合并

项目里有两个地方都写着「满 200 包邮」。你把它们合并成一处共用。

三个月后,运营要求「只在老客户活动里包邮,日常下单不包邮」——你发现自己把两件本来会朝不同方向变的事情焊死在了一起了。拆开比当初复制一遍还麻烦。

这种「长得一样、其实是两件事」的重复,行业里叫巧合的重复。

对:看它们将来会不会因为不同的原因改变

如果这两处将来会因为不同的理由而变 → 让它们各自独立。
如果它们必须永远一样、不一样就是出错 → 合并成一处。

一句话判据:「如果这两处变得不一样了,那是个 bug 吗?」是 → 合并。不是 → 分开。

这个区分不是我编的:前面说的那条「每条知识只留一份」的老规矩,配套就有一条明确的提醒——「巧合的重复」不应该被当成重复来处理,硬合并反而会造出错误的抽象。来源见文末。

🎯 所以表三的正确用法是「标出来」,不是「立刻合并」

表三的第一价值是让你知道它在那儿——改的时候记得两边都改。合不合并是第二步的决定,而且要看上面那条判据。

先知道,再决定。别一上来就动手合并——那正是「越改越多」的另一种走法。

还有一个反向的边界

这个方法也有它看不见的地方。它只看「关系」,不看「好坏」。

一张画得完全正确的结构图,可能对应着一个写得很烂的项目,也可能对应着一个写得很好的项目——图上看不出来。所以:

知道一个方法管什么、不管什么,你才不会在它失灵的时候以为是自己做错了。

10五个一定会撞上的误解

这五条是你真做的时候会遇到的,不是假想的。

1. 我让 AI 画了,它给我贴了一大堆代码,还有「服务层」「依赖注入」这些词。这算画出来了吗?
不算。判据就一条:每一块都能用一句人话说清「它负责什么」,而且这句话里不需要提别的块的名字。出现你不认识的词,就让它换——用第 7 节最后那段追问。词换不掉,通常说明它自己也没分清那块是干什么的。词不是图。
2. 图上箭头特别多,是不是说明我这个项目很乱?
不是。箭头多只说明这个项目块数多、关系密,这在任何规模稍大的项目里都正常。真正说明乱的是「互相指」——A 用 B,B 也回头用 A。那种结构下你没法只改一边,改了谁都可能炸另一边。看方向,不要数数量。
3. AI 读代码给的图和我不懂代码验出来的不一致,信哪个?
信行为。代码是「本来打算怎么做」,行为是「实际会怎么做」。两者不一致的地方,往往是这个项目里最值得你知道的地方——通常意味着有一段代码写在那儿,但从来没真正跑过。这不是 AI 错了,是它只能看到文字。
4. 这个和我在别处听说的「架构图」是一回事吗?
不是,而且别混。架构图是「给同行看的、用来证明设计合理」的图,它追求完整、规范、好看。这张图是「给你自己看的、用来回答『我改这个会牵动什么』」的图。它丑、它不完整、它只服务一个问题——这都对。你要是拿「画得不够专业」当理由放弃它,那正好放弃了它唯一的价值。
5. 三张表我都填不满,是不是我这项目太乱 / 或者我用错了方法?
大概率是你问得太大了,不是你的问题。改法:只问一块。比如把「这个项目有哪几块」换成「这个项目里负责『首页那个列表』的是哪几个文件」。从最小的具体问题开始,答案具体了,再往上拼。表一是拼出来的,不是问出来的。

11一页纸速查

三张表,各一句话

表它回答什么搞错的典型样子
一 · 有哪几块这个项目分成哪几块,每块负责什么照抄目录结构——文件会搬家,职责不会
二 · 谁用谁每块被谁用、从哪个口子用把「名字出现了」当成「真的用了」
三 · 谁在改同一份数据哪些东西存了不止一份、或被不止一处改只看「被多少处用」,不看「被多少处改」

验证三步

1预测
→
2扰动(改一个能撤销的小东西)
→
3对账(看实际变了几处)
对账结果说明该做什么
预测到了、真的变了图上这条线是对的这条可以信了
预测变了、没变图上多了一条线划掉它
没预测到、却变了图上少了一条线补上——这就是你「修 A 出 B」的根源
变了、还没报错最危险:静默出错给它加一道自动检查

看到这些信号就停下来

⚠️ 该回头的信号

改一个小东西,要动三个以上的地方。这不是 bug,这是结构问题。继续埋头改只会越改越多,正确动作是回头看这三张表。

你手上必须有什么(再强调一次)

三样都没有也没关系:拿这个站练。它就在你手上,例子全篇都是它。

12来源与证据边界

外部来源

用在哪出处我说了什么、它实际说了什么
表一的「画到哪一层为止」C4 模型官网
https://c4model.com/diagrams
原文:「不同层级的缩放,让你能对不同的人讲不同的故事」,并且「你不需要用满全部 4 层」,多数团队画到「系统上下文 + 容器」两层就够。我据此说:画到「再往下就需要懂代码」那一层为止。
第 6 节的方法依据影响分析(change impact analysis)的标准定义,出自 Arnold & Bohner 的研究,见 ICSM 2003
https://www.computer.org/csdl/proceedings-article/icsm/2003/19050256/12OmNqGRGeX
定义是「找出一次改动可能带来的后果,或估计为完成这次改动还需要改什么」。专业人士用依赖图、调用图、执行轨迹等工具做;本文教的是手工版。「手工版」是我加的,不是原文说的。
表三的规矩《程序员修炼之道》(The Pragmatic Programmer, Hunt & Thomas, 1999)提出的 DRY 原则原文:「每一条知识在系统里都必须有一份单一的、明确的、有权威的表述」。注意它说的是「知识」,不是「长得像的文字」——这一点在第 9 节展开。
第 9 节的「巧合的重复」Industrial Logic:SPOT and Coincidental Duplication
https://www.industriallogic.com/blog/spot-and-coincidental-duplication/
它指出:看起来一样、但代表不同知识的重复是「巧合的重复」,不该被合并。我把它变成了一个可操作的问句:「如果这两处变得不一样了,那是个 bug 吗?」——这个问句是我加的。

一手材料:这个站自己

第 5 节里那些数字(三十几份副本、1 份样式、2 处日期)是我在 2026-09-16 当天在这个仓库里实际数出来的。你可以自己复核:

# 有多少个页面,就存着多少份那段「深浅色」脚本的副本
grep -l "ln-theme" learn/*.html | wc -l

# 全站样式有几份?(数出来是 1 —— 这就是"干净的那种")
ls learn/style.css | wc -l

# 首页卡片上写着的日期,和文章里写的日期,是两处;校验脚本会逐个比
bash .agents/skills/learn/check.sh --index

「三十几」这个说法是故意含糊的,因为它本来就是个会变的数字:它等于「这个站里有多少个页面」。我写这篇的那天数出来是 34 份,而你读到的时候多半已经更多了——每加一篇文章,就多一份副本;你正在读的这一篇,自己也是其中一份。

这正好又是这篇文章在讲的那件事:一个数字存在多处,而且还会各自变化,那么写在文档里的那个版本迟早对不上。所以要准的,别信任何文档里写的数字,用上面的命令现数。

证据边界

99一句话总结

🎯 核心要点

一个东西被多少处「用」不重要,被多少处「改」才重要——把那几处找出来,你就不是在盲改。

而找它的方法,从头到尾不需要你读一行代码:让 AI 给你三张表,然后用「预测 → 扰动 → 对账」验它。你验的不是代码对不对,是关系对不对——那正好是只有你能做的事,因为 AI 只能读,而你能改。

留给你自己验的那一条

这篇文章里所有结论我都能替你验,除了这一条——它只能你来。

拿出你手边那个最小的半途项目,试着回答:这个项目里,有哪一份东西是「存了不止一份」的?(提示:先别想代码。想想有没有同一个邮箱、同一个数字、同一句说明文字,你记得自己改过两次。)

然后想一想——它有没有一个自动检查盯着?如果没有,你就知道那个「越改越多」是从哪来的了。

⌂