Skip to content

Latest commit

 

History

40 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

中文 · English

YAEO — Yet Another Engine Optimization

又一個引擎優化。差別是:每條規則都附出處。

SEO → AEO → GEO → LLMO,縮寫每季都在增加。這個 repo 不打算再發明一個, 它只做一件事:把「網站對搜尋引擎與 AI 引擎的可見度」變成可以逐條檢查、 而且每條都查得到依據的東西。

Search Engine Optimization(SEO)、Answer Engine Optimization(AEO)、 Generative Engine Optimization(GEO)、Large Language Model Optimization(LLMO) ——四個縮寫講的是同一件事的不同切面:那台機器看不看得見你的內容、讀不讀得懂、 願不願意引用。 差別只在「那台機器」是搜尋引擎、問答引擎,還是語言模型。


為什麼再做一個

市面上的 SEO skill 很多,但有兩個常見問題:

① 無來源的百分比宣稱。 「加上 FAQ schema 可提升 30% 點擊率」這類數字大量流傳, 往回追常常找不到任何原始研究。本 repo 的規則要嘛來自 Google 官方文件, 要嘛來自同行評審論文,要嘛明白標示「從業共識,證據弱」。 不確定的規則寧可標弱,不要加數字。

② 用英文的門檻檢查中文網站。 <title> 60 字元、description 160 字元 是英文的經驗值。套到中文會把一整批正常的標題判成過長——中文的資訊密度不同。 本檢核器偵測中日韓字元比例後切換門檻。

同一個「兩種語言的基準本來就不對稱」也用在別處。L1-LANG-CONTENT-MISMATCH 比對「宣告的語言」與「正文實際的語言」,而它的判準刻意單向:宣告英文卻整塊 中日韓可以報,宣告中文卻整塊拉丁不能報——中文頁出現品牌名、程式碼、縮寫 是常態,反向套用會整批誤判。


LLMO 有幾條規則?0 條

不是漏了。查過了(2026-08-17),結論是沒有可以當依據的實證。

① 同行評審文獻裡的 LLMO 是另一件事。 arXiv 上 LLMO 指的是 Large Language Model Optimizer,也就是「用 LLM 去做最佳化」的方法: 黑箱網路管理最佳化(2507.02689)、 對抗式強健性架構搜尋(2406.05433)。 跟網站可見度無關。

② 回顧 45 篇研究(2023-11~2026-07)的批判性綜述,全文沒有出現 LLMO2607.14035)。一份回顧整個領域三年的綜述 完全不提這個詞,是相當強的反面證據。

③ 以「為 LLM 回答優化內容」這個意思使用 LLMO 的內容,目前全是廠商部落格, 而它們流傳的數字正好是本 repo 開頭反對的那一類:「原創統計數據可提升 30–40% 可見度」、「AI 搜尋來的訪客價值是自然搜尋的 4 倍」——往回追都找不到原始研究。

底層那個問題(內容怎麼被 LLM 撈到、讀懂、引用)確實有文獻,但它們一律歸在 GEO/AEO 之下,已經由 L3-GEO-*SITE-* 涵蓋。 LLMO 不是一個缺口,是同一批研究的另一個行銷標籤。

所以規則按「看不看得見、讀不讀得懂、願不願意引用」來分,不按縮寫分。 再多幾個縮寫,這個分法也不用改。

完整查證紀錄(跑過的查詢、否決理由、要重看的條件)在 watch/investigated.json。 留紀錄的目的是不要重複搜:沒通過門檻的東西如果不寫下來,下一個人會把 同一輪搜尋再跑一次,而且看不到上次否決的理由。 sources.json 記的是通過門檻的出處,這一份記的是沒通過的。


內容

路徑 是什麼
skills/seo-aeo-audit/ Claude Code skill:四層檢核 + 59 條規則(L1 13/L2 29/L3 4/SITE 13)
skills/seo-aeo-audit/scripts/seo-check.mjs 零相依的靜態檢核器(Node,不需 npm install)
skills/seo-aeo-audit/scripts/psi-check.mjs PageSpeed Insights 包裝(需自己的 API key)
skills/seo-aeo-audit/test/ 回歸測試。只有判準出過問題的規則才有,理由見〈哪些規則值得寫測試〉
watch/ 定期檢索:出處是否失效、爬蟲清單是否變動、生態是否有新縮寫

每一條規則的完整索引在 skills/seo-aeo-audit/SKILL.md 的〈完整規則索引〉 ——代碼、級別、是什麼,一條不漏,不必去讀 45 KB 的腳本。

「59」數的是不重複的規則代碼,而且test/rule-index.test.mjs 守著—— 新增規則卻沒補進索引,測試會失敗並指名漏了哪幾條。

⚠ 這個守衛是補的。索引第一版宣稱「一條不漏」卻漏了 4 條,因為當時的抽取腳本 只認 add('warn', 'CODE',把所有嚴重度隨條件變動的規則 (add(isNoindex ? 'info' : 'warn', 'CODE')整類漏掉——而驗證腳本共用同一個 假設,於是「雙向驗過」得到的通過毫無意義。用有相同盲點的工具驗證,等於沒驗。

四層架構

內容 判定
L1 技術基礎 title/description/canonical/OG/lang/sitemap/robots 全自動
L2 內容結構 正文可見量、heading 階層、空標題、假標題、alt、內部連結、JSON-LD 全自動
L3 AI 可見度 站層級可達性(SITE-*)+ 頁層級可引用性(L3-* 半自動
L4 YMYL/E-E-A-T 作者資訊、專業佐證、共識一致性 人工判讀

怎麼用

先 build(檢核的是爬蟲看到的建置產物,不是原始碼):

npm run build
node skills/seo-aeo-audit/scripts/seo-check.mjs --dir ./dist --site https://example.com

在 Claude Code 裡則把 skills/seo-aeo-audit/ 放進 ~/.claude/skills/, 之後說「檢查這個網站的 SEO」就會自動觸發。

跑測試

node skills/seo-aeo-audit/test/dead-link.test.mjs
node skills/seo-aeo-audit/test/bilingual-concat.test.mjs
node skills/seo-aeo-audit/test/lang-content-mismatch.test.mjs
node skills/seo-aeo-audit/test/rule-index.test.mjs
node skills/seo-aeo-audit/test/i18n-dict.test.mjs

零相依、直接跑,輸出是給人看的(每個情境印出在測什麼)。

也可以用 Node 內建的 test runner 拿彙總數字(node --test <檔案>), 但別給目錄——node --test <目錄> 在 Node 24 實測會直接失敗, 而各支測試單獨跑都是通過的。症狀看起來像測試壞了,其實是呼叫方式。


四個設計立場

① 檢核建置產物,不是原始碼。 兩者可以完全不同。實例:某頁的經歷描述用字串插值輸出,HTML 裡是 &lt;a href=...&gt; 的字面文字——使用者看得到正常的連結(JS 載入後重繪過), 但爬蟲拿到的是轉義後的純文字,9 個外連對它們等於不存在。

② 這支腳本不執行 JS——這是特性不是限制。 爬蟲與 LLM 多數也不執行。腳本看到空的,它們就看到空的。

③ 弱訊號不寫成 error。 L3-GEO-* 只報 info,而且不給目標數字——論文說的是「加了會提升可見度」, 不是「沒加就是錯」,也沒有提供閾值。

④ 誤判要回頭修腳本,不是把門檻調寬到不再觸發。 SITE-DEAD-INTERNAL-LINK 曾在採 clean URL 的靜態主機上誤判率 67%:連結寫 /gallery、輸出檔是 gallery.html,永遠對不上。Cloudflare Pages、Netlify、 GitHub Pages 全部預設支援 clean URL——而它是 error 級。 一條 error 整批誤判比漏報更糟:漏報只是少看到一個問題,整批誤判會讓使用者 不再相信整份報告。

它潛伏那麼久的原因值得記下來:開發時用的網站是 directory 輸出 (/a/b/index.html),那是唯一它本來就正確的模式。 在唯一測過的環境裡,它從第一版起就是對的。

一條規則能潛伏多久,取決於你只在一種環境測它。

改法是把方向倒過來:原本猜「連結該長什麼樣」(把 /gallery 正規化再比對), 改成先算出每個輸出檔實際到得了的所有網址形式,再看連結有沒有命中。 前者要窮舉使用者的寫法,後者只要窮舉主機的行為——後者的集合小得多, 而且是查得到的事實。

哪些規則值得寫測試

不是每條規則都有測試,判準是:它錯的時候,會不會讓人不再相信整份報告, 或把人導向錯誤的修法。 看的不是規則多複雜。

而且修「誤判」有一個假解法,長得和真解法一模一樣:把規則放寬到不再觸發, 報告上看起來就像修好了,誤判確實消失了。所以每個測試都在各情境埋一條真的 該報的,斷言「只報這一條」——少報和多報都會失敗。

目前有測試的五項,各自出過不同的事:

規則 出過什麼事
SITE-DEAD-INTERNAL-LINK 在 clean URL 主機上整批誤判,而它是 error
L2-BILINGUAL-CONCAT 數字一直是對的,但把兩種修法完全不同的狀況混在一起
L1-LANG-CONTENT-MISMATCH 判準刻意不對稱,最容易被後人「順手改成對稱」
L2-I18N-DICT-* 「英文欄位裡是中文」——任何「有沒有填」的檢查都會判它通過,只能比對值本身
〈完整規則索引〉與文件計數 宣稱「一條不漏」卻漏 4 條;之後小節標題、出處筆數也各漂過一次

L2-BILINGUAL-CONCAT 混在一起的是這兩種:

狀況 性質 怎麼辦
同一份內容的中英兩版同時在 DOM 裡 架構 改成獨立語言 URL
英文頁上還沒翻譯的內容退回中文 內容進度 翻完自然消失

加判準時試錯兩次,兩次都是靠標記判斷——「有沒有 lang 屬性」會把第一種 一起消掉(常見雙語元件兩半都帶 lang);「兩邊都宣告且語言不同」會漏掉用 class="zh-only" 而不帶 lang 的手刻頁。最後改成靠內容:相鄰兩元素, 前者主要中日韓、後者主要拉丁。所以那個測試的重點不是數字對不對, 是三種不同的標記方式都要判對

L1-LANG-CONTENT-MISMATCH 的測試有一半是反向斷言:機構名出現在英文頁的 連結裡、中文技術文章含大量程式碼與品牌名、通篇英文——這三種都必須保持安靜。 不對稱的判準沒有反向斷言守著,遲早會被改成對稱,然後整批誤判。


這支腳本碰不到什麼

一份檢核報告最容易造成的誤解,是讓人以為「全綠=做完了」。所以這裡把 天花板寫清楚。三件事都有出處,而且都在這支腳本的視野之外。

① 大多數引用失敗是語意問題。 arXiv 2603.09296 把引用失敗分成四類, 在它的樣本裡:技術完整性 10.1%、語意對齊 62.2%、內容品質 27.1%、 系統性排除 0.6%。佔比最大的那一類——意圖分歧、脈絡缺口、資訊過時—— 需要知道使用者想搜什麼、競爭對手寫了什麼,都不在一份 HTML 裡。 (這些百分比是該篇樣本的分佈,不是普世常數。)

這和下面那個「結構欄位 +22%」不衝突:62.2% 說的是引用失敗的原因分佈, +22% 說的是優化結構欄位對被檢索到的效果。一份頁面可以順利被撈進候選集, 然後在生成答案時因為答錯了問題而沒被引用。兩個數字擺在一起容易讀成矛盾—— 先確認它們講的是管線的哪一段。

② 站外訊號,而且它可能比站內更重要。 arXiv 2509.08919(1,000 個查詢、四個引擎) 量到 AI 搜尋對第三方來源的壓倒性偏好:消費電子 92.1%、軟體 74.2%、 汽車 69.1%,而 social 內容在兩個領域是 0%另一篇發現有預測力的是 referring domains (+0.319)與社群聲量(+0.395),GEO 分數與被發現率零相關

這份報告全過,仍然可能因為沒有第三方報導而不被引用。

那該怎麼辦?這一層的工作不是改頁面,是讓別人有東西可以引用你:原始數據、 可複製的方法、明確的立場。這支腳本能幫的是確保那些內容爬蟲讀得到、結構清楚、 有出處——別人想引用你的時候不會被技術問題擋住。剩下的是內容與關係的工作。

不要用互連衝這個數字。 行銷公司常見的做法是讓手上客戶的網站互相連結, 把「有多少網站連到你」拉高。這不是「未來可能被罰」的灰色手法—— Google 垃圾內容政策 的〈Link spam〉一節已經明文列舉:

"Excessive link exchanges ("Link to me and I'll link to you") or partner pages exclusively for the sake of cross-linking"

而且對個人與小團隊來說這條路本來就走不通,它需要一批可控的網站。

③ 訓練語料圈。 arXiv 2601.00869 發現決定品牌能不能被推薦的是 訓練資料的地理來源,不是查詢語言:同樣的英文查詢,中文 LLM 品牌提及率 88.9%、國際模型 58.3%;案例品牌在中文 LLM 65.6%、國際模型 0%。 這給雙語一個 SEO 之外的理由——出英文版是進入另一個訓練語料圈—— 但語料收錄不在建置產物裡,檢核器看不到。

反過來說,站內這一段是有實測支持的arXiv 2602.12187(SAGEO Arena)把 title/description/H1–H6/JSON-LD 當成分開索引的欄位,比較「只優化結構欄位」 與「只優化正文」:前者 +22% Hit Rate、檢索排名 +2.72,後者一致退化 (其中一套自動改寫方法讓檢索掉 36%)。

這值得標出來,因為綜述說 GEO 的證據 碰不到「會不會被撈到」。這篇碰到了,而且量的正是 L1/L2 在檢查的東西。

「改哪裡有用」分三個層次,別混在一起談

市面上關於 GEO 的建議常常互相矛盾。把研究攤開看,矛盾大多來自沒有分清楚 改的是哪一層、影響的是哪一步

你動的東西 影響哪個階段 效果 出處
換句話、調字詞、表層改寫 引用 極小,甚至有害(−14%、−36% 2605.255172602.12187
title/description/H1–H6/JSON-LD 被撈到 +22% Hit Rate、排名 +2.72 2602.12187
統計數據、引用來源、獨特資訊 引用 顯著;消融中這兩項貢獻最大 2604.191132311.09735

這也是為什麼本檢核器分層而不是給一個總分:三層的證據強度不一樣,能做的 判定也不一樣。 L1/L2 敢報 error,L3 只報 info 且不給目標數字, L4 交給人判讀。

一個實際的例子:有一類自動改寫工具的做法是讓語言模型解釋「引擎偏好什麼」, 再照那些解釋改寫正文。SAGEO Arena 實測那套做法讓檢索掉 36%—— 它優化的是第一層(表層改寫),代價卻付在第二層(被撈到)。


出處

來源 用在哪
Google Search Quality Rater Guidelines(2025-09-11 版) L4 全部頁碼依據
GEO: Generative Engine Optimization(Aggarwal et al., KDD 2024,現為 v3) 五戰術與 L3-GEO-*
A Critical Survey of GEO (2023-2026)(回顧 45 篇) L3-GEO-* 的證據強度限定
What Gets Cited(252,000 次試驗) L3-GEO-* 為何不給目標數字
SAGEO Arena(結構欄位 +22% Hit Rate) L1/L2 在檢索階段的實測支持
FeatGEO(13 維特徵、有 ablation) L3-GEO-* 三項訊號的逐特徵消融
Diagnosing and Repairing Citation Failures 靜態檢核的天花板;不執行 JS 的旁證
The Discovery Gap(112 個新創、2,240 次查詢) 四層的排序;LLMO 0 條的第四條證據
How to Dominate AI Search(1,000 個查詢) 站外訊號碰不到(earned media 69–92%)
The Existence Gap 為什麼雙語不只是 SEO 問題
Ahrefs llms.txt 研究(137,210 網域) llms.txt 97% 零抓取;編碼代理是唯一明顯消費端
Google Search Central 官方文件 L1/L2 多數規則

只列主要的幾筆。watch/sources.json 有 23 筆完整紀錄,其中兩筆的 usedBy 刻意留空——geo-sfe-2026e-geo-2026 記錄的是證據衝突,不是任何規則的依據。

查證過但沒通過門檻的主題另存在 watch/investigated.json (目前 6 筆)。那份檔案的用途是不要重複搜:沒通過的東西如果不寫下來, 下一個人會把同一輪搜尋再跑一次,而且看不到上次否決的理由。

watch/sources.json 是機器可讀的完整清單,由 GitHub Actions 每月檢查是否失效。

定期檢查在檢查什麼

規則會過期,而過期的症狀是靜默的——檢核器照跑、報告照出,只是依據已經不成立了。 所以 watch/ 每月做兩件事,結果開成 issue,只報告、不自動改規則 (要不要跟著改是需要讀原文判斷的事):

檢查 怎麼偵測
出處還在不在、有沒有悄悄改版 依來源性質分三種模式:PDF 比檔案大小、arXiv 比版本號、Google devsite 比頁面自帶的 Last updated
AI 爬蟲清單有沒有變 正向:清單裡的名稱是否仍在官方文件裡;反向:文件裡有沒有清單外的新爬蟲
有沒有出現我們還不知道的東西 掃 Google Search Central 部落格與 arXiv 的 GEO/AEO 論文,交給模型篩出「值得回去讀原文」的項目

②的反向檢查在 2026-08 首跑時抓到三支清單外的爬蟲(OAI-AdsBotGoogle-CloudVertexBotmeta-externalads)。三支都經查證後刻意不納入規則—— 前兩支只抓站長自己提交或要求的內容,第三支屬廣告生態,都不影響 AI 回答的引用 與訓練同意。理由逐支記在 watch/crawlers.json,這樣下個月不會再被當成新發現重報。

③是整個 repo 最危險的一步——讓語言模型讀部落格再吐結論,正好是這個 repo 反對的做法。所以它的產物明確定義為「線索」不是「規則」:只列出值得回去讀 原文的項目、一律附原始連結、不產生任何規則文字、不改任何檔案,並且在報告裡 標明是哪個型號判讀的——判讀要能追溯到判讀者。

型號也不寫死:CF_AI_MODEL 優先,沒設就查當下的型號清單自動挑,並印出實際 用了哪一個。寫死等於埋一個「供應商下架那天才會炸」的地雷。

需要的環境變數(都是選填,沒設時對應的檢查會標成「本次未檢查」而不是顯示綠燈):

變數 用途
CF_ACCOUNT_IDCF_API_TOKEN Browser Rendering(Meta 的爬蟲文件對一般抓取回 400,要真瀏覽器)+ Workers AI(③的判讀)
CF_AI_MODEL 覆寫自動挑選。建議留空

Token 權限:Workers AI · ReadWorkers AI · EditBrowser Rendering · Edit


授權

MIT。規則的出處各有其授權,引用時請依原始來源標註。

About

SEO / AEO / GEO / LLMO audit as a Claude Code skill — four layers of checks, every rule with a citable source, CJK-aware thresholds. 又一個引擎優化,但每條規則都附出處。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages