這個部落格寫到現在有 43 篇文章,每篇在 frontmatter 裡帶幾個標籤。把所有標籤拉出來數一數,一共 123 個,其中 87 個只用過一次。用得最多的是“AI”(8 篇)和“原始碼分析”(7 篇),後面跟著“Git”“區塊鏈”“成本測算”這些。
我想把這些文章裡的知識點整理成遊戲裡那種知識樹:讀完一篇,樹上亮起幾格;亮了的格子旁邊,又露出幾格可以接著點的。第一個想到的現成辦法是圖書館的分類法,幾百萬本書都分得下,幾十篇文章應該不在話下。
可是圖書館的分類,真的就是那種能點亮的樹嗎?如果不是,差在哪裡?除了圖書館的辦法,還有沒有更合適的?本文就從把文章放進圖書館分類開始,一步步往下看。
一、圖書館分類法
它解決的是什麼問題
圖書館分類法要解決的是一件很實際的事:書架上每本書放在哪。國內的圖書館用《中國圖書館分類法》(中圖法),分 22 個大類,每類一個字母,往下用數字細分,比如 T 是工業技術,TP 是其中的自動化技術、計算機技術,TP3 是計算技術、計算機技術1。國外多用杜威十進分類法,十個大類,三位數字加小數逐級往下,005 是計算機程式設計與軟體,005.8 是資料安全2。
每本書拿到一個分類號,加上作者號就成了書脊上的索書號。書只能放在一個書架上,所以一本書只有一個主分類號,這是圖書館分類最根本的約束。
現象:放進部落格文章以後
我們拿幾篇文章試著歸類。下表的類號是我對照類目表歸的,只到二三級,不是查館藏得來。
| 文章 | 中圖法 | 杜威 | 文章裡的知識點 |
|---|---|---|---|
| TOTP 與 Google 身份驗證器 | TP309 電腦保安,或 TN918 保密通訊 | 005.8 | HMAC、HOTP、TOTP、數字證書、釣魚 |
| Git 伺服器是怎麼工作的 | TP311 軟體 | 005.1 | Git 物件模型、傳輸協議、GitLab、Gerrit、walgit |
| Hyperliquid 為什麼快 | F83 金融,或 TP311 軟體 | 332.4 或 005 | 區塊鏈、共識演算法、訂單簿 |
| 兩個對不上的 HRV 數字 | R33 人體生理學 | 612.1 | RR 間期、SDNN、RMSSD、自主神經 |
| 注意力有彈性嗎 | B84 心理學,或 R33 | 153.7 | 注意資源、HRV、反應時變異 |
| 誰定方向,誰來幹活 | C93 管理學,或 B84 | 658 或 158 | 形式權威與實際權威、失敗預設 |
黃色的格子都是“兩處都說得通”,只能挑一個。
歸完一遍,能看到三個問題。
一篇文章常常跨類。 TOTP 那篇講的是認證,放在電腦保安下面說得通,放在密碼通訊下面也說得通。圖書館有一套規則幫館員挑一個,比如按“主要論述的方面”、按“使用者最可能去哪找”,但挑完之後,另一邊的讀者就找不到它了。中圖法和杜威都允許加“參見”,可那只是一行註釋,不是結構。
粒度停在文章這一級。 分類號給的是整篇文章的位置,而我們要點亮的是文章裡的知識點。TOTP 那一篇裡就有 HMAC、HOTP、TOTP、數字證書好幾個,它們分別屬於不同的小類,一個分類號裝不下。
樹枝的含義是“屬於”,不是“先學”。 TP311 下面掛著 TP311.1、TP311.5,意思是“後者是前者的一部分”。點亮了 TP311,能說明什麼?說明不了我接下來能學什麼。
前兩個問題,後面會看到別的分類體系能補上。第三個問題更根本:遊戲裡那棵樹,樹枝的意思到底是什麼?
二、遊戲裡的知識樹
現象:點亮一格,旁邊才露出幾格
玩過《文明》或者《流放之路》的都熟悉這種介面。《文明》的科技樹裡,一項科技通常要先研究完一兩項前置科技才能開始;《流放之路》的天賦盤上,只能點和已點亮格子相鄰的格子。樹上的位置只是擺放,真正起作用的是格子之間的那條線:這條線說的是“先有 A,才能有 B”。
這和分類樹裡的線不是一回事。分類樹裡,一個節點只有一個父類,線的意思是“B 是 A 的一種”;科技樹裡,一個節點可以有好幾個前置,也可以是好幾條線的共同前置,線的意思是“B 要求 A”。數學上,前者是一棵樹,後者是一張有向無環圖。
分析:同一個知識點在兩種結構裡
拿“雜湊函式”這個知識點看最清楚。Git 用它給每個物件起名字,TOTP 用它算 HMAC,區塊鏈用它把區塊串起來,三篇文章都要先懂它。
左邊的分類樹裡,雜湊函式只能實打實掛在一個分支下,另兩處只剩“參見”。右邊的依賴圖裡,它在最上面,三條線都從它出發。點亮它,對三個方向都有意義;這正是遊戲裡那種“點了這格,好幾處同時解鎖”的感覺。
所以主結構裡必須有一條“先學 A 才能學 B”的邊,而圖書館分類法裡沒有這條邊。 那麼,那些比圖書館更細、更新的分類體系,有沒有這條邊?
三、學科本體與敘詞表
學科本體:一篇標多個概念
學術界的分類體系,最早遇到的就是“一篇跨好幾類”的問題,因為論文比書更專。ACM 的計算機分類體系 ACM CCS 2012 做了兩個改變:一是允許一個概念有多個上位,比如同一個概念既掛在“安全”下,也掛在“網路”下;二是一篇論文可以選好幾個概念,每個標上權重3。在 ACM 的 LaTeX 模板裡,作者這樣寫:
\ccsdesc[500]{Security and privacy~Authentication}\ccsdesc[300]{Security and privacy~Hash functions and message authentication codes}500、300、100 分別是高、中、低三檔相關度4。數學界的 MSC2020 也類似:分三級,63 個兩位大類、529 個三位類、6022 個五位類,每篇論文標一個主分類,再加若干次分類5。
這樣一來,圖 1 裡“兩處都說得通”的問題解決了:TOTP 那篇可以同時標認證和雜湊兩個概念,一高一中。五位一級的類目也細到了知識點的粒度。
但這兩套體系都只管自己的學科:ACM CCS 裡沒有 HRV,MSC 裡沒有 Git。而且它們的邊還是“屬於”,沒有“先學”。
敘詞表:儲存格式和同義詞
把這類概念體系寫成機器能讀的格式,W3C 有一個標準叫 SKOS,ACM CCS 就是用它釋出的。SKOS 裡每個概念有一個首選名、若干別名,概念之間有三種關係:更寬(broader)、更窄(narrower)、相關(related)6。
SKOS 有兩處正好用得上。別名解決了同義詞:“TOTP”“動態口令”“基於時間的一次性密碼”是同一個節點,讀者搜哪個都能落到這裡。多重上位也允許一個概念掛在幾個上位下面。
可是三種關係裡,related 是對稱的:寫了 TOTP 相關 HOTP,就等於也寫了 HOTP 相關 TOTP,看不出誰先誰後。broader 是“屬於”,也不是“先學”。要表達“先學 HOTP 才能學 TOTP”,只能像圖 3 下面那樣,自己加一個 ex:requires 屬性。SKOS 適合做儲存格式,不適合當主結構。
學科本體和敘詞表都還是在同一個方向上把分類做細。還有一種思路換了方向:與其給一篇文章挑一個位置,不如承認它同時站在好幾個維度上。
四、刻面分類
現象:標籤裡混著幾種東西
回頭看開頭那 123 個標籤,裡面其實混著幾種性質不同的詞。“Git”“Prometheus”“HRV”說的是文章講的物件;“原始碼分析”“成本測算”“回測”說的是文章的做法;“入門”說的是讀者的起點。它們被放在同一個平鋪的列表裡,所以才會長到 123 個,而且大部分只用一次。
原因與解決:把維度分開
印度圖書館學家阮岡納贊在 1933 年提出冒號分類法,第一次把這件事系統化:一本書不再放進預先排好的格子,而是在幾個基本範疇上各取一個值,再組配起來。他的五個範疇是本體、物質、動作、空間、時間,簡稱 PMEST7。後來的 UDC 也允許用冒號把兩個類號組配成一個8。
把部落格標籤按這個思路分開,就是下表。
| 文章 | 物件 | 做法 | 中圖法大類 |
|---|---|---|---|
| Git 伺服器是怎麼工作的 | Git、GitLab、Gerrit | 原始碼分析 | TP |
| E2B 和 Docker 是什麼關係 | E2B、Docker | 原始碼分析 | TP |
| 租雲 GPU 轉賣大模型 API | GPU、大模型 API | 成本測算 | F |
| 幾十美元的小盒子跑大模型 | 邊緣裝置、記憶體頻寬 | 成本測算 | TP |
| 去中心化推理 | llama.cpp RPC | 成本測算 | TP |
| 納指 ETF 的時差利差 | 513100、溢價 | 回測 | F |
按“做法 = 成本測算”篩,會同時拿到 TP 和 F 兩個大類裡的文章。
刻面讓“一篇跨幾類”不再是問題:它本來就該在幾條軸上各有一個值。想看所有成本測算類的文章,按做法篩一下就行,不必管它們在中圖法裡分屬 TP 和 F。
但刻面之間是正交的,沒有先後。“物件 = Git”和“做法 = 原始碼分析”是兩個並列的維度,誰也不是誰的前置。刻面是很好的篩選器,可它同樣不產生“點亮這格才能點那格”。
到這裡,幾種分類方式都試過了,它們回答的都是“這個東西在哪、屬於什麼”。要找“先學什麼”這條邊,得去看研究學習本身的理論。
五、前置依賴:知識空間理論
它在回答什麼問題
1985 年,Jean-Paul Doignon 和 Jean-Claude Falmagne 提出了知識空間理論9。他們關心的問題是:怎樣用盡量少的測驗題,弄清一個學生到底會什麼?
他們的出發點很簡單。把一個領域拆成一組知識項(比如一道道代數題),一個人會的那些項組成一個集合,叫他的知識狀態。關鍵在於,並不是任意一個集合都可能是某人的狀態:一個會解二次方程、卻不會解一次方程的學生,幾乎不存在。項和項之間有前置關係,只有“前置都在、自己才在”的集合才是合法的狀態。
在這個框架裡,有兩個概念正好對上游戲裡的點亮10:
- 外緣(outer fringe):還沒掌握、但前置都已掌握的項。加上任何一個,仍然是合法狀態。這就是“下一步能點亮的格子”。
- 內緣(inner fringe):已掌握、而且沒有別的已掌握項依賴它的項。去掉它,狀態仍然合法。這大致是“最近點亮的末梢”。
商業化的自適應學習系統 ALEKS 就建立在這個理論上:先用一輪測驗估出學生的知識狀態,再從外緣裡挑下一道題。
用部落格文章試一試
我從十幾篇文章裡抽了 20 個知識點,分到系統、安全、Git、區塊鏈、健康五個區域,再給每個點寫上前置。假設一個讀者讀完了 tmux 那篇、HRV 那篇的前一半、Git 伺服器那篇的第一節、TOTP 那篇的 HMAC 部分,點亮的就是圖 5 裡實心的七格。
外緣不用人去數,寫一個小指令碼就能算。依賴關係寫成 YAML,每個節點一行:
# region 只管画在地图哪一块,requires 才决定能不能点亮- {id: 哈希函数, region: 基础, requires: [], from: [git-server-from-clone, totp-google-authenticator]}- {id: HMAC, region: 安全, requires: [哈希函数], from: [totp-google-authenticator]}- {id: HOTP, region: 安全, requires: [HMAC], from: [totp-google-authenticator]}- {id: Git对象模型, region: Git, requires: [哈希函数], from: [git-server-from-clone]}- {id: 区块链, region: 区块链, requires: [哈希函数], from: [hyperliquid-speed]}# ……共 20 个节点指令碼做三件事:檢查依賴裡沒有環(有環就沒法點亮),檢查已點亮的集合是否合法,再算出外緣和內緣。
import sys, yamlnodes = {n["id"]: n for n in yaml.safe_load(open(sys.argv[1]))}lit = set(sys.argv[2].split(","))
# 依赖必须是一张无环图:拓扑排序走不完说明有环seen, order = set(), []def visit(i, path=()): if i in path: sys.exit(f"环:{' → '.join(path + (i,))}") if i in seen: return for r in nodes[i]["requires"]: visit(r, path + (i,)) seen.add(i); order.append(i)for i in nodes: visit(i)
bad = [i for i in lit if not set(nodes[i]["requires"]) <= lit]print("点亮不合法(前置没亮):", bad or "无")fringe = [i for i in order if i not in lit and set(nodes[i]["requires"]) <= lit]print(f"已点亮 {len(lit)}/{len(nodes)}")print("下一步能点亮(外缘):", "、".join(fringe))inner = [i for i in order if i in lit and not any(i in nodes[j]["requires"] for j in lit)]print("最近点亮的末梢(内缘):", "、".join(inner))執行結果:
$ python3 fringe.py tree.yaml 进程与信号,tmux,哈希函数,HMAC,Git对象模型,RR间期,SDNN与RMSSD点亮不合法(前置没亮): 无已点亮 7/20下一步能点亮(外缘): 容器隔离、HOTP、Git传输协议、区块链、HRV最近点亮的末梢(内缘): tmux、HMAC、Git对象模型、SDNN与RMSSD這五格外緣裡,四格指向一篇讀了一半的文章(HOTP 在 TOTP 那篇,Git 傳輸協議在 Git 伺服器那篇,HRV 在 HRV 那篇,容器隔離在 E2B 那篇),區塊鏈則指向一篇還沒讀過的 Hyperliquid。這就是“下一篇讀什麼”的推薦。
知識空間理論給了點亮一個精確的含義。不過它的知識項是一道道能判對錯的題,而一個知識點“亮了”又該怎麼判?讀過一遍算不算?
六、點亮的程度
現象:讀過和會用不是一回事
讀完 TOTP 那篇,大概能說出“六位數是用時間算出來的”;但要自己寫程式碼算出和手機上一樣的六位數,又是另一回事;再往上,是能說清 TOTP 和簡訊驗證碼、通行金鑰各自防住了什麼。三個人都“讀過”這一篇,掌握的程度差得很遠。遊戲裡也常這樣處理:同一個天賦可以點一級、二級、三級。
解決:用 Bloom 分類給節點分級
教育學裡描述“掌握到什麼程度”的經典框架是 Bloom 的認知目標分類。2001 年的修訂版把它分成六級:記憶、理解、應用、分析、評價、創造11。六級對一個個人知識樹來說太細,合併成三級更好用。
| 等級 | Bloom 層級 | 在 TOTP 上意味著 | 怎麼檢驗 |
|---|---|---|---|
| 一級 | 記憶、理解 | 說得出 TOTP 把時間切成 30 秒一段,用段號代替 HOTP 的計數器 | 解釋為什麼手機開著飛航模式也能出碼 |
| 二級 | 應用 | 拿一個金鑰和當前時間,自己算出那六位數 | 寫二十行程式碼,結果和身份驗證器對上 |
| 三級 | 分析、評價、創造 | 說得清 TOTP、簡訊驗證碼、通行金鑰各自防住了什麼 | 給一個登入場景選方案,並說出理由 |
每一級都配一個能判對錯的檢驗,這就回到了知識空間理論“知識項是題目”的要求。
分級以後,前置關係也可以寫得更細:學 TOTP 要求 HOTP 至少一級,而要把 TOTP 點到二級,可能就要求 HMAC 也到二級。
Bloom 分類本身不能當主結構:它對每個節點都是同樣的幾級,是一條縱向的刻度,不是一張圖的骨架。
七、各自的位置
一個節點長什麼樣
到這裡,前面幾種方式各自擅長的地方已經清楚了。它們不是互相替代,而是可以同時出現在同一個節點上,各管一件事。
幾個欄位裡只有 requires 決定樹的形狀。改掉 region,節點只是換個地方畫;改掉 requires,能點亮的順序就變了。
對照:各方案回答什麼問題
| 方案 | 回答的問題 | 邊的含義 | 在知識樹裡 |
|---|---|---|---|
| 圖書館分類(中圖法、杜威、UDC) | 放在哪 | 屬於(單一父類) | 地圖分割槽 |
| 學科本體(ACM CCS、MSC2020) | 屬於哪些主題 | 屬於(可多個) | 某個分割槽要細分時參考 |
| 敘詞表(SKOS) | 叫什麼,和誰有關 | 更寬、更窄、相關 | 儲存格式、同義詞 |
| 刻面分類 | 從哪幾個角度看 | 無(正交的軸) | 篩選 |
| 知識空間理論 | 先學什麼 | 要求(有向、無環) | 主結構 |
| Bloom 分類 | 掌握到什麼程度 | 無(每個節點的刻度) | 節點等級 |
分割槽用哪一套
剩下一個實際問題:地圖分割槽用什麼?可以自己起名字,但我更建議直接借中圖法的大類或二級類,像圖 7 裡那樣在 region 後面記下對應的類號。原因有兩個:分割槽隻影響佈局,用一套現成的、大家都熟的劃分,不必為“這一塊叫什麼”反覆糾結;以後想和別人的知識樹或者圖書館的書目對接,類號就是現成的介面。分割槽不必細,部落格現在的文章,十個以內的區域就夠了。
八、回到圖書館分類法
回到開頭那個念頭:圖書館分類法能不能當知識樹的主結構?
能用,但只能用在一個地方:地圖的分割槽。它把世界上的知識分成了大家都認得的幾塊,這對“這一格畫在哪”很有用。可它的樹枝是“屬於”,一個知識點只能掛一處,它不知道雜湊函式要先於 HMAC,也不知道 HMAC 要先於 HOTP。遊戲裡那種點亮的感覺,全來自“先有 A,才有 B”這條邊,而這條邊只能從知識本身的依賴裡來,需要我們一條條寫出來。
寫依賴邊比給文章挑分類號費事得多。一個可行的起點是在每篇文章的 frontmatter 裡多寫兩行:這篇教了哪些知識點(teaches),讀之前最好會哪些(requires)。文章就像遊戲裡的任務,完成一個任務,點亮一組節點。
小結
- 圖書館分類法放得下部落格文章嗎?放得下,但一篇常跨兩個大類,分類號只到文章,進不到知識點,樹枝的意思是“屬於”而不是“先學”。
- 遊戲裡的知識樹是什麼結構?是一張前置依賴的有向無環圖,一個節點可以有多個前置和多個後繼。“雜湊函式”就同時是 Git、TOTP、區塊鏈三條線的起點。
- 學科本體和敘詞表補上了什麼?ACM CCS 和 MSC 允許一篇標多個概念,粒度也更細;SKOS 給了儲存格式和同義詞。但它們的邊仍然是“屬於”和對稱的“相關”。
- 刻面分類補上了什麼?把“講什麼”和“怎麼做”拆成正交的軸,篩選能橫穿大類,但軸之間沒有先後。
- “點亮”的精確含義是什麼?知識空間理論的外緣:前置都已掌握、下一步能學的項。寫成 YAML 加二十幾行指令碼就能算出來。
- 點亮的深淺怎麼分?用 Bloom 分類合併成三級,每級配一個能判對錯的檢驗。
- 主結構用什麼?用知識點之間的前置依賴圖;圖書館分類退為地圖分割槽,刻面做篩選,Bloom 做等級,SKOS 做儲存。
參考資料
參考資料
-
中國圖書館分類法(第五版)clc.nlc.cn ↗五個基本部類、22 個大類,類號由字母和數字組成,如 TP 自動化技術、計算機技術http://clc.nlc.cn/ ↩
-
Dewey Decimal Classificationoclc.org ↗十個大類,三位數字加小數逐級細分,如 005.8 資料安全、612.1 血液與迴圈生理https://www.oclc.org/en/dewey.html ↩
-
The 2012 ACM Computing Classification Systemacm.org ↗多重上位的概念體系,以 SKOS 格式釋出;論文作者為每篇論文選多個概念https://www.acm.org/publications/class-2012 ↩
-
acmart: Class for typesetting publications of ACMctan.org ↗
\ccsdesc[500]{...}給概念標權重,500 / 300 / 100 對應 High / Medium / Lowhttps://ctan.org/pkg/acmart ↩ -
Mathematics Subject Classification 2020 (MSC2020)msc2020.org ↗三級:63 個兩位類、529 個三位類、6022 個五位類,如 11G15;論文標一個主分類加若干次分類https://msc2020.org/ ↩
-
SKOS Simple Knowledge Organization System Referencew3.org ↗
skos:broader/skos:narrower/skos:related、skos:prefLabel/skos:altLabel;skos:related是對稱關係,skos:broader本身不傳遞,另有skos:broaderTransitivehttps://www.w3.org/TR/skos-reference/ ↩ -
Colon Classificationen.wikipedia.org ↗第一個系統的刻面分類法;五個基本範疇 PMEST:本體(Personality)、物質(Matter)、動作(Energy)、空間(Space)、時間(Time)https://en.wikipedia.org/wiki/Colon_classification ↩
-
Universal Decimal Classificationudcc.org ↗在杜威基礎上發展而來,可以用冒號
:把兩個類號組配成一個https://udcc.org/ ↩ -
Spaces for the assessment of knowledgedoi.org ↗知識狀態是一個人能解出的題目的集合;知識空間是可能的知識狀態組成的族,對並運算封閉https://doi.org/10.1016/S0020-7373(85)80031-6 ↩
-
Knowledge Spaces and Learning Spacesarxiv.org ↗外緣(outer fringe):再加上就仍是合法狀態的項,即下一步準備好學的;內緣(inner fringe):去掉後仍合法的項;學習空間裡一個狀態由它的兩個緣唯一確定。ALEKS 據此推薦下一步https://arxiv.org/abs/1511.06757 ↩
-
A Revision of Bloom's Taxonomy: An Overviewdoi.org ↗修訂版六級:記憶、理解、應用、分析、評價、創造;完整版見 Anderson & Krathwohl (2001) A Taxonomy for Learning, Teaching, and Assessinghttps://doi.org/10.1207/s15430421tip4104_2 ↩