返回所有文章
4966 字18 分钟阅读访问统计加载中

AI 做的页面像模板货又空心:先做信息设计,再把风格写成数字规格

postmortemAI前端

9 月 21 日到 23 日,我用 Claude Code 当主控、便宜模型当苦工,做了五组前端实验。一句提示词就能出一个我满意的大模型发布落地页,换成应用页面就翻车:任务看板是紫色按钮配三张一样的卡片,参数列表页像后台控制台,用量页每个角落都塞着没人要看的字。坑分两层:风格层会滑向几种默认长相,信息层会把需求清单当页面清单逐格填满。现在的做法是先做一棵「要不要」的信息设计树,再把视觉翻成带数字的规格派活,对比度和溢出交给脚本卡。

问题详情

主控是 Claude Code 里的 Opus 5 或 Fable 5.1,苦工是 deepseek-v4.1-flash,通过 opencode 或 pi 会话冷启动,派活规则写在自建 skill 里。主控只写规格、派活、验收,尽量不亲自写代码。下文的「苦工」指这种只拿到任务书、看不到主对话的便宜模型会话。

实验做法结果
虚构大模型落地页,9 月 21 日提示词一句:用 Aceternity UI 风格给 Gemini 4 Pro 做落地页,要炫酷。主控写规格,9 路苦工并发实现82 分钟出活,我验收满意
团队任务看板 A/B,9 月 22 日同一模型、同一需求,只改任务明细A 版紫色主按钮加三张一样的统计卡;B 版守住了令牌,我看后的评价是从不能看变成勉强能看
渔轮参数库列表页,9 月 22 日夜只看需求文档,pi 苦工分三步写单页 HTML令牌纪律干净,整页却像控制台,连顶栏都没有
API 计费平台用量页,9 月 22 日到 23 日同一个页面连做 A、B、C、D 四版A 落进默认长相,B 比 A 难看,D 删完槽位后我给 7 分
信息设计 skill 试跑,9 月 23 日先在渔轮库跑站点层,再用虚构的活动报名工具「到场」跑满三层站点层把「对比」和「数据说明」放进顶栏,跟直接让 AI 做的一样;skill 当天被我清空重写

任务看板 A 版:紫色主按钮、三张一样的统计卡、带阴影的圆角白卡

任务看板 B 版:左侧导航加表格,守住令牌,仍只是勉强能看

渔轮参数库列表页:元素都对,拼起来像后台控制台

排查与原因

风格层:默认长相,以及机械躲开它的反噬

Claude Code 官方的 frontend-design skill 写明,AI 生成的界面集中在三个长相:暖米白底加高对比衬线标题加陶土色点缀;近黑底加一个酸绿或朱红点缀;报纸式版面加发丝线加零圆角。用量页 A 版凭直觉出手,直接落进第二种:近黑底、酸绿、Plus Jakarta Sans,而这个项目的依赖里本来就装着这款字体。

B 版按方法论躲默认,从「记账」题材里挖视觉符号,用了会计 greenbar 账纸的条纹和纯黑柱子。我看后的评价是 B 比 A 难看多了。默认长相成为默认,是因为它们被无数产品打磨过;该换的只有配色,深色壳、卡片、网格这些版面常识不能丢。

走了方法论也不保证令牌合规:A 版 2 项正文对比度不到 4.5:1,B 版 1 项。这一条只能由脚本算。

用量页 A 版:近黑底加酸绿,AI 默认长相之一

用量页 B 版:为躲开默认长相挖出的账本条纹,比 A 难看

信息层:填槽,以及把需求表当答案卷

C 版避开了三个视觉默认长相,却填满了信息层的槽:趋势卡右上角「按日」,分布卡右上角「按费用」,列表右上角「共 12,847 条」但没有分页,需求里没有的「平均耗时」卡是为了凑第四张卡编的,抬头还挂着「截至 14:30」。用户想看新数据自己会刷新,那行字既不能替他刷新,也拦不住他刷新。AI 还有一个反射:在列表底下放「查看全部」链接,因为分页是带状态的组件,链接不用想。

另一头是把需求当答案卷。需求列了 10 个子功能,主控逐行打勾,判「四项不存在」。可单条详情是一个抽屉,失败请求是筛选条上的一个状态,密钥用量是同一张表换一个过滤条件。一个对象的不同状态,被数成了四个缺失的区块。页面于是长成一个形状,每个盒子单看都合理,合起来没有一句话是对着用户说的。

网页感:元素都对,拼起来不像网站

渔轮参数库那页令牌纪律干净,九个色值一个不多,圆角只有两种,零阴影。我看后的结论是界面还行、元素还行,凑一起就怪。缺的是网页独有的东西,顶栏和菜单;筛选页明明可以抄电商的布局,AI 却自己画了一个像后台控制台的东西。这条现在写在全局规范里:禁止凭空设计,先搜友商。

顺着「让 AI 自己去抄」查了一圈模板站。灵感站内容全是截图,文本抓取看不见图,无头浏览器又被拦:Land-book 走 Cloudflare 人机验证,Godly 直接 400。组件站欢迎抓取,shadcn 命令行内置了 382 个第三方注册表,一条 npx shadcn add @aceternity/spotlight-new 就把源码装进项目。两个坑:shadcnblocks 抽样 40 个区块只有 5 个免费,其余返回 401;组件名不能猜,按常见命名试 kokonutui、animate-ui 全是 404,要先拉该站的 llms.txt 或注册表索引拿准确名字。

规范在派活之前就断了

全局规范里写了设计令牌、六态、对比度底线、文案守则,一条都没传到苦工手里:派活明细六项全是功能口径,没有放视觉规范的位置;pi 苦工只读工作目录下的 AGENTS.md,读不到全局配置。最矛盾的一条是规范写着「纯展示层禁止写单测,UI 问题肉眼即可发现」,而无人值守流程规定用户全程不看。

信息设计 skill 第一版

第一版分站点、页面、区块三层,每层派苦工向下展开。渔轮库站点层跑出来的顶栏有六项,含「对比,带已选数量」和「数据说明」。我的反应是:为啥会有人把对比放导航?跟 AI 直接做出来的一模一样。对比是勾选之后才存在的动作,没勾东西时点它落到一张空表;「数据说明」页的每条内容都有更贴近用户提问那一刻的位置,数据源进出处弹层,抓取时间进页脚,全部溶解掉,这页就不该存在。顶层拍板时没有看下一层放什么,是这两个错误的共同原因。

第二个坑是产出没法看。站点文件写了几千字的用户画像和推导,停点汇报把二十几个候选和溶解结论全贴出来,我的原话是「这么多我怎么看」。skill 当天中午被清空,重写成「页面 → 子区域 → 组件」三问树:有没有必要、怪不怪、做成什么样。

第三个坑来自会话本身:切换模型会留下旧进程继续自主干活,同一任务出现三个同源会话抢写同一份文件;skill 目录跑到一半被另一个会话清空,后起的 5 路苦工读不到模板。

「到场」跑满三层后又暴露了并行的副作用:一路只看一个候选,34 路里出现 5 处连锁(A 并入 B,B 又被删)、互推(详情页把到场率推给数据页,数据页推回详情页)和矛盾(设置页一路判删、一路判留);30 路写手各自冷启动,同一个状态各叫各的名字;模板里的说明句被当正文抄进去。

苦工机制

  • 十来轮工具调用后断线。 苦工模型开着思考模式,第一轮 9 路死了 7 路。翻日志,轮次全烧在防御动作上:去 node_modules 里 grep 确认图标存不存在、反复 ls、最后自己跑一遍类型检查。接口层的原因见上一篇 reasoning_content 复盘。
  • 角色提示词把苦工推进循环。 挂上 worker 角色文件的大任务必断,小探针秒过;去掉角色文件、把要求写进任务明细就过了。元凶是角色里那句「改完必须自己验证」。要求苦工在回复里贴全部色值字号的自查清单,同样会把输出撑断。
  • 分步派活丢要求。 响应式写在第一步的明细里,第二步没重复,结果 390 宽下 146 处溢出,站名被筛选栏盖住三分之一。
  • 通道按账号熔断。 9 月 23 日上午,本会话 4 路加另一会话 3 路 pi 苦工同时跑,两分钟后通道对所有请求返回 Concurrency limit exceeded for account,连 say ok 的探针都失败,从 10:45 持续到 12:06。36 路只成功 8 路,每路四次重试全部白费。后来实测并发 4 路稳,6 路开始掉。
  • 主控的知识也会过期。 任务书给的可用图标名单里放了 GitHub 和 Twitter,而 lucide-react 1.47 已经删掉全部品牌图标,全项目仅有的 4 个类型错误全由此而来。
  • 编译通过不等于看着对。 主视觉那路自报完成,主控读代码抓出 4 个缺陷:网格画了两层,把边缘淡出盖掉;噪点工具类自带 3% 透明度,被 opacity-60 覆写成 20 倍;徽章扫光的位移按光带自身宽度算,永远走不进可见区;「100 万上下文」的数字滚动实际从 0 跳到 1。构建对这些一律沉默。
  • 无头截图会骗人。 整页截图把滚动入场动画锁在初始态,大标题整块空白,三个指标停在 0M、≤0ms、0.0%。
  • 门禁脚本自己要先被验证。 第一版用 bash 正则做 emoji 检测,按字节匹配把中文全算进去,报出 1328 处假阳性;改用 Node 的 \p{Extended_Pictographic} 才准。
  • 检测器不认项目规格会反转。 一个 59 条规则的渲染检测器判 A 版 0 条通过、B 版 2 条失败:用了 Roboto,字号 12 到 20 的层级比只有 1.7:1。第二条和定好的高密度工具型规格直接冲突。检测器得先读项目的设计规格,才分得清故意定的和瞎发挥的。

落地页无头整页截图:入场动画锁在初始态,标题空白,指标停在 0

解决办法

先分题材

大模型发布页的骨架是业界典范:导航、主视觉、logo 墙、能力矩阵、跑分、场景、开发者接入、定价、CTA、页脚。主控没查任何资料就列出这 9 段,信息设计等于白送。应用界面没有这层免费午餐,签到页、用量页这类页面必须先做信息设计。

信息设计:一棵要不要的树

页面 → 子区域 → 组件三层,每个节点过三问:有没有必要,需求里有没有人需要它;怪不怪,别的站都不这么放要说得出理由;做成什么样。配套规矩:

  • 定一个节点之前先想它下一层放什么,放不出东西的节点不要。
  • 动作跟着对象走:对比、收藏、导出放在列表行和详情页,不进顶栏,不做悬浮条。顶栏只放「去别处」。
  • 展示页每个元素过删除测试:删了,有没有人少看懂一样东西。答不出就删。具体禁令:「截至 / 更新于」时间戳;卡片角落的「按日」「共 N 条」;凑数的指标卡;两数相减的派生数;「查看全部」。列表要真分页。主数字放最左。
  • 需求文档的功能表是范围合同,写的是系统必须做得到的事,别翻译成页面必须看得见的东西。
  • 树里每行一句。给用户看的只有树和最多三条要他定的事,推导留在文档里。

保留一路冷启动的评审会话,只给它需求文档和树。「到场」三层共 39 条评审意见,全部是真问题、零凑数,其中「没留手机号的候补者永远收不到转正通知」这类产品空洞,主控自己写完看不出来。人手写轮廓时,每行标「定 / 草 / ?」,让 AI 分清哪句是拍板、哪句是随手写;否则它把轮廓当圣经,漏说的就不做。这一条还没实测。

风格层:写成数字,找有名字的参照

落地页那次好看,靠四件事叠加。「Aceternity UI」这个名字带来一整套有名字的组件,Spotlight、Background Beams、Bento Grid、Sticky Scroll,比「炫酷」两个字信息量大得多。主控动工前用 96 秒写了 15.7 KB 的 DESIGN.md,里面没有「高级感」这类话,全是可执行的量:网格 1px、4% 白、40px 间距;光斑模糊 120px;预览卡从后仰 28 度随滚动转正;页脚水印 12vw、3% 白。苦工不需要审美,只负责转录。九个互相看不见的会话,产出像一个人写的:同一条缓动曲线出现在 17 个文件里,品牌色只有 4 个。

应用界面沿用同一招,参照换成同类产品:筛选页抄电商,工具页抄 Linear 这类开发者工具。任务看板 B 版的任务明细比 A 版多了四段硬约束:点名参考对象并说清赌的是什么;令牌给死,11 个 hex、6 档字号、4px 阶梯的 7 个值、2 个圆角、1 条阴影;9 条带原因的拒绝清单,禁渐变、禁 emoji 当图标、禁卡片和按钮加阴影、禁整页居中、禁两个以上强调色、禁阶梯外的数值、禁方括号任意值、禁开发说明文案、禁每个区块配副标题;四态必须做,数据里埋一条 80 字以上的超长标题证明截断生效。苦工守规矩守得一丝不苟:字号恰好 6 档,全文 hex 只有 4 个,间距全部落在阶梯上。

躲默认长相的正确姿势只有换配色。用量页 D 版留下深色壳、卡片、网格,把酸绿换成黄铜色 #E0A85C,底色用 #0A0D0F 带一点青,避开纯中性黑。

用量页 D 版:删完槽位,补上真分页和参考线

派活任务书

  • 把苦工要查的东西提前喂进去:可用图标名单、颜色类名、动画类名全部列死。
  • 收走自检权,类型检查和构建由主控统一跑;推理档位降到 minimal;每个文件一次整份写完;回报只三行。改完这三条重发 7 路,成了 6 路。
  • 角色要求写进任务明细,不挂角色文件;自查结果写进文件再报路径,别在回复里贴清单。
  • 分步派活时每一步重复硬约束,尤其是响应式和令牌。
  • 写死文件归属表:公共文件任何苦工不准碰,各区块只能引入白名单里的包。再加几条护栏:禁止 Math.random(服务端和客户端渲染会不一致)、禁止用 window.innerWidth 判断断点、定时器必须清理、动效只动 transform 和 opacity。它们不让页面更美,但堵住了 AI 前端「看起来坏了」的常见来源。

通道与并行

  • 派活前先跑探针,连续两次失败就判通道整段阻塞,直接切原生子 agent(Claude Code 的 Agent 工具加 Sonnet)。同一份角色提示词和任务书,只把「回复」改成「写到 out.txt,只回一行结论」。原生子 agent 一路 4 到 9 分钟、6 到 10 万 token,比 pi 慢,一次成功率 100%。
  • 苦工要读的模板和词汇表开工时复制到临时目录,任务书指向副本。
  • 收回结论时把所有「并入 X」按目标分组:X 也被删的是连锁,X 也并回来的是互推,逐条改判。
  • 假设汇总用脚本抓「假设」行生成表,别靠人读 30 份输出。模板加一节状态名词表,说明句放进 HTML 注释。
  • 开工前列一遍在跑的会话,有同源会话先发消息叫停。

机器门禁

对比度按 WCAG 的 4.5:1 用脚本算,不达标就求解新令牌:把 #6B716B 压明度到 #616761,纸白 5.39:1、纯白 5.80:1、条纹 4.56:1 三处同时达标,改一行全站生效。溢出和重叠只有真实渲染才抓得到:B 版超长标题截断后省略号怼进「负责人」列,源码扫描、苦工自查、文件模式检测全没抓到,渲染模式报出溢出 717px。源码扫描抓紫色系、border 加 shadow 同元素这类拒绝清单违规,毫秒级。截图给主控自己看只当辅助。

验证结果

任务看板 A/B,同一模型,只改任务明细:

指标A 现行派活B 强约束派活
拒绝清单违规3 / 80 / 8
四态覆盖缺加载态、错误态4 / 4
紫 / 靛色系出现12 处0
border 加 shadow 同元素2 处0
focus 可见态18 处36 处
aria / role0 处8 处

B 版仍有两处问题:截断怼列只有渲染检测抓到;亲手定的两个令牌对比度只有 2.5:1 和 2.9:1,没过 3:1。人拍脑袋定的令牌同样会错。

用量页 D 版删掉了时间戳、角落标签、凑数的平均耗时卡、「已优惠」派生数和贴进界面的需求原文,补上带页码和跳转的分页、趋势图的参考线;对比度 0 项不达标;我给 7 分,人工只需微调。

落地页从提示词到我验收 82 分钟;22 次派发 13 次有效产出;类型检查零错误,生产构建通过,首屏 183 kB;主视觉 4 个缺陷一轮返工修完。移动端从没截过图,规格里 375px 不溢出的要求只有代码层面的自查。

「到场」三层:候选页面 21 保留 8,候选区块 63 保留 30;评审意见站点层 15、页面层 15、区块层 9,全部采纳;待确认需求 48 条,其中 5 条是需求文档本身的缺口。82 路苦工,pi 成功 46 路,Sonnet 36 路;10:33 开工,13:55 定稿,其中 80 分钟耗在通道熔断。

渔轮库按新版 skill 重跑,站点文件从几千字缩成 1.9 KB 的一棵树加三条要我定的事。我看到清单的第一反应仍是 AI 味溢出屏幕,但问题在写代码之前就暴露了。

边界:「好看」没有客观指标,7 分和满意都是我一个人的判断;没有真实用户参与任何一轮;「到场」的两个确认点由主控代行。

参考资料

喜欢这篇文章?

如果这篇文章帮到了你,可以请我喝杯咖啡,支持我继续写下去。

评论