学习指南: 第六部分:制定宪法

模块「第六部分:制定宪法」中第 2 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

主题:第6部分。制定宪法

难度级别:中级

预计学习时间:3-4小时(包括使用Qwen Code进行实践)

先决条件: 对Git和命令行的基本理解

熟悉TypeScript和Node.js

使用markdown文档的经验

理解课程前面部分中的SDD(规范驱动开发)基础

可以访问Qwen Code或类似的AI助手用于实践任务

学习目标: 在开发第一个功能之前,从三个必需文件(mission.md、tech-stack.md、roadmap.md)创建项目宪法

通过"能否经受五个功能不变"的标准,区分长期架构决策(tech-stack.md)和单个功能级别的决策(requirements.md)

与AI代理进行结构化访谈以共同创建宪法,提出三个分组的问题块

基于第一个功能后的git diff分析,识别并将隐式团队规则形式化为QWEN.md

在提交前检查宪法是否存在矛盾、模糊性和阶段过大问题

概述:宪法是人与AI代理以及项目未来参与者之间的项目契约,防止代理反复"猜测"任务、技术栈和工作顺序。在SDD方法论中,宪法在第一个产品功能之前形成,由specs/目录中的三个必需文件组成:mission.md(为什么以及为谁)、tech-stack.md(项目的技术决策)和roadmap.md(分阶段实施计划)。本课程部分不仅教授手动编写这些文档,还教授通过与代理进行结构化访谈共同创建它们、检查矛盾以及将隐式规则转化为显式约定。特别关注宪法决策与功能规范之间的边界,以及基于与代理的实际交互经验将非正式团队规则固定在QWEN.md中的实践。

关键概念: 项目宪法:在功能之前形成的三个文件(mission.md、tech-stack.md、roadmap.md)的集合,位于specs/目录中。作为契约运作:如果跳过,代理将每次都重新猜测任务、技术栈和工作顺序,导致架构退化和完整性丧失。

Mission.md:回答"为什么"和"为谁"的问题。包含产品目的、主要受众和成功标准。课程示例:AgentClinic——一个讽刺性教育应用程序,其中AI代理是心理健康诊所的患者,而人类引发他们的疾病。代码必须保持严肃和教育性。

Tech-stack.md:固定项目的长期技术决策:语言、运行时环境、Web框架、数据库、测试库、依赖限制。关键原则:这里的决策应至少经受五个功能不变。每次变更都需要重新规划(课程第10部分)。

Roadmap.md:简短路线图,分为小阶段,每个阶段可放入一个专注的分支中。阶段应足够小,以便无需"英雄主义"即可验证。示例:阶段1仅证明基本连接的工作性,阶段2添加领域数据。

Tech-stack.md / requirements.md的边界:基本划分规则:tech-stack.md包含项目级别的决策(经受五个功能),requirements.md功能包含单个功能级别的决策(路由、表单字段、验证规则)。简单测试:如果决策在功能合并后被遗忘——它属于requirements.md。示例:"使用Hono"——tech-stack.md;"GET /agents路由返回包含10条记录的HTML列表"——功能requirements.md;"所有列表默认返回10条记录"——tech-stack.md或conventions.md。

Qwen.md和隐式规则:用于固定代理稳定猜测错误的非正式团队规则的文档。典型领域:代码风格和命名、禁止的结构(any、@ts-ignore)、允许的依赖项列表、错误消息格式、错误处理结构、提交格式、合并前仪式。发现的最佳方法——分析第一个功能后的git diff,并找到为代理完成的风格或决策修正。

通过qwen code进行访谈:共同创建宪法的结构化过程:给代理上下文,它提出恰好三个分组问题(任务和受众、技术栈、路线图),在回复中获得具体决策而非一般愿望,然后才记录文件。如果代理跳过访谈——需要停止并要求遵循协议。

宪法检查:提交前的强制步骤:代理检查自己的文件是否存在矛盾、模糊表述和过大的阶段。典型问题:路线图需要英雄主义、技术栈包含"以防万一"的依赖项、mission.md未定义代码读者、SQLite在路线图中提及但不在技术栈中、"现代界面"没有具体限制。

练习: 标题:练习1:决策分类——记录在哪里?

问题:给定AgentClinic项目的五个技术决策。为每个决策确定它进入哪个文档:tech-stack.md、功能requirements.md或roadmap.md。根据"经受五个功能"的标准进行论证。

  1. 使用Hono库作为Web框架
  2. POST /appointments路由接受agentId、ailmentId、date字段并返回201及记录ID
  3. 添加ORM Prisma用于数据库操作
  4. 阶段2:添加治疗表和/therapies页面
  5. 网站上所有表单使用服务器端验证,以统一格式返回错误

解答:1. tech-stack.md——Web框架选择决定整个项目的架构,将经受多个功能。

  1. 功能requirements.md"预约登记"——具体路由、字段和响应代码属于单个功能,实现后将被遗忘。
  2. tech-stack.md——ORM选择是长期架构决策,影响所有数据操作层。
  3. roadmap.md——这是路线图阶段,不是技术决策也不是功能细节。
  4. tech-stack.md(或单独的conventions.md)——项目中所有表单的验证规则,将经受多个功能。如果仅涉及预约表单——则属于requirements.md。

难度:初级

标题:练习2:为新项目编写mission.md

问题:您正在启动"DevGarden"项目——一个以植物花园形式可视化开发者技能成长的平台。每次提交浇灌植物,错过一天——枯萎。编写完整的mission.md文件,包括:目的(讽刺或严肃语气?)、主要受众(至少2组)、成功标准。遵循课程中的结构。

解答:示例答案:

# 使命

DevGarden——一个将开发者提交历史转化为活花园的平台:定期活动浇灌植物,休息导致枯萎。

## 目的

产品是带有游戏化元素的激励工具。切入点以半严肃语气呈现:植物对仓库中的实际活动做出反应,枯萎是"技术债务"在注意力储备中的直观隐喻。

## 主要受众

- 与编写代码的代理一起学习SDD的开发者。
- 实施开发指标游戏化的团队。
- 学习GitHub API集成和TypeScript服务器应用的工程师。

## 成功

开发者应理解SDD工件如何帮助在多个功能中保持统一的产品隐喻,并能够在不丧失架构完整性的情况下用新植物品种扩展花园。

检查:是否有"为什么"的答案(通过隐喻激励)、"为谁"(3组)、具体的成功标准(理解SDD工件的作用,而非简单的"应用运行")。

难度:中级

标题:练习3:分析git diff以创建QWEN.md

问题:与代理完成第一个功能后,您在git diff中发现以下手动为代理完成的修正:

  • 代理使用console.log处理数据库错误 → 您替换为带级别的结构化日志记录器
  • 代理将变量命名为usrData → 您重命名为userData
  • 代理在SQLite查询前放置// @ts-ignore → 您移除并添加正确类型
  • 代理编写提交"some fixes" → 您重写为"fix(db): handle connection timeout in agent repository"
  • 代理为单个函数debounce添加依赖lodash → 您替换为原生实现

基于这些模式,为QWEN.md制定3-5条规则。

解答:QWEN.md示例:

# QWEN.md — AgentClinic项目约定

## 日志记录
- 产品代码中禁止直接使用`console.log`和`console.error`
- 使用统一的结构化日志记录器,带级别(info、warn、error、debug)
- 数据库错误消息必须包含操作上下文,不泄露敏感数据

## 命名
- 禁止缩写:`usr`、`data`、`cnt` → 使用`user`、`data`、`count`
- 变量和函数使用camelCase,类和接口使用PascalCase,数据库字段使用snake_case

## TypeScript
- 产品代码中禁止`any`和`// @ts-ignore`
- 每个数据库查询必须有明确的结果类型

## 提交
- 格式:`<类型>(<<范围>): <现在时动词> + <对象>`
- 示例:`feat(agents): add list endpoint`、`fix(db): handle connection timeout`
- 禁止"fix"、"update"、"some changes"等提交

## 依赖项
- 新依赖项需要讨论并更新tech-stack.md
- 对于简单任务(防抖、节流、简单对象的深克隆),优先选择原生解决方案而非库

关键技能:将观察到的错误模式转化为具体、可验证的规则,而非一般建议。

难度:中级

标题:练习4:检查宪法是否存在矛盾

问题:给定项目的宪法草案。找出提交前检查步骤应识别的至少4个问题。

# mission.md
AgentClinic——AI代理的诊所。面向所有人的教育应用。

# tech-stack.md
- TypeScript
- Hono
- SQLite(本地存储)
- ORM Prisma
- UI使用React
- Vitest

# roadmap.md
## 阶段1
- 安装所有依赖项
- 配置带迁移的数据库
- 创建所有表(agents、ailments、therapies、appointments)
- 实现所有路由(GET、POST、PUT、DELETE)
- 添加管理员认证
- 为所有内容编写测试

解答:发现的问题:

  1. 模糊的任务:"面向所有人"——不是具体受众,没有成功标准,语气不明(讽刺/严肃)。
  1. 技术栈中的矛盾:tech-stack.md中指定了UI使用React,但课程和AgentClinic的典型方法使用Hono JSX服务器端渲染——需要澄清React是否是有意识偏离教育方法。
  1. SQLite在技术栈中,但ORM添加无依据:SQLite在tech-stack.md中提及(正常),但ORM Prisma未经论证就添加——课程明确指出"在ORM出现之前使用直接SQL迁移",即ORM稍后才会出现,不在开始时。
  1. 阶段1需要英雄主义:6个要点,包括"所有"——所有类型的路由、认证、所有测试。这违反了"每个阶段在一个分支中,无需英雄主义即可验证"的原则。应拆分为3-4个阶段。
  1. "以防万一"的依赖项:教育性讽刺应用的第一阶段中的管理员认证——可能是过早的复杂性,未经任务论证。
  1. 技术栈中无限制:缺少添加依赖项的规则,没有禁止"以防万一"。

难度:高级

案例研究: 标题:案例:团队如何因缺少mission.md而损失三次迭代

场景:一个三人开发团队启动了"EcoTrack"项目——一个跟踪碳足迹的应用。技术负责人快速编写了带React Native和Firebase的tech-stack.md,路线图制定了三个大阶段,每个两个月。认为mission.md是多余的——"一切都很清楚,环保之类"。

挑战:第一次迭代后发现,开发者对产品的理解不同:一个做面向消费者的环保购物应用,第二个做ESG报告的企业仪表板,第三个做面向学童的游戏化追踪器。tech-stack.md中出现了冲突添加:用于商店地图的Mapbox、用于报告的Tableau集成、用于游戏机制的Unity。代理(Claude Code)在每个新功能时都重新询问基础问题,并在应用的不同部分为不同受众生成代码。

解决方案:团队停止开发,与代理进行结构化访谈的联合会议。创建了mission.md,明确定义:"EcoTrack——面向中型公司(50-500员工)的B2B SaaS,需要自动化收集GRI标准ESG报告数据。语气:商务,无游戏化"。技术栈清除了Mapbox和Unity,添加了限制"新集成需要为目标公司论证ROI"。路线图拆分为一到两周的阶段:阶段1——Excel数据导入原型,阶段2——基础指标计算,阶段3——GRI报告生成。

结果:实施宪法后,开发速度提高了40%(按冲刺的故事点指标)。代理停止"猜测",开始在给定架构内提出解决方案。代码审查从15个"这是干嘛的?"评论减少到2-3个技术意见。4个月后,产品以三家试点公司启动。

经验教训: mission.md不是"废话",而是所有后续决策的过滤器:没有它,即使是好的tech-stack.md也会在不确定性压力下被稀释

与代理的访谈作为团队融合的催化剂:迫使将隐式约定明确化

大阶段掩盖不确定性:如果阶段无法在一周内验证,意味着其中隐藏了未充分准备的风险

代理作为"镜子"反映项目中的混乱:如果它持续"猜测"不同,问题不在代理,而在缺少宪法

相关概念: mission.md

通过Qwen Code进行访谈

Tech-stack.md / requirements.md的边界

宪法检查

标题:案例:一位开发者如何在第一个功能后创建QWEN.md并节省20小时

场景:独立开发者Anna启动了"BookShelf"项目——一个社区图书交换服务。她使用Qwen Code加速开发。第一个功能后(注册和个人资料),她注意到花了很多时间修改代理返回的代码风格。

挑战:git diff分析显示12次提交中有47次手动修改:代理使用不同的命名风格(snake_case与camelCase),为"简单"添加any,提交用俄语和英语混杂编写,使用console.log而非配置的pino日志记录器。每个新功能都需要重复这个修改循环。

解决方案:Anna没有继续"手动"控制,而是花了2小时基于git diff中的模式创建QWEN.md。文档包括:上下文与命名风格对应表(数据库——snake_case,代码——camelCase)、禁止any及替代类型化模式、带示例的提交模板、要求使用pino及配置中的日志级别。她还添加了"合并前仪式"部分:运行linter、类型检查、一个happy path测试。

结果:第二个功能中,手动修改从47次减少到3次(全部是逻辑性的,非风格性的)。自己PR的代码审查时间从45分钟减少到5分钟。代理开始独立生成正确格式的提交。三个功能后,Anna用"新依赖项需讨论"规则扩展了QWEN.md——代理建议添加lodash,她拒绝了,替换为原生实现,减少了12KB的打包体积。

经验教训: 第一个功能后的git diff是隐式规则的免费审计:每次手动修改都是QWEN.md的候选

QWEN.md在一个功能内回本:编写2小时 vs 后续迭代节省20+小时

QWEN.md中的具体示例比抽象规则更重要:"使用pino"不如"使用pino及config.logLevel级别,非console.log"

QWEN.md是活的文档:它随项目成长,但始于实际痛点,而非假设

相关概念: QWEN.md和隐式规则

宪法检查

Tech-stack.md / requirements.md的边界

学习技巧: 按顺序学习材料:首先理解"为什么需要宪法",然后学习每个文件的结构,再练习与代理的访谈。跳过步骤会导致形式化创建文档而不理解其作用。

使用"平行阅读"方法:同时打开课程原始文档和practice_exercises中的示例,比较结构。这加强独立工作的模式识别。

务必用计时器完成练习4(矛盾检查):限制自己10分钟,如同真实代码审查。时间压力训练识别关键问题,而非"完美"分析。

在编辑器中创建宪法文件模板,带占位符如[目的]、[主要受众_1]。每个新项目都使用它们——物理仪式加速方法论的内化。

记录"代理访谈日记":记录代理问了哪些问题、您给了什么答案、哪里出了问题。3-4个项目后,您将形成个人"经典陷阱"库和有效表述。

对于动觉型学习者:打印一张带"经受五个功能"标准的实体卡片,放在显示器旁。每个决策时物理移动卡片:"这个进技术栈?"——放在tech-stack.md上,"这个进功能?"——放在requirements.md上。

对于听觉型学习者:提交前大声说出宪法检查步骤:"SQLite在技术栈中吗?阶段能放入分支吗?任务说明了谁读代码吗?"——语音节奏创造记忆锚点。

对于视觉型学习者:绘制"决策生命周期"图——从想法出现,通过"五个功能"测试,到文档中的最终位置。颜色编码(红色——tech-stack.md,蓝色——requirements.md,绿色——roadmap.md)加速实时决策。

额外资源: 课程原始文档(第6部分):本指南基于的原始材料——用于澄清细节和代码示例

Hono文档:https://hono.dev——课程推荐的用于服务器端TypeScript的极简Web框架

Conventional commits:https://www.conventionalcommits.org——提交格式标准,QWEN.md的典型元素

Node.js上的Sqlite:https://github.com/WiseLibs/better-sqlite3——无需ORM使用SQLite的流行驱动,符合课程理念

Vitest:https://vitest.dev——示例tech-stack.md中提到的测试框架

Gitlab的mission.md模板:https://about.gitlab.com/handbook/engineering/ux/technical-writing/workflow/#documentation-templates——产品任务结构化的替代方法

"architecture decision records"文章:https://adr.github.io——固定长期决策的相关实践,扩展对tech-stack.md作用的理解

总结:宪法是SDD项目的核心:在第一个功能之前创建的三个文件(mission.md、tech-stack.md、roadmap.md),防止代理的混乱"猜测"并确保架构完整性。本部分的关键技能:通过"五个功能"测试区分长期决策(技术栈)和功能决策(需求);与代理进行结构化访谈而非手动编写;通过git diff分析发现隐式规则并固定在QWEN.md中;提交前检查宪法是否存在矛盾和阶段过大。实践表明:宪法和QWEN.md花费2小时,节省后续迭代20+小时。宪法是活的——它随项目成长,但开始时缺少它将保证架构债务。

我的笔记
0 / 10000

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

课程菜单

课程

基于 Qwen Code CLI 的规范驱动开发
进度 0 / 135