Agent Skill 与网站生成

AI 生成的网站为什么总像模板?一次反模板工作流的工程化实践

从内容主角、设计检索到可观察验收规则,拆解如何让 AI 网站摆脱通用模板。

Agent Skill反模板设计工作流

你可能遇到过这种情况:

把简历、产品介绍或项目资料交给 AI,要求它“生成一个有设计感的网站”。几分钟后,AI 确实交付了一个能运行的页面——大标题、渐变背景、圆角卡片、技能标签、项目网格和滚动淡入,一个不少。

但你总觉得在哪里见过它。

问题不一定是 AI 不会写 CSS,也不一定是卡片、渐变和圆角本身不好。更常见的原因是:AI 在缺少设计约束的情况下,会选择最安全、最常见、最容易组合的界面模式。

如果只在网站生成后说“不要这么模板化”,往往已经太晚了。

我在开发一个作品集网站生成 Skill 时,尝试把“反模板”从模糊的审美要求,改造成一条可以追踪、验证和修复的工程链路:

内容分析
→ 设计数据库检索
→ 前置反模板基线
→ 六项视觉决策
→ 创意方向解析
→ 设计合同
→ React 网站生成
→ 多端截图审计

这篇文章就来介绍这套工作流是如何实现的。


一、AI 生成的网站为什么容易模板化?

先看一个常见提示词:

根据这份简历,帮我生成一个现代、专业、有设计感的个人作品集网站。

它看起来提出了设计要求,但其中几乎没有可以执行的约束。

“现代”“专业”“有设计感”都没有回答以下问题:

  • 哪段内容应该成为视觉主角?
  • 页面为什么采用这种构图?
  • 经历、项目和技能是否应该具有相同权重?
  • 哪个结构是这个网站独有的视觉记忆点?
  • 动效在帮助理解什么?
  • 到了移动端,哪些设计特征必须保留?

缺少这些答案时,AI 最容易回到高频模式:

居中 Hero
→ 技能标签
→ 三列项目卡片
→ 时间线经历
→ 联系方式

每个局部都说得过去,但组合起来很像模板。

模板感的真正来源

模板感通常不是某个组件造成的,而是以下问题共同作用的结果:

  1. 内容没有决定形式;
  2. 所有信息被处理成相近的视觉权重;
  3. 结构、字体、颜色和动效彼此独立;
  4. 设计个性直到生成末期才被讨论;
  5. 审查依赖“感觉”,没有可验证标准。

因此,反模板不能只靠最后一轮美化,而要进入整个生成流程。


二、把反模板设计看成一次“编译”

我采用的核心思路是:

不让 AI 直接把内容翻译成 React,而是先把内容编译成设计约束,再把设计约束编译成网站。

整个过程可以理解为一个设计编译器:

flowchart LR
    A["已确认内容"] --> B["内容地图"]
    B --> C["数据库设计基线"]
    C --> D["前置反模板基线"]
    D --> E["六项视觉决策"]
    E --> F["Creative Direction"]
    F --> G["Design Contract"]
    G --> H["React + Vite 网站"]
    H --> I["截图审计与局部修复"]

其中:

  • 内容地图回答“这个网站属于谁”;
  • 设计数据库提供候选设计知识;
  • 反模板基线回答“这个网站为什么不应该长成通用模板”;
  • 六项决策让用户逐步控制结果;
  • 设计合同把审美方向转换成可观察规则;
  • 截图审计检查最终实现是否兑现了承诺。

这样,React 代码不再是设计过程的起点,而是设计决策完成后的执行结果。


三、第一步:让内容决定视觉方向

反模板设计首先需要理解内容,但这里不能直接把整份简历交给所有后续设计工具。

工作流会先生成一个隐私安全的 content-map.json,只保留设计检索真正需要的信息,例如:

{
  "profile": {
    "role": "frontend engineer",
    "industry": "developer tools"
  },
  "content_density": "high",
  "media_profile": "limited",
  "keywords": [
    "React",
    "design systems",
    "accessibility",
    "interaction design"
  ]
}

它不会包含姓名、电话、邮箱、地址或完整简历正文。

这份内容地图的作用不是决定页面长什么样,而是缩小设计搜索空间。

例如:

  • 内容密度高,可能需要更强的信息层级;
  • 项目决策过程丰富,适合编辑式叙事;
  • 授权媒体较少,应该依赖字体、编号、留白和 CSS 几何;
  • 技术主题集中,可以建立持续出现的项目索引或系统结构。

数据库只提供候选,不替用户做决定

接下来,Skill 会查询内置设计数据库,获得构图、字体、配色、UX 和动效方面的候选证据。

每个候选都必须保留来源 ID,例如:

{
  "id": "direction-1",
  "style_family": "editorial",
  "composition": "asymmetric project narrative",
  "source_ids": [
    "style:editorial",
    "landing:project-story",
    "typography:editorial-technical"
  ]
}

如果数据库无法提供足够完整的候选,流程会停止并报告缺失信息,而不是把 AI 临时构思的方案伪装成数据库结果。

不过,仅仅让数据库提前介入还不够。

数据库可以告诉我们有哪些设计模式,却不会自动回答:哪种组合最能代表当前内容,又如何防止它退化成模板?

这就需要前置反模板基线。


四、在第一次视觉选择前建立反模板基线

早期版本的流程有一个问题:视觉主角、结构签名和反模板规则主要在六项选择结束后才形成。

这意味着字体、颜色和动效可能分别看起来合理,但组合后依然模板化。

为了解决这个问题,我增加了:

design-discovery/anti-template-baseline.json

它在数据库基线生成后、询问整体结构之前创建。

一个简化后的结构如下:

{
  "id": "anti-template-baseline:direction-1",
  "status": "provisional_unapproved",
  "visual_protagonist": "项目决策和工程结果构成的成长路径",
  "content_form_thesis": "项目之间存在因果和递进关系,不应被压成等权卡片",
  "composition_hypothesis": "非对称的项目叙事结构",
  "signature_device_candidates": [
    "持续存在的项目编号索引",
    "连接决策与结果的结构轨迹"
  ],
  "template_independence_claim": "即使移除最终图片和动效,项目索引仍能让页面保持可识别性",
  "anti_template_rules": [
    {
      "id": "anti-template.no-equal-card-grid",
      "criterion": "不得把项目、经历和技能压成重复的等权卡片"
    },
    {
      "id": "anti-template.signature-remains-visible",
      "criterion": "响应式布局中必须保留可识别的结构装置"
    },
    {
      "id": "anti-template.effects-have-purpose",
      "criterion": "表面效果和动效必须服务于内容、层级、交互或导航"
    }
  ]
}

这里有一个非常重要的字段:

"status": "provisional_unapproved"

它表示这只是设计假设,不是用户批准。

反模板基线可以约束后续推荐,但不能:

  • 自动选择整体结构;
  • 代替用户完成六项视觉决策;
  • 因为“系统已经推荐”就开始写 React;
  • 把浏览器预览当作批准。

这是为了避免系统从“没有约束”走向另一个极端:过早锁死设计。


五、把反模板要求分配给六项视觉决策

一个网站是否模板化,不只由整体结构决定。

即使结构有特点,如果字体、配色和动效全部回到常见默认值,最后仍然可能失去个性。

因此,反模板基线会为六项视觉类别分别设置义务。

类别必须保持应避免
整体结构视觉主角和可识别构图居中 Hero 加等权卡片网格
字体系统项目决策与结果的层级差异所有内容使用相同的字体关系
配色系统用颜色强化内容优先级平均分布渐变、发光和强调色
媒体处理给真实素材明确的叙事作用装饰性图库图片和重复占位图
主动效服务叙事推进或导航给所有区块套同一种淡入动画
副动效解释状态、层级或操作与主动效竞争的纯装饰效果

六项选择按照固定顺序执行:

整体结构
→ 字体系统
→ 配色系统
→ 媒体处理
→ 主动效
→ 副动效

后面的选择必须继承前面已经批准的决定。

这很重要,因为设计系统最容易在“分项优化”中失去一致性。

例如:

  • 结构阶段选择了编辑式非对称叙事;
  • 字体阶段却使用普通 SaaS 产品字体;
  • 配色阶段又加入大面积科技蓝渐变;
  • 动效阶段给每个区块统一加淡入。

单独看每个选择都不算错误,但它们组合后会破坏原本的视觉主线。


六、每个候选都必须回答:它是在强化还是破坏设计身份?

每次查询某个视觉类别时,系统都会同时读取:

  • 内容地图;
  • 数据库设计基线;
  • 前置反模板基线;
  • 此前已批准的决策;
  • 当前类别的反模板义务。

生成的候选不只包含“适不适合”,还要声明它与反模板基线的关系:

{
  "id": "structure-1",
  "label": "编辑式项目索引",
  "source_ids": [
    "landing:project-story",
    "style:editorial"
  ],
  "anti_template_evaluation": {
    "baseline_rule_ids": [
      "anti-template.no-equal-card-grid",
      "anti-template.signature-remains-visible"
    ],
    "obligation_ids": [
      "anti-template-obligation.structure"
    ],
    "relationship": "strengthens",
    "rationale": "项目索引能够强化内容优先级,并避免等权卡片结构"
  }
}

relationship 只有三种:

  • strengthens:强化设计主线;
  • preserves:保持设计主线;
  • conflicts:与主线冲突。

冲突候选并非完全不能展示。

如果它代表一种真实的设计取舍,可以明确标记后展示给用户,但不能成为默认推荐。如果某一类别的所有候选都与反模板基线冲突,流程会停止,而不是强行选出一个“最不差”的方案。

这让“推荐”从一句自然语言意见,变成了带规则和证据的判断。


七、让六项选择形成一条可追踪的继承链

每个类别报告都会记录:

{
  "inherited_decision_ids": [
    "structure-1",
    "typography-2",
    "color-1"
  ]
}

这表示当前候选是在什么设计上下文中产生的。

以媒体选择为例,它不是只根据“有没有图片”生成建议,而是要同时考虑:

  • 已批准的整体结构;
  • 字体层级;
  • 配色关系;
  • 视觉主角;
  • 标志性结构装置;
  • 媒体类别自己的反模板义务。

如果用户后来推翻整体结构,结构之后的字体、配色、媒体和动效报告都会失效,需要重新检索。


八、把临时假设解析成正式创意方向

六项选择全部完成后,系统会先生成聚合产物:

design-intelligence.json

它保留:

  • 数据库设计基线;
  • 前置反模板基线;
  • 六项批准结果;
  • 每个候选的反模板评价;
  • 数据库来源和继承关系。

随后生成:

creative-direction.json

这一步需要逐条处理前置反模板规则。

每条规则必须被标记为:

adopted
refined
rejected_by_approved_choice

例如:

{
  "rule_id": "anti-template.no-equal-card-grid",
  "status": "refined",
  "approved_candidate_ids": [
    "structure-1",
    "typography-2"
  ],
  "evidence_ids": [
    "style:editorial",
    "typography:high-contrast-hierarchy"
  ],
  "rationale": "项目允许局部使用同类容器,但经历、项目和技能不能共享同一视觉权重"
}

为什么还需要这一步?

因为前置基线是在用户选择前生成的,其中有些假设可能被后续选择修正。

因此,系统不能偷偷忽略早期规则,也不能要求用户永远服从机器最初的推荐。它必须明确记录:

  • 哪些规则保留了;
  • 哪些规则被细化了;
  • 哪些规则因为用户明确选择而放弃了;
  • 放弃的依据是什么。

验证器会比较前置规则与解析结果。如果少处理了一条规则,创意方向无法通过校验。


九、把审美要求编译成设计合同

creative-direction.json 仍然包含不少抽象设计语言。

在真正生成 React 之前,系统还会生成:

design-contract.json

它将批准的设计方向转成可以通过实现和截图观察的承诺。

设计合同包括:

  • identity_strategy:内容身份与叙事优先级;
  • signature:视觉主角、构图和结构装置;
  • layout:布局关系和响应式变化;
  • typography:字体角色和层级关系;
  • color:颜色角色和使用边界;
  • surface:圆角、阴影、纹理和装饰语言;
  • motion:主动效、副动效及其目的;
  • anti_template_rules:模板化失败条件;
  • acceptance_checks:最终验收条件;
  • traceability:规则来自哪些批准决策。

只有设计合同验证成功后,系统才允许第一次修改 React 源码。

换句话说:

AI 不是先写网页,再解释自己为什么这么设计;而是先提交设计承诺,再依据承诺写网页。


十、一次性生成完整网站,而不是逐步堆叠预览

发现阶段可能会生成浏览器 Gallery,用来比较字体、配色或动效候选。

但这些 Gallery 只是决策证据,不是正式网站。

正式生成时,系统只维护一个可编辑的 React + Vite 项目:

.resume-site-work/site

在最终需求、TODO Plan 和执行方式全部批准后,才会一次性应用:

  • 内容;
  • 页面结构;
  • 字体;
  • 配色;
  • 媒体;
  • 一个主动效系统;
  • 所有兼容的副动效;
  • 响应式和可访问性要求。

这能避免页面在多轮零散修改中逐渐失去整体性。


十一、反模板不能止于生成,还要检查最终截图

设计合同存在,并不代表实现一定正确。

生成完成后,系统还会检查:

  • 1440×900 桌面端;
  • 1024×768 平板端;
  • 390×844 移动端;
  • 代表性交互状态;
  • 粗指针与触摸设备;
  • prefers-reduced-motion
  • 媒体加载、错误和 Poster 回退;
  • 控制台错误和横向溢出。

反模板审查主要检查:

  • 不相关内容是否被压成重复等权卡片;
  • 是否退化成居中 Hero 加对称网格;
  • 圆角、阴影、玻璃和渐变是否无差别重复;
  • 视觉主角是否仍然明显;
  • 标志性结构装置是否仍然可识别;
  • 动效是否具有内容、层级或导航目的;
  • 移动端是否破坏了原有视觉签名。

每个问题都必须形成结构化 finding:

{
  "id": "finding-001",
  "rule_id": "aesthetic.signature-visible",
  "severity": "repairable",
  "viewport_or_state": "mobile-initial",
  "region": "projects",
  "evidence_refs": [
    "mobile-initial"
  ],
  "contract_path": "signature.structural_device",
  "permitted_files": [
    "src/components/ProjectsSection.jsx",
    "src/styles/projects.css"
  ],
  "proposed_local_change": "恢复移动端项目编号的视觉权重",
  "intended_result": "移动端仍能识别项目索引这一结构签名"
}

修复只能修改 finding 允许的文件和区域,最多执行两轮。

这样可以防止 AI 在“修一下移动端”的过程中,顺手重做已经批准的整体设计。


总结:反模板不是一种风格,而是一条约束链

AI 网站容易模板化,根本原因通常不是它不会写前端,而是它在设计发生之前没有获得足够明确的内容和约束。

这次实践将反模板拆成了三道防线:

生成前:建立设计身份

通过内容地图、设计数据库和前置反模板基线,提前确定视觉主角、内容—形式关系和结构签名。

生成中:保持决策连续

让结构、字体、配色、媒体、主动效和副动效逐项继承,并判断每个候选是在强化、保持还是破坏设计身份。

生成后:验证承诺是否兑现

把批准结果编译成设计合同,再通过多端截图、结构化 finding 和有限局部修复检查实现。

最终得到的不是一句抽象提示词:

请生成一个不那么模板化的网站。

而是一条可以执行的工程链路:

内容证据
→ 设计候选
→ 反模板规则
→ 用户批准
→ 正式设计合同
→ React 实现
→ 截图证据
→ 局部修复

这也是我在这套 Skill 中得到的最重要结论:

真正的反模板设计,不是禁止常见组件,而是让每个重要设计选择都能回答——它为什么属于当前内容。

陈涛 · Agent Application Developer

杭州 · 2026