agentleFS
matt-yematt-ye/yaeo/skills/seo-aeo-audit/SKILL.md

seo-aeo-audit

Skill0 starsChanged 3 months agoMITView on GitHub

檢核網站的 SEO/AEO 品質並提出修法。四層檢核——技術基礎、內容結構、AI 引擎可見度、YMYL/E-E-A-T。當使用者要求檢查網站 SEO、發佈前檢核、找出空標題或缺 meta、想被 AI 引擎引用、或問「這頁的 SEO 有沒有問題」時使用。也用於寫作階段套用 GEO 戰術。

  • Reads credentials

2 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 2

    1. warpdotdev/oz-skills★ 825same name
    2. davidanthonyn/claude-skills★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

The file

Files
SKILL.md

SEO / AEO 檢核

規則帶出處是這個 skill 的核心紀律。 市面上的 SEO skill 大量流傳無來源的百分比宣稱 (實測:某 repo 的 GEO 章節整串改善率追不到任何原始研究)。 本 skill 的每條規則要嘛來自 Google 官方文件,要嘛來自同行評審論文,要嘛標「從業共識,證據弱」。 不確定的規則寧可標弱,不要加數字。

四層架構

層內容判定方式
L1 技術基礎title/description/canonical/OG/lang/sitemap/robots腳本全自動
L2 內容結構正文可見量、heading 階層、空標題、假標題、圖片 alt、內部連結、JSON-LD腳本全自動
L3 AI 可見度站層級:標準檔+爬蟲分流(SITE-*,自動)/頁層級:GEO 引用訊號(L3-*,自動)、段落自足性與 Q&A 結構(人工)半自動
L4 YMYL/E-E-A-T作者資訊、專業佐證、共識一致性、AI 內容加值人工判讀

✅ L1/L2 那批欄位在 AI 搜尋管線裡有實測支持(2026-08-17 新增)。 arXiv 2602.12187(SAGEO Arena)把 title/meta description/H1–H6/schema-JSON-LD 當成分開索引的欄位 (照真實搜尋引擎的做法),比較「只優化這些結構欄位」與「只優化正文」: 前者 +22% Hit Rate、平均檢索排名 +2.72;後者一致退化。

這件事值得標出來,因為綜述說 GEO 的證據 「未證實自然可發現性」——也就是碰不到「會不會被撈到」。這篇碰到了, 而且量的正是 L1/L2 已經在檢查的東西。 原本這批規則只有 Google 官方文件 這個「應該這樣做」的依據,現在多了一個管線內的實測。

⚠ 但不改任何嚴重度。 它比較的是兩種優化策略的效果, 不是「缺這個欄位會怎樣」。把策略比較的結論搬去當缺漏的罰則,就是過度推論。

怎麼跑(L1+L2+L3 自動部分)

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

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

參數:--json 輸出機器可讀格式;--fail-on warn 讓警告也算失敗(進 CI 用)。 離開碼:0 通過/1 有問題/2 參數或路徑錯。

Windows 上要接 --json 的輸出時,Get-Content 必須加 -Encoding utf8, 否則中文變亂碼、ConvertFrom-Json 直接報錯(Node 輸出的是標準 UTF-8 無 BOM,錯在消費端)。

效能層:psi-check.mjs

node scripts/psi-check.mjs --url https://example.com/ --key-env GOOGLE_PSI_API_KEY_MATTYE

參數:--strategy both|mobile|desktop(預設 both)、--json。

必須自備 API key(見「已知限制」),從環境變數讀、不接受命令列傳入(避免進 shell 歷史)。

⚠ Windows 坑:setx 寫的是註冊表,當前 shell 讀不到(它的環境是啟動時的快照)。 要嘛開新 shell,要嘛在跑之前注入:

$env:GOOGLE_PSI_API_KEY_MATTYE = [Environment]::GetEnvironmentVariable("GOOGLE_PSI_API_KEY_MATTYE","User")

⚠ API key 不綁被測網域——key 只決定配額算在哪個 GCP 專案,任何 key 都能測任何網址。 多把 key 的用途是配額分開計費,不是存取控制。

三支腳本查的東西不重疊:seo-check.mjs 看結構與內容(離線掃 dist)、psi-check.mjs 看效能、 agent-check.mjs 看 agent 可操作性(連線打線上站)。前兩支發佈前跑,第三支部署後跑。 Lighthouse 的 SEO 分數(psi 會印)只驗表層——實測某站 SEO 100 分,但 h2 掛零、 主要內容不在 HTML、LCP 106 秒。不要把那個 100 分當作 SEO 沒問題。

先讀懂輸出的分級:error 是爬蟲層面的實質損失,warn 是品質折損,info 是提醒。 不要追求歸零——noindex、裝飾性 alt="" 這類是刻意設計,出現在 info 是正常的。

連線層:agent-check.mjs

檢核 agent 能不能操作這個網站——HTTP 狀態碼、機器可讀檔的線上可取性、內容協商。

node scripts/agent-check.mjs --site https://example.com

參數:--json、--fail-on warn。離開碼:0 通過/1 有問題/2 參數錯。

⚠ 檢核的是已部署的線上網站,不是 ./dist。 deploy 之後才跑得有意義。

為什麼另開一支,而不是加進 seo-check.mjs:那支是純檔案系統掃描器(全檔零 fetch), 而這裡每一條規則都要發真實 HTTP 請求才驗得出來。把網路塞進去會毀掉它 「離線、可重現、CI 不需連外」的性質——test/agent-check-rules.test.mjs 有一條斷言釘住這件事。

整支跑完個位數請求,請求間留 300ms,UA 表明身分(yaeo-agent-check/1.0)。

10 條規則:

代碼級抓什麼修完怎麼確認
AGENT-SOFT-404error不存在的路徑回 HTTP 200curl -o /dev/null -w "%{http_code}" <站>/不存在的路徑 要印 404
AGENT-404-STATUSwarn不存在的路徑既非 200 也非 404/410同上,確認狀態碼是刻意的
AGENT-404-NO-POINTERinfo404 頁沒有指向 sitemap/llms.txt/首頁重跑,該條消失
AGENT-ROBOTS-UNREACHABLEerrorrobots.txt 線上取不到,或回 HTML 空殼直接開網址,看 Content-Type
AGENT-LLMSTXT-UNREACHABLEwarnllms.txt 線上取不到,或回 HTML 空殼同上
AGENT-SITEMAP-UNREACHABLEerror/sitemap.xml 與 /sitemap-index.xml 都取不到直接開網址
AGENT-SITEMAP-PROBE-GAPinfo/warn/sitemap.xml 404、實際在 /sitemap-index.xmlrobots.txt 有宣告就是 info,那不是錯誤
AGENT-MD-NEGOTIATIONinfoAccept: text/markdown 沒有內容協商順便報 HTML 有多少比例不是正文
AGENT-MACHINE-CATALOGinfo有沒有 .well-known 機器可讀目錄沒 API 就該是空的,不要補空殼
AGENT-PROBE-FAILEDwarn某次探測連不上這條代表「無法判定」,不是通過

⚠ info 那幾條不是待辦清單。 內容站沒有 API 就不該有 openapi.json; /sitemap.xml 404 而 robots.txt 宣告正確不是錯誤,是 Astro 等框架的預設產物形狀。 為了迎合檢查器的探測習慣去改一個本來正確的設定,是把工具的方便當成網站的目標。

出處與界線:規則對應 Is Agentic(Vercel × Ora,2026-08) 公開報告中出現過的檢查項,以及 RFC 9309、llmstxt.org。 ⚠ Is Agentic 的完整檢查清單不公開——官方稱 127 項,一項名稱都不列,公開報告也只列 失敗與 partial。所以這裡只實作「從公開報告逆推得到、且語意明確」的少數幾條, 不宣稱涵蓋它的評分,也不試圖重現它的分數。它的分數不可審計,不該當診斷訊號用。

先看正文在不在,再看結構對不對

檢核順序有優先級:L2-CLIENT-RENDERED 出現時,其他所有結構檢核的結果都要打折看。 一個頁面可以 title/description/JSON-LD/heading 全部完美,但正文靠 JS 載入—— 對爬蟲來說那就是一張空頁。實例:某站的演講頁結構全過,但 61 筆資料零筆在 HTML 裡。

這是原版腳本漏掉、靠與既有人工盤點對照才發現的缺口——寫檢核工具時 很容易只檢核「看得到的元素」,而忘了問「該有的內容到底在不在」。

這支腳本不執行 JS——這是特性不是限制

它看到的就是爬蟲看到的。如果某頁的標題靠 JS runtime 填字,腳本會報 L2-HEADING-EMPTY, 那不是誤報,那正是 Google 看到的狀態。 修法是把預設語言的文字寫回 HTML,讓 JS 只負責切換。

逐項怎麼修

L1 常見項

代碼修法
L1-TITLE-MISSING / SITE-TITLE-DUP每頁給獨立 title。多頁共用同一個 title 等於告訴搜尋引擎「這幾頁是重複內容」
L1-DESC-MISSING補 meta description。它不是排名因子,但影響 SERP 上的點擊率(Google SEO Starter Guide 的「Influence your title links and snippets」一節有述;Google 也可能改用頁面內文自動生成 snippet)
L1-LANG-MISSING / SITE-LANG-INCONSISTENT全站統一(繁中用 zh-TW,不要 zh-TW 與 zh-Hant 混用)
L1-CANONICAL-MISSING補 canonical,尤其有查詢參數的頁面

hreflang 什麼時候才加:只有中英是獨立 URL 時才有意義。 若同一 URL 用 CSS/JS 切語言,加 hreflang 反而給錯訊號——不要加。

L2 常見項(投報率最高的一層)

代碼修法
L2-FAKE-HEADING<p class="section-heading"> → <h2>,class 原封不動,視覺零變動。這是最便宜的修復:一個標籤名換掉,頁面立刻從「只有一個標題」變成「有結構」
L2-HEADING-EMPTY預設文字寫回 HTML,JS 只做切換
L2-TITLE-NOT-HEADINGinfo 級,數量通常很大(卡片標題)。不要全改——挑「文章列表」「課程列表」這類真的需要被爬蟲讀成清單的地方包 <h3> 就好
L2-CLIENT-RENDERED最嚴重的一類。核心內容由瀏覽器端 fetch,爬蟲與 LLM 看到的是「載入中…」。修法:把 fetch 搬到 build 期寫進 HTML(並準備資料源掛掉時的 fallback,別讓 build 紅)。這種頁面可能其他檢核全過——結構完美但沒有內容
L2-BILINGUAL-CONCAT同頁雙語 DOM,爬蟲讀到「數字看見By the Numbers」這類混雜字串。小修無用,根治要拆成獨立語言 URL
L2-NO-INTERNAL-LINKS孤島頁。加相關文章/系列導覽/麵包屑。若內容有 series 或 category 欄位,用它自動生成 prev/next 是一次修好全部的做法
L2-BREADCRUMB-MISSING補 BreadcrumbList JSON-LD,路徑越深收益越大
L2-ARTICLE-NO-DATEArticle 型必填 datePublished
L2-H1-MULTIPLE / L2-H1-MISSING一頁恰好一個 h1
L2-IMG-ALT-MISSING補 alt。裝飾性圖片用 alt=""(那是刻意的,會歸到 info)
L2-JSONLD-INVALIDJSON-LD 語法錯誤——整段會被搜尋引擎忽略,等於沒寫
L2-ARTICLE-NO-AUTHORArticle 補 author。YMYL 的第一要件是「誰寫的」
L2-FUTURE-DATEdatePublished 在未來=頁面已上線卻宣稱未發佈。多半是把「排程日」當發佈日
SITE-DEAD-INTERNAL-LINK站內連結指向不存在的路徑。會處理 clean URL——連結寫 /gallery、輸出檔是 gallery.html 不算死連結(見下)
SITE-SITEMAP-NOINDEX-CONFLICTsitemap 邀請爬蟲來看一個標了 noindex 的頁——矛盾訊號
SITE-ROBOTS-MISSING / SITE-SITEMAP-MISSING兩個最基本的站層級檔案
SITE-TITLE-DUP多頁共用同一個 <title>=告訴搜尋引擎這幾頁是重複內容

上面兩張表是策展過的:只列最常遇到、且修法需要判斷的。 每一條規則的完整索引見〈完整規則索引〉(本文件末段),不必去讀腳本。

L3 AI 可見度

這一層有兩個不同的問題,報告裡也分成兩組代碼:

問題代碼白話
可達性SITE-*AI 拿不拿得到你的內容
可引用性L3-*拿到之後會不會被引用

兩者不互相取代:擋掉檢索蟲,寫得再好也不會被引用;開放了但內容沒有可引用的 東西,也一樣不會。

站層級(可達性)

自動檢的:robots.txt/sitemap/llms.txt/RSS 存在性,以及爬蟲分流。

訓練蟲與檢索蟲是兩件不衝突的事,這是最多人搞混的一點:

類型代表擋了會怎樣
檢索/引用蟲OAI-SearchBot、PerplexityBot、Claude-SearchBot、Google-ExtendedAI 引擎無法引用你——想被 AI 提及就不能擋
訓練蟲GPTBot、ClaudeBot、CCBot內容不進模型訓練;不影響被引用

(Google-Extended 的作用範圍隨 Google 政策調整過,設定前回查官方文件當日說明。)

llms.txt:Google 官方明確表示不使用它(逐字聲明見文末「出處」)。

2026-08-18 補上三份實測,結論比原本細緻。 原本只寫「放無妨、別期待效果」, 現在說得更準——先看它多沒用,再看它對誰有用:

研究樣本結果
Ahrefs137,210 網域(2026-05)有放的檔案 97% 整個月零抓取
SE Ranking約 30 萬網域與被引用頻率找不到關聯;採用率 10.13%
OtterlyAI單站 90 天日誌AI bot 請求 62,100+ 次,只有 84 次打它(0.1%)

三份的方法不同(爬取普查/關聯分析/伺服器日誌),結論同方向。 不同方法得到同方向結論,比同方法重複更有價值。

但同一份 Ahrefs 資料裡有一個例外,而且它推翻了「純防禦性」這個講法: 在少數真的被抓取的檔案中,編碼代理的抓取量超過所有 AI 檢索爬蟲、AI 助理 與訓練爬蟲,其中 Claude Code 最多。該研究並指出這與 John Mueller 說 llms.txt 適合當「編碼代理的參考資料」一致(⚠ Mueller 該說法經 Ahrefs 轉述, 未直接查證原始出處)。

所以判準是看你的讀者是誰:

  • 讀者會用 Cursor/Claude Code 之類的工具讀你的文件 → 有實際、可量測的用途
  • 一般商業網站 → 放了幾乎不會有人讀,別在提案裡把它講成必做項

⚠ 這一段是從 claude-seo 的 llms.txt 證據檔得到線索後自己回查原始研究才寫的。它那份檔案主張編碼代理會消費 llms.txt 但沒有附出處;回查之後發現主張成立,而且可引的樣本比它引的更大。 線索可以來自別人,出處必須自己查。

頁層級(可引用性)

先確認資格,再談訊號。 L3-AI-SNIPPET-BLOCKED 檢查 meta robots 有沒有 nosnippet 或 max-snippet:0。Google 官方明載:

"To be eligible to be shown in generative AI features on Google Search, a page must be indexed and eligible to be shown in Google Search with a snippet"

快照資格是前提不是加分項。這條與 L1-NOINDEX 分開,因為後果不同—— noindex 是不進索引,nosnippet 是進了索引但 AI Overviews/AI Mode 用不了。 已經 noindex 的頁不重複報。元素層級的 data-nosnippet 只報 info (L3-AI-SNIPPET-PARTIAL),它常被整個套在正文容器上,作用範圍比作者以為的大。


L3-GEO-SIGNALS-NONE / L3-GEO-SIGNALS-THIN 只對 Article 型頁面檢查, 數三件事:外部引用網域數、統計數據處數、直接引言處數。

⚠ 引言的長度門檻分中西兩套(「」『』 要 8 字、"…" 要 40 字元), 理由與 title/description 的門檻同源:中文一字一義,8 字已是短句; 8 個拉丁字元只有一兩個單字,套同一個數字會把 "the fund" 這種強調算成引言。

這是實測踩到的盲區:同一門課的週次頁,中文版引言 18–27 處、英文版 0 處—— 翻譯時把「」換成 "…",整批訊號就消失,26 頁英文課程頁裡 24 頁被誤報成 「缺直接引言」,而它們其實各有 21–23 處。 同一份內容的兩個語言版本結果差這麼多,該先懷疑量測而不是內容。 由 test/geo-quote-detection.test.mjs 守著。

這三項是下面「GEO 五戰術」裡唯一機械可偵測的部分(權威語氣與流暢度是語意判斷)。

✅ 2026-08-17:這三項拿到逐特徵 ablation 了。 arXiv 2604.19113(FeatGEO)把網頁抽象成 13 維特徵 並逐項消融,結論是貢獻 substantial 的是 Statistics 與 Cite Sources、 minimal 的是 Technical Terms,整體由 content 層特徵主導。 也就是說這裡數的三項,其中兩項正好是 ablation 裡最強的兩項。

嚴重度仍然不變。 FeatGEO 一樣沒有給閾值,info + 不給數字的做法照舊。 有 ablation 支持「這幾項有影響」,不等於有依據說「幾個才夠」。

版面結構:加進訊息,但不變成判準

三篇研究指向同一件事——長篇散文缺清單與表格會降低被引用的機率: FeatGEO 的 list_density、SAGEO Arena 的修復工具 「加標題階層與清單」、以及引用失敗分類裡的 「版面無結構」(屬於內容品質那 27.1%)。

處理方式是把數字加進 L3-GEO-SIGNALS-* 既有的訊息,不另立規則。 報告現在會多一句「版面 清單/表格 N 處、次級標題 N 個,未列入判定」。

為什麼不立新規則:三篇沒有一篇給閾值(多長算長篇、幾個清單算夠), 而沒有閾值就只能報 info 且不給數字——那樣它的訊號會和 L2-THIN-CONTENT 高度重疊,同一批長而扁的頁面被念兩次,只是多一條噪音。 完整理由記在 watch/investigated.json 的 list-density-rule。

⚠ 已知代價,寫下來免得以後當成 bug: 三項訊號都齊備的頁面, NONE 與 THIN 都不觸發,於是版面數字也不會出現。 附註掛在既有訊號上,就只能跟著它出現。這是「不另立規則」換來的。

⚠ 2026-08 證據強度下修。 一篇回顧 45 篇研究(2023-11~2026-07)的批判性綜述 (arXiv 2607.14035)指出,KDD 2024 那些被廣泛 引用的增益「在其實驗設定內成立,但以來源已經出現在固定脈絡中為前提; 既未證實自然可發現性,也未證實持久的流量效果」,而且「以被引用為目標的改寫 可能損害檢索表現」。

也就是說這三項影響的是「被撈到之後會不會被引用」,不是「會不會被撈到」。 原本的訊息寫「唯一有同行評審實驗支持的槓桿」說過頭了,已改。 嚴重度不變——本來就只報 info、本來就不給數字,克制的做法是對的。

「結構到底有沒有用」的衝突:其實是階段混淆(2026-08-17,2026-08-17 二訂)

最初只讀到兩篇,看起來直接矛盾:

論文設計結論
2605.25517 What Gets Cited252,000 次試驗、6 個模型、18 個因子逐一配對、mixed-effects,品牌匿名+來源順序對消topical relevance 與 list position 最強,純格式改動影響極小
2603.29979 GEO-SFE6 個引擎結構特徵帶來引用率 +17.3%

補讀另外兩篇之後,矛盾大致消失——它們量的是管線的不同階段,也是不同層次的「結構」:

改什麼在哪個階段效果出處
表層詞彙/格式改寫引用極小,甚至有害(AutoGEO 檢索 −36%、Technical Terms −14%)2605.25517、2602.12187
結構化 metadata 欄位(title/description/H1–H6/JSON-LD)檢索+22% Hit Rate、排名 +2.722602.12187
文件層級的內容屬性(統計、引用來源、獨特資訊)引用顯著;ablation 中 Statistics 與 Cite Sources 貢獻最大2604.19113、2311.09735

處置不變:不新增規則,也不改嚴重度。 但理由變了——原本是「兩篇打架所以不動」, 現在是「三個層次各自成立,而它們對應的檢查 L1/L2/L3 都已經有了」。

值得注意的是這些結論落在哪一邊:它們支持現行做法。 既然表層改寫無效甚至有害, L3-GEO-* 那三項就不該升級成硬規則、也不該給閾值。這次查證的產物是 「原本的克制是對的」,不是一條新規則——這種結果一樣要寫下來, 否則下一個人會以為這個主題沒人查過。

另一個還沒解決的衝突。 2511.20867 E-GEO 主張 存在「普遍有效的 GEO 策略」(domain-agnostic pattern),而 2607.14035 綜述說「通用啟發法轉移性差」。 2604.19113 FeatGEO 報告效果因領域而異,站綜述那邊。 目前 2 比 1,不改任何立場,只記著。

⚠ 同時記下沒有拿來用的東西:2605.25517 也發現「時間戳新」有一致的 正面效果。這不能用來加強 L2-NO-MODIFIED-DATE——「有 dateModified 標記」不等於「內容是新的」,是兩個不同的主張。要做成規則需要一個 「多舊算舊」的閾值,論文沒給。這種跳躍正是本 skill 反對的。

三件刻意的克制,也是使用這條規則時該有的態度:

  1. 只報 info。 論文說的是「加了會提升可見度」,不是「沒加就是錯」 ——把弱訊號寫成 error 正是本 skill 反對的做法
  2. 不給目標數字。 論文沒有提供閾值,我們也不編一個出來
  3. 只對 Article 檢查。 列表頁、工具頁沒有引用來源是正常的

實測一個站的 51 個 Article 頁(2026-08-14 快照,數字會隨該站內容變動): 0 頁完全沒有訊號,12 頁偏少。 其中 8 篇投資專欄的模式最值得注意——統計數據 11~24 處,外部引用 0 個。 大量引用數字卻不標出處,這同時是 GEO 缺口與 YMYL 扣分項。

人工判讀的

  • 段落自足性——每個段落抽出來單獨看,還讀得懂嗎?AI 是以 chunk 為單位擷取的
  • Q&A 結構——標題用真實問句,答案緊接在標題下第一段
  • Bing 收錄——ChatGPT Search 高度依賴 Bing 索引,只顧 Google 會漏掉這條路

L4 YMYL / E-E-A-T(人工判讀,財經、醫療、法律內容必做)

依據:Google Search Quality Rater Guidelines 2025-09-11 版(頁碼標於各條)。 注意 §3.4.1 的框架是「主張類型 × 佐證等級」的配對,不是「作者有沒有證照」:

  1. 具體操作建議(存多少、怎麼配置、幾歲前要達成什麼)必須有對應等級的專業佐證, 不能只用個人經驗帶過(p.28)
  2. 個人心得/使用經驗可以用第一手經驗撐 E-E-A-T,不必偽裝成專家建議(p.26, p.28)
  3. 每篇要有清楚的內容創作者資訊:作者是誰、相關學經歷(p.25, p.62-63)
  4. 涉及付費交易的頁面需要令人滿意的客服/聯絡資訊,只有一個 email 會被判 Low(p.63)
  5. 聲譽佐證要來自獨立第三方,不能只有自我宣稱「我是專家」(p.27, p.63)
  6. 內容須與 well-established expert consensus 一致——不一致會被判不可信甚至 Lowest(p.21, p.48)
  7. 免責聲明不是萬靈丹(指南未給明文豁免效力);未揭露的利益衝突則會獨立拖累 Trust(p.27, p.57)
  8. AI 輔助寫作沒問題,但每篇要有實質人工加值與原創觀點。 ⚠ 精確表述是「AI 生成 + 低努力/低原創/無附加價值 = Lowest」(p.42-43), 不是「用 AI 就低分」——指南明白反駁了那個簡化讀法
  9. 避免模板化批量產出(把常見問題清單餵 AI 生成填充頁)——這正是 Scaled Content Abuse 的示範手法(p.55)
  10. 小型個人網站查無第三方聲譽不算扣分,但 YMYL 主題下其他品質指標會被更嚴格檢視(p.25)

⚠ 第 1、2 條的「教育型內容 vs 個別化建議」二分,是從 §3.4.1 的 Experience-vs-Expertise 框架推論出來的,指南並無此明文條款。引用時要標明這層推論落差。

寫作階段:GEO 五戰術

唯一有同行評審實驗支持的 AEO 戰術(Princeton 等,KDD 2024;論文報告最高約 40% 可見度提升, 單項最強為加入統計數據):

  1. 引用來源
  2. 加入統計數據
  3. 直接引言
  4. 權威語氣
  5. 流暢度優化

這五項本質上就是學術寫作紀律——先寫好內容,這五項會自然滿足,不需要當成額外工序。

檢核報告怎麼寫給人看

跑完腳本後,不要把原始輸出貼給使用者。整理成:

  1. 先給三行結論:掃了幾頁、幾個 error、最該修的是哪一件
  2. 依「修一次影響幾頁」排序,不是依嚴重度排序——29 處假標題改標籤名,比逐頁補 description 划算得多
  3. 每項附具體修法與 file:line,能給出「改哪一個字」最好
  4. L4 的判讀分開寫,標明哪些是推論、哪些有頁碼依據
  5. 最後附〈修完怎麼確認〉——腳本會自己印,別漏掉(見下節)

修完怎麼確認(驗證層級)

這份報告原本只回答「哪裡不對」,不回答「修了怎麼知道有效」。 使用者實際會做的事是重跑腳本、看訊息消失,然後把那當成有效果。 那是兩件事,而把它們混為一談是這支腳本原本默許的誤解:

意思適用範圍
訊息消失建置產物裡的事實改掉了所有規則,確定性
有沒有效果搜尋引擎/AI 的行為變了要分規則

第二欄分兩級,由 seo-check.mjs 的 VERIFY_TIERS 定義,報告尾端會依 本次實際觸發的層級印出:

層級涵蓋怎麼看效果
rerun-then-consoleL1/L2/SITE/L3-AI-SNIPPET-*Search Console 的收錄與爬取資料(有延遲,數天到數週)
no-single-shotL3-GEO-*無法用單次量測驗證

為什麼 L3-GEO 那格寫「驗不了」而不是給一個驗法。 arXiv 2604.07585 在四個引擎上跑 45–46 天, 來源集合的日間 Jaccard 只有 0.34–0.42(每天約 65% 的來源會換掉), 同一天內同時重跑也只有 0.32–0.43;作者建議至少 7 runs/prompt/日、觀測窗 2–4 週。 在那種雜訊水準下,給一個「改完再查一次」的驗法就是在教人做錯的量測。 誠實的答案是「你驗不了」,而那比一個假的驗法有用——這也和 L3-GEO-* 本來就只報 info、不給目標數字是同一個理由。

⚠ 這一節由測試強制。 rule-index.test.mjs 斷言每條規則都歸到了某個 驗證層級,新增規則卻沒歸類就會失敗並指名;同時斷言本節存在。

為什麼要強制:claude-seo 的 README 宣稱「每條建議都帶可證偽檢查」,但實測 grep 它的 schema/tests/scripts 零命中——那個要求只寫在給模型看的提示詞裡。 要做同一件事,就得先解決它沒解決的那一半:讓它成為斷言,不是期望。

別被 SEO 工具的「missing」嚇到

瀏覽器 SEO 擴充(SEO Meta in 1 Click、Ahrefs Toolbar 等)會列出一長串 missing。 其中有一半以上不該修——工具的檢查清單多年沒更新,或檢查的是它自己那套偏好。

先把這些刷掉,剩下的才值得看:

工具報的真相
Keywords is missingmeta keywords Google 2009 年就公開宣布不再使用。填了不會加分,只會讓競爭者看到你的關鍵字策略
Robots meta tag is not defined沒有 robots meta = 預設 index, follow,這正是你要的。特地加一行 index,follow 是多餘的
Images without TITLEtitle 屬性對 SEO 無作用,圖片靠 alt。而且 title 對可及性有害:螢幕閱讀器行為不一致、觸控裝置根本看不到。alt 有就夠了
Links without TITLE同上。連結的語意靠 anchor text,不是 title 屬性
No Schema.org (itemtype only)那個檢查只認 microdata(itemtype= 屬性)。若你用 JSON-LD——那是 Google 官方推薦的格式——它就報 missing。去看工具的 structured data 分頁,通常會正確列出你的 JSON-LD
Hreflang missing只有「同一內容有多個語言 URL」時才需要。中英同頁切換的站加了反而給錯訊號
Domain Rating 低新站本來就低,那是外部連結累積的結果,不是網站本身的缺陷。別把它當待辦事項

判準:工具報 missing 時先問「這個訊號現在還有人在讀嗎?誰讀?」 答不出來就不要修——每一項「為了讓工具變綠」的修改都是技術債。

反過來說,這些工具最該看的一欄

標題階層。擴充的 H1–H6 計數表是最誠實的一欄:H2 = 0 直接證明頁面沒有結構 (見 L2-FAKE-HEADING)。工具在這裡不會誤報,因為它數的是實際標籤。

架構級建議:自動產生的產物要自我驗證

凡是自動產生、不經過人眼的東西——sitemap、RSS、JSON-LD、自動內部連結—— 都該在 build 期驗證自己。理由:人看得到的東西壞了會有人回報,這些不會,只會安靜地漏。

值得照抄的模式(實例):RSS 在 build 期檢查「feed 非空/每個連結在 dist 有對應頁/ 網址是絕對路徑」,任一不符就讓 build 結束碼 1,部署直接被擋。 同時把內容來源抽成單一模組,讓列表頁與 feed 讀同一份—— 避免「兩邊各抄一份,日後新增來源只改了一邊」。

調整門檻時的原則

title/description 長度門檻分中英兩套(CJK 佔比 >30% 走中文門檻), 因為中文資訊密度高,套英文門檻會把正常的中文標題全部報成過短或過長。

噪音比漏報更危險——一份 40 條警告的報告會被整份忽略,1 條真警告才看得見 (這條紀律與 PROMPT_連結驗證與來源查核SOP.md 的「降噪本身就是修復」同源)。 所以:如果某個檢核項在正常內容上大量觸發,先懷疑門檻設錯,不要叫使用者去改一百頁。

noindex 頁的降級判準——以及 OG 為什麼不降

判準只有一句話:這條規則的後果是不是只發生在搜尋結果裡。 是 → noindex 頁降 info(它不是沒修,是本來就不適用);否 → 維持原級別。

目前依此降級的有四條:L1-DESC-MISSING、L1-CANONICAL-MISSING、 L2-JSONLD-MISSING、L2-NO-INTERNAL-LINKS(L1-DESC-SHORT、L2-THIN-CONTENT、 L2-CLIENT-RENDERED 先前就已依同一原則處理)。

這件事的起因是原則套得不均勻:同一個 meta 欄位上,L1-DESC-SHORT 早就降 info 了,L1-DESC-MISSING 卻仍報 error。不一致比嚴格或寬鬆都糟—— 它讓人不知道該相信哪一邊。

⚠ OG/Twitter Card 不降,這是刻意的判斷。 noindex 擋的是索引,不是分享。unlisted 頁往往正是靠連結傳播—— 貼到 Slack/Threads 的預覽卡長什麼樣,對這種頁反而比對一般頁更重要。 「搜尋看不到 → 分享也不重要」是不成立的推論,但它很順口,所以 test/noindex-downgrade.test.mjs 用反向斷言把它釘住。

降級不等於消音。 那四條降成 info 之後仍然要出現在報告裡,否則 「刻意 noindex」與「該修卻沒修」就再也分不開,而這份檢核器是靠 error 歸零 當驗收標準的。測試同時守著這一點。

降級之後誰來接住「誤標 noindex」? 兩條站層級規則把 noindex 頁分完:

狀況規則級別
noindex 卻仍在 sitemap 裡SITE-SITEMAP-NOINDEX-CONFLICTwarn——訊號矛盾,多半是 build 漏排除
noindex 且不在 sitemap 裡SITE-NOINDEX-UNLISTEDinfo——正常形態,但列出來讓人逐一確認

第二條刻意不帶任何閾值。原本的選項是「noindex 頁佔比超過 X% 就報」, 但「多少比例算異常」沒有可靠依據——那會變成又一個憑感覺的數字, 正好違反本節開頭立的規矩。所以它不做判斷,只把清單攤開: 降級讓這些頁不再產生 error,那至少要有一個地方能一眼掃過去。 也因為它報的是正常狀態,級別是 info 而不是 warn——它不是叫你去修。

已知限制

  • 正則解析,不是 DOM 解析:巢狀異常結構可能誤判。發現誤判時回頭修腳本的正則,不要改結論遷就工具
  • <script>/<style> 一律先剝掉再做結構檢核——否則 JS 樣板字串裡的 <div class="${x}-title"> 會被當成真實 DOM(實測踩過)。JSON-LD 例外,它需要從原文解析
  • 不執行 JS(見上方說明,這是刻意的)
  • 不檢核效能(Core Web Vitals 走 PageSpeed Insights API)。 ⚠ PSI API 必須自備 API key:不帶 key 走 Google 公共匿名配額池,實測(2026-08-11) 直接回 429 Quota exceeded。文件寫的每日 25,000 次是有 key 之後的配額
  • 不檢核實際排名與收錄狀態(走 Google Search Console API;2026-06 起含 AI Overview 曝光數據)。 ⚠ 「AI 可見度」尤其不要用單次量測看:arXiv 2604.07585 在四個引擎上跑 45–46 天的每日量測,來源集合的日間 Jaccard 只有 0.34–0.42 (每天約 65% 的來源會換掉),RBO 0.21–0.26;同一天內同時重跑,來源 Jaccard 也只有 0.32–0.43。作者建議品牌可見度至少 7 runs/prompt/日、 來源覆蓋至少 8 runs、觀測窗 2–4 週滾動。 任何工具(包含這一支)宣稱「幫你測 AI 可見度」而只跑一次,數字都不可信。
  • 外部連結是否還活著不在檢核範圍——SITE-DEAD-INTERNAL-LINK 只驗站內路徑。 外連要另外跑連結健檢,判準見 PROMPT_連結驗證與來源查核SOP.md(非 2xx ≠ 失效)

    ⚠ 這條規則修過一次大誤判(2026-08-14),值得當成教材。 第一版只認「目錄形式」的輸出(/a/b/index.html → /a/b/), 於是在採 clean URL 的靜態主機上——Cloudflare Pages、Netlify、GitHub Pages 都是——連結寫 /gallery、輸出檔是 gallery.html,每一條都被報成死連結。 實測誤判率 67%(3 條裡 2 條是誤判),而且它是 error 級。

    它潛伏很久,是因為開發時用的網站剛好是目錄輸出,那個模式從第一版就對。 測試涵蓋的輸出模式,比規則本身寫得多漂亮更重要。

    改法是把方向倒過來:不要猜連結該長什麼樣,而是先算出每個輸出檔 實際到得了的所有網址形式,再看連結有沒有命中。回歸測試在 test/dead-link.test.mjs,三種輸出模式各埋一條真死連結—— 因為修誤判最容易的假解法,就是把規則放寬到不再觸發。

靜態檢核的天花板:大多數引用失敗這支腳本碰不到

arXiv 2603.09296 建了一份引用失敗的分類, 並給出各類在它那份樣本裡的佔比:

失敗類別佔比靜態 HTML 看得到嗎
技術完整性(存取封鎖、JS/動態渲染失敗、無法解析、訊噪比過低)10.1%大多可以
語意對齊(意圖分歧、脈絡缺口、資訊過時、地區錯配)62.2%不行——要知道查詢意圖與競爭對手
內容品質(資訊過淺、版面無結構=密集散文缺標題與表格)27.1%結構可以,深度不行
系統性排除(競爭冗餘、脈絡窗截斷)0.6%不行

⚠ 這些百分比是該篇樣本的分佈,不是普世常數,不要拿去當目標或基準。

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

有用的是那個方向:佔比最大的一類,靜態檢核在建構上就碰不到。 「意圖分歧」要知道使用者想幹什麼、「脈絡缺口」要知道競爭對手寫了什麼, 兩者都不在一份 HTML 裡。所以這支腳本全過不等於內容會被引用—— 它能替你排除的是技術與結構那一段,剩下的是寫作問題。

反過來,這份分類也給了現有立場旁證:

  • 「JS/動態渲染失敗」獨立成一個失敗模式 → 支持〈這支腳本不執行 JS〉
  • 該篇的修復工具裡有「加標題階層與清單」、「把 boilerplate 包進語意容器」、 「頂部摘要框」→ 對應 L2 的 heading 階層與正文可見量。這是 L2 那批規則 第一次拿到「與引用失敗有關聯」的旁證(關聯,不是因果)

另外兩件這支腳本碰不到的事

① 站外訊號,而且它可能比站內更重要。 arXiv 2509.08919(1,000 個消費類排序查詢、 US 與 CA、四個引擎)量到 AI 搜尋對第三方來源的壓倒性偏好:

領域AI 搜尋的 earned media 佔比Google 對照
汽車(CA)69.1%(brand 30.9%、social 0%)earned 40.6%、brand 36.6%
消費電子(US)92.1%brand 32.9%、social 15.4%
軟體(CA)74.2%(social 0%)brand 53.8%

同一效應另有兩篇獨立指向:2601.00912 發現有預測力的是 referring domains(+0.319)與社群聲量(+0.395), 而 GEO 分數與被發現率零相關;2603.12282 在 UK iGaming 上複製了同樣的偏好。

意思很直接:這份報告全過,仍然可能因為沒有第三方報導而不被引用。 本檢核器只讀單一站台的建置產物,站外聲量在它的視野之外。 這比上面那個 62.2% 更難堪,但更該講——一份檢核報告最容易造成的誤解, 就是讓人以為「全綠=做完了」。

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

⛔ 不要用互連來衝這個數字。 行銷公司常見的做法是讓手上客戶的網站 互相連結來拉高「有多少網站連到你」。這不是「未來可能被罰」的灰色手法—— 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%(差 30.6 個百分點,p<.001);案例品牌在中文 LLM 65.6%、國際模型 0%。

這給 L1-HREFLANG-* 那批規則一個原本沒有的理由:出英文版不只是 SEO, 是進入另一個訓練語料圈。 但語料收錄與否不在建置產物裡,所以這不是規則, 是一個判斷雙語投資值不值得時該知道的事實。

順帶一個實用觀察:2509.08919 的跨語言測試(100 查詢 × 10 領域 × 6 語言)顯示 Claude 跨語言重疊高、GPT 低於 Google、Google 只有 0–0.1。 不同引擎會依語言切換整個站台生態,所以「我的英文頁在某個引擎看得到」 不能推論到其他引擎或其他語言。

測試

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 skills/seo-aeo-audit/test/noindex-downgrade.test.mjs
node skills/seo-aeo-audit/test/geo-quote-detection.test.mjs
node skills/seo-aeo-audit/test/agent-check-rules.test.mjs

零相依,直接跑。59 條規則裡只有這幾條有測試——不是因為別條不重要, 是因為只有這幾條的「判準」出過問題:

測試出過什麼事
SITE-DEAD-INTERNAL-LINK在 clean URL 主機上整批誤判(誤判率 67%),而它是 error 級
L2-BILINGUAL-CONCAT數字一直是對的,但把兩種修法完全不同的狀況混在一起
L1-LANG-CONTENT-MISMATCH判準刻意單向(宣告英文卻整塊中日韓可報,反之不可)。沒有反向斷言守著,遲早被改成對稱,然後整批誤判
〈完整規則索引〉宣稱「一條不漏」卻漏 4 條,因為抽取與驗證腳本共用同一個盲點。現在也守文件裡的筆數與測試清單
L2-I18N-DICT-*「英文欄位裡是中文」——任何「有沒有填」的檢查都會判它通過,因為欄位確實填了。只能比對值本身,而且「相同」不等於「未翻譯」
L3-GEO-SIGNALS-* 的引言判準只認中文引號與 blockquote,拉丁引號 "…" 完全不算。同一門課的週次頁中文版引言 18–27 處、英文版 0 處,26 頁英文課程頁裡 24 頁被誤報。判準綁在書寫系統上,同一份內容會因語言得到不同結論
〈連線層〉規則表新增一支會報代碼的腳本,就得同時新增守著它的測試——這個 repo 的文件數字漂過三次。順便釘住「seo-check.mjs 維持零 fetch」,那是兩支分家的理由本身
noindex 降級判準同一原則套得不均勻(同一個 meta 欄位上 L1-DESC-SHORT 降 info、L1-DESC-MISSING 卻報 error)。而降級的邊界——OG 不降——是個很順口就會被人一起降掉的判斷,靠反向斷言釘住

⚠ rule-index.test.mjs 守的是文件,不是程式行為,而文件會用你想不到的 方式漂。它抓過三次同類錯誤:規則索引漏列、小節標題數字沒跟著改、 中英 README 的出處筆數停在舊值。 文件裡有幾個地方寫了數字,就要驗幾個地方——包括這張表自己, 少列一支測試也會失敗。

判斷哪條規則值得寫測試,看的不是它多複雜,是它錯的時候會不會讓人 不再相信整份報告,或會不會把人導向錯誤的修法。

L2-BILINGUAL-CONCAT 的判準為什麼不能靠標記

這條會報「N 處中英黏連」,但那個數字底下有兩種完全不同的狀況:

樣子該怎麼修
① 雙語 DOM同一份內容的中英兩版同時在 DOM 裡架構:改成獨立語言 URL
② 未翻譯 fallback英文頁上還沒翻譯的內容退回中文內容:翻完自然消失

加判準時試錯兩次,兩次都是靠標記:

  • 「有沒有 lang 屬性」 → 常見的雙語元件兩半都會帶 lang, 這樣會把①這種真正該修的一起消掉
  • 「兩邊都宣告且語言不同」 → 漏掉用 class="zh-only"/"en-only" 而不帶 lang 的手刻頁,那些也是①

最後改成靠內容:相鄰兩個元素,前者主要是中日韓、後者主要是拉丁 ——那就是同一份內容的兩個語言版本並排,與標記方式完全無關。

通則:判準要描述「要達成什麼」,不是「長什麼樣」。 綁在特定寫法上的判準,換一種寫法就失效,而且失效時是靜默的。 測試的三個雙語情境(lang 屬性/class/完全沒標記)就是在釘這件事。

  • 效能診斷要「先看總量,再看時序」。 第一個該問的是「這頁到底多大」(total-byte-weight),不是「哪個環節慢」。 ⚠ PSI 的「最慢請求」不能拿來排除網路因素——network-requests 記的是 實際採集時間,而 LCP/SI 是採集後才套用 4G 節流模型算出來的, 兩者是不同座標系的數字。

    實測案例(走了三步才找對):某站 LCP 106 秒,CPU 只用 1.1 秒、最慢請求 490ms, 於是先後懷疑「外部 fetch 逾時」與「輪播污染指標」——兩個假設都被實測推翻。 真正原因是三張 hero 照片共 20.8 MB(total-byte-weight 一直都在報告裡)。 壓縮後 106.1s → 4.4s。

  • Astro 專案的圖片位置決定會不會被最佳化:public/ 原樣送出, src/assets/ 才會經過 <Image> 轉 WebP 並產生響應式尺寸。 相機直出的照片放錯地方,就是幾 MB 直接送到瀏覽器
  • 內部連結判定:/ 開頭、相對路徑、與 --site 同網域的完整網址都算內部; 未傳 --site 時,指向自站的完整網址會被誤判為外連——跨網域檢核時記得傳
  • 結構化資料只驗語法與必填欄位,不驗 rich result 資格——那要到 Google 官方網頁版工具,無 API

完整規則索引

60 條規則:L1 13/L2 29/L3 4/SITE 14。 上面〈逐項怎麼修〉是策展過的常見項,這裡是全部。

這份索引由 test/rule-index.test.mjs 守著:新增規則卻沒補進來,測試會失敗並 指名漏了哪幾條。建立這份索引時漏了 4 條就是因為當時沒有這個守衛—— 抽取腳本只認 add('warn', 'CODE',於是把所有「嚴重度隨條件變動」的規則 (add(isNoindex ? 'info' : 'warn', 'CODE')整類漏掉,而驗證腳本共用同一個假設。

級別的意思:error = 幾乎必然有害且判準明確;warn = 該看但可能有正當理由; info = 訊號弱或數量大,不必清零。調整級別前先讀〈調整門檻時的原則〉。

L1 技術基礎(13)

代碼級別是什麼
L1-TITLE-MISSINGerror<title> 缺失或為空
L1-TITLE-LONGwarn標題的資訊核心過長。量核心不量全長——SERP 從尾端截斷,站名後綴被截掉不損失資訊
L1-TITLE-SHORTwarn標題全長過短。這裡量全長,因為後綴會顯示出來,站名也是資訊
L1-TITLE-REPEATEDwarn標題裡站名重複(頁面自己帶了一次、版型又補一次後綴)。長度檢查抓不到,各段分開看都不長
L1-DESC-MISSINGerror/info缺 meta description。noindex 頁降 info(不會出現在 SERP)
L1-DESC-LONGwarndescription 超過門檻。中文 90/英文 160,依 CJK 佔比自動切換
L1-DESC-SHORTwarn/infodescription 過短,說服力不足(它決定 SERP 點擊率)。noindex 頁降 info
L1-CANONICAL-MISSINGwarn/info缺 canonical,有查詢參數的頁面尤其重要。noindex 頁降 info(沒有索引訊號要合併)
L1-LANG-MISSINGwarn<html> 沒有 lang 屬性
L1-LANG-CONTENT-MISMATCHwarn/info宣告的語言與正文實際語言不符。只計算沒有用 lang 標記的外語——已標記代表作者知道也標對了,那不是缺陷。warn=未標記的外語明顯多於本文語言;info=介面元件(<option>/<button> 等)沒跟著換語言
L1-NOINDEXinfo此頁標了 noindex——確認是刻意的
L1-TWITTER-CARD-MISSINGinfo缺 twitter:card
L1-TWITTER-SITE-MISSINGinfo有 twitter:creator 但缺 twitter:site(作者帳號 vs 網站帳號,用途不同)

L2 內容結構(29)

代碼級別是什麼
L2-CLIENT-RENDEREDerror正文由瀏覽器端 fetch,爬蟲看到「載入中…」。結構可能全過但沒有內容
L2-CLIENT-RENDERED-PARTIALwarn正文量正常,但有局部動態區塊(留言、即時資料)。確認那一區需不需要被看到
L2-CLIENT-RENDERED-NOINDEXinfo同上但該頁已 noindex——讓「刻意的」與「該修沒修」分開計數
L2-THIN-CONTENTwarn/info扣掉 nav/header/footer 後正文過少。有載入佔位(原因已由 CLIENT-RENDERED 說明)或該頁 noindex(如 404,本來就該短)時降 info
L2-TEMPLATE-NOT-RENDEREDerror/info模板佔位元素是空的。比字數更直接的證據——176 字的空殼與 176 字的短文,字數上完全一樣。noindex 頁降 info
L2-ICON-LIGATURE-TEXTinfo圖示字型(Material Symbols 等)的 ligature 名稱就是元素的文字內容,會被爬蟲與 LLM 當成正文讀走(arrow_back dark_mode…)。⚠ 補救方式(aria-hidden="true")屬從業共識,無官方出處,所以只報 info
L2-FAKE-HEADINGerror<p class="section-heading"> 這類假標題。改標籤即可,class 不動、視覺零變動
L2-HEADING-EMPTYerror標題元素是空的(文字由 JS 填)。預設文字寫回 HTML
L2-H1-MISSINGerror沒有 h1
L2-H1-MULTIPLEwarn多個 h1
L2-HEADING-SKIPwarn標題階層跳級。根因常在缺的那一層,不是被報的那一層
L2-TITLE-NOT-HEADINGinfo卡片標題不是 heading。數量通常很大,不要全改——挑真的需要被讀成清單的地方
L2-NO-INTERNAL-LINKSerror/info孤島頁,讀者與爬蟲都走不到下一頁。noindex 頁降 info(索引面傷害消失,只剩讀者動線)——⚠ 這條的降級理由比其他三條弱,要收回先收它
L2-FEW-INTERNAL-LINKSinfo不重複內部連結少於 3 個
L2-IMG-ALT-MISSINGerror圖片沒有 alt 屬性
L2-IMG-ALT-EMPTYinfoalt=""——僅裝飾性圖片才該如此
L2-JSONLD-INVALIDerrorJSON-LD 語法錯誤,整段會被忽略,等於沒寫
L2-JSONLD-MISSINGwarn/info完全沒有結構化資料。noindex 頁降 info(複合式結果與 AI 引用都以已被索引為前提)
L2-ARTICLE-NO-DATEerrorArticle 型缺 datePublished
L2-ARTICLE-NO-AUTHORwarnArticle 型缺 author。YMYL 的第一要件是「誰寫的」
L2-FUTURE-DATEwarndatePublished 在未來=頁面已上線卻宣稱未發佈。多半是把排程日當發佈日
L2-NO-MODIFIED-DATEinfo有 datePublished 無 dateModified。⚠ 不要為了消這條而填假日期——沒有機制與刻意留空是兩回事,見〈調整門檻時的原則〉
L2-NO-TIME-TAGinfo日期只是純文字,沒有帶 datetime 的 <time>
L2-NO-ARTICLE-TAGinfo標為 Article 卻沒有 <article> 元素
L2-BREADCRUMB-MISSINGwarn缺 BreadcrumbList JSON-LD。路徑越深收益越大(首頁不報)
L2-BILINGUAL-CONCATinfo同頁雙語 DOM 造成的中英黏連。訊息會分辨兩種狀況:架構問題 vs 翻譯進度
L2-I18N-DICT-UNTRANSLATEDwarndata-i18n 字典裡,非中日韓語言的值仍是中日韓文字。欄位有填但沒翻——「有沒有填」的檢查抓不到。方向不對稱:中文字典裡有拉丁字母(品牌名、程式碼)不報
L2-I18N-DICT-KEY-MISMATCHwarn/infowarn=data-i18n 用了字典沒有的鍵(切語言時那個位置會是空的);info=各語言字典的鍵集合不一致
L2-I18N-DICT-UNCHECKEDinfo有 data-i18n 但找不到可解析的字典(只認得 zh:{…}, en:{…} 這類物件字面值)。明說未檢查,不是通過——多數站用 i18next 或別的格式

L3 AI 可見度(4)

代碼級別是什麼
L3-AI-SNIPPET-BLOCKEDwarn頁面設定使 AI 快照不可用
L3-AI-SNIPPET-PARTIALinfo快照資格受限
L3-GEO-SIGNALS-NONEinfoArticle 完全沒有可引用訊號(統計、引述、出處)
L3-GEO-SIGNALS-THINinfo可引用訊號偏少。刻意不給目標數字——論文沒有提供閾值

SITE 站層級(14)

代碼級別是什麼
SITE-ROBOTS-MISSINGerror沒有 robots.txt
SITE-SITEMAP-MISSINGerror沒有 sitemap
SITE-NOINDEX-UNLISTEDinfonoindex 且不在 sitemap 的頁面清單。不帶閾值、只列事實——這是 unlisted 頁的正常樣子,報出來是因為降級後這些頁不再產生任何 error,需要有一個地方能一眼掃過去確認都是刻意的
SITE-SITEMAP-NOINDEX-CONFLICTwarnsitemap 邀請爬蟲來看一個標了 noindex 的頁——矛盾訊號
SITE-TITLE-DUPerror多頁共用同一個 <title>=告訴搜尋引擎這幾頁是重複內容
SITE-DESC-DUPwarn多頁共用同一段 description
SITE-LANG-INCONSISTENTwarn同一語言用了多種寫法(zh-TW 與 zh-Hant 混用)。不是「站上有多種語言」——那是雙語站該有的樣子
SITE-DEAD-INTERNAL-LINKerror站內連結指向不存在的路徑。會處理 clean URL 與百分比編碼(見〈已知限制〉)
SITE-RSS-MISSINGwarn沒有 RSS feed——那是 LLM 抓內容的常用管道
SITE-LLMSTXT-MISSINGinfo沒有 llms.txt。Google 明言不使用,且實測 97% 的檔案零抓取;唯一在數據上明顯的消費端是編碼代理,所以判準是「你的讀者用不用 Cursor/Claude Code」
SITE-AI-POLICYinforobots.txt 對 AI 爬蟲的分流現況(擋訓練/開放檢索各幾支)
SITE-AI-CRAWLER-UNSPECIFIEDinfo有 AI 爬蟲未被明確允許或拒絕
SITE-AI-RETRIEVAL-BLOCKEDerror擋掉了檢索型爬蟲——那會讓 AI 回答時無法引用本站
SITE-CLAUDE-USER-BLOCKEDerrorrobots.txt 擋掉 Claude-User。⚠ Anthropic 是唯一會遵守這條的,擋了會讓使用者貼本站網址請 Claude 讀取時真的失敗

出處

出處要能被解析成可驗證的位置,不能只寫名稱。 只寫名稱的話, 「這條規則還成立嗎」沒辦法回查,也沒辦法自動監測它有沒有悄悄改版。

來源用在哪
Google Search Quality Rater Guidelines(2025-09-11 版,182 頁)L4 全部頁碼依據
GEO: Generative Engine Optimization(Aggarwal et al., KDD 2024;arXiv 現為 v3)五戰術與 L3-GEO-*
A Critical Survey of GEO (2023-2026)(回顧 45 篇)L3-GEO-* 的證據強度限定
What Gets Cited: Competitive GEO in AI Answer Engines(252,000 次試驗、6 個模型、18 因子)L3-GEO-* 的「不給目標數字」立場
Structural Feature Engineering for GEO不是任何規則的依據——記錄證據衝突,見下
Diagnosing and Repairing Citation Failures〈靜態檢核的天花板〉;不執行 JS 的旁證
The Discovery Gap四層的排序;GEO 分數與被發現率零相關
Don't Measure Once〈已知限制〉為何不做單次可見度量測
SAGEO ArenaL1/L2 欄位在檢索階段的實測支持(+22% Hit Rate)
FeatGEOL3-GEO-* 三項訊號的逐特徵 ablation
How to Dominate AI Search〈已知限制〉站外訊號碰不到(earned media 69–92%)
The Existence Gap為什麼 hreflang 不只是 SEO 問題
E-GEO不是任何規則的依據——記錄「普遍策略」的衝突主張
Google SEO Starter GuideL1 多數規則
Google robots.txt 規範SITE-ROBOTS-*、SITE-AI-*
Google 結構化資料總覽L2-JSONLD-*、L2-ARTICLE-*
Google AI 功能與你的網站SITE-LLMSTXT-MISSING 的措辭
Ahrefs llms.txt 研究(137,210 網域)llms.txt 97% 零抓取;編碼代理是唯一明顯消費端
SE Ranking(約 30 萬網域)/OtterlyAI(90 天日誌)同上,方法不同、結論同向

最後一條的逐字聲明(段落「Mythbusting generative AI search: what you don't need to do」):

"You don't need to create new machine readable files, AI text files, markup, or Markdown to appear in Google Search (including its generative AI capabilities), as Google Search itself doesn't use them... Doing so will neither harm nor help your site's visibility or rankings in Google Search, as Google Search ignores them."

這份清單的機器可讀版在 watch/sources.json, 由 GitHub Actions 每月檢查是否失效或改版。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.