Copilot 堆叠会话很爽,评审债才刚开始
一个 Agent 会话走错了分支,过去常见的结局是关掉窗口,重新解释需求,再祈祷下一次别把旧坑一起带回来。
GitHub 现在给了另一种结局。
关掉错误的 PR,把已经确认过的设计决定移到正确分支,再从这份改动上生出下一条会话。前一个会话不只是聊天记录,还是后一个会话的代码地基。
这套能力叫堆叠会话与堆叠拉取请求。GitHub 在 7 月 30 日用一个十多年前的 React 项目演示了它。初始任务是现代化前端,做到一半才发现真正在线使用的版本不在 main,而在一条改过一半的 dev 分支。方向改完,控制台又翻出 react-bootstrap 留下的 findDOMNode 和 componentWillReceiveProps 警告。
换成普通 PR 流程,这种项目很容易走向两个极端。
要么把样式迁移、无障碍修复、依赖升级和组件替换全塞进一个大 PR,改到后来没人敢审。要么把任务硬拆成几份互不相认的工单,每个 Agent 都从头读仓库,再把同一套背景重新消化一遍。
GitHub 的做法是让两条链对齐。
会话按依赖关系往下叠,分支和 PR 也按同样的关系往下叠。后一个任务能继承前一个任务的代码状态,又不必把新增范围偷偷塞回原来的 PR。

官方案例中的会话树,失败的首次改造、基于 dev 的样式迁移和 react-bootstrap 移除被放进同一条依赖链。
好家伙,这个变化看着只是侧边栏多了几层缩进,背后改的却是 Agent 工程里最难缠的一件事。
上下文终于不只存在于对话里,它被压进了可评审的代码依赖。
一次做完,正在变成最危险的诱惑
GitHub 那篇文章里有一句很诚实的话。代码不再需要自己逐行写之后,人会非常想造出一个一万行 PR,一口气解决所有问题。
这个诱惑太真实了。
让人类工程师改一个旧前端,他会被工时和体力强迫着切范围。今天先换样式,明天再删旧组件,顺手修一处警告都得掂量一下。Agent 没有这种天然刹车。你多说一句「顺便把依赖也升级」,它就可能继续改几百个文件,直到上下文、预算或测试时间先扛不住。
表面看,Agent 很勤快。
回到团队流程里,这份勤快会变成一个没人愿意接的包裹。评审者面对的不只是更多 diff,还得在同一批改动里同时判断视觉回归、依赖兼容、无障碍、构建链和运行时行为。每一类风险都要换一套脑回路,评论区很快从代码评审长成考古现场。
堆叠 PR 的价值就在这里。GitHub 对 Stack 的定义很直接,同一仓库里的一系列 PR 形成有序链条,每个 PR 指向它下方那个 PR 的分支,最终落到主分支。
它允许你把范围蔓延变成显式依赖。
样式现代化是一层,基于新样式移除 react-bootstrap 是下一层。第二层还不能单独落地,却不必污染第一层。评审者可以先确认样式迁移有没有跑偏,再看组件替换是不是安全,而不是在一万行 diff 里猜哪块属于哪项决策。
坦率讲,这不是一个新鲜的 Git 技巧。很多团队早就在用 stacked PR,Graphite、Git Town 之类的工具也做了很久。
新鲜的是,Agent 会话树和 PR 依赖树开始长成同一棵树。
你不再需要先让 Agent 干完,再由人手工把巨型改动拆回工程流程。任务分解、上下文继承、分支创建和 PR 提交可以在同一个操作面里完成。GitHub Copilot 应用甚至能让父会话创建嵌套会话,把下一项工作直接挂在当前任务下面。
有点子牛逼。
也正因为如此,新的坑会来得更快。
写代码的瓶颈松了,依赖图的瓶颈冒出来了
一条堆叠链看起来很优雅。
dev 上面放 PR A,PR A 上面放 PR B,PR B 上面再放 PR C。三条 Agent 会话各自有明确范围,CI 各自跑,评审也能分别进行。图一画,像把软件工程从毛线团梳成了地铁线路。
真开始跑,第一处堵点往往是底层 PR。
PR B 和 PR C 都依赖 PR A。只要 A 还没过,后面两层就只能在变动的地基上排队。评审者在 A 里要求改接口,B 和 C 的分支要跟着更新。A 合并后,后续 PR 的目标分支还得重新指向正确位置,冲突和检查也可能重跑。
GitHub 已经在公开的Copilot App 变更记录里持续修这类边界问题。里面出现过合并辅助对自动重定向后的 stacked PR 读取了旧 base branch,以及嵌套会话被归档后变成孤儿等故障。产品在补,说明这不是纸面上的漂亮树形图,而是一套真的会产生状态错位的系统。

Copilot 没有替用户猜高风险决定,而是明确列出合并、移植或关闭 PR 三条路径,再按选择从 dev 重开会话。
第二处堵点是 CI。
假设一条栈有四层,每层都跑同样的单元测试、构建和端到端测试。下层改动一更新,上面几层可能一起失效。Agent 把任务拆得越细,PR 数量越多,流水线扇出越大。过去一个大 PR 跑一次完整检查,现在四个小 PR 各跑一遍,代码更好审,机器账单却未必更好看。
这不是在反对拆小。
而是提醒一个容易被功能演示藏起来的成本。堆叠把人类评审的复杂度降下来了,却可能把依赖同步和 CI 计算量抬上去。
第三处堵点更隐蔽,评审顺序。
并行开四条 Agent 会话很爽,四份 PR 同时等人看就不爽了。人类注意力没有因为模型升级一起扩容。一个团队每天能认真审多少代码,能对多少条风险链做判断,基本还是那个数。
所以我自己的判断是,Agent 时代真正稀缺的资源会从编码时间,转到能签字的评审时间。
模型可以在后台继续写,CI 可以加机器扩容,只有责任不会自动并行。谁确认迁移没有破坏线上行为,谁决定底层 PR 的接口可以成为后续三层的地基,责任仍然要落到具体的人。
别把聊天树当成任务树
这里还有一个很容易踩的认知坑。
界面里会话可以嵌套,不代表任务就真的拆好了。
父会话下面挂三个子会话,看起来很有组织感。可如果三个子任务都在改同一批文件,共用一个还没稳定的接口,或者只有一起上线才有价值,那它们只是被画成树的巨型任务。缩进没有消除耦合,只是把耦合藏在了更漂亮的侧边栏里。
判断一层能不能独立成 PR,我觉得可以问一个很朴素的问题。
这一层如果停在这里,它是不是仍然可验证、可回滚、可解释。
样式迁移完成后,页面可以单独跑起来,可以截图比对,也可以在发现问题时整层撤回。那它适合成为一层。
如果所谓的第一层只是先改了一半数据结构,服务根本起不来,必须等第二层补完才能测试,它就不太像一份可评审增量,更像一个被强行切开的 commit。拆得小不等于拆得对。
这块需要注意一下,Agent 特别擅长接受形式化目标。你让它每个子任务开一份 PR,它会照做。至于每份 PR 有没有独立的验收边界,提示词没写,它不会替团队发明工程纪律。
因此,堆叠会话最该继承的不是整段聊天,而是四类可检查的状态。
一类是底层约束,哪些接口和文件已经定了,后面不能随便推翻。
一类是验收证据,测试命令、截图、构建结果和已知失败都得跟着 PR 走,不能只留在 Agent 的对话里。
一类是风险声明,这一层改了什么,没有改什么,下一层为什么必须依赖它。
还有一类是退出条件,底层 PR 被否决后,上层会话是重放、改基,还是直接作废。
GitHub 的公开变更记录里已经能看到这种状态管理在变细。嵌套会话会显示父子关系,删除父会话时会询问是否一起处理子会话,未提交文件在归档前会保存到可恢复的 Git 引用。厉害了,产品开始把过去藏在聊天窗口里的临时状态,当成真正的工程资产来保护。
普通团队先把栈压到三层以内
功能很酷,不代表一上来就该让十个 Agent 叠十层 PR。
如果是普通产品团队,我更愿意从一条很短的栈开始。两层最好,三层已经足够暴露大部分问题。底层放接口稳定、风险最小、能独立验收的改动。上层放明确依赖它的迁移或清理。超过三层,先停一下,看看是不是把一个项目计划伪装成了 PR 链。
每层只认一个主要目的。
不是说只能改一个文件,而是评审者看标题就知道自己要判断什么。视觉现代化、旧组件移除、依赖升级,这三件事可以有依赖,却不该混成一句「清理前端」。标题越模糊,Agent 越容易顺手扩范围,人也越难决定什么时候算审完。
底层 PR 变动后,不要让所有上层会话立刻自动重写。
先看变动属于实现细节还是契约变化。实现细节可以让上层改基后重跑测试。契约变化则应该暂停整条栈,重新确认后续任务还成不成立。否则一个底层接口改名,三个 Agent 在不同分支里各自聪明地修一遍,很快就会修出三套答案。
CI 也别每层无脑全跑。
底层跑完整检查,上层先跑受影响范围的快速检查,临近合并再补全。具体怎么分取决于仓库,但思路很简单,评审单元可以拆小,计算账单不必机械翻倍。GitHub 的 Merge Queue能解决部分合并前验证问题,却替代不了团队自己设计分层检查。
再给栈指定一个人类负责人。
他不一定逐行写代码,却要维护依赖方向,决定哪层先落,处理底层改动对上层的影响,并在整条栈结束时确认没有孤儿分支和遗留 PR。多 Agent 可以多头干活,责任最好别多头漂移。
说真的,看到堆叠会话,我是兴奋的。
它承认 Agent 写代码已经快到需要一套新的交通规则。过去我们担心模型不会写,现在更现实的问题是,它们同时写了太多,人类怎么把这些改动排成一条能安全进主干的路。
Git 的分支、PR 和检查从来不只是交付外壳。它们是团队用来压缩风险的语言。
Copilot 把会话叠起来,只是把这门语言正式教给了 Agent。
接下来真正拉开差距的,不是谁能同时开更多会话。
而是谁知道,哪一层值得成为下一层的地基。