怎么用 AI 审计 Astro 内容站(不用逐文件读)

一套可复用的 Astro 5/6 内容站 AI 审计:抓重复 slug、缺翻译、死内链、draft 泄漏,一个脚本接进 prebuild 就能挡住漂移。

过了 50 篇文章,Astro 内容站就会冒出看不见的漂移:跨语种重复的 urlSlug、指向空的 translationKey、页面改名后没人管的死内链、明明 draft: true 却照样上线的文件。手动逐个文件读既不可扩展,也没法重复跑。这篇教你用 AI 把 frontmatter 规则写成一个 audit-content.mjs 脚本,按严重度分批修,再把脚本接进 prebuild,让同样的漂移下次部署再也回不来。

一句话总结

  • 让一个真正能读文件的 agent(Claude Code 或 OpenAI Codex CLI)读 5 到 10 个 MDX,写出你的 frontmatter 契约。
  • 把契约变成一个 scripts/audit-content.mjs,用 gray-matter 解析 frontmatter,标四类问题:缺必填字段、同语种内 urlSlug 重复、translationKey 配对断裂、死内链。
  • 让脚本在硬问题上 process.exit(1)、软问题只 warn,然后跑 node scripts/audit-content.mjs 小批量修。
  • 把脚本加进 package.jsonprebuild,这样坏页面到生产之前 npm run build 就先失败。

这篇讲什么

这里的产出不只是一份问题清单,而是一个每次 build 都跑的脚本,加一份按严重度排好的修复计划。在 Astro 5 和 6 里,内容放在由 src/content.config.ts 定义的 collection 中(这个文件在 Astro 5.0 从 src/content/config.ts 改名而来),用内置的 glob() loader 加载,每个条目暴露的是 id 而不是旧的 slug。你的审计直接读 .mdx 原文,完全不依赖 Astro 的运行时。

几个关键词:

  • Frontmatter 契约:每个内容文件必须带的字段(urlSlugtranslationKeylangdraftcategory 等),以及每个字段允许的取值。
  • 漂移:新加的内容慢慢违反你半年前定下的契约。没有强制检查,它一定会发生。
  • BLOCKER 与 WARN:BLOCKER 会让 build 挂掉(重复 slug、缺必填字段);WARN 只记录但照样发(翻译还在做、translationKey 暂时配不上)。

这篇适合谁看

Indie 开发者和内容工程师,跑着超过 50 篇文章的 Astro 内容站——尤其是双语 / 多 locale 站,每对翻译都会引入新的不变量要验证。如果你的仓库已经有 prebuild,这套东西可以直接接上去。

什么时候适合用

上线前。content schema 重构后。每个季度。从别的 CMS 迁内容之后。任何要证明”加内容没把已有的弄坏”的时候。文章级审计跑干净后,把同一套打法往上挪一层,对照 AI Category 页审计教程——Category 页和 Tag 页是大多数团队忽略的面,会悄悄拖垮抓取效率。

选对 AI agent

这套流程靠的是能就地读写文件的 agent,而不是一个你往里粘贴的聊天框。截至 2026 年 6 月,两个实用选择:

Agent模型文件访问编辑模式
Claude Code仅 Anthropic(Sonnet 4.6 / Opus 4.7)整个项目树,写入前需批准先出计划,批准后打补丁
OpenAI Codex CLIGPT-5.5沙箱限定在当前项目目录Suggest(默认)/ auto-edit / full-auto

两者都是终端 CLI,都会读一个项目记忆文件(Claude Code 是 CLAUDE.md,Codex 是 AGENTS.md),你可以拿来固定 frontmatter 契约。如果你常驻编辑器,Cursor 的 agent 模式也行。纯聊天模型理论上也能用,但复制粘贴的成本会把”可重复审计”这件事本身的意义抵消掉。这个 agent 怎么延伸到技术 SEO 检查,见 Claude Code SEO 审计教程。官方文档:Claude CodeCodex CLI

开始前准备

  • 工作树要干净(git status 没有改动)。有几类修复是批量改名,你要随时能 git revert
  • 确认本地 build 能跑。Astro 5+ 上审计要在 prebuild 里跑,先得有绿色基线。如果规模大到 build 爆内存,把堆调大:NODE_OPTIONS=--max-old-space-size=8192 npm run build
  • 装一次 frontmatter 解析器:npm i -D gray-matter。它能处理 YAML 的边角情况(多行字符串、列表),这些是手写正则会漏掉的。

具体步骤

  1. 数清面有多大。跑 find src/content -name "*.mdx" | wc -l,留一个数字,后面用来校验脚本。
  2. 抽出契约。让 agent:“读 src/content 下随机 8 个 MDX,写出 frontmatter 契约——哪些字段必填、哪些可选,以及 langcategorysubcategory 各允许什么值。” 把结果贴进 CLAUDE.md / AGENTS.md
  3. 收紧契约。agent 只看了样本,会把一些必填字段标成可选。把实际必填的提回来(urlSlugtranslationKeylang)。
  4. 用这段 prompt 生成审计脚本:
写 scripts/audit-content.mjs(ESM)。遍历 src/content/**/*.mdx,
用 `gray-matter` 包解析每个文件的 frontmatter,并标出:
- 按上面契约缺必填字段                      -> BLOCKER
- 同 lang 内 urlSlug 重复                    -> BLOCKER
- translationKey 一个 lang 有、对应 lang 没有 -> WARN
- 非 WIP 文件上的 draft: true               -> WARN
- 内链(/en/articles/<slug>/ 或 /zh/...)    -> BLOCKER
  解析不到已有的 urlSlug
每行一条发现,前缀严重度,末尾一个汇总块。
有任何 BLOCKER 就 process.exit(1),否则 exit 0。
  1. 跑起来并捕获输出:node scripts/audit-content.mjs | tee audit.txt
  2. 按根因分组。把 audit.txt 喂回去:“这是 N 条发现,按根因分组,每组提最小修复。” 一个改名的页面常常一口气解释掉十几条死链发现。
  3. 分批打补丁。每个 BLOCKER 组让 agent 写真实改动——frontmatter 编辑、文件改名或链接重写——每批之后重跑脚本。如果计数不降反升,立刻停。
  4. 接进 build。在 package.json 里加:
"scripts": {
  "audit:content": "node scripts/audit-content.mjs",
  "prebuild": "node scripts/audit-content.mjs"
}

这样未来任何漂移都会在坏页面生成之前让 npm run build 非零退出。

第一次实操怎么跑

  1. 跑审计但什么都先别修。冷读一遍报告。
  2. 挑出现最多的那一条(通常是 translationKey 不匹配或 urlSlug 重复)。只修这一类,然后重跑。
  3. 确认计数恰好降了你修的那么多。没降就说明脚本有 bug——先修脚本,再动内容。
  4. 故意种一个已知坏案例:临时把一篇已发布文章设成 draft: true,确认审计抓到了。没抓到,说明规则没在检查你以为的东西。

完成后检查

  • 一条被标的发现能用手工 grep 复现吗?如果 grep 那个 slug 和脚本说的对不上,规则里有误报。
  • 多次运行结果稳定吗?顺序随机没关系,数量随机就是 bug。
  • 够快能上 prebuild 吗?1,000 个文件 3 秒内算正常——Astro 5 的 content layer 让 Markdown 构建快了最多 5 倍,但你的审计跑在它之外,所以 I/O 要尽量精简。
  • 汇总块里”看到的文件总数”和 find ... | wc -l 对得上吗?对不上说明 glob 漏了文件。

怎么复用这套流程

  • scripts/audit-content.mjs 入版本控制。别每次重生成——演进它。
  • 发现新漂移模式就增量加规则(孤儿 tag、缺 hreflang、description 过长)。脚本会随站的生命周期越攒越值。
  • 大批量加内容之前也跑一次,不只是之后跑,让你从已知干净的状态出发。
  • frontmatter 和 slug 收拾干净后,再叠一层按你技术栈生成的 SEO checklist,让 render mode、hreflang、schema 这些项跟内容一起被检查。

容易踩的坑

  • **靠人工逐文件读。**会漏,而且下季度跑不动。
  • **一次把所有修复都应用了。**build 挂了你说不清是哪条修的。分批,每批后重跑。
  • **跳过 prebuild 接线。**下个月同样的漂移又回来,因为没东西在防它。
  • **不给例子就让 agent 写规则。**给它 3 到 5 个已知坏文件;从真实案例长出来的规则更准。
  • **把每条 WARN 都当 BLOCKER。**你永远发不了。翻译还在进行中是 WARN,不是 build 失败。
  • **没 commit 就重跑。**未提交状态会把下一轮分组搅乱。

FAQ

  • 哪种 AI 最适合这件事?:Claude Code(Anthropic 模型)或 OpenAI Codex CLI(GPT-5.5),两者都有直接的文件访问。Codex 默认把写入沙箱限定在项目目录里;Claude Code 每次写入前会请求批准。纯聊天模型也能用,但复制粘贴成本会侵蚀掉整套流程。
  • Astro 5 和 6 都能用吗?:能。审计读的是 .mdx 原文,跟 Astro 运行时无关。只要记住配置文件是 src/content.config.ts(Astro 5.0 改的名),条目暴露的是 id 而不是旧的 slug
  • 双语站怎么处理?:每个 lang 各跑一遍做 slug 唯一性检查,最后再跑一遍配对检查,断言每个 /en 里的 translationKey/zh 都有对应。翻译还在做时缺对应算 WARN,已上线就算 BLOCKER。
  • 非 MDX 内容呢?:同流程,换 glob。JSON 内容文件、纯 Astro Markdown、YAML 数据文件,都受益于”契约 → 脚本”的做法——把 gray-matter(或 JSON.parse)指向对的文件即可。
  • 多久跑一次?:通过 prebuild 每次 build 都跑。大批量导入内容前手动跑一次,content schema 重构后也跑一次。
  • 1,000+ 文件时审计脚本爆内存。:流式读文件清单、逐个读文件,别把所有正文一次性加载进内存;或者把审计按 category 分批跑。把 Node 堆调到 --max-old-space-size=8192 只是权宜之计,不是根治。

相关阅读

标签: #教程 #SEO #AI 编程 #Astro #审计