ADR-NNNN: [决策标题]
【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
Date: YYYY-MM-DDStatus: proposed | accepted | deprecated | superseded by ADR-NNNNDeciders: [相关人员]
Context
这个决策或变更是由什么问题或情况引发的?
[用 2-5 句话描述当前情况、约束条件和影响因素]
Decision
我们提议和/或正在进行的变更是什么?
[用 1-3 句话清晰地陈述决策]
Alternatives Considered(考虑的备选方案)
Alternative 1: [名称]
- Pros: [优点]
- Cons: [缺点]
- Why not: [该选项被拒绝的具体原因]
Alternative 2: [名称]
- Pros: [优点]
- Cons: [缺点]
- Why not: [该选项被拒绝的具体原因]
Consequences(影响)
这一变更会让哪些事情变得更容易、哪些更困难?
Positive
- [益处 1]
- [益处 2]
Negative
- [权衡 1]
- [权衡 2]
Risks
- [风险及缓解措施]
模板的核心设计意图值得拆解: - **头部元信息**:`Date`、`Status`、`Deciders` 三项构成了 ADR 的可追溯性基础。`Status` 字段的四个取值(proposed / accepted / deprecated / superseded)直接对应文档后文的 ADR 生命周期,其中 `superseded by ADR-NNNN` 通过引用编号建立决策之间的链式关系。 - **Context 与 Decision 的篇幅约束**:Context 限定 2-5 句,Decision 限定 1-3 句。这不是随意设定,而是与"优秀 ADR 的要素"中"保持简短——一份 ADR 应在 2 分钟内读完"的原则呼应。AI 生成内容天然容易冗长,字数上限是防止 Agent 写出"essay"级文档的硬约束。 - **Alternatives Considered 是强制小节**:每个备选方案必须同时给出 Pros、Cons 和 Why not。这一设计直接对抗"我们只是选了它"这种无效理由——如果某个备选方案连"为何不选"都写不出来,说明决策本身就没有被真正论证过。 - **Consequences 三分类**:Positive(积极影响)、Negative(权衡)、Risks(风险与缓解措施)分开列出,迫使记录者诚实地面对"每个决策都有代价"这一事实。 ### 一个真实的 ADR 示例:Redis 向量存储决策 [架构师代理文档](https://link.gitcode.com/i/4dccfae2f182448359dd10b2caa11dd4) 中给出了一个可直接对照模板的完整示例——"ADR-001:使用 Redis 进行语义搜索向量存储": ```markdown # ADR-001:使用 Redis 进行语义搜索向量存储 ## 背景 需要存储和查询用于语义市场搜索的 1536 维嵌入向量。 ## 决定 使用具备向量搜索能力的 Redis Stack。 ## 影响 ### 积极影响 - 快速的向量相似性搜索(<10ms) - 内置 KNN 算法 - 部署简单 - 在高达 10 万个向量的情况下性能良好 ### 消极影响 - 内存存储(对于大型数据集成本较高) - 无集群配置时存在单点故障 - 仅限于余弦相似性 ### 考虑过的替代方案 - **PostgreSQL pgvector**:速度较慢,但提供持久化存储 - **Pinecone**:托管服务,成本更高 - **Weaviate**:功能更多,但设置更复杂 ## 状态 已接受 ## 日期 2025-01-15这个示例展示了三个值得注意的实践点:其一,决策陈述非常具体——"Redis Stack"而非"某个向量数据库";其二,消极影响与积极影响同样翔实,包括"仅限于余弦相似性"这样的功能性限制;其三,替代方案清单给出了拒绝理由(慢、贵、复杂),而不是简单罗列。这三者恰好就是"优秀 ADR 的要素"中"具体明确""诚实地陈述后果""包含被拒绝的备选方案"三条准则的落地。
工作流程:捕获新 ADR 的 8 步闭环
技能的"工作流程"章节给出了从检测到归档的完整操作序列,共 8 步:
- 初始化(仅首次):如果
docs/adr/不存在,需先征求用户确认,然后创建目录、一个以索引表头预置的README.md(格式见下文),以及一个供手动使用的空白template.md。未经明确同意不得创建任何文件——这是贯穿全文的权限边界,即使 Agent 检测到了决策信号,文件系统写入也必须经过用户授权。 - 识别决策:从对话中提取正在做出的核心架构选择。
- 收集上下文:是什么问题引发了此决策?存在哪些约束条件?
- 记录备选方案:考虑了哪些其他选项?为什么拒绝了它们?
- 陈述后果:权衡是什么?什么会变得更容易/更难?
- 分配编号:扫描
docs/adr/中现有的 ADR 编号并递增(即 NNNN 取当前最大编号 + 1)。 - 确认并写入:先向用户展示 ADR 草稿供审查,仅在获得明确批准后才写入
docs/adr/NNNN-decision-title.md;如果用户拒绝,丢弃草稿、不写入任何文件。 - 更新索引:将新条目追加到
docs/adr/README.md。
这条工作流有两个设计精髓:一是**"草稿先行、批准后写"的两阶段提交模式,把 Agent 的"生成能力"与"写入权限"彻底分离,从根本上避免了 AI 擅自改动仓库;二是编号递增**保证了 ADR 序列的稳定性——即使某条 ADR 后来被弃用,其编号也不会被复用,从而保证索引中的引用永不失效。
读取现有 ADR 的流程
当用户问"我们为什么选择了 X?"时,技能定义了与写入对称的只读流程:
- 检查
docs/adr/是否存在;若不存在,回复:"このプロジェクトでADRが見つかりません。アーキテクチャ決定の記録を始めたいですか?"(该项目中未找到 ADR,是否要开始记录架构决策?); - 若存在,扫描
docs/adr/README.md索引寻找相关条目; - 读取匹配的 ADR 文件,向用户呈现 Context 与 Decision 小节;
- 若未找到匹配项,回复:"その決定についてのADRが見つかりません。今すぐ記録しますか?"(未找到关于该决策的 ADR,是否现在记录?)。
注意这里的"呈现"范围是 Context 和 Decision——即先给出"为什么"和"是什么"两个最核心的信息,而不是把整份 ADR 倾倒给用户,体现了面向阅读效率的设计。
目录结构与索引格式:ADR 日志的组织方式
技能文档规定了标准的目录布局:
docs/ └── adr/ ├── README.md ← 所有 ADR 的索引 ├── 0001-use-nextjs.md ├── 0002-postgres-over-mongo.md ├── 0003-rest-over-graphql.md └── template.md ← 供手动使用的空白模板README.md作为索引,采用如下 Markdown 表格格式:
# Architecture Decision Records | ADR | Title | Status | Date | |-----|-------|--------|------| | 0001 | Use Next.js as frontend framework | accepted | 2026-01-15 | | 0002 | PostgreSQL over MongoDB for primary datastore | accepted | 2026-01-20 | | 0003 | REST API over GraphQL | accepted | 2026-02-01 |文件名遵循NNNN-decision-title.md的约定(如0001-use-nextjs.md),编号与索引表格一一对应。这个结构解决了三个实际问题:可发现性(索引表一屏总览全部决策)、可链接性(superseded by ADR-NNNN可以精确指向替换文档)、可扩展性(新 ADR 只需追加一行索引,无需维护复杂元数据)。从仓库现状看,docs/下目前尚未出现adr/子目录,这也印证了技能中"首次使用时需初始化并征得用户同意"的设计——ADR 日志是由团队按需启动的工程资产,而不是仓库自带的默认设施。
决策检测信号:Agent 如何识别"决策时刻"
为了让捕获流程的"第 1 步"真正可自动化,技能将对话中的决策信号分为显式与隐式两类。
显式信号(用户直接表达决策意图):
- "让我们选择 X"
- "我们应该使用 X 而不是 Y"
- "权衡是值得的,因为……"
- "将此记录为 ADR"
隐式信号(建议记录 ADR,但未经用户确认不得自动创建):
- 比较两个框架或库并得出结论;
- 做出数据库模式设计选择并陈述理由;
- 在架构模式之间选择(单体 vs 微服务、REST vs GraphQL);
- 决定身份验证/授权策略;
- 评估备选方案后选择部署基础设施。
显式与隐式的区分非常关键:显式信号意味着用户已经在做决策陈述,Agent 可以直接进入捕获流程;而隐式信号只是"决策正在发生"的旁证,Agent 的正确动作是主动建议记录 ADR,把决定权交还给用户。这条规则与 8 步工作流中的"初始化需确认""写入需批准"一起,构成了完整的"Agent 可建议、不可擅动"权限模型。
优秀 ADR 的要素:写作质量准则
技能用"Do / Don't"对照表定义了 ADR 的质量边界。
应该做:
- 具体明确——"使用 Prisma ORM",而不是"使用一个 ORM"。具体到产品名而非类别名,是 ADR 有用性的第一前提;
- 记录原因——理由比内容更重要("the rationale matters more than the what");
- 包含被拒绝的备选方案——未来的开发者需要知道考虑了哪些选项;
- 诚实地陈述后果——每个决策都有权衡,隐藏代价等于伪造记录;
- 保持简短——一份 ADR 应在 2 分钟内读完;
- 使用现在时态——"我们使用 X",而不是"我们将使用 X"。现在时表明决策是当前生效的事实,而非尚未兑现的计划。
不应该做:
- 记录琐碎的决定——变量命名或格式化选择不需要 ADR;
- 写成论文——Context 部分超过 10 行就太长了;
- 省略备选方案——"我们只是选了它"不是有效的理由;
- 追溯记录而不加标记——如果记录过去的决定,必须注明原始日期;
- 让 ADR 过时——被取代的决策应引用其替代品。
这些准则对 AI 辅助写作尤其有约束力:Agent 生成内容时天然倾向于"信息堆砌",而"2 分钟可读完""Context 不超过 10 行""现在时态"这些可校验的硬标准,正是对抗生成式冗长与时态漂移的有效手段。
ADR 生命周期:决策状态的演进与退役
技能定义了 ADR 的状态机:
proposed → accepted → [deprecated | superseded by ADR-NNNN]【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考