配套仓库三种用法稳定性差很远:pin 到 commit 零坏,跟 main 两处全挂。 模板只该留「需要你替换的洞」;判断标准是「这一行描述的是谁」。 书会过时的是命令名、模型名、界面位置、价格;不会过时的是闭环和四件套。
这是全书的最后一节。 讲三件跟时间有关的事:配套代码怎么用、模板怎么改、书过时了怎么办。 Demo 真建一个上游仓库和三个下游项目,让上游发一版破坏性变更,看三种用法各自坏几处; 再用 diff 量一次模板和项目之间的真实差异。
一、配套代码怎么看
拿到配套仓库,第一件事不是 clone,是决定「跟不跟」。 三种用法,稳定性差很远。
| 用法 | 升级后坏几处 | 待解冲突 |
|---|---|---|
| pin 到 commit | 0 | 无 |
| 跟 main | 2 | 无 |
| fork 后自己改 | 2 | 有 |
Demo 里上游发了一版破坏性变更:run 改名成 execute,--fast 改成 --speed。 两条探针分别查「符号还在不在」和「参数还认不认」。 pin 那份两处都不坏,因为它压根没跟着升。 这就是版本锁定的全部作用:把「必然发生」变成「可以选择」。 它不保证兼容,只保证「什么时候升」由你决定。 跟 main 那份两条全挂,原因很干净:接口真的变了。 fork 那份也坏两处,但原因不一样:pull 打出了 CONFLICT,冲突标记被写进文件,整个模块没法导入。 这一行正好说明「坏几处」这个指标会骗人:它分不清「接口变了」和「文件坏了」。 所以看到数字要先问一句「坏在哪」。 一个可用的默认:学的时候 pin 到 commit,用的时候跟 tag,不要跟 main。
二、模板怎么改
Demo 用 diff 量了一次模板和项目之间的真实差异:三个文件,加三行、删两行。
| 文件 | 加了几行 | 删了几行 |
|---|---|---|
| AGENTS.md | 1 | 1 |
| config.yml | 1 | 1 |
| rules.md | 1 | 0 |
改动量这么小,正是模板该有的样子:它只留下需要你替换的那几个洞。 如果一个模板要改几十行才能用,那它不是模板,是别人的项目。
| 文件 | 改动 | 该不该改 |
|---|---|---|
| AGENTS.md | 项目名 | 必须改:换成自己的 |
| rules.md | 加一条团队约定 | 该改:规则本来就该长 |
| config.yml | name 一个值 | 看情况:路径和名字要改 |
模板里最容易改错的是结构:把别人的目录约定、脚本名一起搬过来,结果在自己项目里对不上。 判断标准是「这一行描述的是谁」——描述项目名的必须改,描述流程的尽量别动。 「尽量别动」的意思不是「不能动」,是「先按原样跑通,再决定要不要动」。 先跑通能给你一个基准:动完之后坏了,你知道是改动引起的。
三、书会过时,方法不会
书里写的具体东西,隔一年就会有一部分不再成立。 但「哪些会变」本身是可以分类的。
| 会过时的 | 怎么在三十秒内验一下 |
|---|---|
| 命令名和参数 | 跑一次 --help,看参数还在不在 |
| 模型名 | 看厂商文档的模型列表 |
| 界面位置 | 打开工具,按书里说的路径找一遍 |
| 价格和限额 | 看账单页,不看旧文章 |
| 配套仓库的分支 | git ls-remote,看分支还在不在 |
| 不会过时的 | 为什么 |
|---|---|
| 闭环:出题、执行、验证、交付 | 这是流程的形状,不是工具功能 |
| 四件套:说明、护栏、装配、流水线 | 再多工具也是这四类 |
| 验收标准先写 | 跟工具无关,是判断顺序 |
| 归因再动手 | 错因分类不随版本变 |
| 工作流会折旧 | 依赖会变,这是工程的性质 |
两张表的关系是:左边是你需要跟着更新的,右边是你需要记住的。 左边越用越旧,右边越用越熟。 一个具体建议:把左边那五行抄进 AGENTS.md,每次升级工具时照着走一遍。 这比收藏十篇「最新教程」有用——因为那五行是可执行的检查,而教程是不可执行的阅读。
四、本章小结
第十四章讲的是边界。 边界不是「能力不够」,是「知道它在哪一步会失手,并且提前把这一步变成可检查的」。
| 节 | 讲的事 | 压成一句 |
|---|---|---|
| 14.1 | 归因 | 先分类,再动手 |
| 14.2 | 出域 | 出域是单向的坡 |
| 14.3 | 分工 | 时间可交,责任不可交 |
| 14.4 | 折旧 | 当周修,别攒 |
| 14.5 | 更新 | 左边跟着换,右边记牢 |
五件事的共同点:它们都不提升上限,只保住下限。 保住下限听起来不性感,但工程里绝大多数事故不是因为上限不够,是因为下限漏了。 全书到这里结束。 从第 1 章的「交付与补全差在证据链」,到第 14 章的「边界是可检查的」, 中间的每一章都在回答同一个问题:怎么让一次成功变成可重复的成功。 答案是四个字:写下来,验一遍。 写下来解决「别人能不能用」,验一遍解决「你自己有没有把握」。 两件事都做到,工具换成什么都无所谓。
五、动手 Demo:配套仓库、模板与在线更新:书会过时,方法不会
真建一个上游仓库和三个下游项目,让上游发一版破坏性变更,看三种用法各坏几处。 再用 diff 量一次模板和项目之间的真实差异。 最后一张表是「哪些会过时、怎么三十秒验一次」。
up = fresh("up")
put(up, "tool/__init__.py", "def run(argv=None):\n return 'v1'\n")
gitinit(up)
sha1 = git(up, "rev-parse", "HEAD")[1].strip()
pin = clone("proj_pin"); git(pin, "checkout", "-q", sha1)
main = clone("proj_main")
fork = clone("proj_fork")
# 上游发 v2:run -> execute,--fast -> --speed
put(up, "tool/__init__.py", "def execute(argv=None):\n return 'v2'\n")
git(up, "commit", "-qam", "v2")
# 两条探针:符号还在不在、参数还认不认
PROBES = ["from tool import run",
"import tool.cli as c; assert c.run_flag(['--fast'])"]
实跑输出:
--------------------------------------------------------------------
配套仓库、模板与在线更新:书会过时,方法不会
--------------------------------------------------------------------
这一章最后一节,讲三件跟「时间」有关的事:配套代码怎么用、模板怎么改、书过时了怎么办。
① 配套仓库的三种用法,稳定性差很远
--------------------------------------------------------------------
| 用法 | 升级后坏几处 | 待解冲突 |
|---|:---:|:---:|
| pin 到 commit | 0 | 无 |
| 跟 main | 2 | 无 |
| fork 后自己改 | 2 | 有 |
两条探针分别查「run 这个名字还在不在」和「--fast 这个参数还认不认」。
pin 那份两处都不坏,因为它压根没跟着升——这就是版本锁定的全部作用:
把「必然发生」变成「可以选择」。
跟 main 的两条探针全挂,原因很干净:run 改名成 execute,--fast 改成 --speed。
fork 那份也坏两处,但原因不一样:pull 打出了 CONFLICT,冲突标记被写进了 cli.py,
文件根本没法导入。
这一行正好说明「坏几处」这个指标会骗人:它分不清「接口变了」和「文件坏了」。
所以看到数字要先问一句「坏在哪」。
! 两条探针只能证明这两处没坏,证明不了全部兼容。这是升完级后最小的体检,不是完整的兼容性测试。
② 模板要改哪、不该改哪
--------------------------------------------------------------------
| 文件 | 加了几行 | 删了几行 |
|---|:---:|:---:|
| AGENTS.md | 1 | 1 |
| config.yml | 1 | 1 |
| rules.md | 1 | 0 |
三个文件加起来加了 3 行、删了 2 行——改动量很小,这正是模板该有的样子:
它只留下需要你替换的那几个洞。
| 文件 | 改动 | 该不该改 |
|---|---|---|
| AGENTS.md | 项目名 | 必须改:换成自己的 |
| rules.md | 加一条团队约定 | 该改:规则本来就该长 |
| config.yml | name 一个值 | 看情况:路径和名字要改 |
模板里最容易改错的是结构:把别人的目录约定、脚本名一起搬过来,结果在自己项目里对不上。
判断标准是「这一行描述的是谁」——描述项目名的必须改,描述流程的尽量别动。
③ 一份三十秒能做的过期体检
--------------------------------------------------------------------
书里写的具体东西,隔一年就会有一部分不再成立。但「哪些会变」本身是可以分类的。
| 会过时的 | 怎么在三十秒内验一下 |
|---|---|
| 命令名和参数 | 跑一次 --help,看参数还在不在 |
| 模型名 | 看厂商文档的模型列表还是不是这个 |
| 界面位置 | 打开工具,按书里说的路径找一遍 |
| 价格和限额 | 看账单页,不看旧文章 |
| 配套仓库的分支 | git ls-remote,看分支还在不在 |
| 不会过时的 | 为什么 |
|---|---|
| 闭环:出题、执行、验证、交付 | 这是流程的形状,不是工具的功能 |
| 四件套:说明、护栏、装配、流水线 | 再多工具也是这四类 |
| 验收标准先写 | 跟工具无关,是判断顺序 |
| 归因再动手 | 错因分类不随模型版本变 |
| 工作流会折旧 | 依赖会变,这是工程本身的性质 |
左右两张表的关系是:左边是你需要跟着更新的,右边是你需要记住的。左边越用越旧,右边越用越熟。
一个具体建议:把左边那张表的五行抄进 AGENTS.md,每次升级工具时照着走一遍。
这比收藏十篇「最新教程」有用。
④ 这一章、这本书的收尾
--------------------------------------------------------------------
第十四章讲的是边界。
边界不是「能力不够」,而是「知道它在哪一步会失手,并且提前把这一步变成可检查的」。
第 62 节讲归因,第 63 节讲出域,第 64 节讲分工,第 65 节讲折旧,第 66 节讲更新——五件事的共同点:
它们都不提升上限,只保住下限。
! 保住下限这件事听起来不性感,但工程里绝大多数事故不是因为上限不够,是因为下限漏了。
三行结果里,pin 那行是零坏。
这不是「锁定就不会坏」,是「锁定之后坏了也跟你无关」——你用的还是老版本,它当然不会坏。
代价是拿不到新功能,这个取舍要自己认。
fork 那行坏两处,但原因跟接口无关。
pull 冲突把 <<<<<<< 标记写进了 cli.py,整个文件语法错。
这就是「坏几处」这个指标的盲区:它数的是失败次数,不是失败原因。
模板那段 diff 只有加三行删两行。
这个数小得有点出乎意料,但它说明模板设计得好:它把「你必须改的」压缩到了三处。
如果一个模板要改二十行,说明它预设了太多别人的环境。
最后两张表,左边的五行是可执行的检查,右边的五行是判断顺序。
左边的会过期,右边的不会。
所以每次工具升级,跑一遍左边,别去重读整本书。
全书到这里收尾。
这一节没有新技术,只有一句:把会变的和不会变的分开,然后只花时间在会变的那一半。
30 秒实验
- 打开你正在用的配套仓库,看它是 pin 还是跟 main。 是跟 main 的话,改成 pin 到今天这个 commit。
- 把你项目的 AGENTS.md 和模板 diff 一次。 差异超过十行,就有一半是你不该改的。
- 把「会过时的」五行抄进 AGENTS.md,加上「升级时照着走一遍」。 这五行比任何教程都耐用。
常见误区
- 「跟 main 才能拿到最新修复。」 最新修复和新破坏是同一批提交带过来的。 跟 tag 是折中:拿到版本,不拿未发布的改动。
- 「模板要按自己习惯改一遍。」 先按原样跑通再改。 没跑通就改,出了问题分不清是模板的问题还是你的问题。
- 「书里的命令跑不通,说明书过时了。」 先跑一次 --help 看参数还在不在,再判断是过时还是拼错。 这两种情况的处理方式完全不同。
自测三问(点开对答案)
1. pin 到 commit 零坏,为什么还说它有代价? —— **零坏的代价是拿不到上游的修复和新功能。** **锁定把「什么时候升」变成可选项,但可选项也得有人选。** 2. 为什么「fork 后自己改」那行坏两处,不能算作接口破坏的证据? —— **因为失败来自冲突标记,不是来自接口变更。** **文件里被写进了 `<<<<<<<`,整个模块导不进来。** 3. 「会过时的」和「不会过时的」怎么分? —— **看它描述的是「某个工具现在的样子」还是「做事的顺序」。** **前者一定过时,后者不会。**全书到这里结束。下一步不是学更多工具,是把这 66 节里的任意一条,在自己项目里跑通一遍。
- ☐ (全书完)