目录

上一篇末尾我留了把尺子:判断一个工具的三层是不是真结合,看它们是否共用一份状态。这一篇就来兑现这个判断——三层从头到尾没有互相调用过一次,它们靠磁盘上的一份文件交接。顺带还有个我当初没预料到的副作用:因为这份文件是按功能切开的,这条流水线不止能纵向走一条,还能横向铺开同时跑好几条。

上一篇把三层各自落在 pdlc-skills 的哪个位置说清楚了:所有命令共用的那套规矩是提示词层,自动往下推进的那一段是 Loop 层,阶段顺序和关系图是 Graph 层。

但知道谁管什么,跟知道它们怎么拼在一起,是两回事。

顺着这个想法,最直接的办法是去代码里找那行调用——Graph 在哪儿调用了 Loop,Loop 又在哪儿调用了提示词层。但你找不到——这三层之间没有任何一行代码互相引用。

那它们是怎么凑到一起干活的?

钥匙是「节拍」,不是「调用」

三层之所以不需要互相认识,是因为它们根本不在同一个时刻起作用

什么时候起作用 管的是什么
Graph 阶段边界 准不准进下一步
提示词 一次调用内部 这一次给模型看什么
Loop 阶段之间 还要不要再来一轮

打个比方:Graph 在门口检票,提示词在场内讲话,Loop 在场外数还剩几场。三个人从没打过招呼,靠的是同一块记分牌。

那块记分牌,就是磁盘上那份文件。

三条泳道的时间线:Graph 只出现在阶段边界上,提示词在每次调用内部展开,Loop 落在两个阶段之间

跟着一个功能走一遍

抽象说完了,跟着一个真功能走一遍,看每一拍是谁在出手。

第一拍,起手。 一个新功能刚立项,磁盘上什么都没有。这时候能接住它的命令只有一条——写需求。为什么?因为别的命令都声明了自己需要什么前置文档:做设计要先有需求,写测试要先有设计,一样前置条件都不满足。这不是”建议先写需求”式的劝告,而是没有前置产物就进不来这道门。 这就是 Graph 在起作用,它只管”放不放你进来”。

第二拍,干活。 进了门,Graph 就退场了,接下来是提示词层的场子。这一次调用里,模型看到的不只是这条命令自己的正文,还有一整套所有命令共用的规矩——产物必须落盘、交接前必须自检、修复只做一次。这些规矩写在一处,调用时展开进来,而不是在每条命令里各抄一遍。

产出的东西也不是随手写的散文。文件名、放哪个目录、有哪几章,都是定死的;文档顶上还带一小段身份信息,写着它属于哪个功能、处在哪个阶段、上一份文档是谁。格式细节这篇不展开,只说它意味着什么:产物自己带着坐标,往回翻能一路串到最初的需求。

第三拍,收尾写盘。 这一拍最关键。主要的活干完,流程还没结束——命令必须往那份文件里记一笔:我这一段干完了、干得怎么样、下一步该谁接。这份文件在磁盘上,一个功能一份

第四拍,判停。 循环这时候才出场,而且它只读那份文件——不看代码,不看产物,也不看聊天记录。读完吐出一个结果:下一步该跑哪条命令,或者”完事了”,或者”卡住了”。外层脚本拿着这个结果去跑下一条,跑完又回到第三拍。

走到评审完成,循环停止,输出”完事了”,然后等人。发布和部署永远不在循环里——一旦发出去就收不回来,影响的还是线上的真实用户。

所以整条链上真正的交接只有三处,每一处交出去的都是一个名字,不是一次调用

  • Graph 交给这次调用的是”你该干哪一段”;
  • 这次调用交给磁盘的是”我干完了,结果是这样”;
  • 磁盘交给循环的是”还要不要继续”。

三层谁也没碰过谁。

三个交接点:Graph 交出该干哪一段,阶段收尾把结果写进磁盘,循环从磁盘读出还要不要继续

那份文件里最关键的一处设计

“真跑出来的”和”模型自己说的”,放在两个格子里。

第一个格子只准填真跑命令得到的结果:测试过没过、覆盖率够不够、代码检查干不干净——全是从退出码翻译过来的真假值。如果某个阶段压根没有命令可跑(比如只产文档的需求和设计阶段),就留空;不许因为”我觉得这段做得挺好”,就填个”过了”。

第二个格子才是模型的自我检查,只记有几项没通过,仅供参考,永远不参与判停

差别在哪儿?循环判停只看第一个格子。也就是说,模型自评是在数据结构这一层被排除在判停链路之外的,不是靠一句”请你如实汇报”的约定。它在第二个格子里写什么,都改变不了这一轮停不停。

上一篇说”三层共用一份状态”,共用的就是这几个格子。

状态文件里两个格子的区别:一个只装真跑命令的结果并决定停不停,另一个装模型自评、只供参考

真正的循环,其实有两级

到这儿得承认一件事:上面画的那条循环,只是内层循环

我自己真拿它干活的时候,跑的是这样的结构——

主控 agent:整体设计 → 拆成 N 个互相独立的功能点
    ↓
外层脚本:给每个功能点各起一条
    ↓
内层循环 × N(各跑各的功能点)   ← 同时跑
    ↓
各自停在「评审完成」或「卡住」 → 人工汇总,决定发布

先由一个主控 agent 做整体设计,把要做的事拆成若干个相互独立的功能点;外层脚本给每个功能点各起一条内层循环;这些循环并行往前跑,各自停在自己的终点;最后由人把 N 条的结果收拢起来看。

凭什么敢同时跑? 前提是拆出来的必须是相对独立的功能点——彼此之间没有依赖,才谈得上同时开工。在这个前提下,状态文件也按功能点切开,一个功能点一份文件,相互不依赖。

功能编号用的是”日期 + 时分秒”,不是当天的第几号。仓库里写明的理由是——多人或者多个 AI 同时开工时,各自去取”当天最大号加一”必然撞号,撞了状态文件就同名冲突,只能手工重编。改成创建那一刻的时分秒,各干各的也几乎不会撞号。这个编号格式本来就是为并行准备的,只是我当时没把它当成什么正经设计,就当个防冲突的小技巧写进去了。

代码那一层也得隔离开:每个功能点的内层循环跑在自己的 git worktree 里,互不干扰,产物各走各的 PR。

那为什么”拆分”这一步必须留给人、或者留给主控 agent? 上一篇给过一条判据:能自动发现错误的交给循环,不能的留给人。”这批需求该拆成几个功能点、哪些之间有依赖”——拆错了不会有任何命令报错——它是判断题,不是校验题。所以它在循环外面。

两级的终点也不一样:内层的终点是评审完成,外层的终点是”N 条都收敛了”。而发布仍然是唯一那道人工闸门——不管同时跑了多少条,最后按下去的还是人。

这套方式我自己在一个命令行工具项目上真跑过。怎么把它跑起来、护栏怎么设、真跑一夜跑出什么数据,后面几篇专门讲,这一篇只画形状。

两级循环:主控拆成 N 个相对独立的功能点,外层脚本各起一条内层循环跑在自己的 worktree 里,最后汇总到人工发布闸门

下一篇:怎么在自己项目里跑起来

如果这篇只留一句话,我希望是这句:三层能联动,不是因为它们互相调用,而是因为它们对着同一份文件各写各的格子。

接口是名字,不是函数——这也是为什么改一层不会波及另一层,也是为什么这条流水线能横向复制出好几条。

这一篇有意没有往下钻:那份状态文件具体有哪些字段、循环的护栏和上限怎么定、并行跑起来怎么收口,都留到后面几篇。先把形状看清楚,再看零件。

到这儿,三层是什么、各自落在哪、怎么联动,三篇讲完了。下一篇换个方向:在你自己的项目里,怎么把它装上、怎么起手、老项目怎么接进来——从这篇的图纸,走到你终端里第一条真正跑起来的命令。


想自己试一下

curl -fsSL https://raw.githubusercontent.com/kanfu-panda/pdlc-skills/main/install.sh \
  | bash -s -- --global

仓库在这里:https://github.com/kanfu-panda/pdlc-skills

觉得有用的话,给个 star 是对我最大的支持 ⭐


这篇里那张”两级循环”的图,是我自己真跑的方式,画出来之前一直只在脑子里。如果它让你对这套东西有了具体的印象,点个赞让我知道;要是你身边也有人在琢磨怎么让 AI 同时干好几件事,转给他看看。