RFC 与技术方案写作

RFC 与技术方案写作——为什么 senior 工程师要把问题定义、方案比较、迁移路径、风险说明和决策记录写清楚,以及怎样把一份文档写成团队可执行的共识。

RFC 与技术方案写作

这件事为什么重要

很多团队都承认“文档重要”。

但真到做决策时,还是会退回到几种熟悉的方式:

  • 开会拍板
  • 在聊天群里来回争
  • 靠某个熟悉系统的人口头解释
  • 方案改来改去,却没人能复述最初为什么这么做

RFC 的价值就在这里。

它不是为了让流程看起来更正规。

它是把模糊讨论变成结构化判断,把“我觉得”变成“我们知道自己在解决什么、承担什么代价、准备怎么落地”。

这也是为什么很多成熟工程团队会保留某种形式的 proposal、design doc、RFC、ADR。

名字可以不同。

本质很接近:

在决策真正进入执行前,先把问题、方案、边界和代价写明白。

先把 RFC 这个词讲清楚

RFC 原本是 Request for Comments

简单说,它不是“最终定稿”,而是“把一个足够完整、可讨论的提案摆到桌面上”。

这句话里有两个重点:

第一,它不是随手记点子。

第二,它也不是拍板后的公告。

它处在中间那段最关键的区间:

  • 问题已经比较清楚
  • 方案还需要讨论
  • 团队需要围绕同一份材料达成共识

如果把时序再讲得直白一点:

  • 想法阶段,通常还是口头讨论、草图、临时笔记
  • RFC 阶段,开始进入可评审、可修改、可比较的提案
  • 决策后阶段,会沉淀成执行计划、任务拆解、ADR、运行手册或长期文档

所以 RFC 不是“写文档”这么简单。

它更像是一次正式决策前的思考容器。

它解决的不是“有没有文档”,而是“讨论质量”

很多团队文档并不少。

真正缺的是高质量讨论材料。

一个问题在没有被写清楚之前,团队经常会出现这些情况:

  • 每个人讨论的其实不是同一个问题
  • 方案比较时,评价标准不一致
  • 会议里最会说话的人影响最大
  • 过一段时间再回看,没人记得当时的 trade-off

一份好的 RFC 至少能把这几件事拉回正轨:

  • 问题定义统一
  • 备选方案摆在同一张桌子上比较
  • 风险不再藏在口头表达里
  • 决策背景可以被后来的人追溯

这就是它真正的工程价值。

为什么 senior 工程师特别需要这项能力

因为 senior 的影响力往往不再只来自“自己把代码写出来”。

更多时候,影响力来自:

  • 帮团队把问题定义准确
  • 在分歧里建立共同语言
  • 让复杂决定变得可沟通、可执行、可复盘

如果只会在会议里讲得热闹,却不能把判断沉淀成文档,很多经验都很难真正复用。

所以 RFC 写作不是“表达加分项”。

它已经是工程判断的一部分。

什么时候需要写 RFC,什么时候不需要

这点一定要讲清楚。

不是所有改动都值得写一篇长文档。

如果什么都要求 RFC,团队最后只会讨厌文档。

比较值得写 RFC 的场景通常有这些特征:

  • 影响面跨团队或跨系统
  • 变更不可逆或回滚成本高
  • 有两种以上合理方案,需要比较
  • 迁移周期长,需要分阶段推进
  • 决策里有明显 trade-off,后续很可能被反复追问

不太需要正式 RFC 的情况也很常见:

  • 局部重构,影响边界清楚
  • 已经有明确团队共识,只是常规执行
  • 风险很低,回滚容易
  • 问题本身还没有被定义清楚,先做小实验更合适

换句话说,RFC 不是成熟的象征。

对问题规模的判断,才是成熟的象征。

一份好 RFC 最先要解决什么

不是展示作者懂多少。

而是回答四个问题:

  1. 我们到底在解决什么问题?
  2. 为什么是现在解决?
  3. 为什么是这个方案,而不是别的方案?
  4. 这个决定会给执行、运行和未来演进带来什么后果?

如果这四个问题没回答清楚,图画得再漂亮,文档也还是空的。

文档最容易写偏的地方:方案写得太快,问题写得太少

这是最常见的问题。

很多工程师一动笔就写:

  • 新架构怎么搭
  • 新模块怎么拆
  • 新 API 长什么样

结果读者看完会问:

“所以我们为什么要做这件事?”

这说明问题定义没有站住。

成熟的 RFC 往往会把不少篇幅放在问题本身:

  • 现状是怎样的
  • 痛点是什么
  • 痛点的证据是什么
  • 受影响的是谁
  • 不处理的后果是什么

这不是绕远路。

这是给后面的方案比较提供地基。

问题定义怎么写,才不至于空

一个常见误区是写成泛泛口号:

  • 系统复杂度高
  • 开发效率低
  • 性能不够好
  • 维护成本高

这些都不算真正的问题定义。

它们更像是情绪化标签。

更可用的写法应该尽量具体:

  • 哪类页面在什么条件下性能差
  • 哪个链路的发布经常出事故
  • 哪类需求每次都要重复造轮子
  • 哪些团队协作点经常因为边界不清而返工

当问题被写成可以被观察、被验证的事实,后面的讨论才会落地。

一个实用的 RFC 骨架

不同团队模板会不一样,但核心部分通常离不开这些:

1. 摘要

用一段话说明:

  • 提案是什么
  • 解决什么问题
  • 预期收益是什么
  • 这次评审需要大家关注什么

摘要不是“全文缩写”。

它更像给读者一个入口。

2. 背景与问题定义

这里要说明:

  • 现状
  • 业务与工程背景
  • 明确的痛点
  • 已知约束

如果有数据、事故记录、用户反馈、性能观测,应该尽量带上。

3. 目标与非目标

这是极容易被省略、但非常值钱的部分。

目标告诉团队“这次一定要解决什么”。

非目标告诉团队“这次不解决什么”。

没有非目标,讨论很容易无限膨胀。

4. 方案设计

这里才开始写方案。

应包括:

  • 整体思路
  • 关键流程
  • 接口与数据边界
  • 兼容性
  • 安全、性能、运维影响

5. 备选方案

很多文档这一节只是形式化凑数。

真正有价值的备选方案不是列出“明显不行的方案”来衬托主方案。

而是把当时真正可能选择的路线摆出来比较。

6. 迁移与发布计划

如果方案需要上线落地,就不能只写“后续逐步推进”。

需要明确:

  • 分几阶段
  • 怎么灰度
  • 怎么回滚
  • 如何验证
  • 谁负责哪些部分

7. 风险与开放问题

成熟文档不会假装所有事情都确定了。

把不确定性显式写出来,反而会提高讨论质量。

ADR、design doc、RFC 之间是什么关系

很多团队会纠结命名。

其实不必过度神圣化。

可以把它们理解成偏重点不同:

  • RFC 更强调“提案待评审”
  • design doc 更强调“设计细节与实施说明”
  • ADR 更强调“记录已经做出的关键架构决策”

在实践里,它们可以串起来:

  • 先写 RFC 讨论方向
  • 方案收敛后补 design doc
  • 最终关键结论沉淀成 ADR

也有团队把这些合并成一种统一模板。

这没问题。

关键不是名字。

关键是文档是否真的承载了决策过程。

好文档的核心不是“全”,而是“让读者能判断”

很多工程师写文档时会掉进两个极端:

  • 太短,只有结论,没有推理
  • 太长,堆满细节,看不到重点

真正好的技术方案文档,不一定最厚。

但它会让读者抓到几件关键事:

  • 背景是什么
  • 作者的判断链路是什么
  • 哪些地方已经想清楚
  • 哪些地方仍然存在风险
  • 现在需要评审者做什么

如果读者读完还是没法判断,那文档就没有真正完成它的工作。

什么叫“诚实地写 trade-off”

这也是 senior 感很强的一部分。

很多方案文档会把主方案写成“全面占优”。

现实里很少有这种情况。

真正可信的文档会明确承认:

  • 这个方案在 A 上更好
  • 在 B 上会付出额外成本
  • 团队选择它,是因为当前约束更重视 A

比如:

  • 更强的一致性,可能换来更高的实现复杂度
  • 更低的运行成本,可能换来更高的迁移成本
  • 更灵活的扩展性,可能换来更陡的学习曲线

把这些写出来,不会显得方案不稳。

恰恰相反。

这会让评审者更相信作者知道自己在做什么。

数据、样例和图示为什么重要

工程文档不是文学作品。

很多判断如果没有具体材料支撑,会显得很飘。

常见的有效材料包括:

  • 请求量、错误率、性能数据
  • 一个典型时序图
  • 关键接口样例
  • 当前实现与目标实现的对照
  • 迁移阶段的边界图

但也要避免另一个极端:

为了显得专业,塞进一堆图和表。

图示不是装饰。

它应该帮助读者更快理解结构和边界。

读者意识:你写给谁看,决定你怎么写

同一份 RFC,常见读者可能包括:

  • 同组工程师
  • 上下游团队
  • 技术负责人
  • 测试、运维、产品

这意味着文档不应该只对作者自己友好。

比较稳妥的写法通常是:

  • 主叙事尽量讲清业务背景和工程问题
  • 细节留在具体小节或附录
  • 关键术语第一次出现时给一句解释

不是所有人都需要读到最底层实现。

但所有相关方都应该能理解“这次变更会对自己有什么影响”。

评审流程怎么设计,才能减少空转

很多团队写 RFC 不难,真正难的是评审机制。

常见失败方式有三种:

  • 没有人真正阅读,只在会议里即兴讨论
  • 评论很多,但没有人负责收敛结论
  • 文档通过了,执行却没人跟进

一个更实用的评审流程通常包括:

1. 小范围预热

先找最关键的几位同事看一版。

目的是尽早发现大方向是否站得住,而不是正式盖章。

2. 异步评论

让大家围绕同一份文本提问、指出风险、补背景。

异步评论的好处是:

  • 讨论更可追溯
  • 不被会议时间限制
  • 思考更完整

3. 同步收敛

如果争议点比较大,再开会。

会议的目标不应该是“第一次看文档”。

而应该是“围绕已暴露的分歧做收敛”。

4. 决策记录

接受、拒绝、延期、补充验证,都应该明确写回文档。

否则过一阵子,大家又会从头争一遍。

评论怎么写才有用

无论你是作者还是评审者,都需要区分评论类型。

常见类型包括:

  • 事实纠正
  • 风险提醒
  • 备选方案
  • 范围控制
  • 纯编辑性建议

这很重要。

因为不是所有评论都应该阻塞文档前进。

比较成熟的做法是显式标记:

  • blocking
  • non-blocking
  • question
  • suggestion

这样讨论会清楚很多。

一个成熟作者在评审里应该怎样表现

不是死守主方案。

也不是谁提意见就立刻全改。

更好的状态是:

  • 愿意解释判断依据
  • 愿意承认没有想清楚的地方
  • 愿意在关键分歧上补实验或补数据
  • 能把评论吸收进文档,而不是散落在聊天记录里

这也是为什么文档能力和领导力能力经常绑在一起。

因为它们都在处理同一件事:

如何让多人围绕复杂问题建立共同理解。

常见失败模式

1. 把 RFC 写成产品宣传页

只写好处,不写风险。

这类文档读起来顺,但不可信。

2. 把 RFC 写成实现细节堆叠

读者看完知道每个函数怎么写,却不知道为什么选这个方向。

3. 备选方案形同虚设

如果备选方案都是“明显不成熟”“明显不适合”,那这一节就失去意义了。

4. 范围无限膨胀

没有目标和非目标,评论一多,文档就会越来越像重写整个系统。

5. 通过后没人维护

文档接受了,但执行现实发生变化,文档却不再更新,最后反而误导后来的人。

RFC 和代码之间的关系

文档不是代码的替代品。

但它也不只是代码的附庸。

可以这样理解:

  • RFC 决定大的结构和边界
  • 代码实现把它具体化
  • 回头看代码时,RFC 解释了“为什么不是另一种写法”

当系统进入长期维护阶段,这个“为什么”非常值钱。

因为很多复杂决策不是从代码里自然显现出来的。

适合练表达的点

这类主题很适合做表达训练,因为它天然要求你把抽象判断说清楚。

尤其值得练的点包括:

  • 怎么区分问题和方案
  • 怎么解释 trade-off
  • 怎么说明目标与非目标
  • 怎么说清“为什么现在做”
  • 怎么把技术结论和组织现实连起来

如果一个工程师能把这些讲清楚,往往说明他已经不只是在做局部实现。

一个可以直接用的 RFC 写作框架

下面这个框架不是唯一标准。

但在多数工程团队里都足够实用。

标题

标题要具体。

例如:

  • “统一前端缓存失效策略”
  • “将图片处理链路迁移到边缘运行时”

不要写成:

  • “架构优化方案”
  • “系统升级提案”

摘要

三到六句话即可。

把问题、方案和预期收益说清楚。

背景

描述现状和约束。

目标

列出必须达成的结果。

非目标

明确这次不处理的边界。

方案

给出结构、接口、流程、发布策略。

备选方案

至少写出当时真正有竞争力的替代路线。

风险

把性能、兼容性、运行稳定性、团队学习成本等都摆出来。

验证计划

说明如何通过实验、灰度、监控来判断方案是否成立。

决策记录

记录接受、拒绝、修改和后续 action item。

中国互联网语境下,RFC 经常会卡在哪里

在很多节奏很快、业务压力很重的团队里,大家并不是不知道文档重要。

更常见的问题是:

  • 时间被排期压缩
  • 需求变化太快
  • 决策更依赖少数熟悉业务的人
  • 组织习惯同步会议多于异步评审

所以在国内语境里,推动 RFC 往往不能走“形式先行”路线。

更现实的做法通常是:

  • 先从跨团队、高风险决策开始
  • 模板尽量轻,不一上来就写成论文
  • 评审关注执行价值,而不是格式完整度

这样更容易活下来。

海外互联网语境下,为什么 design doc / RFC 传统更强

很多海外工程团队长期依赖异步协作。

团队分布、时区协作、书面文化、公共 API 稳定性要求,都会推动文档体系更成熟。

这也是为什么你会在 Google、Rust、React、Go 这些生态里看到更明确的 proposal 或 RFC 传统。

文档在这些环境里不只是补充说明。

它本身就是协作接口。

这一题在面试或分享里怎么讲更像 senior

不要上来背模板。

更好的讲法是:

先说明 RFC 解决的是讨论质量和决策可追溯性问题。

然后再说:

  • 什么场景值得写
  • 一份好文档最重要的是问题定义和 trade-off
  • 怎么组织评审
  • 怎么让文档进入执行闭环

这样听起来会更像你真的用过它,而不是只是看过模板。

练习建议

练习 1:把一次真实争议写成短 RFC

练什么:

把口头分歧转成结构化文档。

最小交付物:

一篇 2 到 4 页的内部提案。

验收标准:

  • 能清楚复述问题
  • 有至少两个真实备选方案
  • 有明确的目标和非目标

常见误区:

  • 只写结论
  • 把备选方案写成陪跑

练习 2:给一篇旧设计文档补 ADR

练什么:

把决策结果从执行细节里抽出来。

最小交付物:

一页 ADR。

验收标准:

  • 能回答为什么做这个决定
  • 能说明当时放弃了什么

常见误区:

  • 把 ADR 写成实现摘要

练习 3:做一次评审收敛记录

练什么:

训练把评论区的分歧真正收拢。

最小交付物:

一次文档评审结论更新。

验收标准:

  • 评论被归类
  • 决策状态明确
  • 后续动作清楚

常见误区:

  • 评论很多,但没有最终结论

延展阅读