進行中

System Design Every Day

我自己的系統設計學習網站:一張依先修關係排好的學習地圖,AI Agent 每週寫三篇附互動模擬器的文章,地圖往哪裡長由我決定。

  • Node.js
  • Cursor Cloud Agent
  • Cursor Automation
  • Claude Code
  • Agent Skills
  • GitHub Actions
  • GitHub Pages
  • JavaScript
croso1024.github.io/system-design-every-day
系統設計學習網站的首頁:分類卡片依先修關係由左到右排成一張學習地圖,右側列出最近發布的文章

System Design Every Day 是我為自己做的系統設計學習網站。把讀過、想讀的系統設計知識集中成一張自己的學習地圖,依主題之間的關係分類、排出閱讀順序;網站的內容成長方向由我和 Agent 討論訂下後,再交由雲端沙箱中的 Agent,依照我們設計的閘門與規範自動撰寫與維護文章。

作為一名後端工程師,系統設計對我來說是個有趣又變化莫測的主題,而且非常浩瀚,每個領域都能拆出一堆細分子項。我在這個領域的啟蒙,是碩士班期間讀的、由 Alex Xu 撰寫的《內行人才知道的系統設計面試指南》,作者用生動的例子說明實際開發中會遇到的各種系統設計範式。到了有 2 年工作經驗再接著讀第二輯,對書中的概念有了更多共鳴,也多了贊同與質疑。

《內行人才知道的系統設計面試指南》第一輯封面 《內行人才知道的系統設計面試指南》第二輯封面

會想要自己做一個系統設計學習入口的契機是什麼?網路上的概念教學已經好多好多,基本上想得到的主題都有人寫過,動動手指直接問 AI 也是很方便的做法。但每次讀完一篇,我都會深刻感受到,自己看的只是系統設計這片浩瀚海洋裡某個領域的冰山一角。遇到一個概念就去查、工作上遇到新主題就去深挖當然可行,但長期下來,更有效的方式是把這些知識集中、分類管理:學習時物以類聚、舉一反三,往後需要拿出來重新咀嚼時,也能一次檢視相同類型的概念。所以我才有個點子是製作一張自己的學習地圖(知識圖譜),去儲存與管理所有我學過的、有興趣的系統設計知識。

一張看得出閱讀順序的地圖

我想像中的學習地圖,就是網站首頁上的這張。

首頁學習地圖選取「Agent Protocols」分類:地圖標出從 Search & Analytics 到 Agent Protocols 的五步先修路徑,右側面板依序列出每一步的分類與文章

主題一多,會遇到的問題是「該從哪裡讀起?」。這是我以前零碎地照著工作需要去查,或在書中看到某個主題想順著讀下去時常踩到的問題:因為少了某些先備知識,讀起來效果受限,或是得一直往更源頭的概念回頭補。例如讀 Raft 共識之前最好先懂資料複製,讀 RAG 之前最好先懂向量搜尋。

所以我在這個專案中採用的做法,是將相關的知識整理成一群群的小卡,依先修關係從左邊的基礎主題一路排到右方的進階主題(我一開始嘗試過星狀排列,但在主題數量一多之後反而覺得不容易看)。點擊地圖就能看出這個主題領域前後的脈絡,並得到一組建議的閱讀順序。

讀完一篇文章後,就可以在地圖上把它標記成已讀,追蹤自己在地圖上完成的狀況。首頁會標記每個分類讀了幾篇,路徑面板也會跳過已讀的文章。

已讀紀錄目前是放使用者的 Local Storage。這是考量我自己的使用習慣,對一個純靜態頁面來說不掛 Server 端就能直接做的範圍。

一篇文章內有什麼

點進一篇文章,左側是章節目錄,右上角可以切換成全螢幕閱讀。每一章穿插幾種重點框,用來標示出重要的觀念與取捨,或者提醒常見的誤解;需要比較幾種做法時會放比較表,圖表則依內容選形式,說明「誰先誰後」用時序圖,說明狀態怎麼轉換用狀態圖。每一章的結尾還有一句「一句話答法」,用一句話濃縮該章重點。

文章頁版型:左側章節目錄、右上角全螢幕按鈕,內文以嵌入式資料庫為例,有重點框與 SQLite、RocksDB、PostgreSQL 的比較表

早在做這個網站之前,我就試過讓 AI Agent 針對某些特定知識領域產生學習文件。我認為 Agent 寫的學習文件相比大部分網路文章有一個優勢:它可以根據你的需求,順手做出可視覺化的互動 Demo。在這個網站上,這個想法轉成我希望每篇文章都有的互動模擬器。讀者可以拖動參數、切換情境,看結果怎麼跟著變,更直接地理解章節中的重要概念。一篇文章也可以有好幾個小 Demo,各自放在它解釋的那一章旁邊。

不同主題適合的互動方式不一樣,網站上的模擬器分成六種形式:

  • 時序推進:按「下一步」走過一套固定的步驟,適合本來就照順序進行的協定,例如 TCP 三向交握。
  • 參數掃描:拖動參數,結果即時重算。例如 HTTP/1.1 與 HTTP/2 那篇,可以拖動頁面要載入的資源數量、切換網路延遲與連線方式,兩條載入時間軸同時重算。
  • 並排對照:同一組輸入同時交給兩種做法。例如資料庫擴容那篇,比較兩種擴容策略要搬多少資料、要雙寫多久、擴容後的資料分布有多不平均。
  • 空間視覺化:在畫布上拖曳、點選。例如向量搜尋那篇,可以移動查詢點、切換三種索引方式並調整搜尋範圍,對照正確答案,看找回了幾個、比較了幾次距離。
  • 決策器:回答幾個問題,得到選型建議與理由,適合「什麼情況該用哪個」的主題。
  • 拆解器:輸入一筆真實資料,一層一層拆開標註,例如子網遮罩。

下面三張依序是參數掃描、並排對照與空間視覺化的例子。

HTTP/1.1 與 HTTP/2 的載入瀑布圖:拖動子資源數量、切換網路延遲與連線策略,兩條時間軸同時重算總耗時 資料庫擴容的並排模擬器:同一組租戶與參數下,比較 Hash 重分配與目錄式路由表的搬遷量、雙寫窗口與擴容後的傾斜比 向量搜尋的互動模擬器:在畫布上移動查詢點、切換 Flat/IVF/HNSW 並調整 nprobe,對照正確答案,看召回率與距離比較次數

不過,有按鈕、有拉桿,不代表模擬器真的在計算。在這個網站運行初期,有不少 Demo 只是看起來能操作,這件事怎麼被發現、怎麼處理,留到後面的檢查閘門再說。

學習地圖擴展和自動化工作流

目前網站上的文章都是讓 Agent 在雲端沙箱中完成的。Agent 依照排程自動醒來,透過給定的 CLI 工具理解 Repo 狀態與各種工作流程規範。

我對這個專案的想法是長期的,這是一個我自己會來閱讀的網站。我想讓 Agent 在這個專案上長期維運,讓網站持續成長。我沒有選擇直接給定一堆主題、讓大量 Agent 併發開工,因為我不想做一個一口氣產出幾十篇、我自己卻不會去看的東西。

所以我給自己在這個專案中的定位是掌舵人:由我決定學習地圖的成長方向,要擴充哪些新的領域、這些領域和既有領域之間有什麼關係、每個領域如何劃定子題,子題與子題之間如何分工,讓我自己和讀者更清楚該領域下不同主題的職責範圍與邊界。

日常的維運,就是定期與 Agent 討論這些方向,並決定撰寫特定系列文章時要著重在什麼樣的脈絡上,例如這篇要偏重哪些面向、Demo 想用什麼方式呈現,或者這個系列應該圍繞什麼樣的使用情境來介紹。擴充地圖這件事只由我在本機做,雲端的 Agent 被規定不能新增主題,也不能改動地圖。

而下面這張圖就是目前工作流程的大致架構,從左到右分別是由我介入的學習地圖維護,雲端 Agent 負責的撰文主流程,以及上線前由 GitHub Actions 進行的檢查。

產線運作圖:左邊是我負責的規劃圖譜與主題池;中間是 Agent 依排程在雲端跑的迴圈:依圖譜挑題、讀規範、撰寫文章與模擬器、自我檢查後發布;右邊是 GitHub Actions 的上線前檢查,文章、進度、權限都通過才會上線到線上手冊,並解鎖先修已經齊全的主題

這個專案沒有 DB,所有的進度都記在 Repo 中持久化的狀態檔裡。為了避免文章變多後狀態檔跟著變大,讓 Agent 每次都得直接讀寫整份檔案,我提供了一組 CLI 工具來限制它的存取範圍:Agent 依排程醒來後,只透過 CLI 查詢下一篇該寫的主題,以及撰寫時真正需要參考的近幾篇發布紀錄,完成後也透過 CLI 更新狀態。排程則按照我自己的閱讀節奏,定在一週三篇。

用腳本檢查 Agent 的產出,沒通過就不上線

Agent 從撰文到發布都在雲端完成,所以需要有方法去檢查 Agent 交出的每樣東西。整套檢查流程目前分三層,其中文章與進度更新這兩層 Agent 在工作流程收尾時被要求自己先做一次;推上 GitHub 之後、文章上線之前,GitHub Actions 會再跑一次,任何一項沒過就阻擋文章上線。

第一層是文章本身,前面提到的假 Demo 就是在這裡擋下的。Agent 在雲端工作一段時間後,自己摸索出一種「播放器」式的 Demo:有按鈕、可以調節的拉桿,但實際上只是把預先寫好的說明照順序播出來,之後的文章也開始沿用這種偷工減料的寫法。因此後來我對當時全站的模擬器做了一次重構,現在規定計算和畫面要分開寫,腳本能把計算單獨拿出來跑,逐一調整每個參數,確認結果真的跟著變,模擬器才算是模擬器。另外兩道檢查分別看模擬器的元件結構,以及和最近幾篇採用的互動形式是否重複。

第二層是進度。前面提到進度都記在狀態檔裡,狀態檔一旦和實際的文章對不上,下一次排程就會挑錯題。所以文章上線前會比對:同一個主題不能同時在待寫和已發布清單裡、每篇文章都要在地圖上、首頁要和狀態檔同步。

第三層是權限。擴充地圖只由我實際動手,由 GitHub Actions 把關。因此每次雲端 Agent 推上來的改動被限制只能落在文章與發布進度更新的特定幾個位置。一旦碰到學習地圖或腳本就阻擋文章上線,且會一路阻擋後續的雲端 Agent 繼續在壞掉的狀態上工作,直到由我確認狀況並修正後才解除鎖定。


回頭看,其實設計這套系統的過程本身也讓我學到很多。每次和 Agent 討論學習地圖的擴展方向時,我也能從它的回應中釐清:自己感興趣或工作上需要的主題,如何與既有的領域關聯起來,背後又需要其他哪些領域的知識。

當整套流程開始穩定運行、我也跟著規律閱讀之後,才發覺這套系統帶來的幫助比我一開始預期的更大。就像任何的習慣養成、學習,或者我平常的跑步訓練一樣,重點都在於持續的累積——現在有了三層檢查替雲端產線把關,網站就能照著一週三篇的節奏自己往前走;而我也回到讀者的身分,每週打開網站讀新文章、操作模擬器、在地圖上打勾,等手邊的主題讀得差不多了,再坐下來規劃下一塊想探索的領域。