跳至主要內容

開發紀錄

延伸閱讀如何從穩定 metadata 自動產生

沿著本站的延伸閱讀規則,拆開發布資格、語言、tags 計分與排序,說明自動清單能減少哪些重複工作,又有哪些編輯判斷不能交給分數。

林予晴
發布
  • Astro
  • 內容工程
  • Metadata
  • 排序

文章末尾的延伸閱讀,會把讀者帶到下一個問題。如果每一篇都手寫一份清單,新增文章之後,就得再決定哪些舊文章應該補上它;文章越多,這份人工對照也越容易漏掉。

本站先用文章已經有的 metadata 產生候選,再以固定規則選出少量文章。我在意的是這套規則能不能說清楚:一張卡片為什麼出現在這裡、哪些內容絕對不能進來,以及當結果不理想時,應該回頭檢查什麼。它不需要假裝理解了文章全文。

以下依 2026 年 10 月 25 日的實作與本機輸出說明。這是一個以分類、tags 和日期排序的小型規則,不是依讀者行為訓練的推薦系統。

先決定哪些文章有資格被推薦

發布資格和相關程度,是兩個不同的問題。

文章頁先呼叫 getPublishedNotes(locale),取得該語言可公開的文章。這一層會排除草稿、缺少發布日期,以及發布日期晚於台北當天的內容;接著才把集合交給 selectRelatedNotes()。

後者再排除兩種候選:語言和目前文章不同,或 stableId 與目前文章相同。因此,延伸閱讀不會把自己列進去,也不會為了湊滿卡片而突然帶出另一種語言。

這個分工有一個需要記住的限制:selectRelatedNotes() 本身不檢查草稿與發布日期。若別的使用位置直接把全部文章交進來,它不會替呼叫者補上發布過濾。我用受控資料確認過這個差異,所以不能只看到函式名稱,就把它當成安全的公開查詢入口。

首頁、列表、文章頁與 sitemap 為什麼要共用發布查詢談的是同一組公開資格。延伸閱讀接在這組資格之後,才開始回答「先放哪幾篇」。

分數來自分類與相同的 tags

目前每一個候選的分數是:

同分類加 3 分,每一個相同 tag 加 2 分。

這裡的「相同」是字串相同,沒有大小寫轉換、同義詞整理或語意分析。Astro 和 astro 不會被當成同一個 tag;標題裡即使出現同一個技術名稱,也不會因此得到 tag 分數。

假設三個候選都和目前文章同分類,計分結果如下。這是用來解釋規則的受控例子,不是三篇真實文章的成效比較。

候選情境 分類分數 tags 分數 總分
有兩個相同 tags,發布較早 3 4 7
有一個相同 tag,發布較新 3 2 5
沒有相同 tag,發布最新 3 0 3

第一個候選仍然排在前面。日期只會在分數相同時決定先後,不會讓較新的文章直接越過分數較高的文章。

本站目前的分類只有 development,所以同語言候選的分類分數都是一樣的。現階段真正拉開分數的主要是 tags;保留分類權重,不代表網站已經建立多分類推薦,也不能把這個權重說成經過讀者研究的最佳比例。

同分之後,還需要可預期的順序

排序依序比較分數、publishedAt,最後才比較 stableId。同分時,新發布的文章在前;連發布時間都相同,才以穩定識別字打破平手。

我把兩個同分、同發布時間的候選放進受控集合,確認它們最後依 stableId 排序;也確認函式不會改動傳入集合的原始順序。這些檢查是在核對排序契約,不是在證明哪個候選比較值得讀。

穩定的順序讓結果比較容易追查。若某張卡片換了位置,可以回頭看 tags、日期或候選集合是否改變,而不是先猜測是不是推薦系統「有自己的想法」。

不必湊滿,也不代表一定高度相關

函式預設最多取兩篇。有多少合格候選,就從排序後的集合取多少,不會複製同一篇來補位置。文章版型也只在清單非空時輸出延伸閱讀區塊;草稿預覽則直接不建立這份清單。

但目前沒有最低分數門檻。即使沒有相同 tag,只要仍在候選集合裡,也可能被選中。以現在只有一個分類的狀態來說,這種候選還是會拿到相同的分類分數,接著靠日期排序。

所以「卡片出現了」只能解讀成它通過目前的候選與排序規則,不能解讀成它已被確認為最適合的下一篇文章。若文章量繼續增加,低關聯候選反覆出現,才有理由評估最低門檻或人工指定;不需要先替未出現的問題加上一整套設定。

自動清單仍然有編輯責任

tags 一旦參與排序,就不只是文章上方的裝飾文字。調整 tag 拼法,可能改變哪些文章彼此靠近;隨意加上一批過於寬泛的 tags,也可能讓原本不同的題目看起來一樣相關。

我會先檢查文章真正回答的問題,再決定 metadata 要不要改。如果兩篇都談「驗證」,一篇教讀者檢查發布輸出,另一篇談 AI 誤判後如何撤回結論,它們可以共享某個 tag,但不因此成為同一篇文章的替代品。

這套規則目前不讀全文,不追蹤點擊、不辨識先備知識,也不保證先推薦入門篇再推薦進階篇。需要一條明確閱讀路徑時,正文裡有理由的文章連結,仍然比一份自動清單更能交代為什麼要往那裡讀。

更新 metadata,也會改變下次建置的結果

延伸閱讀是在 Astro 產生文章 HTML 時決定,卡片本身是一般連結,不必等瀏覽器再向推薦服務取資料。相對地,新增文章、調整 tags 或改變發布資格之後,既有靜態頁面的清單也要隨重新建置與部署才會更新。

本機核對時,我用實際的公開集合計算預期清單,再比對 HTML 語意篇三語文章頁的兩張卡片與順序,結果相符。這能證明選定頁面的輸出接上了目前規則;沒有點擊分析,也就不能順便說這樣的推薦增加了閱讀量。

我會先維持這份能解釋的清單。等到有具體的錯配案例,再判斷是 metadata 不準、排序規則不足,還是讀者其實需要一條人工安排的閱讀路徑。