- 人工智能
- AI Agent
- 代码智能体
- Agent 编排
- CLI
- AI 应用
【免费下载链接】gsd-2
A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture
本文围绕 19-when-to-scrap-and-start-over.md 展开,系统讲解编码 Agent(Coding Agent)在自主长时任务中如何判定"当前方案是否该被推倒重来",以及如何通过接口契约、测试套件与 git worktree 隔离让重写的成本趋近于零。你将掌握四大失效信号的具体形态、一次聚焦 LLM 重新评估调用的完整触发方式,以及 Gemini"沉没成本启发式"与 Grok"并行实验"两种跨模型方法论在 GSD-2 项目中的真实落地路径。
一、为什么"推倒重来"必须被制度化为可执行协议
长期自主运行的编码 Agent 面临一个根本矛盾:做得越久,沉没成本越高,越不愿意承认当前架构走错了方向。当复杂度开始滚雪球时,Agent 的自然倾向是继续叠加补丁,而不是止损并重建。GSD-2 的研究文档将这一难题拆解为三个可操作的部分:
- 如何尽早识别需要推倒重来的信号(而不是等架构崩溃);
- 如何评估当前方案是否真的不可挽回(而不是凭直觉放弃);
- 如何让重写本身足够便宜,使"推倒重来"从高风险赌博变成低成本常规操作。
其中第三点正是 GSD-2 的架构核心。项目通过 ADR-001 分支无关 worktree 架构 与其后续演进,把"每个主要方案放在一个可随时丢弃的分支上"从理念变成了默认实现——这为本文讨论的"Scrap and Start Over"提供了工程基础。
二、四大信号(跨模型共识):何时判定当前方案失效
原文档给出的核心成果是Four Signals:这是多个前沿模型在交叉验证后收敛出的共识——以下任一信号的持续出现,都意味着复杂度正在累积而非被解决。
| 信号 | 具体表现 |
|---|---|
| 迭代次数呈上升趋势 | 任务 1:3 次迭代;任务 2:5 次;任务 3:8 次。复杂度在叠加,而不是在收敛。 |
| 测试闪断(flakiness)增加 | 之前通过的测试开始间歇性失败——隐藏耦合正在被拉紧。 |
| 同一文件被反复修改 | 每个任务都触碰同一个核心模块——"上帝对象"吸收了过多职责。 |
| 验收标准开始需要例外 | 出现"除 X 场景外都能工作"或"忽略测试 Y 就能通过"——Agent 正在与验收标准讨价还价。 |
2.1 信号一:迭代次数上升趋势
这是最直观也最容易量化的信号。正常收敛的任务,迭代次数应当持平或下降;而当连续多个任务的迭代次数单调上升(3 → 5 → 8),说明每次新增需求都在撬动更多既有代码,Agent 的每次尝试都在制造新的修复点。GSD-2 的自主循环恰好内置了这类迭代观测能力:在 auto-mode.md 中,auto 循环通过.gsd/journal/记录unit-start、unit-end、iteration-end等事件,每次迭代结束都会留下可追溯的失败类与原因字段——这些正是计算"迭代次数趋势"的第一手数据源。
2.2 信号二:测试闪断增加
测试从"稳定绿"变成"间歇红",通常不是测试本身的问题,而是被测模块之间的隐式依赖正在被改动撑裂。闪断的本质是隐藏耦合被拉紧:某个模块的副作用经由非契约路径泄漏到另一个模块的测试环境。该信号在 GSD-2 中同样有对应的制度性响应:artifact-verification-retry这类可归因的重试被明确记录,而无法自证的闪断会被滑动窗口检测器捕获(详见第五节的 stuck-loop 机制)。
2.3 信号三:同一文件被反复修改
如果每个任务都必然触碰同一个核心模块,说明该模块承担了过多职责——典型的"上帝对象(god object)"反模式。反复修改该文件 = 每次改动都在同一片泥潭里打转,边际成本持续上升。GSD-2 的 长期重构计划(2026-05-03) 中把这类复杂度热点作为重构的首要对象,并主张"复杂度热点应被显式拆分,而不是继续吸收职责"——这正是对上帝对象信号的正向回应。
2.4 信号四:验收标准出现例外
当 Agent 开始用"除 X 外都能工作"、"忽略测试 Y 就能通过"来修饰交付结果时,它实际上正在与验收标准谈判——降低标准以适配一个结构上错误的实现。这是最危险的信号,因为它意味着 Agent 的自我评估已经失真。原文档的处置建议是:此类措辞一旦出现在任务摘要中,就应视为需要触发重新评估协议(见第三节)。
值得注意:单一信号出现一次不足以判定方案失效,四个信号是趋势指标,判断依据是持续性而非偶发性。
三、重新评估协议(The Reassessment Protocol)
当上述信号的阈值被跨越时,原文档规定了一个明确的触发动作:发起一次聚焦的 LLM 调用(focused LLM call),而不是让 Agent 继续埋头修补。
该调用的输入必须是结构化的,共四类材料:
- manifest(当前方案的清单/契约清单);
- 原始 spec(最初的规格说明,用于对照"我们到底要解决什么");
- 任务摘要(已执行任务的汇总,用于呈现实际进展);
- 信号数据(四大信号的量化证据,用于呈现失败模式)。
对应的提示词模板原文如下:
"Is the current approach viable or would a different architecture serve better? If different, what and why?"(当前方案是否可行,抑或不同的架构能做得更好?若需改变,是什么、为什么?)
这一协议的价值在于三点:
- 成本受控:它是"一次调用",不是无限次自我怀疑循环;
- 视角切换:输入包含原始 spec,迫使评估回归最初目标,而不是被当前实现细节绑架;
- 可审计:评估的输入输出都有记录,后续可回溯为什么做出重写决策。
从 GSD-2 的实际机制看,类似的"聚焦评估调用"已有雏形:在 auto-mode.md 中,GSD 检测到 stuck loop 后会"retry once with a deep diagnostic prompt"(以深度诊断提示重试一次)——失败后再次失败才停止。这套"重试一次深度诊断"的节奏,与重新评估协议"一次聚焦调用定生死"的思路高度一致,区别在于前者面向单次循环卡死,后者面向整个架构方向。
四、关键架构使能器:让重写变得便宜(Make Rewrites Cheap)
这是原文档中最重要的工程结论:推倒重来的决策是否正确,取决于重写的成本是否足够低。如果一次重写意味着数小时的迁移与回归风险,那么即使信号已经亮起,理性的 Agent 也会选择继续打补丁——这正是沉没成本陷阱的根源。
原文档给出了四条使重写变便宜的原则:
- 清晰的接口契约 + 良好的测试套件→ 重写内部实现而保留接口,风险极低;
- 测试用同一套验收标准验证新旧实现→ 重写不改变行为期望;
- 接口契约保证下游不被破坏→ 调用方无需感知内部被替换;
- 每个主要方案都放在一个分支上→ 可随时丢弃而不影响其他任何部分。
4.1 GSD-2 的落地:分支无关的 worktree 架构
最后一条原则在 GSD-2 中被贯彻得最为彻底。项目的 ADR-001 分支无关 worktree 架构 及其 PRD 描述了一次典型的重写决策:旧的"slice-branch-per-slice"模型产生了 770+ 行合并/冲突/自愈代码、15+ 次 bug 修复,最终被判定为架构性问题,无法通过修补解决——这正是本文讨论的"Scrap and Start Over"在真实项目中的完整案例。
重写的目标架构极其简洁:
main ──────────────────────────────────────────── main │ ↑ └─ worktree (milestone/M001) │ │ │ commit: feat(M001): context + roadmap │ commit: feat(M001/S01): research │ commit: feat(M001/S01/T01): implement │ commit: feat(M001): milestone complete │ │ │ └──────────── squash merge ─────────────────┘- worktree 隔离:每个活跃里程碑一个独立 worktree(
.gsd/worktrees/<MID>/),文件系统级隔离; - 单一分支顺序提交:worktree 内只有一个
milestone/<MID>分支,不存在分支切换; - squash merge:里程碑完成时一次性 squash 合并回
main。
从源码看,worktree 的创建、解析与回收由 src/resources/extensions/gsd/worktree-manager.ts 负责,其注释明确写着:创建git worktree add .gsd/worktrees/<name> -b worktree/<name>,完成后git worktree remove+ 分支清理。这套机制让"跑一个实验性方案、看效果、不行就整体丢弃"的成本降到了接近一次git worktree remove的水平。
4.2 接口契约:GSD-2 重构的"安全内胆"
"重写内部而保留接口"在 GSD-2 的长期重构中体现为契约包优先策略。2026-05-03 的 重构计划 中:
- Phase 1A建立
packages/contracts(@gsd-build/contracts),把 RPC 命令/事件/响应信封、会话状态、bash 结果、UI 载荷统一为规范契约,runtime 与 rpc-client 都从同一契约包导入,并用 golden JSONL fixtures 锁定行为; - Phase 5DB 拆分时明确"保持单写入者不变式(single-writer invariant)",将
gsd-db.ts保留为兼容门面,内部按仓库拆分,导出名不破坏既有调用方。
这两步的本质都是:契约在外、实现在内,重写实现不动契约。测试则通过"用同一套验收标准验证新旧实现"来兜底——契约 fixtures 与 prompt golden fixtures 一旦回归即阻断合并。
五、跨模型方法论(一):Gemini 的"沉没成本启发式"
Gemini 对"何时止损"给出了可量化的两个阈值,统称Sunk-Cost Heuristic,其核心是持续监控一个指标:任务重入率(Task Re-entry Rate)。
触发"白板会议(Whiteboard Session)"的条件有两个,满足其一即触发:
| 触发条件 | 含义 |
|---|---|
| 同一组 3 个测试被尝试超过 5 次 | 反复在同一批测试上失败,说明修复方向本身可能错误 |
| 重构-特性比(refactor-to-feature ratio)超过 4:1 | 为交付一个特性所付出的重构工作量超过特性本身 4 倍,投入产出严重失衡 |
"白板会议"即回到第三节的重新评估协议:把信号数据打包,做一次聚焦评估,而非继续执行第 6 次尝试。
GSD-2 的自主循环为这套启发式提供了天然的检测基建。在 auto-mode.md 中:
- 滑动窗口 stuck-loop 检测:不是简单的"同一单位派发两次"计数,而是分析近期派发历史中的重复模式,可捕获
A→B→A→B这类循环。检测到后先以深度诊断提示重试一次,再次失败才停止; - 同单位连续派发上限:
complete-milestone、validate-milestone、research-slice允许同一阶段连续派发两次,第三次触发 repeat-cap 警告并停止; - 产物验证重试上限:每个单位完成后验证预期产物(artifact)是否存在,缺失则带失败上下文重派,上限 3 次,仍缺失则暂停 auto 模式并报"Artifact still missing..."。
这些上限本质上是把 Gemini 的"重试 N 次即止损"阈值制度化——只不过 GSD-2 将其落在了派发与产物验证层面,而文档将同样的逻辑推广到测试尝试与重构投入层面。二者的互补关系是:项目层面的启发式决定是否重写整个方案,循环层面的上限决定是否继续尝试当前补丁。
六、跨模型方法论(二):Grok 的并行实验(Parallel Experimentation)
Grok 的方法论补上了 Gemini 启发式缺失的一环:仅仅判定"该重写了"还不够,还要避免把整条主路堵死去赌一个未经证实的方案。Grok 的做法是并行实验:
- 创建一个"Rewrite Branch" 子图(独立的实验分支/工作区);
- 在干净起点上,用同一个愿景跑一条垂直切片(one vertical slice),即挑选一个代表性功能,完整地在新架构上实现一遍;
- 对比新旧方案的指标(测试通过率、迭代次数、代码复杂度等);
- 只有指标优于原方案才合并;否则整个实验被丢弃。
其成本分析是:因为实验与主线并行运行,且失败即丢弃,所以成本近乎为零(near-zero)——真正昂贵的只有让实验污染主线。
这一理念在 GSD-2 中有两处直接呼应:
- 并行里程碑编排。
parallel-orchestrator.ts(见 src/resources/extensions/gsd/parallel-orchestrator.ts)为每个里程碑创建独立 worktree 并派生独立 worker 进程,多个里程碑可同时运行,由项目根目录的 SQLite/WAL 运行时协调心跳、租约与派发归属。虽然当前主要用于独立里程碑并行,而非同一方案的竞争性对比,但其"每个实验在独立 worktree 中运行、互不污染"的隔离模型正是 Rewrite Branch 所需的执行容器。 - milestone 内 reassess。GSD-2 在里程碑推进中内置了 reassess 机制(源码与测试见 src/resources/extensions/gsd/tests/reassess-detection.test.ts),在完成每个切片后重新评估路线图——这与"跑完一条垂直切片再对比、再决定是否继续"的节奏同构。
值得强调的边界是:Grok 的"成本近乎为零"有一个隐含前提——必须有独立、可丢弃、可并行的执行环境。如果没有 worktree/branch 级隔离,并行实验就会变成主线污染。因此,第四节的架构使能器是本节方法论成立的前提。
七、为你的 Agent 落地这套机制的实操清单
综合原文档与 GSD-2 的实践,将"Scrap and Start Over"制度化需要五个步骤:
建立信号数据源:在 Agent 的循环中记录每个任务的迭代次数、测试闪断率、被修改文件清单、验收标准措辞。GSD-2 的做法可参考:journal 事件(
unit-start/unit-end/iteration-end)逐条记录,事后可用/gsd forensics做异常定位与相关性分析(见 auto-mode.md)。设定量化阈值:把四大信号翻译成可执行规则。可借鉴的阈值包括:任务重入率(同一组测试尝试 >5 次)、重构-特性比(>4:1)、同单位连续派发上限(3 次)、产物验证重试上限(3 次)。
预留聚焦评估调用:确认触发后,仅做一次 LLM 调用,输入为 manifest + 原始 spec + 任务摘要 + 信号数据,提示词采用原文档模板(见第三节),输出要么"继续",要么给出替代架构及理由。
让重写便宜:这是前置工程投入,包括①接口契约层(保证下游不感知内部替换,GSD-2 的
packages/contracts是现成范例);②同一套验收标准的测试套件;③分支/worktree 级隔离(每个主要方案独立分支,GSD-2 的worktree-manager.ts管理整个生命周期)。允许并行验证:新架构不直接替换主线,而是先在独立 worktree 中跑一条垂直切片,指标优于原方案才合并——否则丢弃实验分支,成本仅是一次 worktree 清理。
需要说明的适用前提:本文的阈值与机制源自 GSD-2 的自主编码循环设计,其他项目落地时应按自身任务规模调整具体数字;但"信号 → 聚焦评估 → 低成本重写 → 并行验证"的链路本身是可迁移的方法论骨架。
八、结语:把"放弃"变成一等公民能力
GSD-2 的经验表明,"何时推倒重来"不是一个哲学问题,而是一组可观测信号、一次受控评估调用和一套低成本重写基建的组合。从 ADR-001 放弃 slice-branch 模型,到 2026-05-03 重构计划 中按契约包、workflow kernel、DB 拆分顺序逐步重写,GSD-2 反复实践着"重写内部、保留接口、测试把关、分支兜底"的范式。对任何希望 Agent 长期自主运行的团队而言,值得复制的不是某条阈值,而是这套让决策可量化、评估受控、重写可逆的完整机制。
延伸阅读:本系列文档入口见 docs/dev/building-coding-agents/README.md;与本文最相关的邻篇包括 15-legacy-code-brownfield-onboarding.md(遗留代码接管)与 17-irreversible-operations-safety-architecture.md(不可逆操作安全)。
- 人工智能
- AI Agent
- 代码智能体
- Agent 编排
- CLI
- AI 应用
【免费下载链接】gsd-2
A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture
相关推荐
WinFsp代码重构:重构风险评估与规避
WinFsp代码重构:重构风险评估与规避 1. 引言 在软件开发过程中,代码重构是一项至关重要的活动,它旨在改进代码质量、提高可维护性和可扩展性,同时不改变软件
存储驱动开发JTAppleCalendar代码重构度量:评估重构效果的指标
JTAppleCalendar代码重构度量:评估重构效果的指标 重构指标体系构建 代码重构效果评估需建立多维度度量体系,结合静态代码分析与动态行为验证。JTAp
移动开发UI组件从0到10+:brpc协议栈如何支撑多协议通信架构?
从0到10+:brpc协议栈如何支撑多协议通信架构? 你是否遇到过服务端需要同时处理HTTP、Redis、Thrift等多种协议的场景?是否为不同协议需要独立部
RPC框架后端微服务网络通信
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考