AI Agent 改完前端后,如何在提交前证明它没有碰坏别的页面?SightDiff 的本地视觉验收
让 AI 编程 Agent 改一个筛选器、按钮或页面布局很快,但“它说完成了”不是验收结果。尤其在前端项目里,Agent 很可能修改了共享 CSS、组件默认值或路由层逻辑:目标页面看起来正常,仪表盘、设置页或登录后的视图却发生了位移。代码 diff 能告诉你改了哪些文件,却不直接说明浏览器实际渲染出了什么。
SightDiff 是一个仍处于早期访问阶段的本地视觉验收工具。它把工作流压缩为两步:在提示 Agent 前为关心的页面和状态拍摄基线;Agent 完成改动后重新渲染、逐像素比对,并生成一张把变化与未变化页面放在一起的 proof sheet(证明页)。它不接入 Claude Code、Cursor 或 Copilot,而是观察正在运行的应用,因此其核心价值不是“替 Agent 做测试”,而是在 git commit 之前独立复核 Agent 的结果。
本文不把它描述成已经成熟可下载的测试框架:官网目前只提供 waitlist/创始用户早期访问,且明确写出首批打磨目标是 React + Vite 或 Next.js。下面的命令和能力范围均以官网已公开的说明为准。
为什么 Agent 时代更需要渲染层验收
常规代码审查擅长检查逻辑、类型与危险 API,但它有三个视觉盲区。
第一,样式依赖通常跨组件传播。一个 Agent 为某页增加间距,可能修改了公共 class;源码 diff 看着很小,实际却影响多个路由。第二,视觉状态不只由 URL 决定:空数据、加载中、已登录、权限不足、深色主题或动态日期都可能产生不同画面。第三,若让 Agent 自己打开浏览器并说“已验证”,验证对象与实施对象仍是同一个执行体;它可能只检查了自己改过的区域,甚至没有意识到共享样式影响了哪些页面。
SightDiff 的边界更明确:它需要一个本地开发服务器,以及一份列出待检查页面和状态的小型配置。基线和二次渲染都在本机完成,不上传代码或截图;工具也不替你判断产品需求是否正确,而是回答一个更窄但很实用的问题:在已声明的页面集合中,哪些画面真的变了,哪些应当保持不变却被波及?
把它放在 Agent 工作流的两个检查点
官网给出的基本节奏是 snap → Agent 工作 → check。假设团队已经启动本地开发服务器,且 SightDiff 已按早期访问版本的安装说明可用,最小操作如下:
sightdiff snap : "让 Agent 实现需求,例如:在产品列表页加入价格筛选器" sightdiff check
sightdiff snap 会为配置中的每个页面/状态记录截图基线;sightdiff check 则再次渲染并做像素差异比较。官网说明,命中的变化会被优先放到证明页中并高亮;未发生变化的页面会被标记为已验证一致。若发现被标记的问题,check 会以非零退出码结束,这使它可以成为人工提交前的门槛。
这里的关键不是把这两条命令塞进所有 CI,而是把基线时机固定下来。正确基线应来自已知可工作的分支或已验收工作树;如果在 Agent 已经改坏页面之后才执行 snap,后续比较只会把错误当作正常状态。对于一次任务,推荐把流程写进任务描述:先确认本地服务稳定和测试账号状态,再执行基线;之后才允许 Agent 改代码;最后由人读取 proof sheet,而不是只接收终端里一句“通过”。
页面集合要覆盖“共享依赖”,而非只覆盖需求页
视觉回归工具最容易被误用成“只测我要改的那一页”。例如,需求是给 /products 增加筛选器;如果该页面与 /dashboard、/settings 共用导航、按钮或布局 class,那么后两页才是最有价值的哨兵。SightDiff 官网上的示例正是这种失败模式:Agent 的目标改动完成了,却因共享 CSS 让另一个 dashboard 也发生变化。
可以按风险而非路由数量设计配置中的页面与状态:
- 目标面:需求直接涉及的页面,以及空态、加载态、错误态等关键状态。
- 共享面:共用导航、表单控件、卡片、排版令牌或全局主题的代表性页面。
- 权限面:如果页面依赖登录或角色,至少覆盖一个授权视图和一个受限视图。
- 不稳定面:时间、随机内容、广告位或实时数据会制造噪声;应利用工具所述的动态内容遮罩能力,或在本地用固定 fixture 提供可重复数据。
官网还提到 sightdiff discover 可以通过爬取应用来写出配置。这适合为项目建立初始清单,但不应让自动发现替代人工选择:爬虫知道页面可达,不知道哪些状态属于业务承诺。实际团队可以先用 discover 得到候选,再将关键路由、测试数据和遮罩规则纳入代码审查。
: "根据可渲染页面生成初始配置候选;之后人工审阅页面和状态" sightdiff discover : "重新建立或更新已审阅范围的基线" sightdiff snap : "Agent 改动后,用非零退出结果阻止未读证明页的提交" sightdiff check echo "exit code: $?"
最后一行不是额外的产品命令,而是 shell 对前一条命令退出码的读取方式。只有把失败退出码接到本地 Git hook、任务脚本或人工检查清单中,视觉差异才会从“可选报告”变成真正的发布前信号。
它与 Chromatic、Percy 的取舍不同
SightDiff 官网把自己的定位放在本地、dirty working tree、Agent 刚停止工作的时间点;这与典型云端视觉回归服务在 PR 提交并推送后检查的阶段不同。两者并非互斥:云端服务适合在受控构建环境里保留 PR 历史、做跨浏览器或团队级审批;本地检查则适合在你决定要不要创建那个 commit 之前,快速发现“Agent 顺手伤到别处”的问题。
相应地,SightDiff 也有公开说明的边界。它当前是对已配置的所有页面/状态进行拍摄和像素比较,还不会根据代码 diff 自动推断“只受影响的界面”;基线由 snap 创建,而不是持续后台维护。若页面覆盖范围过大,本地渲染会更慢;若范围过小,又会遗漏共享样式回归。它更适合页面数可控、视觉质量敏感、并且已经能稳定启动本地开发服务器的 Web 项目。
一个可执行的验收习惯
把 Agent 输出从“改了什么文件”升级为“哪些用户可见界面保持了什么”,不一定要先引入复杂测试平台。对于一次前端改动,可以采用如下最小闭环:先将关键页面和状态列成清单;在干净的已知状态拍基线;让 Agent 完成局部功能;运行比较;打开 proof sheet 阅读所有意外变化;确认后才提交。对反复被共享 CSS、主题和权限状态拖累的项目,这比要求 Agent 多说几次“我已经检查过”可靠得多。
SightDiff 的价值恰恰在于它不相信 Agent 的自我陈述,也不要求你换用某个 Agent。只要应用能在本地渲染,它就把“看一眼别的页面”这件容易被省略的事,变成了一个可以留痕、可以失败、也可以由人最后裁决的检查点。
还有一个常被忽视的好处是,它能帮助团队把视觉验收从个人习惯变成共享约定。把需要覆盖的路由、状态和动态内容处理方式跟应用代码一起维护,新成员不必猜测“这次为什么还要看设置页”;Agent 也不会因为提示词只提到一个组件,就默认其他界面无需检查。配置当然需要随着功能增长调整,但这种显式范围本身就是质量边界:未被纳入的页面不是“已经验证”,而是“尚未被本次检查覆盖”。在评审 proof sheet 时应区分这两种结论,避免把工具的未发现误读成产品绝对没有视觉问题。更稳妥的做法是在每次新增共享组件、全局主题或认证流程后,回头补充代表性状态,并重新审阅基线是否仍代表当前可接受的界面。