Community程式設計與開發github.com

Baukaalm/system-design-first

在實作功能前先進行系統設計:需求、負載估算、現狀與目標對比、模式權衡,以及包含「為什麼」的簡潔設計摘要。

system-design-first 是什麼?

此技能強制在撰寫任何程式碼之前,先進行系統設計審查,適用於 Cloude Code 或 Cursor 等 AI 代理。它將開發任務分類為 L0(瑣碎)至 L3(子系統)四個層級,並針對每個層級提供適當的設計深度。其核心是一個六步驟流程:範圍界定、負載估算、映射現有架構、提出目標設計、深入探討風險,最後產出結構化的設計摘要。此技能特別強調基於數據的決策(例如,建議使用 Kafka 前需先有 QPS 估算)、尊重原始作者的設計意圖,以及將前端視為系統設計的一部分。它內建了完整的參考資料庫(框架、估算、模式、前端、可視化),讓 AI 能夠對實際的系統權衡做出明智的判斷,而非只是猜測。

相容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Baukaalm/system-design-first/tree/HEAD

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

系統設計優先

大多數任務描述只說明要做什麼,卻隱藏了決定功能能否在生產環境中存活下來的關鍵問題:有多少使用者、使用頻率、資料量多大、相依服務變慢時怎麼辦、兩個寫入者競爭時誰擁有真理。此技能強制在撰寫程式碼之前,以任務作者能夠閱讀並提出異議的形式,將這些問題明確提出來。

審查流程為:範圍界定 → 估算 → 高階設計 → 深入探討 → 總結,並應用於實際工作中:包含現有程式碼庫、有明確意圖的作者,以及預算限制。目標是從系統的角度,描繪出該功能的清晰圖像。

請使用使用者輸入的語言回覆。設計摘要是寫給他們看的,不是寫給你的。

1. 先評估深度

過度設計一個拼寫修正,和設計不足一個金流功能一樣糟糕。選擇層級,用一句話說明,並據此投入時間。

層級典型任務你需要產出的內容
L0 – 瑣碎文案變更、重新命名、樣式調整、可透過本地修復的明顯錯誤無需額外產出。如果存在潛在風險,最多用一句話說明(例如:「此標籤在 CDN 上也有 24 小時的快取」)。然後直接執行任務。
L1 – 局部變更新增欄位、新增過濾條件、小型端點變更、鉤子(hook)、查詢微調在程式碼中內嵌一個 3-7 行的設計檢查:說明會觸及哪些部分、承載的負載量,以及最可能出錯的一件事(N+1 問題、快取失效、分頁、冪等性)。然後開始實作。
L2 – 功能具資料流的新畫面、新增端點與儲存、通知、搜尋、匯出、第三方整合一份設計摘要(第 4 節),約一頁長度。然後根據摘要進行實作。
L3 – 子系統新服務、即時通道、事件管道、多租戶資料模型、熱路徑遷移、任何含有「擴展」一詞的任務完整摘要,加上針對每個高風險元件的深入探討、考量過的替代方案、遷移路徑,以及上線後需要監控的指標。

將任務層級提升的信號:使用者感受到的延遲、並發寫入者、扇出(一個事件送給多個接收者)、表格或清單的無限增長、第三方速率限制、金錢相關、個人識別資訊(PII)、任何排程任務,或是那些明顯會變成永久方案的「暫時」解決方案。將任務層級降低的信號:僅少數使用者使用的內部工具、資料量小到永遠可以放在記憶體中、具有 Kill Switch 的功能旗標實驗。

如果使用者明確要求設計審查或更深入的分析,無論規模大小,都視為 L3 層級。

2. 逐步審查流程

依序進行以下步驟。對於 L1,將其壓縮成幾行說明;對於 L2/L3,每個步驟都成為設計摘要中的一個章節。references/framework.md 包含每個步驟的問題清單;在同一個對話中初次執行 L2 以上審查時,請先閱讀它。

步驟 1 — 理解與範圍界定

  • 從系統的角度,用一段話重新描述該功能:參與者、觸發條件、輸入、輸出、副作用。
  • 區分功能需求(做什麼)與非功能需求(做得如何:規模、延遲、可用性、一致性、持久性、安全性、成本、可操作性)。任務幾乎從不明確指出後者;請根據產品上下文推斷,並標明是推斷結果。
  • 明確寫出哪些不在範圍內,以免設計摘要無聲無息地擴大。
  • 收集作者的意圖:任務描述、PR 描述、評論、連結的設計文件、現有 ADR(架構決策記錄)、以及此程式碼庫中類似功能是如何建立的。作者通常心中已有設計藍圖;你的任務是將它呈現出來,而非取代它。
  • 僅向使用者詢問那些會實質改變設計的問題(例如:「這個必須在一秒內可見,還是一分鐘也可以?」)。對於其他所有問題,提出假設並繼續進行;假設會寫入設計摘要中。

步驟 2 — 估算

數字能將意見轉化為決策。即使任務中沒有提供,也要進行粗略估算;references/estimation.md 提供了參考數字(延遲階梯、2 的冪次、可用性 9 的數量、每節點容量)以及實際計算範例。

  • 使用者 / 租戶數 → 每日活躍使用者數 → 每日操作次數 → 平均與尖峰 QPS(尖峰通常是平均值的 2-5 倍,對於突發性流量如「所有人都在早上 9:00 打開 App」則更高)。
  • 讀寫比率、資料酬載大小 → 每日/每年儲存量、頻寬。
  • 增長:如果產品成功,12 個月後的數字是多少?
  • 如果存在真實數據(分析資料、資料庫行數、現有儀表板、設定限制),請使用它們並標明來源;否則,提供一個範圍並標明是假設。

然後用這些數字來排除模式,而不僅僅是為了正當化它們:「在每秒 30 次寫入的情況下,一個有索引的 Postgres 表格就足夠了;我們不需要隊列來處理吞吐量,除非我們需要重試機制以及與郵件服務提供商解耦。」

步驟 3 — 繪製當前設計(現狀)

在描述之前先閱讀程式碼。指名具體的檔案、模組、表格、端點、任務、快取、隊列。不要憑空創造元件。

  • 該功能會觸及哪些元件?用簡短的文字圖表繪製資料流(client → BFF → service → Postgres、event → queue → worker)。
  • 狀態在哪裡,誰擁有它(資料庫、快取、客戶端儲存、URL)?
  • 有哪些現有基礎元件可以重複使用(一個 Outbox 表格、一個任務執行器、一個查詢快取、一個 WebSocket Hub、一個共用的 Pagination 元件)?
  • 熱路徑、已知瓶頸、現有單點故障(SPOF)、該功能會繼承的當前限制(速率限制、頁面大小、超時設定)。
  • 對於前端任務,「現狀」仍然是一個系統:資料擷取層、快取策略、打包邊界、即時傳輸 — 請參閱 references/frontend.md。

步驟 4 — 提出目標設計(目標)

從作者的意圖開始。如果它合理,就贊同並加以完善;如果它與估算數字或已知的失敗模式衝突,則顯示衝突及其後果,並提供能解決問題的最小變更方案。由作者做最終決定;你的工作是讓權衡取捨變得可見。

  • 以文字圖表呈現的高階設計,加上 API 契約(具有形狀的端點/事件/訊息)和 資料模型(表格、鍵、索引、保留策略)。
  • 對於每一個非瑣碎的選擇,請指明所採用的模式以及你拒絕的替代方案,並給出與步驟 2 數字相關的理由。references/patterns.md 是模式目錄:包含擴展、快取、非同步/隊列、資料儲存與一致性、API 風格與即時傳輸、速率限制、ID 生成、可靠性、可觀測性 — 每個模式都有「使用時機 / 避免時機 / 權衡取捨」。
  • 當合適時,將該功能映射到一個典型系統(例如:「這是一個通知系統:隊列 + 每個通道的工作者 + 去重」、「這是新聞饋送的扇出模式」、「這是一個速率限制器」)。目錄的最後一個章節列出了典型系統的形狀及其標準構建模組。這個類比能為讀者提供一個已知的參考點,以及此類系統通常需要哪些元件的一份清單。
  • 優先使用程式碼庫中現有的基礎元件,以及能滿足數字需求且留有餘裕的最簡單設計。明確說明哪些升級被推遲了,以及觸發這些升級的信號是什麼(「當此查詢的 p95 超過 200 毫秒或表格超過 5000 萬行時,才添加一個讀取複本」)。

步驟 5 — 深入探討可能出錯的部分

對於 L2,挑出風險最高的 1 到 2 個部分;對於 L3,則逐一審查所有部分。標準問題,大致按照它們最常出問題的頻率排序:

  1. 並發與冪等性 — 重複提交、重試、兩個寫入者、至少一次傳遞。冪等鍵在哪裡?唯一約束是什麼?
  2. 一致性 — 誰會讀取到過期資料,會持續多久?這是否可以接受?快取失效路徑是什麼?讀取自己寫入的資料?
  3. 相依服務故障 — 服務提供者當機、隊列延遲、遠端模組載入失敗。超時設定、帶抖動的重試機制、斷路器、優雅降級、使用者會看到什麼。
  4. 熱點 — 熱鍵、大型租戶、無限制增長的列表、N+1 查詢、全表掃描、缺少索引、快取過期時的雪崩效應。
  5. 增長 — 無限制增長的表格/列表/隊列;保留策略、歸檔策略、分頁(使用游標而非偏移量)、分區策略。
  6. 遷移與上線 — 資料回填、雙寫期間、功能旗標、回滾路徑、向後相容的合約變更。
  7. 安全性與隱私 — 資料層級的授權(租戶隔離)、日誌/隊列中的 PII、公開端點的速率限制、輸入驗證。
  8. 可觀測性 — 哪個指標能證明它正常運作(SLI)、哪個警報會在其故障時觸發、為了除錯單一請求需要記錄哪些日誌。

步驟 6 — 總結,提供視覺化選項

圖表會耗費大量代幣,因此是選擇性的。設計摘要本身只使用單行的文字流程(client → API → Postgres)。

對於 L2 和 L3,在設計摘要結尾,用使用者的語言提出一個問題,連同待解決的開放問題:

繪製架構圖?1 — 在終端機中繪製現狀/目標圖表 · 2 — 再加上一個 design 資料夾(Mermaid + architecture.html)· 3 — 不用

  • 僅在使用者選擇 1 或 2 之後才進行繪製,遵循 references/visualization.md 的指引。不要等待這個問題的答案再開始實作;如果使用者繼續進行而沒有回答,則視為「不用」。
  • 僅在使用者已經要求繪製圖表、圖片、視覺化或 design 資料夾時,才跳過問題並立即繪製。
  • 如果沒有人可以回答(例如非互動式執行、CI/CD、評測環境),則不要繪製也不要提問;用一句話說明可應要求提供圖表。
  • 切勿在 L0 或 L1 時提供此選項。

產出設計摘要(下一節),然後繼續執行任務:根據設計摘要進行實作,同時將摘要保留在 PR/MR 描述中,並列出待解決的開放問題給作者,而不是默默地自行決定。

3. 判斷原則

  • 數字優先於模式。 未經估算證明其必要性之前,切勿推薦 Kafka、分片、CQRS、專用快取叢集或微服務。簡潔是一種功能;複雜性必須證明自己的價值。
  • 解釋,而非說教。 每個建議都應附帶一句作者可以驗證的「因為」。歡迎使用典型系統的類比;不歡迎列舉流行詞。
  • 尊重作者的設計。 將分歧呈現為「X 會在 Z 負載下導致 Y 問題;最便宜的解決方案是 W」。如果作者仍然偏好他們自己的方式,就依他們的方式實作,並在設計摘要中註明風險。
  • 現有程式碼就是證據。 閱讀它。一份描述不存在元件的設計摘要比沒有摘要更糟糕。
  • 區分必要與加分項。 將每個建議標記為「現在就需要」、「上線前需要」或「大約在 N 個使用者時需要」。
  • 前端也算在內。 客戶端快取、分頁、樂觀更新、即時傳輸、打包邊界和故障隔離都是系統設計;references/frontend.md 涵蓋了每個步驟在客戶端的版本。
  • 使用使用者的語言和詞彙。 如果團隊有習慣用語,請翻譯模式名稱;在第一次出現時保留英文術語於括號中。

4. 設計摘要

對於 L2 和 L3,請使用此結構。保留標題;只有在某個章節確實為空時才刪除它,並用一句話說明原因。L2 的目標長度為一頁。references/brief-template.md 提供了一個完整的 L2 範例以及簡潔的 L1 內嵌形式。

# 設計摘要:<功能名稱>

**深度:** L2 · **狀態:** 提案 · **作者意圖:** <一句話說明>

## 1. 範圍
功能需求:...
非功能需求(除非特別說明,否則為推斷結果):規模 · 延遲 · 可用性 · 一致性 · 安全性 · 成本
不在此範圍:...
假設條件:...

## 2. 估算
| 指標 | 目前 | +12 個月 | 來源 |
| --- | --- | --- | --- |
| DAU / 租戶數 | | | |
| 尖峰 QPS(讀取 / 寫入) | | | |
| 儲存增長 | | | |
結論:<這些數字允許/禁止了哪些做法>

## 3. 當前設計(現狀)
<單行文字流程> · 狀態所有權 · 可重複使用的基礎元件 · 繼承而來的限制
受影響檔案:...

## 4. 目標設計(目標)
<單行文字流程> · API 契約 · 資料模型 · 典型系統類比
模式選擇:<模式> — 因為 <原因>;拒絕了 <替代方案> 因為 <原因>。

## 5. 風險與深入探討
1. <風險> → 緩解措施(現在就需要 / 上線前需要 / 在 N 個使用者時需要)
...

## 6. 上線、遷移、可觀測性
功能旗標、資料回填、回滾 · SLI 與警示 · 需要記錄的日誌

## 7. 給作者的開放問題
- ...
- 繪製架構圖?1 — 終端機圖表 · 2 — 再加上設計資料夾 · 3 — 不用

## 8. 實作計畫
按順序排列的步驟,每個步驟都足夠小,易於審查。

5. 參考資料 — 何時閱讀

檔案何時閱讀
references/framework.md在同一個對話中首次執行 L2 以上的審查時:包含每個步驟的問題清單、非功能需求列表、如何提取作者意圖、分析反模式。
references/estimation.md任何需要數字的時候:延遲階梯、可用性九的數量、每節點容量、QPS/儲存計算、實際範例。
references/patterns.md選擇或正當化一個模式時;將一個功能映射到典型系統(聊天、饋送、通知、搜尋自動完成、檔案同步、速率限制器、KV 儲存、ID 產生器、支付...)時。包含目錄。
references/frontend.md任務涉及 UI / SPA / 微前端的變更時:資料擷取快取、分頁、即時功能、打包邊界、故障隔離、客戶端數字。
references/brief-template.md撰寫設計摘要時:包含完整的 L2 範例和簡潔的 L1 內嵌形式。
references/visualization.md僅在使用者要求繪製圖表之後(步驟 6):終端機方框圖規則、Mermaid 慣例、設計資料夾佈局、如何填充 assets/architecture.html。

相關技能