关于 rfc-writer
这是一个用于撰写工程 RFC 的 Skill,面向技术决策和架构变更。它帮助团队记录问题、方案、备选项、权衡及实施考量,供评审和日后查阅。
主要功能
- 01组织技术提案结构
- 02说明目标与非目标
- 03记录备选方案及拒绝理由
- 04涵盖实施与迁移计划
- 05分析安全和性能影响
- 06记录发布与可观测性变更
适用场景
- 01提交架构变更供团队评审
- 02在技术决策前比较方案
- 03记录已批准设计的决策依据
- 04规划迁移与发布事项
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mohitagw15856/ pm-claude-skills --skill rfc-writer安装后在 Claude Code 中输入/rfc-writer确认已加载。
详细介绍
RFC 撰写技能
针对技术决策或架构变更,撰写一份完整的工程 RFC(征求意见稿)。RFC 是一份结构化的提案文档,而不是说服性文档。其目的是让决策接受审视,揭示权衡,记录考虑过的替代方案,并永久留存做出选择的原因。
一份优秀的 RFC 能让不在场的人在多年后依然理解团队当初为何以这种方式构建某项内容。
必需输入
如果尚未提供,请询问以下信息:
- RFC 标题和作者 — RFC 的主题以及提议者
- 要解决的问题 — 当前有哪些问题、缺失之处或不足;为何现在需要采取行动
- 提议的解决方案 — 作者推荐的方法,至少说明大致方向
- 背景和限制 — 团队规模、现有架构、时间压力、预算限制、合规要求
- 考虑过的替代方案 — 作者至少考虑过的 2 种替代方法
- 当前状态 — 尚未决策(征求反馈),还是已做出决策(记录已做出的决策)?
输出格式
RFC [编号]:[标题]
作者:[姓名] | 团队:[团队名称] 创建时间:[日期] | 上次更新:[日期] **状态:**草稿 | 审核中 | 已批准 | 已拒绝 | 已被 RFC-[X] 取代 工单:[JIRA-XXX] | Slack 讨论串:[#频道链接] 审核截止日期:[日期 — 应提交意见的截止日期]
摘要
[用 2–4 句话概述整份 RFC。应能独立成篇——仅阅读此部分的人也应了解提议的内容、原因和主要权衡。最后撰写此部分。]
1. 问题陈述
[描述要解决的问题。聚焦于问题,而非解决方案。尽可能具体并量化。]
当前状态: [描述目前的运作方式——现有系统、流程或架构。包括任何相关限制或约束。]
为何现在要解决这个问题: [为何现在要处理,而不是更早或更晚?引用指标、事件、产品需求或扩展阈值,说明为何此事紧迫或时机恰当。]
实际问题示例: [能说明问题的具体场景或事件。这有助于审核者理解实际影响,而不只是抽象描述。]
// Example: current behaviour that illustrates the problem
[code snippet, log output, or sequence description showing the problem]
不解决此问题的影响:
- [影响 1 — 例如:“为新租户开户,每个账户需要 3 小时手动配置”]
- [影响 2 — 例如:“身份验证服务处理 400 req/s;按当前增长速度,预计 8 周内达到容量上限”]
- [影响 3 — 例如:“当前方案与即将提出的多区域要求不兼容”]
2. 目标与非目标
目标:
- [具体、可衡量的结果 — 例如:“将租户开户时间从 3 小时缩短至 <5 分钟”]
- [例如:“身份验证服务支持 2,000 req/s,P99 延迟 ≤50ms”]
- [例如:“无需更改应用层即可支持多区域部署”]
非目标: (本 RFC 明确不涉及的内容)
- [例如:“本 RFC 不涉及内部服务间调用的身份验证——参见 RFC-042”]
- [例如:“不涉及现有系统的性能改进——本 RFC 将取代该系统”]
- [例如:“不涉及历史数据迁移——相关内容由后续 RFC 涵盖”]
成功指标:
| 指标 | 当前值 | 目标值 | 测量方法 |
|---|---|---|---|
| [例如:开户时间] | [3 小时] | [<5 分钟] | [开户任务持续时间的 Prometheus 直方图] |
| [例如:身份验证延迟 P99] | [120ms] | [≤50ms] | [Datadog APM] |
| [例如:工程师环境搭建时间] | [4 小时] | [<30 分钟] | [入职调查问卷] |
3. 背景与动机
[提供评审者评估提案所需的背景信息。这不是对问题陈述的重复,而是相关的技术和业务背景。]
现有系统概述: [描述当前架构中相关的部分。如果组件之间的关系有助于理解,请附上 ASCII 图。]
[ASCII diagram of current architecture — optional but strongly recommended for architectural RFCs]
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Client │────▶│ [Service A] │────▶│ [Service B] │
└──────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ [Database] │
└──────────────┘
先前工作与相关决策:
- [RFC-XXX:标题 — 相关的先前决策;链接]
- [ADR-XXX:标题 — 架构决策记录]
- [为本提案提供参考的外部标准、博客文章或供应商文档]
约束:
- [例如:必须在 12 个月内与 v1 API 客户端保持向后兼容]
- [例如:团队不熟悉 Rust — 解决方案必须使用 Python 或 Go]
- [例如:必须能在不停机维护的情况下部署]
4. 提议的解决方案
[清晰、具体地描述提议的方案。提供足够的细节,让工程师能够据此开始实现,但不要编写代码 — 代码应留给 PR。]
4.1 高层方案
[用 1–3 段描述整体解决方案。说明核心思路,以及它为何能解决问题。]
4.2 架构
[ASCII diagram of the proposed architecture — what the system looks like after this RFC is implemented]
┌──────────┐ ┌──────────────────┐ ┌──────────────┐
│ Client │────▶│ [New Component] │────▶│ [Service B] │
└──────────┘ └──────────────────┘ └──────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ [Store A] │ │ [Store B] │
└──────────────┘ └──────────────┘
4.3 详细设计
[将解决方案拆分为关键组件或决策。逐一说明其作用,以及采用这种设计的原因。]
组件 / 决策 1:[名称]
[描述此组件 — 它的作用、工作方式,以及选择这种方案的原因。]
// Example interface, API contract, or pseudocode (not implementation code)
[Relevant schema, API definition, data flow, or pseudocode]
组件 / 决策 2:[名称]
[描述]
组件 / 决策 3:[名称]
[描述]
4.4 API 变更
如果 RFC 引入或修改任何 API 端点、事件或接口,请填写此部分。
新增端点 / 事件:
[HTTP method + path or event name]
Request: { ... }
Response: { ... }
修改的端点:
[endpoint]:[变更内容及原因;向后兼容说明]
弃用的端点:
[endpoint]:弃用,改用[new endpoint]— 移除时间表:[日期/版本]
4.5 数据模型变更
如果需要变更数据库架构或数据结构,请填写此部分。
[概述架构变更。详细迁移步骤请参考 database-migration-plan 技能。]
-- Key schema changes (abbreviated — full migration in [link])
[DDL statements for key additions/changes]
5. 考虑过的替代方案
每个替代方案都必须明确说明拒绝它的原因。“我们选择了提议的方案”不算理由。
替代方案 1:[名称]
描述: [此替代方案涉及的内容。]
优点:
- [优点 1]
- [优点 2]
缺点:
- [缺点 1]
- [缺点 2]
拒绝原因: [具体原因 — 例如:“基础设施成本是原方案的 3 倍”“不符合多区域要求”“团队不具备这项技术的经验,熟悉所需时间会导致错过 Q3 截止日期”]
替代方案 2:[名称]
描述: [此替代方案涉及的内容。]
优点:
- [优点 1]
- [优点 2]
缺点:
- [缺点 1]
- [缺点 2]
拒绝原因: [具体原因]
替代方案 3:不采取行动 / 暂缓
描述: 接受当前状态,并在[时间范围]后重新审视该问题。
拒绝原因: [说明为何不能暂缓 — 参考第 1 节中不解决此问题所带来的影响。]
6. 实施计划
预计工作量: [X 个工程师周] | 目标完成时间: [日期 / 季度] 团队: [负责构建的人员——姓名或角色]
| 阶段 | 描述 | 时长 | 依赖项 | 负责人 |
|---|---|---|---|---|
| 1 | [例如:核心实现——构建并测试新组件] | [X 周] | [无] | [姓名] |
| 2 | [例如:集成——将新组件连接到现有服务] | [X 周] | [阶段 1 完成] | [姓名] |
| 3 | [例如:发布——先进行金丝雀部署,再全面发布] | [X 周] | [阶段 2 + 预发布环境验证通过] | [姓名] |
| 4 | [例如:清理——弃用旧系统,移除功能标志] | [X 周] | [阶段 3 稳定运行 X 周] | [姓名] |
关键里程碑:
- [日期]:[里程碑——例如:“核心实现完成并通过代码审查”]
- [日期]:[里程碑——例如:“预发布环境验证完成”]
- [日期]:[里程碑——例如:“10% 的金丝雀流量未出现回归”]
- [日期]:[里程碑——例如:“全面发布完成”]
- [日期]:[里程碑——例如:“旧系统已停用”]
7. 迁移计划
如果 RFC 要求迁移现有用户、数据或 API 使用方,请填写本节。
迁移策略: [一次性切换 / 分阶段 / 并行运行 / 自愿加入]
受影响对象:
- [例如:所有现有 API v1 使用方——需要更新客户端库]
- [例如:
orders表中有 X 百万行需要回填]
迁移步骤:
- [步骤 1——描述操作、执行人员和预计时长]
- [步骤 2]
- [步骤 3]
向后兼容期: [旧系统/API 将继续提供多长时间?]
沟通计划:
- [需要通知哪些人、何时通知以及如何通知——例如:“旧端点移除前 3 个月,API 使用方将收到弃用通知”]
8. 安全影响
[描述此变更的安全影响。如果没有安全影响,请明确说明并给出理由——不要将本节留空。]
| 关注点 | 影响 | 缓解措施 |
|---|---|---|
| [例如:新 API 端点暴露于互联网] | [例如:扩大攻击面] | [例如:速率限制、要求身份验证、WAF 规则] |
| [例如:存储新数据——用户个人身份信息] | [例如:GDPR 适用范围扩大] | [例如:静态加密、访问日志、数据保留策略] |
| [例如:服务间通信] | [例如:令牌伪造风险] | [例如:服务间使用 mTLS] |
是否已制定或更新威胁模型? [是——链接 / 否——实施前必须完成 / 无需——理由]
9. 性能影响
[描述预期的性能影响。包括新系统的预测数据及其估算方法。]
| 指标 | 当前值 | 预测值 | 测量方法 |
|---|---|---|---|
| [例如:/api/auth 的 P99 延迟] | [120ms] | [≤50ms] | [负载测试结果——链接] |
| [例如:每次请求的数据库查询次数] | [12] | [3] | [预发布环境中的查询日志] |
| [例如:每个实例的内存] | [512MB] | [768MB] | [性能分析——链接] |
| [例如:基础设施成本] | [$X/月] | [$Y/月] | [AWS 成本计算器估算] |
负载测试: [是否已完成负载测试?请提供结果链接。如果尚未完成,计划何时进行?]
性能风险:
- [风险 1——例如:“新组件会增加一次网络跳转,在网络拥塞时可能导致尾延迟增加——需要在 2× 峰值负载下验证”]
10. 可观测性变更
描述此 RFC 引入的新指标、日志、追踪和告警,或对它们所做的变更。
新指标:
| 指标名称 | 类型 | 描述 | 告警阈值 |
|---|---|---|---|
[service].[component].[metric] | [计数器/仪表盘/直方图] | [测量内容] | [例如:P99 > 100ms,持续 5 分钟] |
新日志事件:
| 事件 | 级别 | 发出时机 | 关键字段 |
|---|---|---|---|
[event.name] | INFO | [何时] | user_id、duration_ms、result |
分布式追踪: [是否为新组件添加了 span?哪些操作加入了追踪?]
仪表盘变更: [新建仪表盘 / 更新现有仪表盘——链接]
11. 发布计划
发布策略: [功能标志 / 金丝雀发布 / 蓝绿发布 / 逐步切换流量 / 全量部署]
| 阶段 | 流量占比 | 持续时间 | 成功标准 | 回滚触发条件 |
|---|---|---|---|---|
| 内部测试 | 0%(内部试用) | [X 天] | [内部使用期间无错误] | 出现任何错误 |
| 金丝雀发布 | 1% | [X 小时] | [错误率 <0.1%;P99 延迟符合预算] | 错误率 >0.5% |
| 有限发布 | 10% | [X 天] | [同上,且业务指标稳定] | 错误率 >0.2% |
| 全量发布 | 100% | — | [满足第 2 节中的所有成功指标] | 任一 SLO 未达标 |
功能标志: [功能标志名称,如适用] — 在 [LaunchDarkly / Unleash / 配置] 中管理
回滚流程:
// How to roll back if the rollout needs to be reversed
1. [Step 1 — e.g. Toggle feature flag to off]
2. [Step 2 — e.g. Deploy previous version]
3. [Step 3 — e.g. Notify stakeholders]
12. 未决问题
[列出所有尚未解决的问题、尚未敲定的设计决策,或作者特别希望征求反馈的事项。为每项指定负责人和解决期限。]
| # | 问题 | 负责人 | 截止日期 | 解决情况 |
|---|---|---|---|---|
| 1 | [例如:对于 [resource] 的并发更新,我们应该使用乐观锁还是悲观锁?] | [姓名] | [日期] | [待处理 / [答案]] |
| 2 | [例如:[新数据类型] 的保留策略是什么?] | [姓名] | [日期] | [待处理 / [答案]] |
| 3 | [例如:上线时,此查询模式是否需要只读副本,还是可以推迟?] | [姓名] | [日期] | [待处理 / [答案]] |
13. 决策
评审期结束后填写。
决策: [已批准 / 已拒绝 / 修改后批准] 决策日期: [日期] 决策者: [姓名]
已处理的关键反馈摘要:
- [反馈事项及其解决方式]
批准条件(如有):
- [例如:必须在第 2 阶段开始前完成负载测试]
质量检查
- 问题陈述具体且有量化数据——不是“当前系统很慢”,而是“P99 延迟为 800ms;预算为 200ms”
- 目标部分包含可衡量的成功指标,而非愿景式表述
- 每个备选方案都有明确的拒绝理由——不能只列出缺点
- 已填写安全影响部分,不能留空
- 性能影响包含预测数据,而不只是“应该会更好”
- 未决问题已分配给明确的负责人并设定截止日期,不能悬而未决
- RFC 的写法应让未参与规划讨论的人也能读懂
- 迁移计划涵盖所有受影响方——用户、API 消费者和数据,而不仅是技术步骤
反模式
- 不要把 RFC 写成说服文件——它的目的是揭示权衡,而不是推销某个决策
- 不要列出备选方案却不给出明确的拒绝理由——“我们更倾向于提议的方案”不是理由
- 不要将安全影响部分留空,也不要在没有合理解释的情况下写“N/A”
- 不要提出未指派明确负责人和解决期限的未决问题
- 不要跳过“未解决此问题的影响”部分——没有这一部分,评审者就无法评估紧迫性
示例触发短语
- “编写一份 RFC。”
- “记录一份技术提案。”
- “创建一份设计文档。”
- “编写一份供评审的架构决策。”
- “编写一份供团队反馈的技术规范。”