AI 生成的 MDX 模板大多一开始很漂亮,写到第 30 篇就难看了——一次性组件太多、间距不统一、版式跟内容打架。这篇给 10 个能扛过 1000 篇的版式模式、让 LLM 干净产出它们的 prompt 结构,以及把词汇表在构建期锁死的 Astro 加 Shiki 配置。
TL;DR
- 挑 5-7 个版式模式,每种定义成一个组件或一个 CSS 类,禁止其他所有临时样式块。
- 用三样东西驱动 LLM:固定模式清单、一篇真实文章当风格锚点、新选题。不挂锚点,出来就是通用 SaaS 博客腔。
- 词汇表分两层强制:Astro 内容集合上的 Zod schema(管 frontmatter),加一个约 30 行、挂到
prebuild的 lint 脚本(管正文结构)。 - 文章为主的站点直接手写:5 个组件加约 200 行 CSS 胜过一整套组件库。代码高亮用构建期的 Shiki(零客户端 JS),别用浏览器里的 Prism。
为什么固定词汇表很重要
MDX 是 Markdown 加组件,所以一个文章模板本质上就两个决定:哪些 Markdown 元素做全局样式,哪些专门组件对外暴露。AI 这两件都能做好,前提是你给它约束。让它”设计一个漂亮的文章模板”,出来就是渐变背景加 Tailwind 糊汤。给它一份固定组件清单加一篇内容样本,出来的东西真的能维护。下面 10 个模式是我们一个 1200 篇双语站正在用的。
模板漂移的成本是非线性的。50 篇时不一致还像”差一口气的修饰”。500 篇时每次漂移都要改几百个文件。过了 1000 篇,你就不再 refactor,转而用样式覆盖把漂移盖过去——这是最差的中间状态。词汇表要早定。
怎么判断你需要这个
- 在搭新内容站,或想刷一遍老站的版式。
- 当前模板每篇文章里有 6+ 个临时样式 div,自己都在反复调。
- 新作者(或 AI)每次都自创标题层级,因为模板没有清晰词汇表。
- 想用同一套模板撑教程、故障排查、清单、评测四类内容。
一句话结论
从下面 10 个里挑 5-7 个核心模式。每种定义成一个组件,或标准 HTML 元素上的一个 CSS 类。禁止其他临时样式块。让 AI 在这个固定词汇表里生成文章,而不是每篇自创新形状。
10 个模式
- 步骤清单:带粗体起手短语的有序列表。用普通
<ol>加<strong>首句即可,不需要专门组件。 - 对比表:最多 3 列(选项、何时用、何时不用)。普通 Markdown 表格,全局加斑马纹和小型大写体表头。
- 决策树:带条件缩进的列表。嵌套最多 2 层,更深就单独开一节。
- 结论盒:单段
<aside>,左侧边线样式。每篇文章靠前位置只放一个。 - 带说明的代码块:code block 紧跟一行斜体说明。不需要专门组件,用 CSS 兄弟选择器。
- 诊断表:症状、原因、修法,三列 Markdown 表格。故障排查类必用。
- 行内复选清单:
- [ ]任务列表。「开始前准备」一类章节常用。 - 引用块:真实的平台报错或拒绝原因截图文字。样式做成 callout,不是普通 blockquote。
- 对比示例:Bad / Good 代码或文本对。用
textcode block 加Bad:/Good:前缀就行,越简单越好。 - 相关链接组:
## 相关下的 3-6 条链接,总是在末尾,每篇形状一致。
让 LLM 出干净输出的 prompt 结构
给模型三样:固定模式清单、一篇真实 MDX 样本、新文章选题。用下面这组约束锚定 prompt:
- 只用列出的 10 个模式。不要发明新组件或样式 div。
- 标题:只用 ## 层级,内容确实超 4 个子节再用 ###。
- 不用 emoji,不用感叹号,不用营销腔。
- 首段:2-3 句,无标题。
- 末节始终是 "## 相关",含 3-6 条链接。
- 语气和样本文一致。
不挂样本文章,模型会在它的训练数据上做平均,出来就是通用 SaaS 博客腔。挂上样本,它会模仿你的风格——通常好到每篇 10 分钟微调就能用。
截至 2026 年 6 月,当前两家前沿编码模型都能稳定做到这点:Claude Opus 4.7 和 Sonnet 4.6 能在长文里守住整组约束,GPT-5.5(Thinking)水平相当。这里的高性价比主力是 Sonnet 4.6——每 1M 输入/输出 token 3/15 美元,大约是 Opus 4.7(5/25 美元)的一半,做模板化正文足够。把 Opus 留给少数结构确实难搞的文章。
怎么强制执行词汇表
强制执行分两层,两层你都要。
frontmatter——用 Zod schema 管。 Astro 内容集合(截至 2026 年 6 月,Astro 6 用 Zod 4 schema)在构建期校验每篇文章的 frontmatter。把键定义一次、标记必填,少一个或类型错了,渲染任何页面之前 build 就先失败:
const articles = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/articles" }),
schema: z.object({
title: z.string().max(70),
description: z.string().min(50).max(160),
tags: z.array(z.string()).min(1),
translationKey: z.string(),
}),
});
正文结构——用 lint 脚本管。 Zod 看不进 MDX 正文,所以再加一个约 30 行的脚本扫所有文件:数 ## 标题数、检查末节是不是 ## 相关、标记 allowlist 之外的组件、标记正文里的裸 <div> 标签。挂到 prebuild,文件失败就 build 失败。再留一个 examples/ 目录,每个模式一份 MDX 当作活文档,模型生成新内容时能读到。每篇新文章 PR 附一行清单:用了哪几个模式、没用哪几个、为什么。
老模板迁移
- 盘点现有所有文章里用到的组件。多数老模板有 30+ 个组件,一半只出现过一次。
- 把每个现有组件映射到 10 个模式里的一个,或标记删除。目标 5:1 缩减。
- 跑一遍 codemod,把废弃组件替换成标准等价物。给模型 3-5 个 before/after 例子,它写 codemod 写得很好。
- 50-100 篇一批迁。每批 build 一次;一篇意外炸了,通常是 codemod 漏了某个边角情况。
手写 vs 组件库
文章为主的内容站,手写在体积和可维护性上都赢。下面这张表就是实际的取舍。
| 方案 | 客户端 JS | 1000+ 篇时的维护成本 | 最适合 |
|---|---|---|---|
| 5 个组件 + 约 200 行 CSS | 基本为零 | 低——只管一套词汇表 | 文章 / 内容站 |
| shadcn/ui 之类 | 每组件一份打包 | 较高——库本身在变 + 用不到的部分 | 应用面板、交互式 UI |
| 每篇文章的样式 div | 不一定 | 最差——漂移会累积 | 没有;别用 |
代码高亮:Shiki,配一次
截至 2026 年 6 月,Shiki 是 Astro 默认的高亮器,在构建期高亮代码,页面就不会为高亮发任何客户端 JS。有一个配置坑人人都会中:astro.config.mjs 里的 markdown.shikiConfig 对 .md 和 .mdx 的代码围栏生效,但独立的 <Code /> 组件不会继承它。通过 CSS 变量配明暗双主题,运行时切主题就零成本:
// astro.config.mjs
markdown: {
shikiConfig: {
themes: { light: "github-light", dark: "github-dark" },
},
}
Astro 把高亮后的标记输出在 .astro-code 元素上(不是 .shiki),暗色模式 CSS 要对这个类写。什么都不设时,默认单主题是 github-dark。
容易踩的坑
- 让模型为「视觉多样性」自创组件。多样性会杀掉一致性;模式清单本身就是多样性。
- 让模型「设计一个漂亮的模板」无约束。出来是渐变 + 动效 + 三种字体。
- 生成的组件没在 MDX 里先测就上。有些库会在 MDX 花括号上炸——正文里一个
{value}就能让 build 失败,先在一篇文章里跑通再推广。 - 跳过样本文章。模型默认套用它训练集里流行的博客模板,不是你的风格。
- 每节之间加装饰性分隔线(
---)。MDX 渲染成<hr>,纯视觉噪声、没信息量。
常见问答
能让模型直接设计组件吗? 第一版可以。最终样式自己来,或者让设计师配模型。AI 提形状还行,挑间距和配色弱一些。
怎么防止 1000 篇里模板漂移?
两层。内容集合上的 Zod schema 在构建期挡住 frontmatter 问题;挂到 prebuild 的约 30 行 lint 脚本查正文结构(标题层级、末节是不是 ## 相关、有没有用 allowlist 外的组件)。两层一起,绝大多数漂移会在部署前被挡下。
EN 和 ZH 能共用一套模板吗? 能。间距、字体栈、行高定义一次。中文版通常要稍紧的行高和不同的字体回退;其他完全一致。
暗色模式怎么处理? 定义语义色变量(background、foreground、muted、accent),每个组件都读这些变量。绝不在组件里硬编颜色。
要用 shadcn 还是自己写? 文章为主的内容站自己写。shadcn/ui 做应用 UI 很好,但对文章站是多余的体积。约 200 行 CSS 加 5 个组件这里就胜过一套组件库。
代码高亮放哪?
用构建期的 Shiki,不要浏览器里的 Prism。Shiki 不往客户端发任何 JS,渲染效果一样。配两套主题,用 CSS 变量切换。记住独立的 <Code /> 组件要单独配主题——它不吃 markdown.shikiConfig。
需要 MDX provider 注册全局组件吗?
看实际复用度。Aside、Callout 之类跨多文件用的组件再考虑。5 个组件的小词汇表,每文件 import 就行,build 更简单。
模板要不要做版本?
非正式地做。大改动记到 CHANGELOG.md,知道哪些文章是在 v1 写的、哪些是 v2。排查老文章样式异常时很有用。