Docs 是知識的書面紀錄。通常他能讓我們用最少的文字 去理解整件事情的全貌。
對於一個 repo 也是一樣,好的 Docs 能讓我們在不用去理解程式碼的情況下,了解程式碼所帶來的功能與意義。
我們可以把 docs 想像成 錨點:不論是人或 agent,當今天是新進人員,或者討論過於發散時,都能透過它快速掌握專案目前所扮演的地位與角色。
人員會更替、記憶會淡化;coding agent 則更加極端,每個新的 session 都從零開始,它所知道的只有當下讀進 context 的內容。
而 身為錨點的 docs,能將知識有效率的傳承下去,幫助人 or agent 更快速的理解。由此可見其重要性。
但,Docs 也是 Context 的一種。
並且因為其錨點的特性,他會被反覆閱讀,並影響著閱讀者。
所以 Day3 整理的那些 context 問題,同樣會出現在 docs 上,docs 的品質,會直接變成 context 的品質。
所以 docs 的核心精神不是「寫得越多越好」,而是:只留下需要的、品質好的、而且現在仍然有效的 docs。
Why we need correct docs
文件類型多到數不完,但如果從「它要告訴 agent 什麼」來看,大致可以收斂成三類:
| 類型 | 告訴 agent | 回答的問題 | 什麼時候更新 | 代表文件 |
|---|---|---|---|---|
| Current truth | 現在不能搞錯什麼 | 系統現在是什麼、怎麼用? | 系統行為改變時,同步更新 | README、Spec、Runbook |
| Design knowledge | 為什麼不能亂改 | 系統為什麼變成這樣? | 做出新決策時新增;舊決策標記為被取代 | Design doc、ADR |
| Working state | 這次工作做到哪裡 | 這次工作接下來怎麼做? | 工作進行中隨時更新;完成後移除或轉移 | Plan、Spec(本次工作) |
分類的重點不在文件叫什麼名字,而在它要活多久、誰負責讓它保持正確。
專案中最重要的唯一真理:如果想知道這個 repo 現在到底提供了什麼,看這些就對了。
Current truth 描述的是 repo 現在的狀態,所以它的要求也最嚴格:只要和現況不符,它就是錯的。
README
README 回答的是:這是什麼?我要怎麼開始?
內容應該是高層、簡短的:purpose、quick start、基本 setup,以及重要文件的連結。
README 通常也會包含另外兩種 current truth:
專案還小、內容還少的時候,全部放在 README 裡沒有問題。
但隨著內容增加,這會讓每個讀者都被迫讀進所有細節:agent 可能只是想知道「這個專案到底在幹嘛」,卻連同所有操作步驟與規格一起讀進 context,造成 context 污染。
所以好的 README 會更接近一個 orientation layer(導覽層):自己只負責回答「這是什麼、怎麼開始」,再把 Spec、Runbook、Design doc、ADR 拆成獨立文件並連過去,讓讀者依任務需要往下讀。
Spec
Spec 描述系統應該滿足什麼:
Code 描述「做了什麼」,spec 描述「應該做什麼」;兩者不一致時,代表其中一方需要被修正。
Spec 在 Working state 中也會再出現一次,那是它被產生的地方;這裡的 spec 則是工作完成後,累積下來的系統現況。
Runbook
Runbook 描述系統怎麼跑:
它的標準很單純:照著做就能完成。 只要有一步和現況不符,整份 runbook 就失去了信任。
What 通常可以從 code 看出來,但 why 很容易隨時間消失。
Code 只記錄了最後的選擇,不會記錄為什麼這樣選、以及那些沒被選上的方案。
Design knowledge 類的文件,就是為了保留設計背後的理由而存在。
Design doc
Design doc 是一整場設計討論的文件,在 Google,大多數團隊啟動重大專案前都要求先有一份。
一份好的 design doc 會包含:
但可以想像,這會是一份非常雜的文件。它記錄的是整個討論過程:有些內容在決定之後就該移除,有些只是討論中途冒出、品質不高的想法。
對當下的討論來說,這些都有價值;但對之後接手的人或 agent,大部分只是雜訊。
所以在決定之後,會再從中留下一份精簡的 ADR。
ADR(Architecture Decision Record)
ADR 是從 design doc 中,抽出值得永久保存的決策:
ADR 建議放在 application code 附近,最好在同一個版本控制系統中。
決策改變時,舊的 ADR 不刪除,而是標記為 superseded(被取代),並指向新的 ADR。對 agent 來說,知道「哪個決策已經被取代」,和知道決策本身一樣重要,否則它可能會依照一個早已被推翻的理由去修改 code。
Design doc 是過程,ADR 是結論。 所以 repo 裡可以只留下 ADR,完整的 design doc 則另外存放,需要追溯時再去查。
Working state 是這一次工作的文件。plan 與 spec 都應該先定義好,再請 agent 開始。
Spec(本次工作)
它是這次工作最後的驗收依據,也是產生 test 的基礎。
Plan
如 Day3 提到的,一開始就給出完整的 plan,會比對話中逐步迭代補充來得好。
工作完成之後
驗收並完成後:
Working state 如果沒有被清理,就會變成最典型的過期文件。
水能載舟,亦能覆舟。乾淨的 docs 絕對能幫助 agent,但不好的 docs 也能讓 agent 變得更糟。
以前我很容易寫出一堆千行以上、什麼都有的文件,原因不是不想寫好,而是沒有搞懂每一種文件的定義:不知道一段內容該放在哪、該活多久、什麼時候該刪,所以只能一直往裡面加。
分清楚三種類型之後,這些問題都能變成明確的規則:
| 類型 | 放在哪 | 寫什麼 | 什麼時候更新/刪除 |
|---|---|---|---|
| Current truth | repo 內,README 作為入口 | 現在有效的用途、行為、操作方式 | 行為改變時,和 code 同一個 commit 更新 |
| Design knowledge | repo 內,靠近 code | 決策與理由 | 只新增;被取代時標記 superseded |
| Working state | 工作期間存在 | 本次目標、驗收標準、步驟與進度 | 完成後:plan 刪除,spec 合併並轉成 test |
有了規則,agent 就不只是 docs 的讀者,也可以是維護者:
Docs 的價值不在數量,而在每一份都知道自己是什麼、該活多久。