取舍)
如果一個(gè)項(xiàng)目的 README 從第一屏開始就是一大張 Mermaid 圖你會先覺得專業(yè)還是先在心里存一個(gè)疑點(diǎn)我最近在看一類被稱為“autonomous OSS 創(chuàng)作集體”的開源項(xiàng)目時(shí)越來越傾向于后者。并不是說圖不能畫而是當(dāng) Mermaid 的出場率高到某種程度它就不再是一種圖表工具而變成了一種風(fēng)格指紋。你甚至不需要看作者署名只要看到那種節(jié)點(diǎn)密、箭頭多、子圖疊子圖的渲染方式就能猜出背后的流程大概有機(jī)器深度參與。Dex Horthy 在技術(shù)討論里調(diào)侃這個(gè)現(xiàn)象時(shí)很多人的第一反應(yīng)是大笑第二反應(yīng)是“我也見過”。但調(diào)侃底下藏著一個(gè)不太容易消化的結(jié)論流程可以自動化表達(dá)的取舍卻不能全部外包。1. 一句玩笑背后不是 Mermaid 的錯而是文檔正在“通脹”1.1 “autonomous OSS 創(chuàng)作集體”是一個(gè)什么輪廓很多第一次看到“autonomous OSS 創(chuàng)作集體”這個(gè)說法的人會誤以為它是一個(gè)工具名或者某個(gè)具體平臺。更準(zhǔn)確的讀法是把它理解成一種協(xié)作形態(tài)的描述它更像是傳統(tǒng)開源協(xié)作與“自動化內(nèi)容生產(chǎn)”之間的一段光譜。傳統(tǒng)開源項(xiàng)目通常由人主導(dǎo)人寫 issue、人寫代碼、人評審、人維護(hù)文檔。即使有 CI 和輔助工具它們也只是流程中的一部分。而當(dāng)協(xié)作走向“autonomous”那一端時(shí)大量生成、修改、排版甚至發(fā)布環(huán)節(jié)會由腳本或模型完成。創(chuàng)作的內(nèi)容不一定只是代碼也可能是博客、文檔、圖表、新聞稿或?qū)W習(xí)材料。整個(gè)項(xiàng)目本身以開源倉庫的形式存在所以叫“autonomous OSS”。這個(gè)形態(tài)里出現(xiàn)了一個(gè)很有意思的中間詞“open code”。它不只是指開源代碼更指一種表達(dá)方式把創(chuàng)作成果用代碼形式保存下來。文檔不是只讀長文而是倉庫里的 Markdown插圖不是設(shè)計(jì)稿而是可以用文本描述的圖表流程不是口頭共識而是能自動運(yùn)行的腳本和配置。當(dāng)創(chuàng)作過程變成代碼自動化就變得順理成章。問題是機(jī)器最容易生成的文本輸出里有一種東西非常顯眼Mermaid 圖。1.2 Mermaid 為什么會被這種協(xié)作方式選中Mermaid 的優(yōu)勢在今天已經(jīng)不需要科普。它用文本寫圖表天然可以進(jìn)入 git 倉庫它不產(chǎn)生二進(jìn)制圖片diff 時(shí)能看到具體改動它能在 GitHub 等平臺上直接渲染不需要額外設(shè)計(jì)資源對自動化系統(tǒng)來說生成幾十行 Mermaid 代碼的成本遠(yuǎn)遠(yuǎn)低于生成一張布局合理的圖片。所以你會看到幾乎每一個(gè)嘗試做“發(fā)布內(nèi)容自動化”的開源項(xiàng)目都會把 Mermaid 當(dāng)成默認(rèn)可視化語言。但問題也隨之而來當(dāng)幾乎所有候選內(nèi)容都由同一類模型生成并按照同一類 prompt 模板輸出時(shí)產(chǎn)出的圖表風(fēng)格會迅速收斂。收斂不是問題問題在于這種收斂反映的不是某家公司的審美而是一種“機(jī)器認(rèn)為合理”的默認(rèn)值。被調(diào)侃的 Mermaid 渲染風(fēng)格通常長這樣節(jié)點(diǎn)很多每個(gè)組件都要有自己的框箭頭很多但很多箭頭并沒有解釋因果只是表示“這兩個(gè)東西有關(guān)系”子圖很多但子圖邊界常常只是服務(wù)模塊劃分而不是幫助讀者理解問題域圖上沒有明顯主路徑讀者必須自己從一堆分支里找入口和出口。這種圖乍看很完整細(xì)看很空。它不是某個(gè)人的技術(shù)不行而是文檔正在經(jīng)歷一種“通脹”同樣的信息正在用越來越多的視覺單元去表達(dá)。2. 為什么自動化程度越高的項(xiàng)目圖反而更容易雷同2.1 生成器擅長模仿形態(tài)不擅長判斷“讀者此刻缺什么”理解這個(gè)問題的關(guān)鍵是先接受一件事圖不是給作者看的是給讀者看的。作者畫出十個(gè)節(jié)點(diǎn)是因?yàn)樗肋@十個(gè)節(jié)點(diǎn)之間的關(guān)系。機(jī)器生成十個(gè)節(jié)點(diǎn)是因?yàn)樗诖罅坑?xùn)練文本中看到“架構(gòu)圖”往往會包含很多組件。一個(gè)模型可以通過 token 概率推斷出“下一步該畫一個(gè)服務(wù)、一條連線或一個(gè)子圖”但它很難判斷現(xiàn)在的讀者是否需要知道這個(gè)服務(wù)當(dāng)自動化系統(tǒng)承擔(dān)文檔創(chuàng)作時(shí)它最常犯的錯誤是“把所有信息都平鋪出來”。原因不復(fù)雜很多結(jié)構(gòu)生成任務(wù)都會要求模型“完整、全面、不要遺漏”。于是模型把每個(gè)組件都描述出來每條可能鏈路都畫進(jìn)去結(jié)果是一張圖里找不到重點(diǎn)。這不是模型故意把圖變復(fù)雜而是它缺少一個(gè)關(guān)鍵的心智模型讀者現(xiàn)在只需要一個(gè)路徑而不是一張系統(tǒng)全圖。2.2 自動化流程需要可視化“完成證據(jù)”另一個(gè)容易被忽略的原因是激勵結(jié)構(gòu)。在自動化協(xié)作流程里任務(wù)是拆分給機(jī)器去做的。一個(gè) agent 完成一輪生成后需要一個(gè)能被審查者看見的產(chǎn)出物。文字改動常常藏在 PR diff 里不容易一眼看出價(jià)值但一張 Mermaid 圖渲染出來以后會非常醒目地出現(xiàn)在頁面中像一份“我做完了”的證據(jù)。于是工作流會慢慢形成一種激勵不是讓內(nèi)容更精準(zhǔn)而是讓交付物更可見。圖表天然滿足這個(gè)需求。這種激勵結(jié)構(gòu)一旦成立文檔容量會不斷增長。每個(gè)任務(wù)都配上一張圖每個(gè)流程變更都重生成一張圖最后倉庫里的圖越堆越多但信息密度沒有同比例上升。這正是被調(diào)侃現(xiàn)象產(chǎn)生的現(xiàn)實(shí)土壤圖本身不是項(xiàng)目的必需品卻成了自動化產(chǎn)出的“過程證明”。2.3 統(tǒng)一工具鏈會催生統(tǒng)一審美而審美又會反噬表達(dá)當(dāng)同類項(xiàng)目使用同一套生成模板、同一套繪圖工具、同一套 Prompt 框架時(shí)它們產(chǎn)出的圖風(fēng)格高度雷同幾乎是必然的。風(fēng)格趨同是不是壞事不一定。一個(gè)團(tuán)隊(duì)內(nèi)部統(tǒng)一圖表風(fēng)格反而能降低閱讀成本。但當(dāng)整個(gè)技術(shù)社區(qū)都開始用同一種“高密度、去分層、無主次”的方式表達(dá)架構(gòu)時(shí)就會出現(xiàn)一個(gè)副作用讀者不再能從排版和結(jié)構(gòu)中獲得判斷依據(jù)。你看到節(jié)點(diǎn)很多無法判斷它是不是真的復(fù)雜你看到箭頭很密無法區(qū)分關(guān)鍵鏈路和旁支細(xì)節(jié)所有圖都長成一個(gè)樣子于是那些真正需要復(fù)雜度的系統(tǒng)也被淹沒在同樣的視覺噪聲里。這也是調(diào)侃能引起共鳴的原因大家不是在笑某一種配色而是在笑一種“用圖的數(shù)量替代思考的深度”的文檔狀態(tài)。3. 不是圖不夠多而是“語義密度”太低3.1 先看一張“看起來很忙”的 Mermaid 圖下面這個(gè)例子是對一類典型圖表的簡化模仿。你可以只看最終感受不需要糾結(jié)節(jié)點(diǎn)的具體含義flowchart TD A[收集靈感] -- B[生成大綱] B -- C[生成初稿] C -- D{是否通過評審} D -- 否 -- C D -- 是 -- E[生成配圖] E -- F[生成 Mermaid 圖] F -- G[發(fā)布] G -- H[收集反饋] H -- I[生成改進(jìn)計(jì)劃] I -- J[創(chuàng)建新 issue] J -- A這張圖有一個(gè)完整的閉環(huán)也有判斷分支。但它有一個(gè)致命問題它想表達(dá)的信息可能只需要兩句話“創(chuàng)作流程是一個(gè)從靈感到發(fā)布再到反饋的閉環(huán)如果評審不通過就回到初稿重新生成。”這兩句話里沒有任何一個(gè)信息要求你必須看圖才能理解。圖里的每個(gè)箭頭、每個(gè)節(jié)點(diǎn)只是在把原來的文字翻譯成視覺語言并沒有增加新的判斷依據(jù)。這就是典型的“低語義密度”圖。3.2 再看一張只保留核心路徑的圖同樣描述創(chuàng)作流程如果先明確“我要讓一個(gè)新讀者在 30 秒內(nèi)知道內(nèi)容是怎么從起點(diǎn)走到終點(diǎn)的”那這張圖可以變成更短的形式flowchart LR A[選題] -- B[寫初稿] B -- C{評審} C -- 通過 -- D[發(fā)布] C -- 不通過 -- B這張圖的信息量反而更高。它讓人一眼看到入口是選題出口是發(fā)布評審不通過則回到初稿。它沒有畫配圖、反饋、issue、計(jì)劃不是因?yàn)槟切┉h(huán)節(jié)不重要而是因?yàn)樗鼈儾皇恰昂诵穆窂健钡囊徊糠帧H绻x者需要了解完整 SOP可以用文字列出細(xì)節(jié)如果讀者需要理解團(tuán)隊(duì)如何收集反饋可以再單獨(dú)畫一張反饋流程圖。一張圖只解決一個(gè)問題。這是一個(gè)簡單但很有用的原則。3.3 用“語義密度”判斷一張圖是不是多余我建議用一個(gè)不太精確但很好用的指標(biāo)來判斷一張 Mermaid 圖是否值得存在語義密度 讀者真正獲得的結(jié)論數(shù)量 ÷ 圖上所有需要處理的視覺節(jié)點(diǎn)數(shù)量。視覺節(jié)點(diǎn)包括每個(gè)框、每根箭頭、每個(gè)標(biāo)簽。讀者獲得的結(jié)論數(shù)量是指那些“如果他不知道就無法繼續(xù)理解”的信息單元。如果一張圖刪掉一半節(jié)點(diǎn)剩余圖表仍然能回答核心問題那說明被刪掉的部分很可能是裝飾。真正需要保留的節(jié)點(diǎn)通常滿足兩個(gè)條件它改變了讀者對流程或系統(tǒng)的理解它是讀者做出下一步判斷所必需的信息。如果一個(gè)節(jié)點(diǎn)既不改變理解也不影響判斷那它就該被刪掉。這在自動生成場景里特別重要因?yàn)闄C(jī)器默認(rèn)會保留所有與主題相關(guān)的節(jié)點(diǎn)而人必須主動做減法。4. 給 Mermaid 上“護(hù)欄”從畫圖到表達(dá)邊界4.1 畫圖之前先回答四個(gè)問題我自己的習(xí)慣是任何一張 Mermaid 圖合入倉庫之前先回答下面四個(gè)問題。如果回答不流暢就說明圖還不該生產(chǎn)這張圖要給誰看是給用戶、給開發(fā)者、給運(yùn)維還是給新加入項(xiàng)目的人我希望他在 30 秒內(nèi)得出一個(gè)什么結(jié)論這個(gè)結(jié)論能不能用兩三行文字直接表達(dá)如果能為什么還要圖如果只能保留其中的五個(gè)節(jié)點(diǎn)我會保留哪五個(gè)第四個(gè)問題最關(guān)鍵是。它逼著畫圖的人或者生成圖的人做取舍。自動生成往往不考慮取舍它只考慮覆蓋而一張有價(jià)值的圖恰恰是取舍的結(jié)果。4.2 一個(gè)簡易的“Mermaid 體檢表”在實(shí)際項(xiàng)目里硬性規(guī)則很難覆蓋所有真實(shí)場景但一個(gè)參考維度可以提醒你有問題。這里分享一個(gè)我在團(tuán)隊(duì) review 時(shí)常用的體檢表檢查項(xiàng)參考閾值超限后建議動作主圖節(jié)點(diǎn)數(shù)5 到 10 個(gè)超過 10 個(gè)先拆出另一張圖關(guān)鍵分支數(shù)量不超過 2 到 3 個(gè)分支過多說明圖沒有唯一主路徑箭頭標(biāo)簽盡量用“動詞或條件”只寫“數(shù)據(jù)”或“連接”的箭頭要刪除子圖數(shù)量不超過 3 個(gè)超過 3 個(gè)說明讀者需要先理解邊界渲染后的寬度盡量控制在單屏以內(nèi)超寬圖通常是沒有分層的表現(xiàn)這個(gè)表格更像是一份提醒不是一份標(biāo)準(zhǔn)。有些系統(tǒng)圖天生復(fù)雜也確實(shí)需要很多節(jié)點(diǎn)但如果一張圖需要專門花 5 分鐘講解那它不是圖是謎題。4.3 分支多不是問題重點(diǎn)是先有主路徑很多被調(diào)侃的 Mermaid 圖本質(zhì)上不是“復(fù)雜”而是“沒有主路徑”。讀者不知道應(yīng)該從左往右看還是從中間往兩邊看不知道哪個(gè)節(jié)點(diǎn)是入口哪個(gè)節(jié)點(diǎn)是結(jié)果。拆分思路很簡單先畫一張“主路徑圖”只包含從入口到出口的關(guān)鍵步驟把關(guān)鍵分支拆成單獨(dú)圖把非核心細(xì)節(jié)放到文字段落或列表里如果同一張圖需要服務(wù)不同讀者就按照讀者類型拆而不是按組件拆。例如用戶想知道“一次請求會發(fā)生什么”時(shí)不需要看到內(nèi)部部署結(jié)構(gòu)開發(fā)者想知道“組件如何依賴”時(shí)不需要看到完整用戶流程。兩者應(yīng)分別畫圖而不是合成一張。5. 在自動協(xié)同流程里人工守護(hù)應(yīng)該落在哪個(gè)環(huán)節(jié)5.1 先文字后圖示把“理解”留在生成之前如果你處在類似 autonomous OSS 創(chuàng)作集體的協(xié)作模式里最容易犯的錯就是一上來讓機(jī)器生成“結(jié)構(gòu)圖”。自動化系統(tǒng)的能力很強(qiáng)但它對“該畫什么”的理解來自 prompt 指令和訓(xùn)練分布。如果一開始就沒有人明確說清這張圖要解決什么問題最終結(jié)果大概率是“什么都有但什么都不精”。更好的順序是先在 issue 中用文字寫清目標(biāo)讀者和核心結(jié)論用純文字描述流程控制在 100 字以內(nèi)人工確認(rèn)這段文字已經(jīng)準(zhǔn)確再讓機(jī)器根據(jù)這段文字生成 Mermaid 草稿最后復(fù)查圖是否和文字表達(dá)一致。這里的重點(diǎn)是文字模型要先于圖表模型。文字本身就是在建立語義結(jié)構(gòu)如果文字沒有想清楚生成出來的圖只會放大模糊。5.2 把 Mermaid 代碼當(dāng)成代碼來審而不是只做渲染合成在自動化產(chǎn)出場景里Mermaid 圖以文本形式進(jìn)入代碼倉庫所以它也應(yīng)該被當(dāng)成代碼來審查。審查時(shí)不能只看渲染后的畫面“好不好看”。你需要看這次改動為什么動了這張圖新增節(jié)點(diǎn)是否真正帶來了新的判斷是否為了“重新生成一遍”而引入了原本可以避免的布局變化這張圖是否已經(jīng)超出了它最初承擔(dān)的解釋范圍如果一次 PR 只是修改了一行文案卻把整張圖的節(jié)點(diǎn)布局全部重排那說明這張圖的穩(wěn)定性還不夠不應(yīng)該直接合入。自動生成工具可以把圖改得很頻繁但這不一定是優(yōu)化可能是噪聲。如果要加一點(diǎn)技術(shù)護(hù)欄可以用一個(gè)簡單的腳本統(tǒng)計(jì) Mermaid 圖中的節(jié)點(diǎn)數(shù)量和箭頭數(shù)量超過閾值就在 PR 里自動提醒。注意這只能是提醒不是硬性失敗條件因?yàn)樘厥馇闆r下大圖確實(shí)必要。提醒的意義是讓人停下來看一眼而不是直接替代人的判斷。5.3 定期做“圖表清理”比不停新增圖更重要長期維護(hù)的文檔項(xiàng)目最終都會面對同樣的問題圖一旦進(jìn)入倉庫就很少被刪掉。尤其當(dāng)圖表由自動化流程生成時(shí)刪除需要人工判斷而人工最缺的是時(shí)間。我的建議是項(xiàng)目里維護(hù)一個(gè)docs/diagrams/README.md為每張圖寫一行說明它存在的理由。理由不是“描述系統(tǒng)”而是“這張圖幫助讀者弄明白了什么”。如果一張圖已經(jīng)沒有對應(yīng)的流程或者它已經(jīng)被另一張圖覆蓋就可以刪除。刪圖不等于承認(rèn)之前的自動化做得不對而是承認(rèn)文檔是有維護(hù)成本的。長期看文檔倉庫的可靠性和代碼倉庫一樣修剪和新增同樣重要。6. 調(diào)侃的盡頭是一道關(guān)于注意力的選擇題6.1 一個(gè)可復(fù)用的四步閥門面對一張 Mermaid 圖不管是人畫的還是機(jī)器生成的我會用下面這個(gè)四步過濾器決定是否保留它。第一步這個(gè)結(jié)論用文字能說清楚嗎如果能就不強(qiáng)行畫圖。第二步這張圖只服務(wù)一個(gè)核心路徑嗎分支是否超過兩個(gè)刪掉一半節(jié)點(diǎn)后信息還成立嗎第三步合入倉庫前有沒有被一個(gè)項(xiàng)目之外的人看過他能否在 30 秒內(nèi)復(fù)述出這張圖的主路徑第四步未來讀者會不會因?yàn)檫@張圖而更省時(shí)間如果會留下如果不會刪掉。前兩步解決“圖畫得對不對”后兩步解決“圖在該項(xiàng)目里值不值得存在”。這個(gè)過濾器對純?nèi)藢懳臋n、半自動寫作、全自動產(chǎn)出都適用只是執(zhí)行方式不同。6.2 自動化的真正價(jià)值不是讓內(nèi)容變多而是讓內(nèi)容變得可迭代很多人把自動化創(chuàng)作理解成“生成更快、批量更大”。這個(gè)理解并不完整。自動化真正有價(jià)值的地方是它能快速產(chǎn)生候選內(nèi)容并且在系統(tǒng)發(fā)生變化時(shí)批量生成新的版本供人選擇。比如一個(gè)項(xiàng)目的架構(gòu)變了如果圖是用 Mermaid 寫的自動化可以快速更新候選圖然后讓人來決定哪些節(jié)點(diǎn)值得保留、哪些路徑需要突出。機(jī)器負(fù)責(zé)“做得快”人負(fù)責(zé)“選擇得對”這才是人機(jī)協(xié)作更健康的形態(tài)。如果反過來機(jī)器負(fù)責(zé)“選擇保留什么”人只負(fù)責(zé)“接受已經(jīng)渲染好的結(jié)果”那么項(xiàng)目會迅速進(jìn)入一種失去重點(diǎn)的狀態(tài)。所有文檔都在增長所有圖都在更新但沒有一個(gè)人能說出整個(gè)項(xiàng)目最核心的路徑是什么。這是比“圖表風(fēng)格相似”更值得警惕的事。6.3 風(fēng)格背后其實(shí)是工程判斷力一次針對 Mermaid 渲染風(fēng)格的調(diào)侃真正拿出來討論的不應(yīng)該只是“圖好不好看”而是自動化創(chuàng)作軟件如何用更少的表達(dá)解決更多的問題。被記住的文檔風(fēng)格通常不是因?yàn)樗昧硕喔呒壍睦L圖工具而是因?yàn)樽髡吒矣诜艞墶7艞壯b飾性的節(jié)點(diǎn)、放棄多余的箭頭、放棄“為了顯得完整而把所有內(nèi)容都放在一起”的沖動。下次再看到一大張來自自動生成流程的 Mermaid 圖別急著修改配色或調(diào)整連線。先刪掉一半節(jié)點(diǎn)試試。刪完之后如果它的信息仍然成立那張圖就活了刪完之后它頓時(shí)散架那它本來就沒有承載什么。這大概就是那句調(diào)侃真正想提醒我們的事。