1. 项目概述从“能用”到“好看”的鸿沟如果你和我一样经常使用 Claude Code、Cursor 这类 AI 编程助手来生成前端代码那你一定对下面这个场景不陌生你拿到了一段代码运行起来页面确实“能用”了。按钮能点表单能填布局在手机和电脑上也能自适应。但当你把它展示给别人或者自己多看几眼时心里总会冒出一个声音——“这看起来好像还差点意思。”没错这就是 AI 生成前端界面时最普遍也最恼人的问题功能齐备但美感欠佳。布局在技术上是正确的区块划分清晰响应式逻辑也基本成立但最终的视觉效果却常常显得局促、扁平、千篇一律更像是一个教学示例而非一个打磨过的产品。在过去几个月里我反复被这个问题困扰。我尝试寻找那些专门用于评审 AI 生成前端视觉质量的工具但发现要么没有要么和我的需求对不上。于是我决定自己动手这就是AetherPane诞生的起点。AetherPane 不是一个组件库也不是一套僵化的样式规则合集。它的目标是成为一个“设计智能层”审视 AI 智能体产出的前端代码从几个关键的设计维度进行打分并提供结构化的评审报告从而让后续的优化步骤变得有据可依。简单说它试图回答一个问题当你说一个 AI 生成的页面“不好看”时到底是哪里不好看以及你该如何清晰地告诉 AI或者你自己去改进它2. 核心设计思路从模糊感受走向结构化评审2.1 为何“再提示一次”往往无效当 AI 生成的界面看起来平庸时我们的第一反应通常是继续向它发送提示词“让它看起来更高级一点”、“改进一下间距”、“让它更有质感”、“增加一些层次感”。有时候这招管用但更多时候它像是在开盲盒。问题的核心在于这些提示词本身是模糊的而反馈循环是低效的。如果结果变好了你很难精确指出是哪个改动起了作用如果变得更糟你也没有一个结构化的方法来理解哪里退步了。这种基于直觉和反复试探的流程不仅效率低下也让人难以积累可复用的经验。我意识到我们需要一种比直觉更具体的东西。我们需要一种方法能够像经验丰富的设计师一样系统地审视一个页面并提出具体的问题视觉层次清晰吗间距是否让人感到呼吸感界面元素有足够的深度和质感吗文字的对比度和层级关系是否明确2.2 确立四个核心评审维度基于上述思考我为 AetherPane 确立了四个核心的评审维度。它们并非要取代人类的设计判断而是为了让设计评审过程变得可描述、可度量、可迭代。1. 视觉层次这个维度评估页面中重要元素是否真正脱颖而出。AI 生成的代码常常会让所有标题、按钮、卡片看起来“差不多大”、“差不多显眼”。视觉层次混乱的页面用户会感到迷茫不知道视线该落在哪里。AetherPane 会分析元素的大小、颜色、粗细、位置等属性判断主次关系是否分明。2. 呼吸空间这个维度评估页面元素之间的间距是否让人感到舒适、开放而不是拥挤、压抑。AI 在布局时有时会过于机械地遵循栅格系统或基础间距单位导致元素间缺乏节奏感。适当的“留白”是营造高级感和可读性的关键。工具会测量元素内边距、外边距以及区块之间的间隙判断其是否构成了有韵律的间距体系。3. 玻璃质感这个名字有点抽象但它指的是界面表面的深度、层次和精致度。一个“扁平”的界面可能只有背景色和文字色。而一个有“质感”的界面会通过微妙的阴影、渐变、边框、圆角或背景模糊来创造层次让元素看起来像是浮于不同的平面上。AI 常常会忽略这些提升细节质感的样式。4. 字体排印这个维度评估文本的对比度、比例尺度和层级关系。它检查是否使用了足够的字体大小差异来区分标题、副标题和正文字重粗细的变化是否合理行高是否确保了良好的可读性以及文字颜色与背景色的对比度是否满足无障碍阅读的最低标准。这四个维度共同构成了一个快速评估页面视觉健康度的“体检表”。它们将“不好看”这种模糊感受分解成了若干个可以单独审视和修复的具体问题点。3. 工具实现与核心技术解析3.1 整体架构与技术选型AetherPane 被设计为一个命令行工具这是经过深思熟虑的。我的目标是让它能无缝嵌入到现有的 AI 编程工作流中。无论你是用 Cursor 的 Chat 生成代码后保存为文件还是通过 Claude Code 的指令直接输出下一步都可以立即通过命令行调用 AetherPane 进行评审。技术栈上我选择了 Node.js。原因很简单生态成熟、处理 DOM 和 CSS 解析有现成的强力库、且与前端开发者的环境天然契合。核心的工作流程可以概括为输入一个 HTML 文件路径 - 工具解析文件并构建一个无头浏览器环境来渲染页面 - 通过一系列规则引擎对渲染后的页面进行“体检” - 输出结构化报告。这里的关键在于“无头浏览器渲染”。为什么不能直接分析 HTML 和 CSS 文件因为页面的最终视觉效果是由浏览器渲染引擎计算出来的。内联样式、外部样式表、CSS 变量、甚至 JavaScript 动态设置的样式都必须在一个真实的渲染环境中才能被准确获取。我使用了 Puppeteer 库来启动一个无头的 Chrome 实例加载目标 HTML 文件等待页面稳定后再从中提取所有元素的完整计算样式和几何信息。3.2 核心评分算法的实现细节每个维度的评分算法都是独立开发的核心模块。下面我以“呼吸空间”维度为例深入拆解其实现逻辑。首先工具会使用document.querySelectorAll(*)获取页面中所有非隐藏的块级和内联块级元素。然后对于每个元素通过getComputedStyle和getBoundingClientRect()获取其详细的外边距、内边距、宽度、高度以及在视口中的位置。“呼吸空间”的评分并非简单计算间距的平均值。我设计了一套基于“间距节奏”的算法收集间距值遍历所有相邻的兄弟元素计算它们之间的垂直和水平间隙。同时收集所有元素的padding值。标准化与聚类将收集到的所有像素值转换为相对单位如相对于 16px 根字体的rem然后进行聚类分析。目的是找出页面中重复出现的、作为“基础单位”的间距值例如0.5rem, 1rem, 2rem。评估节奏感检查这些间距值是否呈现某种倍数关系如 1x, 2x, 4x。一个具有良好节奏感的页面其间距通常基于少数几个基础值进行缩放。如果聚类结果散乱没有明显的主旋律则扣分。评估极端情况检查是否存在“窒息点”如两个大区块之间仅有 1px 间隔或“断裂点”如本应关联的元素间距过大。这些都会严重影响得分。// 伪代码示例分析垂直间距节奏 function analyzeVerticalRhythm(elements) { const gaps []; for (let i 0; i elements.length - 1; i) { const rectA elements[i].getBoundingClientRect(); const rectB elements[i1].getBoundingClientRect(); // 简单判断垂直方向是否相邻 if (rectA.bottom rectB.top) { gaps.push(rectB.top - rectA.bottom); } } // 将像素值转换为rem并四舍五入到指定精度 const remGaps gaps.map(pixel Math.round((pixel / 16) * 4) / 4); // 规整到0.25rem的倍数 // 统计频率寻找主导间距 const frequency {}; remGaps.forEach(gap { frequency[gap] (frequency[gap] || 0) 1; }); // 如果最高频的间距占比过低说明节奏混乱 const maxFreqKey Object.keys(frequency).reduce((a, b) frequency[a] frequency[b] ? a : b); const rhythmScore frequency[maxFreqKey] / remGaps.length; return rhythmScore; }“视觉层次”和“字体排印”维度的实现则大量依赖 CSS 属性的计算值对比。例如通过比较页面中所有h1-h6标签的font-size和font-weight可以判断字号和字重的层级是否足够鲜明。通过计算文本颜色与背景色的对比度比值可以评估可访问性。注意算法规则并非金科玉律。它们是我基于常见设计原则和大量 AI 生成页面样本归纳的启发式规则。因此AetherPane 的评分报告应被视为“问题提示”或“优化建议”而非绝对真理。有时为了特定的艺术效果打破常规反而是正确的。3.3 报告生成与可视化评分完成后生成一份对人友好的报告至关重要。单纯的数字分数如“呼吸空间65/100”信息量有限。AetherPane 的报告会包含维度总分每个维度的百分制分数。问题清单列出该维度下发现的具体问题按严重程度排序。例如“检测到 3 处相邻区块的间距小于 0.5rem可能显得拥挤”。代码定位尽可能指出问题所在的 HTML 元素选择器方便开发者快速定位。优化建议提供一两条具体的、可操作的 CSS 修改建议。例如“建议将.card组件的margin-bottom从1rem调整为1.5rem以增强区块间隔”。为了让报告更直观我最初尝试生成带标注的截图但这引入了复杂的图像处理依赖。最终我选择了在终端内用字符和颜色来高亮显示问题摘要并将详细报告输出为结构化的 JSON 文件方便与其他工具集成。4. 集成到实际工作流从评审到优化4.1 基础使用流程AetherPane 的核心价值在于嵌入工作流。一个典型的使用场景如下生成你在 Cursor 中向 AI 描述一个需求“创建一个展示产品特性的登录页包含导航栏、英雄区域、三个特性卡片和页脚。”保存AI 生成代码后你将其保存为landing-page.html。评审在终端中你运行命令npx aetherpane critique landing-page.html。分析工具运行几秒后在终端输出一个简洁的评分卡和问题摘要。同时生成一个更详细的landing-page-aetherpane-report.json文件。优化你打开 JSON 报告看到“呼吸空间”得分较低问题指出“特性卡片之间的水平间距不一致且与上方标题间距过小”。于是你回到 Cursor给出更精确的指令“调整.feature-grid的gap属性为2rem并增加.section-title的margin-bottom到3rem。”迭代AI 根据指令修改代码。你再次保存并运行 AetherPane 评审。这次“呼吸空间”得分显著提升。你继续根据报告优化其他维度。这个流程将原本模糊的“感觉不对 - 瞎猜提示 - 碰运气”循环转变为了“生成 - 量化评估 - 精准调整 - 验证效果”的闭环。每一次迭代都有明确的改进目标和度量标准。4.2 与不同 AI 工具的配合心得在实际使用中我发现 AetherPane 与不同 AI 工具的配合有些微妙的差异与 Cursor 的 Chat/Composer这是最流畅的体验。你可以在同一个编辑器内完成生成、保存、运行评审、查看报告、然后继续对话优化。几乎是无缝衔接。与 Claude Code或其他聊天式 AI你需要手动复制生成的 HTML 代码到本地文件然后再运行评审。多了一步但依然有效。一个技巧是你可以直接把 AetherPane 生成的 JSON 报告部分内容如具体问题描述复制粘贴回聊天窗口作为下一轮提示的依据效果极佳。与 GitHub Copilot 等行内补全工具这类工具更适合微观代码片段生成完整页面的场景较少。AetherPane 在此类工作流中作用有限。实操心得不要追求一次性拿到满分。AI 很难在一次生成中就满足所有维度的完美要求。更有效的策略是“分维度击破”。比如第一轮先解决“视觉层次”和“字体排印”这两个对整体观感影响最大的问题。等 AI 把标题、正文的层级和对比度调整好后第二轮再专门用提示词去优化“呼吸空间”和“玻璃质感”。这样给 AI 的指令更聚焦它执行起来也更准确。5. 开发中的挑战与解决方案实录5.1 挑战一样式计算的复杂性与性能最初我试图用jsdom在 Node.js 中直接解析 HTML 和 CSS 文件来计算样式。这很快遇到了问题jsdom对 CSS 的支持不完全尤其是复杂的 Flexbox/Grid 布局和 CSS 自定义属性变量的计算经常出错且无法处理外部网络字体等资源。解决方案转向使用无头浏览器 Puppeteer。这虽然引入了更大的开销但保证了样式计算的绝对准确性。为了平衡性能我做了以下优化资源拦截配置 Puppeteer 拦截并阻止加载图片、字体、视频等非必要资源大幅加快页面加载速度。视口设置将视口设置为一个标准的桌面端宽度如 1440px确保布局稳定避免响应式变化导致测量波动。超时与重试设置合理的页面加载超时并实现简单的重试机制应对偶尔的网络或渲染延迟。5.2 挑战二设计规则的普适性与特殊性如何定义“好”的视觉层次或“足够”的呼吸空间过严的规则会把许多有创意的但有效的设计判为不合格过松的规则又会让工具失去意义。解决方案采用“阈值权重”的弹性评分系统。我为每个检查点如对比度比值、间距最小值设置一个“建议阈值”和一个“危险阈值”。在建议阈值之内得满分在危险阈值之外得零分介于两者之间则按比例线性得分。同时不同问题点的权重不同。例如“正文对比度不满足 WCAG AA 标准”的权重远高于“次要按钮的阴影略微不足”。这样报告能优先暴露最严重的问题。我还引入了“上下文感知”判断。例如对于“呼吸空间”的评估在导航栏这种需要紧凑布局的区域和网页主体内容区域会采用不同的间距期望值。这需要通过分析元素的语义角色通过标签名、类名、ARIA 属性推测来实现。5.3 挑战三让报告对开发者真正有用早期的报告只是干巴巴的数据和规则编号比如“VH-003违规”。这对开发者来说就像天书。解决方案投入大量精力在报告的可读性和可操作性上。通俗化描述将规则编号转化为自然语言描述。不说“VH-003”而说“主要标题与正文之间的字号差异不足建议将标题字号至少调整为正文的 1.5 倍以上”。代码定位不仅给出选择器还尝试给出该元素在 HTML 文件中的大致行号范围通过解析 HTML 字符串实现让定位更快。提供“修复提示”这是最具价值的部分。报告会直接给出可尝试的 CSS 代码片段。例如“问题卡片阴影过弱。建议尝试为.card添加box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);”。6. 常见问题与排查技巧在实际使用和开发 AetherPane 的过程中我遇到了一些典型问题以下是排查思路和解决方法。问题一运行工具后评分极低报告显示大量元素“未找到”或样式为默认值。可能原因目标 HTML 文件严重依赖 JavaScript 来渲染内容或动态加载样式。Puppeteer 在页面加载后立即开始分析此时 DOM 可能还未准备就绪。排查与解决检查命令输出看是否有页面加载错误。为page.goto或page.setContent方法增加waitUntil选项。可以尝试waitUntil: networkidle0网络空闲或更激进的waitUntil: load。在分析代码前手动添加一个延迟await page.waitForTimeout(2000)。这是最粗暴但有时最有效的方法。如果页面是复杂的 SPA单页应用可能需要等待某个特定元素出现await page.waitForSelector(.app-loaded)。问题二“字体排印”维度总是低分但页面上的文字看起来明明很清楚。可能原因工具计算的对比度是基于浏览器计算出的最终颜色。如果文字或背景使用了半透明rgba、CSS 变量或复杂的背景图片计算可能会不准确。排查与解决打开生成的 JSON 报告找到具体被标记为低对比度的元素和其计算出的前景色/背景色值。手动在浏览器的开发者工具中检查该元素使用颜色选择器确认最终渲染颜色。如果确实是工具计算有误可能是元素叠加了多层半透明背景。目前 AetherPane 对多层背景混合的计算支持有限这是一个已知限制。对于此类复杂情况建议暂时忽略该条评分或手动确保对比度足够。问题三工具认为“视觉层次”不好但我认为当前的设计是故意的比如极简主义、特大留白风格。说明这是一个关键认知。AetherPane 的规则基于“通用良好实践”它无法理解特定的艺术风格或设计意图。建议将工具视为一个严格的“代码审查员”而非“设计总监”。当它提出警告时你应该做的是“审视”这个警告而不是“服从”。如果经过审视你确认当前设计符合你的特定意图那么完全可以忽略这个低分。工具的价值在于它强迫你思考并确认“是的我故意让这些标题大小接近这是我的设计选择。”问题四如何扩展 AetherPane添加我自己的评审规则方法AetherPane 的架构是模块化的。每个评审维度如typography.js都是一个独立的模块导出一个评分函数。要添加新规则找到对应的维度模块文件。在模块的评分函数中添加你的新检查逻辑。你可以访问到页面上所有元素的 PuppeteerElementHandle数组和计算样式。你的逻辑需要返回一个符合格式的“问题”对象包含描述、严重程度、选择器和建议。主程序会自动收集所有模块的问题并汇总到报告中。7. 未来展望与社区共建AetherPane 目前处于早期但可用的状态。开源发布后我收到了来自不同背景开发者的有趣反馈。一些前端开发者希望它能集成到 CI/CD 流水线中自动评审每次提交生成的页面原型一些产品经理则希望有一个可视化界面能上传截图进行分析。我个人认为这个工具类别的需求会越来越强烈。随着 AI 编程助手在生成“能用”的代码方面越来越强那最后的、也是最顽固的差距——“好看”——就会愈发凸显。我们需要的不是替代设计师的 AI而是在 AI 生成代码的流程中嵌入一个“设计意识”的检查点。下一步我计划在几个方向深化更多维度探索对“颜色系统”、“交互动效微交互”、“无障碍ARIA”的自动化评审。智能修复建议不仅指出问题还能结合上下文生成更精准、更具体的修复代码补丁甚至可以直接应用于原文件。插件化架构让社区能够轻松贡献针对特定框架如 Tailwind CSS、Material-UI或特定风格如新拟态、玻璃态的评审规则包。这个项目的初衷是解决我自己工作中的痛点。如果它也能帮你更高效地驾驭 AI生成不仅功能完备而且视觉精良的前端代码那便是它最大的价值。开发工具的过程本身也是一个不断厘清“什么是好设计”的过程。每一次为 AetherPane 编写一条新的评审规则都迫使我更深入地思考那些习以为常的设计原则这或许是这个项目带给我的、超出工具本身的额外收获。