為什麼會做這個
我幫網站做 SEO 體檢時,發現一個尷尬的事:我的文章標題寫得太「文案」了。
例如這篇:
「空拍機與病蟲害視覺辨識:你的 24 小時免費植物醫師」
讀者覺得有趣,但 Google 抓不到核心關鍵字「農業 AI」「植物醫生」。搜「農業 AI 教學」找不到我——白寫。
問題是我有 195 篇文章,人工檢查不可能。我需要一個工具:
- 掃過全站
- 從每篇標題抽出主關鍵字
- 檢查這個關鍵字有沒有出現在 description、前 300 字
- 標記出有問題的文章
為什麼不用現成工具?
中文 SEO 的悲慘現實:
| 工具 | 中文支援 |
|---|---|
| Yoast SEO | ❌ 假裝有 |
| SEMrush | ⚠️ 簡體尚可,繁體很差 |
| Ahrefs | ⚠️ 同上 |
| Screaming Frog | ❌ 不檢查內容質量 |
而且這些工具都假設你站在 WordPress 上。我用 Astro,所有內容是 .md,要套這些工具還得先架一個 staging server。寫 100 行 Node 比較快。
中文最大的坑:沒有空格
英文 SEO 工具能做的事,大半建立在「文字用空格切詞」這個假設上。中文沒有空格——這是中文 NLP 第一道難題。
正規解法是用 jieba(結巴分詞),但這需要安裝 Python、載 200MB 詞典、跑模型。對一個 build-time 腳本太重了。
我的啟發式做法:取標題前 2 個 CJK 字符當主關鍵字。
function extractPrimaryKeyword(title) {
let head = title.split(/[::((]/)[0]; // 1. 截到第一個冒號/括號之前
head = head.replace(/AI/gi, '') // 2. 去掉「AI」這個無意義詞
.replace(/[「」『』,,。!!??\s+]/g, '');
while (head.length && STOP.has(head[0])) { // 3. 去掉開頭的停用字
head = head.slice(1);
}
const m = head.match(/[\u4e00-\u9fa5]{2}/); // 4. 抓第一段連續 2 個 CJK 字
return m ? m[0] : head.slice(0, 2);
}
例子:
- 「會計的 AI 實戰指南」→
會計 - 「製造業 AI 工廠」→
製造 - 「空拍機與病蟲害視覺辨識」→
空拍(這個有點偏,但比拿整段更實用)
這個 heuristic 不完美,但目的不是學術研究,是「對啦你這篇 description 沒寫核心關鍵字」這種粗暴提醒。夠用就好。
評分邏輯
function score(article) {
const kw = extractPrimaryKeyword(article.title);
const head = article.body.slice(0, 300);
const issues = [];
if (!article.description.includes(kw))
issues.push(`description 缺主關鍵字「${kw}」`);
if (!head.includes(kw))
issues.push(`前 300 字未出現「${kw}」`);
if ([...article.title].length > 35)
issues.push(`title 過長 (SERP 約 30 字截斷)`);
if ([...article.description].length > 80)
issues.push(`description 過長`);
if ([...article.description].length < 30)
issues.push(`description 過短`);
if (issues.length === 0) return 'PASS';
if (issues.length === 1) return 'WARN';
return 'FAIL';
}
真實結果
SEO Health Check — 195 articles scanned
PASS 69 WARN 67 FAIL 59
第一次看到這個數字我嚇了一跳。59 篇 FAIL——也就是 30% 的文章在 SEO 上是裸奔的。
最常見的 FAIL 模式:標題寫得很「文青」,description 直接抄標題的延伸,結果主關鍵字一次都沒出現在前 300 字。
例如:
[FAIL] career/ai-arch-bidding.md (kw: 公共)
公共工程標單與估價解析:三秒破解巨型 RFP 招標書
· description 缺主關鍵字「公共」
· 前 300 字未出現「公共」
這篇文章內容講「建築業如何用 AI 解 RFP」,但整篇前 300 字都在講「我的客戶痛苦的故事」,等講到「公共工程」已經是第 4 段了。Google 看不到。
學到的事
- 不要假設「中文 SEO 工具」存在。它不存在。或者存在但很爛。最快的解法是寫 100 行 Node。
- 啟發式 > 完美 tokenizer。我花 30 分鐘寫的「取前 2 個 CJK 字」雖然粗糙,但它真的能跑 195 篇文章 並標出 59 個問題。完美的中文分詞器需要花一週搞定。
- 「文案感」與「SEO 友善」是 trade-off。我的標題寫得讓人想點,但 Google 看不到。正確做法不是放棄文案感,而是兩個都要:標題前半放關鍵字,後半放文案。例:「會計 AI 實戰:用 ChatGPT 把月結從 4 小時變 30 分鐘」。
- 零依賴工具是長期資產。這個腳本沒有 npm install 任何東西,只用 Node 內建模組。三年後我重灌電腦、換 Node 版本、刪 node_modules,它都還能跑。
接下來要做的事
- 把 59 篇 FAIL 文章逐篇修 description(這是 SEO 報酬率最高的單一行動)
- 加
--fixflag,讓腳本自己提議新的 description(餵給 LLM 改寫) - 整合到 CI:PR 如果引入新的 FAIL 文章就 block
原始碼在
scripts/seo-check.mjs。100 行,零依賴,可直接 fork 套到你的 Astro 站。