Open source

上線前擋下來的 五道檢查。

contentgate 是我們自己每天在用的守門工具。每一道檢查都是在某件事已經上線、並且付出代價之後才寫的。現在用 MIT 授權開源。

唯一的設計原則

沒被證明失敗過的守門,只是裝飾。

每一道檢查都附負面測試 —— 它被要求必須擋下來的輸入。測試會在給出任何結論之前先跑一次,如果測試沒過,程式直接退出而且不對你的內容發表意見。一個沒辦法證明自己還抓得到已知錯誤的檢查器,沒有資格告訴你網站沒問題。

這不是理論。我們寫過的守門包括:一個把關鍵字讀進頁尾共用區塊、因此每頁都放行的;一個被放在「重新產生它要檢查的檔案」那一步之後才跑的;還有一個退出碼被 shell 吃掉、所以一邊印「擋下部署」一邊讓部署繼續跑的。三個看起來都很正常。三個都是靠「故意叫它失敗」抓出來的。

五道檢查

目標關鍵字覆蓋

文章把題目寫完了,卻始終沒出現真正有人在搜的那個詞。比對一律逐字,不做空白正規化 —— 有空格跟沒空格是兩個不同的字串,搜尋量也不同。

翻譯結構走鐘

譯稿在結構上已經不是同一份文件:表格少一列、價格數字被改掉、站內連結掉了語系前綴,讀者一點就被丟回原文站。

內容頁的商業內鏈

一篇排得上、也有人讀的指南,卻把人送不到任何地方,因為全文唯一的商業連結長在每頁都有的共用 CTA 裡。所以這道檢查只看正文,不看共用區塊。

績效宣稱

金融、博弈、醫療類文案把結果講成事實會被拒登。難的不是抓到那個詞,是不要對「我們不做保證獲利宣稱」這種免責句誤判。

sitemap 日期誠實

每次建置把今天的日期蓋在每一個網址上,是每天說一次的謊。正解是內容雜湊狀態機:內容真的變了,日期才動。

怎麼做的

兩份實作。Python CLI 卡在部署前面,退出碼就是契約;MCP server 讓 AI 在寫稿當下就檢查,而不是等頁面已經上線。

兩邊共用同一個測試檔,而且被要求對每一個案例給出完全一樣的判定。CI 會逐案比對,只要有一項不一致就是其中一邊走鐘了,直接擋下。

拿去用

MIT 授權,Python 端零相依套件,只用標準函式庫。

git clone https://github.com/adsandcode/contentgate
cd contentgate
python -m contentgate init      # 產生設定檔
python -m contentgate check     # 跑檢查

退出碼就是契約:0 全過、1 你的內容沒過、2 守門自己的負面測試沒過(所以它不對你的內容發表意見)。接在部署前面,接住退出碼就會擋下部署。

同一套檢查也做成了 MCP server,讓 AI 在寫稿當下就查,而不是等頁面上線之後:

npx mcp-server-contentgate

六個工具:關鍵字覆蓋、翻譯結構、商業內鏈、績效宣稱、sitemap 日期、內容雜湊。每個都是純函式,內容進去、判定出來,不碰檔案、不連網路、不寫任何東西。啟動時會先跑自己的負面測試,沒過就拒絕啟動。

GitHubnpm

相關的實作筆記

這些檢查背後的問題,我們都寫成過文章:

sitemap lastmod 天天說謊怎麼修 關鍵字自食:35 個字散在 6 頁的real case 新站零收錄先查 canonical 你的網站可能正在燒掉抓取預算

需要有人幫你把這些做完

這些檢查是我們日常交付的一部分。如果你的站需要有人從頭把地基做對,把情境講給我們聽。

用 Telegram 聊需求
TG 聊需求