阅读材料: 应用部分 3. 项目宪法:第一次规则公投

模块「应用部分 3. 项目宪法:第一次规则公投」中第 1 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

实践部分 3. 项目宪法:首次规则公投

状态:建议。immutable_principlesmutable_rules 分离,并显式标注 ttlmax_scoperollback_condition,是一种稳健的实践。带有确定性平局规则(tie-breaker)的智能体自动公投尚处于前沿:其具体形式取决于团队和模型。

对于教学完成度来说,手动填写 constitution.md 并检查可变规则是否包含 ttlmax_scoperollback_condition 已经足够。自动公投和外部仲裁属于完整的 production 轨道。

这里的「项目宪法」是一个经过版本管理的不变量、可变规则和修订批准程序的集合。该集合在任何危险动作执行前都会被检查。

一个词,两个不同的文件

在第一卷中,项目宪法分布在三个文件中:mission.md(我们为什么做这件事)、tech-stack.md(我们用什么技术)、roadmap.md(按什么顺序做什么)。该契约描述的是产品。

在第二卷中,同一个词下出现了第四个文件 —— constitution.md。它描述的不是产品,而是安全自动化的边界:禁止智能体执行哪些动作、哪些动作在受限条件下被允许、谁以及如何更改规则。这是一层叠加,而不是替代。第一卷的文件保留在原位,constitution.md 添加在旁,并在任何危险动作执行前被读取。

如果想要一行话划清边界:mission/tech-stack/roadmap 回答「我们在构建什么」,constitution.md 回答「即使很想做,智能体也不能对它做什么」。

在教学最低要求中,一个小小的 constitution.md,包含两条不可变禁令与一条可变规则就足够了。智能体公投、外部仲裁和剧本(playbook)的自动核查仅对完整轨道是必要的。本章以 第一卷第 6 部分mission.mdtech-stack.mdroadmap.md 的来源)和 第 18 部分(SDD 流程安全性的概念来源)为依托。

阅读前

  • 第一卷的依托:第 6 部分引入 mission.mdtech-stack.mdroadmap.md;第 18 部分解释 SDD 的安全性。
  • 本地教学案例:node_not_ready,因为它能清晰展现「允许的轻量动作」与「危险操作禁令」之间的差别。
  • 留给 capstone/ 的痕迹:两条 immutable_principles、一条 mutable_rule,以及针对 high_memory_usage 的简短 governance_protocol
  • 第一遍阅读的主要术语:immutable_principlesmutable_rules。第三层 governance_protocol 是参考性的,只有在团队引入投票规则时才需要。
  • 暂时可以略过:智能体公投、外部仲裁和剧本的自动核查。

单独设置 production 层的理由很简单:node_not_readyautoscale_200pct 这样的场景没有时间在聊天中讨论。危险动作必须通过形式化的关卡,或者被直接阻止。关于这个关卡的安全性,我们将在依托 第 18 部分. SDD 安全性 中讨论。与已有代码交互的联系在 第 13 部分. 支持现有项目 中。

本章路线图

本章篇幅较长,无需线性阅读。行进地图如下:

  1. 最低教学场景。 手动填写 constitution.md:两条 immutable 禁令、一条带有六个字段的 mutable 规则。这就是通过本章所需的一切。
  2. 核心思想。 解释为什么最低要求长这样。
  3. 通过 Qwen Code 进行访谈。 一种加速填写 constitution.md 的方法。第一遍可以跳过 —— 手动填写同样有效。
  4. 完整轨道。 governance_protocolchange_logdecision_hash、公投。第一遍阅读时非必须:只有在团队出现自动关卡时它们才变得必要。

如果你是第一次阅读,请在「核心思想」一节后停下,去做练习。完整轨道等你在 capstone/constitution.md 中用最简片段收尾之后再回来读。

目标

到本节结束时,你将为自动修复(auto-remediation)开发出一份可工作的 constitution.md。不变量与可变规范将变得清晰,通过智能体公投演进,并在修订谱系中完全可追溯。

这在实践中的意义。智能体不再依据零散的提示行事。它会将每项决策与形式化的项目契约比对。这样的契约有助于加速对重复性事件的响应,但不会让速度成为自动绕过备份、审计、爆炸半径(blast radius)限制和安全回滚条件的权利。

最低教学场景

教学案例

对于 node_not_ready,需要允许 triage 阶段的轻量级智能体重启,但要禁止针对 production 数据库、备份和审计的危险操作。目标是得到一份小巧的 constitution.md,在每次 production 动作前都可以人眼检查。

准备

  • book2/examples/templates/proposal.md —— 修订提案的格式。
  • 一份不能被自动执行的危险动作清单。
  • 一个可重复出现的 unknown 模式,可能演变为可变规则。

第一次阅读可以使用这样的起始集合:

dangerous_actions:
  - delete_namespace
  - restart_database
  - bypass_audit_trace
candidate_mutable_rule:
  incident_type: node_not_ready
  pipeline_phase: triage
  permitted_actions: ["soft_restart_agent"]
  max_scope: "single_node"

ttl: "30d"
  rollback_condition: "repeat_incidents_same_node>=2 or Safety veto"

如果你正在把本章适配到自己的项目,请替换动作的名称,但不要去掉 max_scopettlrollback_condition

步骤

  1. 将至少两条 immutable_principles 写成禁令,而不是建议。
  2. 添加一条 mutable_rule,包含 incident_typepipeline_phasepermitted_actionsmax_scopettlrollback_condition
  3. 描述 governance_protocol:角色、法定票数、Safety 的 veto、以及平局打破规则。
  4. 填写一份简短的 proposal.md:规则为何出现、谁投票、何时激活、如何回滚。
  5. 用一个问题检验文件:「即使会降低 MTTR,智能体也无法执行哪个动作?」*期望:答案在 immutable_principles 中,而不在聊天里。*
  6. 与 [examples/spec-ci/](examples/spec-ci/README.md) 中的可运行示例做对比:思路相同 —— 动作执行前必须有一道可验证的关卡。

验收事实

每条可变规则都必须包含 ttlmax_scoperollback_condition。只要缺少其中任一字段,该规则就不被纳入宪法,只能作为 proposal 草案保留。

可以使用与 capstone/ 中相同的可运行示例来检查文件:

cd book2/examples/constitution
python3 scripts/check.py \
  --constitution specs/constitution.yaml \
  --proposal proposals/valid_proposal.md

你将得到 verdict: PASS。然后换成 proposals/missing_evidence.mdproposals/conflict_with_immutable.md 再跑一遍 —— 你会得到 verdict: BLOCK 和相应的原因。这就是危险动作执行前的教学关卡。

迁移到 high_memory_usage

本章的本地案例是 node_not_ready,但要考核的是 high_memory_usage。迁移只需一条原则,而不是复制整条规则。

node_not_ready 中取什么写到 capstone/constitution.md 中给 high_memory_usage 的内容
immutable「没有连续两次 OK,不关闭事件」immutable「不关闭 high_memory_usage,除非确认 RSS 已连续两次回到 80% 以下」
mutable soft_restart_agentttl: 30dmax_scope: single_nodemutable restart_podttl: 14dmax_scope: single_podrollback_condition: 5xx_increase OR memory_percent>=90% after 2 windows
扩大爆炸半径时的 Safety-veto试图将 restart_pod 扩大到 namespace 时的 Safety-veto

如果无法用一条原则表达出来,那么本地案例还没有提炼出可迁移的原则 —— 在进入 capstone/ 之前请回到本地案例。

如何进入 capstone/

将两条 immutable_principles、一条 mutable_rule 和一段简短的 governance_protocol 迁移到 capstone/constitution.md。如果你编写过 proposal.md,请在 capstone/README.md 中留下一行说明规则出现的原因。如果自动公投并未实际运行,请不要把完整的智能体公投迁移过去。

最简片段:

immutable_principles:
  - "没有 audit_trace 不得执行 auto-remediation。"
  - "没有确认过的备份不得触碰有状态工作负载。"
mutable_rules:
  - incident_type: high_memory_usage
    pipeline_phase: recovery
    permitted_actions: ["restart_pod"]
    max_scope: "single_pod"
    ttl: "14d"
    rollback_condition: "memory_percent>=90% after 2 windows or 5xx increases"
governance_protocol: "任何 max_scope 的扩展都需要单独的 proposal。"

可评审的痕迹

在教学包中,请将 constitution.mdproposal.mdchange_log 记录一同保存。没有出处的修订不被视为 production SDD 的一部分。

核心思想

constitution.md 的第一层是 immutable_principles。所谓 immutable_principles(不可变原则),是指永远不能被自动关闭的规则。它们包括安全层级的禁令与义务:

  • 没有最新备份,不得重启 production 数据库;
  • 不得为了释放空间而删除备份;
  • 没有确认过的稳定化,不得将事件转为 resolved
  • 不得在安全关键命名空间执行绕过(bypass)。

请把这些规范表述为不变量,而不是建议。正是它们在压力时刻约束智能体,因为缩短 MTTR 的最短路径可能造成更大的级联故障。

第二层是 mutable_rules。这是具有精确作用半径的可变规范(与 immutable_principles 不同,这类规则可以通过正式程序被撤销或重写)。每条这样的规则至少需要包含六个字段。其含义如下:

  • incident_type —— 规则适用的事件类别;
  • pipeline_phase —— 响应阶段(triagerecovery 等);
  • permitted_actions —— 被允许的动作列表;
  • max_scope —— 爆炸半径的限制(例如 single_node);
  • ttl(time to live,存活时间)—— 规则的有效期,到期后需要重新审视或续期;
  • rollback_condition —— 自动回滚规则所触发的条件。

没有这些字段,修订就过于宽泛,开始与不变量争夺空间。请对比两种写法。

差:

- id: node_not_ready_soft_restart
  incident_type: "NodeNotReady"
  permitted_actions: ["soft_restart_agent"]

问题:缺少 ttlmax_scoperollback_condition。规则无期限、无爆炸半径边界。半年后将无人再评审它。

好:

- id: node_not_ready_soft_restart
  incident_type: "NodeNotReady"
  pipeline_phase: "triage"
  permitted_actions: ["soft_restart_agent"]
  max_scope: "single_node"
  ttl: "30d"
  rollback_condition: "repeat_incidents_same_node>=2 or Safety veto"

例如,对 incident:NodeNotReadytriage 阶段允许轻量重启(soft restart),但对 incident:DBWriteLagrecovery 阶段禁止。同一动作在不同上下文下,对数据与可用性的风险不同。

第一遍的暂停点

如果你是第一次读到这儿,那么到这里你已经掌握了通过本章所需的一切:两条 immutable 禁令、一条带六个字段的 mutable 规则,以及它与第一卷 mission/tech-stack/roadmap 的区别。接下来是 完整轨道 —— governance_protocolchange_logdecision_hash、公投。这些机制在团队出现自动关卡、并围绕它配置三到四个角色时才会变得必要。对于考核的 capstone/constitution.md,它们不是必须的。

如果你的项目还没有任何自动化动作,请直接跳到「产物与就绪标准」一节,完整轨道等读完第 8 章后再读(那里的角色会再次出现在文件仲裁中)。

完整轨道:governance_protocol

让演进的触发器可观测:同一 pattern_id 出现三次及以上反复出现的未预测事件时,强制启动针对修订的公投。这一阈值将单次异常与稳定的规则缺口分开,避免在每次嘈杂告警后都修改宪法。

固定一个聚合窗口,例如 48 小时。在候选修订(即送交公投的那份 proposal.md)中包含:

  • 输入事件;
  • 当前的 unknown 分类;
  • 预估风险;
  • 预期效果;
  • 撤销条件。

为什么这里要立刻引入多个角色,而第一卷中一个评审者就够。在 第一卷第 16 部分 中,一个评审者就够,因为评审的对象是 AgentClinic 教学项目中某个特性的代码。代价是返工特性。在 production 场景中,评审的对象不同:针对线上服务的自动危险动作。代价是数据丢失、爆炸半径扩大、P0 被悄然关闭。一个评审者不够,不是因为不够聪明,而是因为人很难同时在脑中维持不变量正确性、剧本适用性以及对 production 的风险。因此评审被拆分到多个角色上,每个角色负责一个狭窄的问题。在最简形式下,它们仍可以是同一智能体的三个模型,依次阅读同一文件 —— 但它们的问题不同。

请在 governance_protocol 中描述投票流程。包括智能体角色、票权、法定票数、召集时间,以及确定性的平局打破规则。最简组成是三个角色:

  • Verifier(验证者)—— 查找不变量违反;
  • Implementor(实施者)—— 评估剧本中的适用性;
  • Safety(安全)—— 检查爆炸半径、隐私与回滚条件。

通过条件设为两票、2 approve + no Safety-veto 的规则、触发后 15 分钟内召集,平局打破规则为 safety-first。在这样的打破规则下,Safety 的关键风险始终导致否决。

第四个角色 Coordinator(协调者)不在 governance_protocol 中投票。它出现在更高一层 —— 文件仲裁(第 8 部分),在那里负责 judgment.md 与回合顺序。在本章的宪法中,Coordinator 仅负责将投票结果记入 change_log

将每次更新作为不可篡改的痕迹记录,而不是没有出处的修改。记录中应包含:

  • versionparent_version —— 当前与上一版宪法;
  • reason —— 修订原因;
  • votes —— 各角色的投票结果;
  • decision_hash —— 决策的密码学哈希,可被复算与校验;
  • incident_context —— 触发该决策的事件;
  • activation_time —— 修订生效的时间点;
  • 指向仓库内 diff 的链接。

这样的日志将修订史转化为证据链。如果之后出现「为什么智能体被允许执行该动作」的问题,答案将不再出现在团队聊天里,而出现在可复算的决策谱系中。

示例与应用

constitution.md 的基本结构可以如下:

immutable_principles:
  - id: prod_db_no_restart_without_backup
    rule: "Production database restart is forbidden unless a verified backup exists."
    enforcement: "always_on"

  - id: backups_are_protected_assets
    rule: "Backup deletion, overwrite, or quarantine bypass cannot be executed automatically."
    enforcement: "always_on"

mutable_rules:
  - id: node_not_ready_soft_restart_triage
    incident_type: "NodeNotReady"
    pipeline_phase: "triage"
    permitted_actions:
      - "cordon_node"
      - "soft_restart_agent"
    max_scope: "single_node"
    ttl: "30d"

rollback_condition: "increase in repeat incidents or Safety veto"

governance_protocol:
  roles:
    verifier:
      vote_weight: 1
    implementor:
      vote_weight: 1
    safety:
      vote_weight: 1
      veto: "critical_risk"
  quorum: 2
  pass_rule: "at_least_2_approve_and_no_safety_veto"
  convene_after: "3_unknown_incidents_same_pattern"
  convene_within: "15m"
  tie_breaker: "safety_first_then_latest_matching_precedent"

change_log:
  - version: "1.2.0"
    parent_version: "1.1.0"
    reason: "3 unknown NodeNotReady incidents in 48h"
    votes:
      verifier: "approve"
      implementor: "approve"
      safety: "abstain"
    decision_hash: "sha256:..."
    activation_time: "2026-05-17T12:00:00Z"

应将宪法接入剧本执行前的关卡检查,而不是执行之后。步骤顺序如下:

  1. 本地脚本检查 immutable_principlesmutable_rules
  2. Qwen Code 在 Plan Mode 下解释风险与缺口;
  3. 执行者获得动作授权。

/constitution/tasks 并非 Qwen Code 的内建命令。如果需要它们,请将它们实现为项目的自定义命令(project custom commands)。

通过 Qwen Code 进行访谈

在手动编写 constitution.md 之前,请进行与 第一卷第 6 部分 相同的访谈。production 层在经典的 mission/tech-stack/roadmap 三件套之上增加两个回路,进入这两个回路必须有人类做出明确决定:智能体在未经确认时有权执行哪些动作、谁拥有 veto、triage 阶段允许的最大爆炸半径是多少。

请求:

/clear
我们正在扩展 AgentClinic-production 的宪法。
请阅读 @specs/mission.md、@specs/tech-stack.md、@specs/roadmap.md
以及 @specs/playbooks/node-not-ready.md。

请创建一份 @specs/constitution.md 草稿,包含三个章节:
- immutable_principles
- mutable_rules
- governance_protocol

在写入磁盘前,请向我提出正好三组问题:
1. 智能体在 production 中哪些动作始终被禁止(备份、审计、密钥)。
2. 哪些动作可以在带爆炸半径限制与 ttl 的条件下,授权给 triage 阶段。
3. 谁投票、谁拥有 veto、按什么阈值召集公投。

先不要写文件。收到我的回答后,请展示变更计划,并等待批准。

如果 Qwen Code 立刻开始写 YAML 而没有提问,请叫停它:

停下来。在访谈完成前不要写文件。
请先按 QWEN.md 的要求提出三组问题。

人类对访谈的好回答包含决定,而不是愿望:

不可变原则:
没有经过验证的备份,不得自动重启 production 数据库。
不得自动删除备份、审计与密钥 —— 即使在释放空间的压力下也不允许。
事件必须在连续两次 OK 之后才能转为 resolved。

可变规则:
在 triage 阶段对 NodeNotReady 允许 soft_restart_agent,max_scope=single_node,ttl=30d。
规则回滚条件 —— 同一节点上出现两次重复事件或 Safety 否决。
未经公投不得扩大 max_scope。

治理:
Verifier、Implementor、Safety 参与投票。每票权重为 1。
法定通过条件 —— 2 票 approve 且无 Safety veto。
公投召集条件 —— 48 小时内同一 pattern_id 出现 3 次 unknown 事件。
平局打破规则 —— safety_first。

然后请 Qwen 检查自己的草稿:

检查 @specs/constitution.md。
找出被写成「建议」而非禁令的 immutable 规则。

找出缺少 ttl、max_scope 或 rollback_condition 的 mutable 规则。
找出缺少平局打破规则(tie-breaker)的 governance_protocol。
不要修改文件,返回不符合项列表。

这一步的常见错误:

  • 不可变规则被写成「尽量避免」 —— 这是建议,不是禁令;
  • 可变规则缺少 rollback_condition,事件发生时它就成了无期限规则;
  • governance_protocol 没有描述平局打破规则 —— 出现平票时系统会卡住;
  • 缺少 change_log,宪法的第一次修改就会丢失出处。

只有按这份清单走完之后,才能在项目中锁定草稿。在教学用的 book2/ 中,这一步不需要 git 命令:重要的是一份带规则出处的可读 constitution.md

> 宪法关卡:可运行示例与项目接口。 可运行检查位于 [examples/constitution/](examples/constitution/README.md) —— 它读取 YAML 格式的宪法和带 YAML frontmatter 的 Markdown(修订提案),返回 verdict: PASS|BLOCK 与阻止原因列表。在考核中用它就够了。在真实项目中,这个关卡还要补两步:Qwen Code Plan Mode 下的请求,以及剧本 max_scope 与规则 max_scope 的比对。三步作为一个整体执行。

# [runnable] — 用宪法检查提案
python3 book2/examples/constitution/scripts/check.py \
  --constitution book2/examples/constitution/specs/constitution.yaml \
  --proposal book2/examples/constitution/proposals/valid_proposal.md

# [project script] — 在你自己的宪法和剧本上做同样的检查
python3 scripts/constitution/check.py \
  --constitution specs/constitution.yaml \
  --proposal proposals/<your-proposal>.md

# [project script] — Qwen 在 Plan Mode 下做的额外关卡
qwen -p "检查 @specs/constitution.yaml 与 @specs/playbooks/node-not-ready.md。
模式:仅规划。请说明该修复计划是否违反 immutable_principles,
并指出需要哪些 mutable_rules 才能放行。" \
  --approval-mode plan \
  --output-format json \
  > out/node-not-ready-constitution-review.json
flowchart TD
A[事件] --> B[Plan Mode 与脚本对 immutable 的检查] --> C[可变规则检查] --> D[放行 / 阻止] --> E[动作执行]
C --> F[Unknown 事件] --> G[Unknown 阈值达成] --> H[形成 proposal] --> I[公投] --> J[Commit] --> K[新宪法]

公投很适合在回放场景中演练。三个相同的 unknown 事件会生成一份 proposal.md,智能体投票,通过的修订连同决策哈希一起记入 change_log

例如:临时规则 hotfix_ticketing_flood 可以允许 12 小时内的简化工单路由。前提是存在检查点(checkpoint),并保留对审计丢失的不可变禁令。修订通过后,请确认它没有变成无期限规则。确保 ttlrollback_conditiondecision_hashactivation_time 与变更记录一起在仓库中可见。

小结

constitution.md 为自动修复划定了边界:智能体可以适配什么、以及它没有权利为了局部优化而关闭什么。

这层边界中的角色分工如下:

  • 不变量保护备份、审计、数据与关键区域;
  • 可变层允许针对重复事件细调剧本;
  • 智能体公投使规则变更可被验证;
  • 修订谱系保存原因、票数、决策哈希与生效时刻。

接下来,这些规范将在 LLM 对决中得到检验:Verifier 对阵 Implementor。

产物与就绪标准

产物就绪条件
specs/constitution.md不可变规则被表述为禁令而非建议;通过文件可以读出智能体即使为了改善 MTTR 也不能执行的动作
一条 mutable_rule填齐 incident_typepipeline_phasepermitted_actionsmax_scopettlrollback_condition —— 全部六个字段
proposal.md 或规则的出处记录修订有出现的理由,否则它不属于 SDD 包

完整轨道还会增加若干具有不同爆炸半径的修订、含 parent_version、票数与 decision_hashchange_log 记录,以及一个在剧本执行前检查宪法的项目级关卡。完整轨道可以视为就绪的条件是:关卡确实在执行前阻止了对不可变层的违反;公投具备法定票数、Safety 的 veto 与确定性的平局打破规则;已通过的修订可从事件上下文一路追溯到 diff。

练习

  1. 打开 book2/examples/templates/proposal.md,针对一个危险域(部署、迁移、事件、密钥)填写:至少两条 immutable_principles(写成禁令)和一条 mutable_rule,包含 incident_typepipeline_phasepermitted_actionsmax_scopettlrollback_condition期望:每条可变规则都包含全部六个字段;教学场景的验收事实成立。
  2. 编写 governance_protocol:角色、法定票数、Safety 的 veto 与平局打破规则;自问「即使会降低 MTTR,智能体也无法执行哪个动作?」。*期望:答案在 immutable_principles 中,而不在聊天里。*
  1. 迁移到 capstone/constitution.md:两条 immutable_principles、一条 mutable_rule 与一段简短的 governance_protocol(格式参考本章教学场景中的片段);如果运行过 proposal.md,请在 capstone/README.md 中添加一行说明规则出现的原因。期望:没有出处的修订不会进入 SDD 包。

复习题

  1. 项目的哪些规则应该是不可变的,哪些不应该?
  2. 为什么可变规则需要 ttl?一年后没有它会发生什么?
  3. 当 Safety 行使 veto 时应该发生什么?为什么它不能被两个 approve 绕过?
  4. 48 小时内出现三次相同的 NodeNotReady,公投触发器已经激活,但此时正有一个活跃事件在处理。你会接受、推迟该修订,还是回滚触发器?
我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

在 Qwen Code CLI 开发中使用 SDD。应用课程
进度 0 / 95