
做软件的人几乎都经历过同一种痛:需求文档写在 Confluence 里,设计画在图里,真正说了算的却是仓库里那堆已经跑上线的代码。在AI时代,在经历了Vibe Coding这样一种相对随意的编码方式后,终于有人认识到,即便在AI时代,传统的软件工程流程依然需要遵循,需要改变的是如何更好地实现AI与人的协作,解决AI上下文管理以及生成代码存在的各种缺陷,提出了一种新的驱动模式:规约驱动开发(Specification-Driven Development,SDD) 。规约驱动开发的核心理念可以概括为:
这套理念用在新功能、新产品上很自然。那重构呢?重构的“意图”往往不是用户故事里的新按钮,而是“这坨代码闻起来不对、将来会咬人”。若仍沿用“看见不爽就改”的即兴发挥,在 AI 辅助下尤其危险——模型很乐意帮你大改特改,却未必守得住外部行为不变这条底线。
为此,我参考SDD的理念和过程,借鉴了SDD的骨架,提出AI重构的一种方法,把SDD中“规约的内容”从用户需求更换为由AI识别出来的“代码坏味道(bad smells)”,故而命名为坏味道驱动重构(Bad smells-Driven Refactoring,BDR)。
什么是坏味道驱动重构
流程上,它与 SDD 五步同构,只是工件名字与内容不同:
步骤 | 角色(类比 SDD) | BDR 在做什么 |
|---|---|---|
1 | 宪法 / 最高原则 | Constitution:全局重构原则、标准步骤、门禁(例如:小步、可测试、可回滚;改变对外行为须走 SDD) |
2 | 需求 / 功能规约 | Bad smells:在宪法约束下,把 AI 或人工审阅识别出的坏味道,写成可验收的规约条目(固定落在 badsmells.md) |
3 | 任务分解 | Tasks:每条任务必须能追溯到 badsmells.md 的条目 ID,写清依赖、DoD、是否 [SDD] 联动 |
4 | 对齐与冲突解决 | Analysis:badsmells.md 一变,就做差分——缺任务、孤儿任务、DoD 过期,先改任务文档再动代码 |
5 | 实现 | Refactor:严格按宪法里的“标准步骤”执行;每个任务结束要用户确认再继续 |
五步标准工作流如下图所示:

最关键的认知转变是:坏味道不是聊天框里一闪而过的牢骚,而是和 PRD 同级的事实源。 你可以用专门的提示词在 Vibe Coding 里让 AI 帮你嗅味道,也可以用静态分析、人工走读;但无论哪种来源,落不到 badsmells.md 里,就不进入 BDR 正式流程——这正是宪法里写死的纪律。
重构宪法
显然,BDR的核心是我们制订的重构宪法,它制订了重构领域的“根本法”,内容包括使命、BDR权威工件、重构第一性原则、BDR重构标准步骤、重构过程的基本原则和BDR流程门禁。可以认为,整个BDR过程都是在它的指引和约束下逐步完成的。
以下是重构宪法的主要构成。
使命
BDR权威工件

坏味道(badsmells)环节的产出
badsmells.md。bdr/badsmells.md(与本目录其他 BDR 文档同级),不得 使用其它文件名作为该环节的正式规约载体。
元规约与具体规约的分工:
badsmells.md 中的 具体清单。任务(tasks)环节
badsmells.md 的当前内容 进行 规划与拆分(每条任务须能追溯到 badsmells.md 中的条目或 ID)。更新任务)。
分析(analyze)环节与文档迭代:
badsmells.md 允许不断迭代(增删改条目、调整版本号与修订说明)。分析环节(analysis.md):
tasks.md 中的任务(覆盖、依赖、DoD 是否仍有效);tasks.md(及必要时 specification.md / analysis.md 本体的结论段),再 按更新后的任务执行重构。
badsmells.md 不可兼得,先动 badsmells.md / specification 或启动宪法修订流程,不得静默硬改代码绕过文档。重构第一性原则
重构的第一性原则,其实就是Martin Fowler在《重构》一书的副标题表示的,即在重构现有代码时,需要在 不改变既有代码外部功能(对调用方与测试所固定的可观察行为)的基础上,提升代码的 内部质量。基于我的认识,我认为代码内部质量的评价因素可包括:
在重构宪法中定义该第一性原则,就可以使得AI按照BDR过程进行重构时,能够识别到大多数常见的代码坏味道。
重构的标准步骤
步骤 1:识别坏味道
依据 badsmells.md 与 specification.md,明确待消除条目与优先级。
步骤 2:确定测试覆盖
确定存在坏味道的代码 是否已被单元测试(或等价自动化测试)覆盖;若 没有,先为其编写测试,锁定当前行为。
步骤 3:运行测试并修复至绿
运行单元测试,确保 全部通过;若失败,首先修复失败的测试(或修正测试与规约的一致性),直至通过。
步骤 4:重构以消除坏味道
在 测试绿 的前提下实施最小必要重构,对准已识别的坏味道,避免无关扩散。
步骤 5:回归与确认
再次运行测试,确保重构 未破坏 既有功能;测试通过后,经用户(维护者)确认,再对 下一坏味道 重复 步骤 1~5(或按 tasks.md 进入下一任务)。
这五个步骤形成“识别-补测-测绿-重构-再测绿”的闭环,形成了重构的绝对底线:

为了让整个过程必须按照BDR规定的流程执行,需要明确地在重构宪法中告知具体的约束:
badsmells.md 中的条目;计划范围内坏味道均已消除或显式降级(文档记载原因) 后,本轮 BDR 结束。流程门禁确定了每一步跃进到下一步的约束标准,避免AI乱折腾:
与本文 §3~§5 无冲突;条目可验证、可映射到任务;版式符合 §2.1;修订历史含 提交版本(见 specification.md §7-修订历史表与提交版本门禁))规约门禁、任务门禁、分析门禁和执行门禁给AI这匹野马套上了辔头,这也符合Harness Engineering的思想:

元规约specification规定了坏味道的描述格式、编号规则、优先级维度与验收口径,并给出了BDR的重构目标:
badsmells.md 中每条坏味道 可追踪(稳定 ID)、可验收(消除标准不含糊)。确定了优先级维度:
说明:「优先级」用于 排序与裁剪范围,不表示可跳过测试与标准步骤。
还有关键的坏味道清单条目格式,它是写入 badsmells.md 的规约要求。每条坏味道 至少 包含:
BS-类别-序号(如 BS-CLARITY-001)或连续编号并在 analysis.md 中维护 ID 映射表。可选:建议重构手法 — 非强制,以任务设计为准。
重构过程的规约
既然名其为坏味道驱动,因此就必须明确这样的坏味道规约究竟长什么样?和需求一样,坏味道也是随着时间推移不断增长和变化的,故而需要确保它的版本变更。
与传统重构不同之处在于,坏味道的识别过程完全依据AI执行。如果采用BDR过程执行重构,由于它已经定义了重构的第一性原则,通过Cursor打开你的项目后,在项目中定义BDR对应的规约文档,就可以在对话框中输入以下提示词:
遵循 BDR 过程,识别坏味道
AI会进行如下所示的思考:
正在阅读 BDR 文档与相关规范,以便按流程识别坏味道。
正在扫描 src/{project-name} 以识别符合 BDR 宪法 §3 的坏味道,并按要求写入 badsmells.md,随后同步 analysis.md 与 tasks.md。
这意味着,在确定了重构宪法(constitution.md)以及坏味元规约(specification.md)之后,AI将自动识别坏味道,然后将坏味道按照元规约规定的格式以条目形式写入到badsmells.md中。一旦确定了坏味道,AI会执行计划,对坏味道条目进行任务分解,获得tasks.md,并通过分析检查BDR文档链的一致性。
以我自己的一个项目为例,违背“复用”质量标准的一个坏味道条目如下所示:
BS-REUSE-001
bootstrap_from_env 与 bootstrap_from_openai_compat_serial_env 结构重复
src/eywa/kernel/core/bootstrap.py与坏味道条目BS-REUSE-001对应的任务则如下所示:
bootstrap 双路径重复逻辑badsmells.md §2 BS-REUSE-001。src/eywa/kernel/core/bootstrap.pybootstrap_from_env 与 bootstrap_from_openai_compat_serial_env 共享同一套装配逻辑;tests/test_m17_kindle_batteries.py 及相关测例全绿。一旦确认了BDR的所有工件之后,接下来才真正开始执行重构。执行重构的方法很简单,只需要在对话框中输入:
执行重构任务 B-T01
AI可以识别该重构任务,并按照BDR的要求执行,仍然以B-T01为例,得到的执行结果为:
B-T01 已完成(BS-REUSE-001)
代码改动
在 bootstrap.py 中抽出 _bootstrap_from_filled_registry:在 LlmProfileRegistry 已填好且 default_llm_profile_id 有效时,统一完成 ToolRegistry → OpenAICompatibleClient → build_runtime_and_crew → 返回五元组。
bootstrap_from_openai_compat_serial_env:仍只负责 register_openai_compat_serial_profiles(reg),再调用上述辅助函数。bootstrap_from_env:仍只负责 register_llm_profiles_from_env(reg),再调用同一辅助函数。公开签名、返回类型与字段顺序未改。
测试
uv run pytest tests/test_m17_kindle_batteries.py:11 passeduv run pytest:115 passed文档
HEAD:345d98508491022988bd25d6edbc11cffdffb8b0)。若你随后把本次改动打成 新 commit,请把该行 提交版本 改成那次提交的 git rev-parse HEAD。按 BDR 确认门:若你认可本次结果,可继续 B-T02;若要调整实现,说明一下即可。
观察重构后的代码,如下图所示:

坏味道发现bootstrap_from_openai_compat_serial_env()和bootstrap_from_env()两个方法存在重复代码。执行重构时,通过提取一个私有方法_bootstrap_from_filled_registry() 完成对重复代码的消除。
一旦完成一个重构任务,AI会将对应任务标记为已勾选 [x],同时,还会更新tasks.md文档的“修订记录”,如下所示:
| 0.4.1 | 2026-03-31 | `345d98508491022988bd25d6edbc11cffdffb8b0` | **B-T01** 完成:`_bootstrap_from_filled_registry` 合并 `bootstrap_from_env` / `bootstrap_from_openai_compat_serial_env` 装配路径;全量 pytest 绿。
修订BDR规约
无论采用Vibe Coding还是SDD,即便严格按照Harness Engineering的要求,依旧不能挽救从代码稀缺到代码泛滥的发展趋势,这是AI时代软件工程不可避免的结果。因此,随着需求不断增加,代码库不断增长,之前识别的坏味道必然越积越多,如果不及时控制,就会造成“债台高筑”的糟糕结果。
BDR将坏味道视为整个过程的“唯一事实”,与其他AI重构不同,发起重构的唯一驱动力是坏味道规约,发起重构的信号则是根据坏味道规约分解出来的任务。当代码库又累积了新的还未发现的坏味道时,不应直接执行重构,而是继续按照BDR的过程执行。因此,可以要求AI修订BDR规约,提示词可以很简单:
遵循BDR过程,识别现有代码的坏味道
AI会聪明地思考:
按 BDR 流程审阅代码并对照 `badsmells.md`,识别未记录或可更新的坏味道。正在读取规约与关键代码路径。
正在更新 `badsmells.md`(条目索引、刷新已缓解条目的描述、新增识别项),并同步 `analysis.md` 差分与 `tasks.md` 中的新任务。
重要之处在于它会基于已经执行了的重构任务进行差分。以我自己的项目为例,执行以上提示词得到的结果如下:已按 BDR 做完一轮 识别 → 写入
badsmells.md →
analysis 差分 →
tasks 增补,摘要如下。
1. docs/bdr/badsmells.md v0.4.0
§1:说明「已消除」条目可保留正文,以 §2.0 索引与代码为准。
§2.0 索引表:对照 B-T01~B-T07,标明各 BS 为 已消除 / 部分残余 / 开放。
BS-CLARITY-001:按当前代码改写——B-T05 已抽出
SpiritSeerCatalog,但
Spirit 仍约 430+ 行,Large Class 残余仍成立。
新增三条(开放):
BS-ROBUST-002:
llm_retry.complete_with_network_retry 的
except Exception 无日志、
str(e) 未脱敏,与 B-T06 后工具/HTTP 路径不一致。
BS-SEC-002:
base_url 仅在
LlmProfileRegistry.register 校验,直接
OpenAICompatibleClient(profile) 可绕过。
BS-CLARITY-003:
serial_multi_agent.py 结构校验 / 模板解析 / 槽位消解混在同一模块,Long Module 风险。
§3 修订历史:已增 v0.4.0 行(提交版本为当前
git rev-parse HEAD;你本地若随后单提交文档,请改成该次 HEAD)。
2. docs/bdr/analysis.md v0.3.5
§2.1 已按 v0.4.0 / v0.5.0 重写(条目 A~F、B-T08~B-T10)。
注明 BS-CLARITY-001 残余 尚未单独拆任务(可后续补 B-T11 或并入 Spirit 续瘦身)。
3. docs/bdr/tasks.md v0.5.0
新增 B-T08(BS-ROBUST-002)、B-T09(BS-SEC-002)、B-T10(BS-CLARITY-003)。
backlog 头与 §3 已对齐
badsmells v0.4.0。
4.docs/bdr/specification.md v0.2.5
§4「对齐原则」枚举中补上 一致;修订历史增一行。
说明:BS-ROBUST-001 / BS-SEC-001 等条目的旧描述仍保留作基线;是否已消除以 §2.0 索引为准。若你希望历史条目正文也改成「已消除」摘要,可以再说,我可以再改一版文档结构(例如「归档」小节)。
下一步按宪法应走:维护者确认 → 从 B-T08 起做小步重构(先测再改)。显然,BDR的核心是维护一份重构的规约,一切重构的开始,都以此规约为准。这可以称为是AI时代的重构纪律。它遵循一条冲突处理的黄金准则:先改文档,再改代码。通过处理规约的演进,运用AI帮助我们一步步进行代码的重构。这一过程显然既适用于从0开始的绿地项目,也适用于拥有大量遗留代码的棕地项目,二者的唯一区别,仅在于坏味道和重构任务的多寡。为了避免创造大量的“AI遗留代码”,需要在AI研发的过程中,严格遵循此纪律。如此就能形成良好的人机协作:
如下图所示,二者分工清楚,方向盘虽然掌握在AI手中,但人才是发号施令的真正掌舵者。要是研发者忽略此重构纪律,代码质量自然没有任何改变。可BDR的AI重构显著降低了代码重构的难度与成本,当遵守纪律变得轻松自如时,纪律也就不再成为推行的枷锁了。

若你认同 SDD 的方向,又苦于 AI 重构“改得欢、收不了场”,就可以考虑推行BDR的重构过程。
由于BDR过程是我个人参考SDD并结合项目实践总结出来的,没有任何大语言模型认识它、了解它。如果你希望在Cursor等类似的AI IDE下推行BDR,需要先通过提示词告诉它,让它了解BDR的原则、过程。使用如下提示词,甚至可以让AI IDE直接在你的项目中生成BDR的权威工件,当BDR的内容成为AI研发过程中的上下文后,执行重构任务就变得简单许多。
提示词如下:
借鉴SDD的开发流程,设计基于坏味道驱动重构的重构流程,简称为BDR,步骤为:
1. 宪法(constitution):整个重构流程都需要遵循的全局性的原则和要求
2. 坏味道(badsmells):基于宪法的重构要求,识别现有代码的坏味道,生成坏味道的规约文档
3. 任务(tasks):根据坏味道规约文档,将重构工作分解为一个个独立的有互相依赖,前后顺序的任务
4. 分析(analyze):检查坏味道和任务间的差异,发现冲突先改任务文档而不是先改代码
5. 重构(refactor):执行任务,并严格按照宪法规定的重构步骤推进,每个任务的执行需要用户确认
BDR的文档与SDD的文档处于同一级,放在bdr目录下,文档格式保持一致。
制订重构宪法时,需要定义以下内容:
## 重构第一性原则
重构现有代码时,需要在不改变既有代码外部功能的基础上,提升代码的内部质量,包括:
1. 清晰:保持代码结构的清晰度,确保各个模块的职责分配合理,边界清晰,满足高内聚低耦合原则。
2. 一致:确保设计与编码实现的一致性;确保编码风格的一致性;确保错误处理的一致性;确保接口定义和通信方案的一致性;确保对外访问的一致性。
3. 可读:类、方法、变量命名遵循编码规范,体现业务含义;在确保命名可理解基础上,确保名称尽可能简短;若代码实现逻辑相对复杂,可为代码添加适度注释。
4. 复用:遵循DRY原则,避免代码出现不必要的重复;应清晰定义领域对象,并遵循“信息专家模式”和迪米特法则;确保各个类职责分配的合理性,遵循单一职责原则和接口隔离原则;合理运用函数和lambda表达式实现小粒度的代码片段抽象。
5. 扩展:不对未来的需求做任何假设,但需要遵循开放封闭原则和依赖倒置原则;应考虑接口定义的规范性和标准性,增加对接口版本的管理,使其能够满足向前向后的兼容;进行合理的抽象,并能以最小修改成本支持更多的基础设施、第三方框架、外部系统等;具有可测试性,通过mock框架可以轻松地为主体业务逻辑编写单元测试。
6. 健壮:确保代码能够正确处理各种错误情形,通过分级方式处理异常,并通过日志记录各种异常信息,不会因为各种异常的发生导致程序崩溃
7. 安全:消除各种潜在的安全风险
8. 简单:以上各条按照重要性先后排列,在满足以上要求的基础上,确保代码的简单性,即遵循奥卡姆剃刀原则,若无必要,勿增实体(模块、类、方法、函数)。
## 重构的标准步骤
步骤1:识别坏味道
步骤2:确定存在坏味道的代码是否被单元测试覆盖,如果没有,为其编写单元测试
步骤3:运行单元测试,确保全部测试通过;如果测试失败,首先修复失败的测试,直到测试通过
步骤4:重构以消除坏味道
步骤5:运行单元测试,确保重构没有破坏现有功能,测试通过后,在用户确认后,重复以上步骤,开始对下一个坏味道的重构
## 重构过程的基本原则
1. 重构过程必须遵循重构的标准步骤进行
2. 每一步重构都必须确保代码是可用的
3. 识别的坏味道是重构的驱动力,消除所有坏味道后,重构过程结束
AI会根据以上要求生成BDR的权威工件。如果在执行BDR过程中,BDR权威工件的指导与约束作用存在偏差,你还可以通过修订BDR工件的方式,优化你的BDR过程。
工件的内容终归是形式,必须理解BDR的核心原理,即“以代码坏味道为唯一事实的规约,驱动AI重构的过程”。整个过程又收敛成三条行动:
badsmells.md 管事实。这三条行动又称为BDR的三步走策略:

坏味道从来不是目的,可维护、可验证、可持续演进的代码才是。BDR只承认一件事:在 AI 时代,若没有一个和代码同权的规约层,“重构”最容易退化成“不可审计的聊天”。把坏味道上升为重构的“纲”,让规约走在前面——SDD 已经证明了这条路在产品上走得通;BDR 说的是:重构也值得同等待遇。
