RFC 撰寫工具 是做什麼的?
協助使用者撰寫能夠通過審查的 RFC。RFC 是強迫進行清晰思考的工具,而非事後補寫的文件。其價值在於它所強迫的思考過程:誠實的目標、真正的替代方案、明確指出的風險,以及具體的設計。一份詞藻華麗、替代方案含糊不清、目標籠統的文件是毫無價值的。此技能的存在就是為了防止這種情況。
此技能設計上就是互動式的。它會透過訪談引導使用者思考,將每一個主張都建立在真實的程式碼庫之上,並在開始撰寫任何說明文字之前,先向使用者展示設計的實際運作程式碼。它絕不會憑空創造困難的章節。
原則
- 思考過程本身就是產出。 文件只是副產品。如果某個章節無法誠實地填寫(沒有真正的替代方案、不知道任何風險),就直接說明,而不是編造填充內容。
- 每個主張都要有根據。 在儲存庫中,用檔案參考來支持關於當前系統的陳述。在沒有讀過程式碼的情況下,絕不能斷言程式碼的運作方式。
- 展示,而非敘述。 設計是透過一個實際運作的 API/程式碼範例來溝通,這個範例是使用者從真實選項中挑選出來的,而不是用文字描述。這是不可妥協的(請見第 3 階段)。
- 被拒絕的選項並非浪費。 使用者未選擇的方法會變成「已考慮的替代方案」章節,並附帶它們的程式碼。這就是為什麼這裡的替代方案是真實的,而不是稻草人。
- 只問尚未回答的問題。 如果使用者的請求、連結的票證或程式碼已經回答了某個面向,就不要重複詢問。改為確認你的推論。
- 極致簡潔。 每個觀點都用最少的文字表達清楚。寧可使用條列式而非段落,一個句子勝過三個。沒有前言、沒有贅述、沒有填充內容。如果一個章節可以用一行交代,就用一行。程式碼片段承載了設計,所以周圍的說明文字保持最少。讀者應該能在幾分鐘內瀏覽完畢整份 RFC。
- 不要在產生的文件內容中使用 em-dashes。請使用逗號、冒號、句點或括號。
流程
digraph rfc {
rankdir=TB;
"解析輸入" [shape=box];
"第 1 階段:建立基礎" [shape=box];
"在儲存庫中?" [shape=diamond];
"掃描程式碼 + 偵測範本" [shape=box];
"第 2 階段:訪談" [shape=box];
"第 3 階段:設計選項" [shape=box];
"已選擇選項?" [shape=diamond];
"第 4 階段:組合" [shape=box];
"第 5 階段:自我審查" [shape=box];
"第 6 階段:審查迴圈" [shape=box];
"已核准?" [shape=diamond];
"第 7 階段:輸出" [shape=box];
"解析輸入" -> "第 1 階段:建立基礎";
"第 1 階段:建立基礎" -> "在儲存庫中?";
"在儲存庫中?" -> "掃描程式碼 + 偵測範本" [label="是"];
"在儲存庫中?" -> "第 2 階段:訪談" [label="否"];
"掃描程式碼 + 偵測範本" -> "第 2 階段:訪談";
"第 2 階段:訪談" -> "第 3 階段:設計選項";
"第 3 階段:設計選項" -> "已選擇選項?";
"已選擇選項?" -> "第 3 階段:設計選項" [label="修改/新選項"];
"已選擇選項?" -> "第 4 階段:組合" [label="是"];
"第 4 階段:組合" -> "第 5 階段:自我審查";
"第 5 階段:自我審查" -> "第 6 階段:審查迴圈";
"第 6 階段:審查迴圈" -> "已核准?";
"已核准?" -> "第 6 階段:審查迴圈" [label="變更"];
"已核准?" -> "第 7 階段:輸出" [label="是"];
}
請勿跳過任何階段。 如果使用者一次提供多項答案,請接受並跳過他們已回答的部分。絕不能跳過第 3 階段(使用者必須看到並從真實的程式碼選項中選擇設計)或第 5 階段(自我審查)。
第 1 階段:建立基礎
解析輸入
使用者可能會提供:自由形式的描述、GitHub PR/議題、Linear 票證,或只是一個主題。從中提取已經回答的內容,這樣你就不會在第 2 階段重複詢問。
如果在儲存庫內部(強制)
掃描程式碼以了解使用者提案的真實背景。 如果不了解提案會影響到的系統,就無法撰寫有根據的 RFC。
- 偵測儲存庫慣例。 全域搜尋現有的 RFC 設定:
rfcs/、docs/rfcs/、docs/rfc/、**/*rfc*template*、adr/、docs/adr/、.github/*TEMPLATE*。如果存在範本檔案,採用其章節標題及其目錄,而非內建範本,並用一行告訴使用者:使用您儲存庫的 docs/rfcs/template.md;已覆蓋我的預設結構。無需詢問確認。 - 掃描相關的子系統。 讀取目錄樹(名稱)、README/架構文件,以及提案會觸及的實際模組。了解:受影響區域目前的運作方式、已在使用中的模式和抽象概念、真實的限制(型別、介面、資料流程)。這將為背景章節奠定基礎,更重要的是,能讓第 3 階段的程式碼選項符合現有慣例。
- 記下你將在 RFC 中引用的檔案參考(
path:line)。
如果在儲存庫之外:跳過掃描和偵測;訪談流程將使用內建範本產出獨立的文件。
第 2 階段:訪談
引導使用者討論以下維度。對於每個維度,首先檢查它是否已從輸入或程式碼掃描中得到答案;如果是,確認你的推論(我讀到 X 是透過 Y 運作的 - 對嗎?),而不是直接提問。一次只問一個真正開放的問題。當程式碼掃描為你提供了候選答案(尤其是替代方案和風險)時,提出來,讓使用者做出反應,而不是從頭開始生成。
核心維度(務必涵蓋)
| # | 維度 | 餵養的章節 |
|---|---|---|
| 1 | 問題 - 什麼東西壞了/遺漏了,目前的痛點 | 背景/動機 |
| 2 | 為何現在 - 觸發因素,不行動的成本 | 動機 |
| 3 | 目標 - 成功長什麼樣子,盡可能可衡量 | 目標 |
| 4 | 非目標 - 明確排除在範圍之外 | 非目標 |
| 5 | 提議的方法 - 在第 3 階段中作為設計選項處理 | 提議的設計 |
| 6 | 替代方案 - 從第 3 階段被拒絕的選項中自動產生 | 已考慮的替代方案 |
| 7 | 風險/取捨 - 可能出錯的地方,它的成本 | 風險與取捨 |
| 8 | 上線計畫 - 遷移、分階段、向後相容、測試 | 上線計畫 |
| 9 | 核准者/利害關係人 - 誰決定,誰受影響 | 核准者 |
| 10 | 開放問題 - 已知的未知 | 開放問題 |
條件性維度(僅在必要時詢問)
- 安全性/隱私 - 當提案觸及驗證、機密、PII 或信任邊界時。
- 效能/成本 - 當它觸及熱門路徑、新增服務或有資源預算時。
- 可觀測性 - 當它引入新服務或值得告警的失敗模式時。
根據程式碼掃描和提案範圍判斷相關性。不要反射性地審問使用者這些問題。
目標品質檢查
在訪談中針對模糊的目標提出質疑。「讓它更快」不是目標;「租戶列表端點的 p99 低於 200ms」才是。要求提供可衡量的版本。
第 3 階段:設計選項(此技能的核心)
這是 RFC 展現其價值的地方。提出 2-3 個具體、不同的設計方法,每個都以實際運作的 API/程式碼片段呈現,並以第 1 階段的程式碼庫慣例為基礎。不是文字描述:而是實際的程式碼,展示最終的 API、函式簽章、架構或設定會是什麼樣子。
對於每個選項,提供:
- 一個簡短的名稱和一行摘要。
- 一個程式碼片段,展示最終的 API/用法/簽章(未來工程師實際會用來開發的東西)。
- 它的取捨:擅長什麼、成本是什麼、排除了什麼。
將它們並排呈現,並請使用者選擇或修改。如果他們想要一個新選項或混合選項,則進行迭代。
被選擇的選項將成為「提議的設計」(附帶其程式碼)。他們拒絕的選項將成為「已考慮的替代方案」章節,每個選項都保留其程式碼片段和落選的原因。 這就是為什麼這些 RFC 中的替代方案是真實的:它們是附帶運作中程式碼的真正候選方案,而不是事後發明的稻草人。
如果確實只存在一個可行的方法,就直接說明,並附上明確的註釋,說明已考慮過替代方案以及為何不可行。不要為了填滿表格而製造假的選項。
第 4 階段:組合
將完整的 RFC 寫入輸出檔案(路徑在第 7 階段解析,並在早期確認)。保持精簡(參見「極致簡潔」原則):使用條列式而非段落,使用最簡短的措辭並保持清晰,不要有填充內容。程式碼片段負責說明,文字只是用來框架它。如果第 1 階段偵測到儲存庫的內部範本,請使用它;否則使用以下內建結構。
當設計的結構值得展示時(架構、序列、資料流程、狀態機),包含一個 Mermaid 圖表。一個圖表回答一個問題。對於純粹是 API 層級且沒有有趣流程的變更,則跳過。
內建範本
# RFC:<標題>
## 摘要
<讀者在 30 秒內能掌握的 TL;DR:此提案的內容與原因。>
## 背景與動機
<問題、當前狀態(如果在儲存庫中則附上檔案參考),以及為何現在。
如果什麼都不做會發生什麼事。>
## 目標
<盡可能可衡量。使用條列式。>
## 非目標
<明確排除在範圍之外,這樣審查者就不會重複爭論。>
## 提議的設計
<所選的方法。以第 3 階段實際運作的程式碼/API 範例開頭。
然後解釋它是如何運作的,並以實際模組為基礎。如有必要,可附上圖表。>
## 已考慮的替代方案
<第 3 階段中每個被拒絕的選項,附帶其程式碼片段和落選的原因。>
## 風險與取捨
<每個風險都應搭配一個緩解措施,或者明確標註「已接受,因為...」。>
## 上線計畫
<遷移、分階段、向後相容、測試策略。>
## 開放問題
<已知的未知。與其假裝它們已解決,不如明確指出。>
## 核准者
<誰簽核,誰受影響。列出名字,這樣決策權歸屬就很清楚。>
僅在第 2 階段判斷為相關時,才包含條件性章節(安全性、效能、可觀測性)。
選擇性元資料(僅在使用者要求時)
預設情況下,不要添加 frontmatter 或編號。如果使用者要求,則在前面加上:
---
status: Draft # Draft | In Review | Accepted | Rejected | Superseded
author: <名稱>
date: <YYYY-MM-DD>
approvers: [ ]
---
僅在目標目錄中已存在 NNNN-*.md 檔案時,才使用自動編號(NNNN-slug.md);掃描以找出最高的數字並遞增。否則使用純 slug 檔案名稱。
第 5 階段:自我審查(強制,在使用者看到草稿之前)
依照以下評分標準審查組合好的 RFC,並修正你能修正的部分。然後報告你發現了什麼、以及哪些部分仍需要使用者處理。
- 目標可衡量? 將模糊的期望收緊為可測試的項目。
- 替代方案真實? 至少有一個真正的替代方案,附帶其自己的程式碼,而不是稻草人。(第 3 階段應保證這一點。)
- 每個風險都已緩解? 每個風險都有一個緩解措施,或明確標註「已接受,因為...」。
- 設計具體? 提議的設計包含實際的 API/程式碼片段,而不僅僅是文字描述。
- 主張有根據? 每個關於程式碼庫的陳述都有檔案參考支援。沒有無根據的斷言。
簡短報告,例如:自我審查:收緊了 2 個模糊目標;標記了一個尚未有緩解措施的風險(資料遷移停機時間) - 需您決定。其他部分皆有根據。
第 6 階段:審查迴圈
RFC 已寫入 <路徑>。請在 Markdown 預覽器中開啟以檢視圖表。需要任何變更嗎?
透過編輯檔案來套用變更。迴圈直到核准為止。
第 7 階段:輸出
路徑解析(在第 4 階段開始時及早確認)
- 具有偵測到 RFC 目錄的儲存庫:
<該目錄>/<NNNN->slug.md。 - 沒有偵測到 RFC 目錄的儲存庫:
docs/rfcs/<slug>.md。 - 在儲存庫之外:目前工作目錄,如果目前工作目錄不可寫入,則為暫存區。
事先問一次:我將把 RFC 寫入 docs/rfcs/<slug>.md。需要更改位置嗎?
完成時
- 自動為使用者在新 VS Code 視窗中開啟:
code --new-window "<絕對路徑>"。 - 在終端機中列印簡短的摘要(標題 + 一行說明 + 路徑)。不要在終端機中傾印完整文件。
錯誤處理
- 無輸入/只有主題 - 沒問題,訪談流程會處理。直接開始第 2 階段。
- 引用的 PR/議題/票證無法讀取 - 告知使用者,然後根據他們的描述繼續進行。
- 儲存庫太大,無法完整掃描 - 將掃描範圍限定在提案相關的子系統;記錄你跳過了哪些部分。
- 使用者無法回答某個維度 - 將其記錄為一個開放問題,而不是憑空編造答案。