真正开始写网站的时候,我反而希望 Agent 稳一点。先把静态站这件事跑通,再谈风格和表达。
在 Idea2Site 里,真正负责生成网站的主要是两个 skill:
make-personal-site
copy-website-style
这两个 skill 都会产出 HTML/CSS/JS 静态站,但它们解决的是两类完全不同的问题。这个地方如果不拆,后面会非常乱。
make-personal-site 解决的是:
我已经有了一个方向,现在帮我原创一个个人网站。
copy-website-style 解决的是:
我有一个具体网站/截图/模板,帮我做一个气质和结构接近的静态版本。
看起来都是建站,但它们的目标、风险和检查点都不一样。一个是原创,一个是复刻,这两个任务要分开处理。
1. 为什么建站执行层要分成两个 skill?
一开始我也想过,是否可以只写一个 make-site,既能原创,又能参考,又能复刻。
后来发现这样很容易混乱,而且混乱得很具体。
因为“松散参考”和“高保真复刻”完全是两种任务。
比如用户说:
我喜欢这个网站的感觉,帮我做一个类似的个人主页。
这可能只是风格参考。我们可以借它的布局节奏、配色克制、文章列表方式,但内容和结构可以重新组织。
但如果用户说:
就照这个网站来,布局、动效、交互都尽量像。
那就完全不一样了。这时候需要:
- 打开目标网站观察;
- 记录第一屏布局;
- 分析滚动和 hover;
- 看移动端断点;
- 映射内部页面;
- 把 framework route 转成静态路径;
- 清掉原站身份和资产;
- 和目标做浏览器对比。
如果用一个 skill 同时处理这两类任务,它很容易复刻不够像,原创时又过度贴近某个参考,两个方向都做得不干净。
所以拆成:
make-personal-site:原创静态站
copy-website-style:具体参考站风格复刻
这两个 skill 的共同底座是静态交付,但工作方式不同。
2. make-personal-site:从方向生成可用静态站
make-personal-site 是最核心的建站实现 skill。它负责把前面已经确定的方向真正变成文件。
它的目标非常明确,而且很朴素:
用纯 HTML / CSS / 可选 vanilla JS 创建一个个人网站。
零框架。
零构建步骤。
零 package install。
零运行时依赖。
直接打开 index.html 能预览。
部署到静态托管也能工作。
我觉得这个约束很重要,甚至可以说是这个项目能跑起来的基础。
因为 Agent 做网站最容易被复杂工具链拖走。用户只是想要一个个人博客,结果它给你生成 Next.js、Tailwind、npm、build script、配置文件,最后依赖装不上,页面都看不到。这种情况真的很常见。
make-personal-site 的思路是先收住:
先把最小可用静态站做好。
结构清楚。
路径清楚。
页面完整。
后续好改。
2.1 默认站点结构
对于一个新站,它推荐的结构大概是:
site/
index.html
EDITING.md
about.html
blog.html
projects.html
posts/
first-post.html
assets/
style.css
script.js
images/
data/
posts.json
profile.json
这个结构的目的很直接:让未来 Agent 能读懂。因为我们要同时考虑这一轮生成和下一轮用户继续改时是否接得住。
index.html 是首页。 about.html 是身份和背景。 blog.html 是文章列表。 projects.html 是项目页。 posts/ 里放文章详情。 assets/ 放样式、脚本和图片。 data/ 可以放重复内容数据。 EDITING.md 记录以后怎么改。
我觉得 EDITING.md 是这个 skill 里很关键的设计。
因为一个站点生成完只是开始。未来用户会继续说:
把首页第二块改一下。
再加一篇文章。
项目页换成我的真实项目。
颜色太冷了,改暖一点。
有了 editing guide,未来的 Agent 可以直接理解整个结构。
有了 EDITING.md,它能知道:
- 哪个文件对应哪个页面;
- 首页每个 section 在哪里;
- 文章怎么加;
- 项目列表存在哪里;
- 颜色变量在哪;
- 哪些内容还是 placeholder。
这其实是给未来协作留的接口。
2.2 页面要超过首页
make-personal-site 里明确要求:完整个人站需要超过一个 homepage。
如果是博客,就至少要有文章详情页和列表页。
如果有项目,就要有项目页。
如果首页链接了关于页,那关于页必须存在。
这点很小,但非常容易被普通生成忽略。
很多模型会写:
<a href="blog.html">Writing</a>
然后根本没有 blog.html。
或者首页展示文章卡片,但点击进去没有文章页。
这对于 demo 截图没关系,但对于真实网站是硬伤。
所以 make-personal-site 的 success gate 里有一个核心要求:
Required page types exist and navigation points to real relative paths.
也就是说,导航要真的能点。
它真的要能点。
2.3 纯静态路径规则
这个 skill 最重视的工程细节之一是路径。
生成静态站时,默认必须使用 page-relative path。
比如 root 页面里:
<link rel="stylesheet" href="assets/style.css">
<a href="about.html">About</a>
<a href="posts/example.html">Post</a>
文章页在 posts/example.html,就要写:
<link rel="stylesheet" href="../assets/style.css">
<a href="../index.html">Home</a>
<a href="../blog.html">Blog</a>
这里要避免随手写:
<link rel="stylesheet" href="/assets/style.css">
为什么?
因为 /assets/style.css 在本地 HTTP 根目录下可能能工作,但在这些场景会坏:
- 用户双击
index.html; - GitHub Pages 项目页部署在
/repo-name/子路径; - 站点被放到某个子目录;
- 文章页和首页路径深度不同。
静态站最难受的很多 bug 都是路径 bug。
所以 Idea2Site 选择了一个保守策略:
默认全部页面相对路径。
除非用户明确接受 server-root-only。
这件事看起来不起眼,但它决定了生成站点是否能被普通用户直接打开。
2.4 交互只用 vanilla JS
make-personal-site 允许有明确价值的轻交互。
比如:
- 移动端导航;
- 主题切换;
- 标签过滤;
- 复制按钮;
- 轻微 hover 效果;
- 小的 progressive enhancement。
但是它避免:
- 重动画框架;
- 必须 dev server 才能运行的效果;
- canvas 大装饰;
- 影响阅读的闪烁、glitch、复杂滚动。
个人博客的第一优先级还是阅读和维护。
如果一个动效让文章页变得难读,那它就不该存在。
2.5 它的失败模式
make-personal-site 常见 badcase 大概有几类:
第一类是页面范围不完整。
比如只有首页,文章详情和项目页都缺位。
第二类是路径不兼容。
比如 nested page 里仍然引用 assets/style.css,导致文章页没有样式。
第三类是 placeholder 不清楚。
模型随手写了一个虚构身份:
Hi, I'm Alex, a full-stack engineer from San Francisco...
这看起来完整,但对用户来说是假的。
更好的做法是使用清晰可替换 placeholder,避免编造详细事实。
第四类是过度 landing page。
个人博客被写成了产品官网,第一屏是一句大 slogan 和 CTA,但没有任何真实内容入口。
所以这个 skill 一直强调:
个人站要避开营销 landing page 的写法。
第一屏要有用。
3. copy-website-style:从具体参考站重建风格
copy-website-style 是另一个复杂得多的 skill。它处理的是“我就喜欢这个网站,你帮我做一个像的”这种需求。
它处理的是用户给出具体目标的场景:
参考这个 URL。
复制这个网站风格。
做一个像这个截图一样的网站。
这个模板很好看,帮我做一个静态版。
这个 skill 的核心原则是:
复制风格和交互模式。
代码、资产、个人身份和私有内容默认留在原站。
用干净的 HTML/CSS/JS 重新实现。
3.1 为什么避免直接扒源码?
从工程上说,直接下载目标网站源码当然可能更快,但这条路很危险。
但是这个项目不希望这么做,原因有几个。
第一,版权和许可不清楚。
公共网站的 HTML/CSS/JS 可以作为研究材料,别人的代码、图片、字体、文章、头像、统计 ID、社交链接默认留在原站。
第二,原站实现未必适合静态交付。
目标站可能是 Next.js、Astro、React、Tailwind、Framer Motion、CMS、路由系统、构建产物混在一起。直接搬回来,用户后续很难维护。
第三,用户想要的是自己的站。
如果保留了原作者名字、文章标题、友链、域名,整个任务就会滑向内容复制,偏离风格复刻。
所以 copy-website-style 的策略是:
源站作为研究对象。
实现重新写。
内容替换成用户自己的或 placeholder。
3.2 浏览器探索是第一步
高保真复刻需要浏览器观察。光看 HTML 或截图,很容易漏掉真正有辨识度的东西。
这个 skill 要先在浏览器里观察目标网站。
观察内容包括:
- 桌面第一屏结构;
- 移动端第一屏;
- 导航和内部页面;
- opening animation;
- scroll behavior;
- hover/click 状态;
- 键盘交互;
- 图片和字体;
- DOM 和 CSS 变量线索;
- console/network 状态。
如果目标站是动效驱动的,截图会漏掉很多东西。
比如有的网站第一屏很普通,但滚动时会横向推进; 有的网站 hover 会触发 mask; 有的网站文章列表和侧栏有很强的布局节奏; 有的网站移动端 nav 是整个体验的一部分。
这些都需要浏览器观察。
3.3 Signature Inventory
我觉得 copy-website-style 里最有意思的是它要求建立 signature inventory。这个其实就是先搞清楚目标站最像自己的地方在哪里。
也就是在写代码前,先记录目标站的几个“签名特征”:
signature layout
signature motion
signature interactions
signature visuals
比如:
- layout:页面结构、导航位置、列宽、断点、重复 motif;
- motion:首屏进入、滚动联动、hover、loading;
- interaction:点击、复制、键盘、移动端菜单、active state;
- visuals:颜色、字体、边框、阴影、mask、混合模式、背景。
为什么要这样做?
因为复刻最容易出现的问题是“结构像,但气质不像”。你看着它好像有 header、有 card、有文章列表,但是一眼就知道不对。
比如目标站的核心是低密度排版和大留白,但 Agent 只复制了卡片; 目标站的核心是滚动节奏,但 Agent 只复制了颜色; 目标站的核心是字体和行距,但 Agent 只复制了布局。
signature inventory 的作用就是提醒 Agent:先抓住最有辨识度的东西。
3.4 全站范围规则
这个 skill 默认不只复刻首页。
除非用户明确说 homepage only,否则它应该根据目标站导航生成可浏览的静态结构:
- 主导航页面;
- 文章详情页;
- archive/category/tag;
- links/theme/search/settings;
- 移动端菜单里才能看到的页面;
- 分页或列表页。
当然目标是生成代表性页面类型,避免复制目标站所有真实文章。
比如:
posts/sample-post.html
archive/index.html
category/index.html
links/index.html
这样用户拿到的是一个可以继续填内容的网站壳,首页只是其中一部分。
3.5 框架和动效翻译
目标站可能用了各种现代前端技术,但输出仍然要是纯静态。
所以这个 skill 里有一套翻译规则:
| 源站实现 | 静态翻译 |
|---|---|
| React/Next/Astro components | 重复 HTML section + CSS class |
| Tailwind utility | 普通 CSS |
| framework route | .html 静态页面 |
| content collection | 静态列表或本地 JS data |
| Framer Motion spring | CSS easing 或 requestAnimationFrame |
| scroll-linked transform | scroll progress + CSS custom properties |
| copy-to-clipboard animation | 两状态文字切换 |
| minimap tracker | active state + transform |
这里的重点在于复现用户感受到的行为,技术栈完整复现放在次要位置。
如果一个复杂 WebGL 没有处在核心体验里,可以降级成静态 topic map; 如果一个物理动效太重,可以用近似 easing; 但核心特征要先保住,再考虑降级方案。
3.6 内容和资产安全
复刻类任务最容易遗留别人的信息。
所以 copy-website-style 有专门的 residual source audit。
要检查:
- 原作者名字;
- nickname/handle;
- 原域名;
- 原文章标题和正文;
- 邮箱和社交链接;
- 友链;
- analytics ID;
- 私有 URL;
- license/statistics 文本;
- 头像、封面、图标、截图、字体资产。
默认做法是:
保留视觉结构。
替换内容身份。
原站资产留在原处。
这对一个“给用户做自己的网站”的工具来说非常重要。
4. 两个建站 skill 的共同原则
虽然 make-personal-site 和 copy-website-style 处理场景不同,但它们共享几条底层原则。
4.1 纯静态优先
输出应该能直接部署,不依赖框架。
4.2 页面相对路径
不默认使用 /assets/... 这种根路径。
4.3 UTF-8 源码可读
中文、日文、英文混排都必须在源码里可读,浏览器显示和源码都要正常。
4.4 需要 editing guide
新站或复刻站都应该有 EDITING.md,帮助未来继续修改。
4.5 浏览器验证
文件生成之后,还要打开本地 HTTP,看页面、交互、移动端和 console。
4.6 不编造用户身份
用户没给的信息,用 placeholder,具体学校、公司、奖项、城市、年份都来自用户材料。
5. 一个完整例子
假设用户说:
我喜欢某个个人博客的侧栏和文章列表,但是内容要换成我的。
如果用户喜欢的是整体感觉,对高度一致要求较低,可以走:
find-style-references -> make-personal-site -> personalize-site -> review-static-site
如果用户明确说:
布局和交互尽量像这个网站。
那就走:
copy-website-style -> personalize-site -> review-static-site
其中 copy-website-style 会先观察目标站,建立 signature inventory,然后重建:
- 首页;
- 文章列表;
- 文章详情;
- 侧栏;
- 移动端导航;
- 核心 hover/scroll/click 交互。
但最终内容会被替换为用户自己的或 placeholder。
这就是它和“复制网站”的区别。
它复制的是体验语言,避开别人的网站本体。
6. 小结
建站执行层其实承担了整个项目最容易被用户感知的部分。
但我觉得它真正重要的是这些更基础的交付能力:
- 页面结构是否完整;
- 静态路径是否可靠;
- 未来是否好改;
- 参考站是否被正确抽象;
- 用户身份是否被保护;
- 生成结果是否能通过 review。
make-personal-site 和 copy-website-style 的拆分,让原创和复刻这两类任务各自有了清晰边界。
前者追求从方向到原创站的稳定落地。
后者追求从具体目标到静态重建的高保真和安全替换。
这两个 skill 合在一起,构成了 Idea2Site 的建站执行核心。