jevgrep 截图对比评审技能实战:用“更不错误“原则与视觉遥测指标客观裁决截图
【免费下载链接】jevgrepFind code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.项目地址https://gitcode.com/gh_mirrors/je/jevgrep点击查看免费下载本文深入解读 jevgrep 仓库中.agents/skills/compare-screenshots/SKILL.md所定义的截图对比评审技能。它解决的是视觉开发中最棘手的判断问题当候选渲染图与基准图存在差异时如何客观判断哪一边更接近正确而不是机械地要求匹配基准。读完本文你将掌握一套完整的六步评审工作流、双图对比与单图自检的全部指标语义、固定的距离分数公式以及配套脚本visual-parity-diff.mjs的真实用法与自检方式可直接用于 UI、游戏画面、文档渲染、图表等任何生成资产的接受/拒绝决策。核心原则判断哪张图更不错误而非是否匹配基准该技能的第一条纪律就是反转直觉比较的目标是哪张图更不错误less wrong而不是候选图是否与基准一致。基准baseline只是更早的一次尝试它同样可能是错的——可能相机意图不对、内容缺失、光照错误或裁剪有问题。因此两张图都只是候选者candidates统一用你自行建立的目标target来衡量指标的作用是定位两张图在哪些地方不同locate divergence它们永远不会替你裁决谁是对的距离为 0 不代表成功可能是两张图错得一样距离很大也不代表失败更丰富的场景、更清晰的模型、更实的标签、真正的深度、更好的光照都会合法地拉大距离。这一原则贯穿整个技能所有指标、公式、脚本产物都围绕定位差异设计而把裁决留给第 4 步基于目标的逐项判断。六步评审工作流技能的完整工作流如下每一步都不可跳过从第一性原理建立目标Establish the target from first principles。在查看任何距离指标之前先决定这张图应该呈现什么视觉需求、设计意图、真实世界里物体长什么样以及拥有该画面话语权的领域技能。这——不是基准——才是 ground truth。用一两句具体的话写下来例如低角度的太阳应向东投下长影树木应填满树冠标签在这个缩放级别下保持可读。如果正确答案不明确——存在互相竞争的合理解读、品味或产品意图之争、只有负责人能拍板的权衡——停下来问用户正确答案应该是什么并把对比结果展示给他们。不要为了省事而悄悄默认基准那会把基准犯下的错误固化下来。确认可比性Confirm comparability确保你看到的差异是真实的而非采集伪影相同的视口viewport、DPR、路由/页面、冻结的时间/帧、相机意图、UI 状态、数据、字体/资源。不可比则修正采集设置或只对比差异无害的裁剪/局部特征。生成定位差异的产物Generate artifacts to locate divergence规模与问题匹配并排图side-by-side、关键特征裁剪/放大crops/zooms、灰度图、绝对灰度热力图、pixelmatch 差异图、每张图的 Sobel 边缘图、边缘差异热力图以及 JSON 指标。逐项对照目标裁决每个差异Judge each divergence against the target。对每一处不同用平实的语言说出那里实际有什么——内容缺失、相机错误、层级混乱、对比度弱、深度错误、文字重叠、布局偏移、边缘被裁、意外模糊、风格不匹配——并判断哪一边更接近正确。答案可以是候选对、基准对、两者都错、或真正的难分伯仲。对争议或高风险结论获取中立第二意见Get a neutral second opinion让一个全新的子代理subagent只拿到两张图和中性标签进行独立判断配置见 references/subagent-visual-review.md。以一个裁决收尾Conclude with one verdict候选更不错误接受并在存在基准时重新 bless 基准、基准更不错误拒绝、两者都错需要再来一轮——指出还差什么、或结论不清询问用户。绝不因为分数更低就接受、或因为分数更高就拒绝。绝不隐藏内容、模糊细节、裁掉差异、或让采集变得不真实来推动某个数字。双图对比指标为问题挑选度量在完整视觉对比中技能建议报告以下指标全部可追溯到脚本visual-parity-diff.mjs的实际输出字段指标含义说明mae灰度平均绝对差0..255越低越接近rmse灰度均方根误差越低越接近diffRatio16/32/64灰度差超过 16/32/64 的像素占比三个阈值下越界像素的比例pixelmatchRatio灰度图上 pixelmatch 的不匹配像素占比由 pixelmatch 库在阈值 0.08、含抗锯齿includeAA: true下计算edgeEnergyCurrent/edgeEnergyCandidate两侧的平均 Sobel 边缘强度判断画面结构丰富度edgeEnergyRatio候选/当前的边缘能量比远低于 1 通常意味着几何、道具、标签或地形缺失远高于 1 通常意味着噪点或错误细节edgeDiffRatio32Sobel 边缘差异超过 32 的像素占比结构差异的量化avgLuminanceCurrent/Candidate/Delta平均亮度及差值当渲染明显偏暗/偏亮、即使整体距离分数改善时使用针对场景还提供内容代理指标content proxiesblack/void 占比blackRatio、类地形占比terrainLikeRatio、水类占比、队伍颜色占比、标签/文字掩码占比。脚本中的isTerrainLike实现为g 72 r 62 b 38 r b * 0.92 g b * 0.92。对于 UI/文档/布局类评审还应使用裁剪边界crop bounds、文字/前景掩码覆盖率、对比度检查、边缘裁切、元素位置与前后尺寸——这些在击败全局像素距离时优于全局像素指标。单图指标没有对照时如何判断一张截图是否值得每一对指标都在图 vs 图没有任何一个能回答这张截图值不值得——当没有东西可比时而且对分数是对称的巨大的距离永远不说明哪一边是空帧。以下绝对数值可以它们在单张 PNG 的粗网格上计算colorEntropyBits低于约 3.0或dominantColorShare超过约 0.6一种颜色统治了整帧——稀疏场景、未点亮场景、或主体从未被画出来。edgeDensity低于约 0.04几乎没有任何形状——空取景、图元主导的场景、或主体在裁剪框之外。luminanceContrast低于约 60雾、黑暗或薄雾把整帧压进同一个色带。transparentShare在应当不透明的截图上大于 0截图本身错了。透明像素保留着遗留的 RGB所以一帧不可见的画面在被合成前可能看起来很丰富——场景指标先做合成再测量并如实报出不可见占比而不是让你去推断。成对指标仍读取存储的 RGB所以这个字段是透明度被如实讲出来的唯一位置。从源码看computeSceneMetrics按约 160×90 的粗网格采样stepX max(1, floor(width/160))stepY max(1, floor(height/90))每通道取 4 bit 分桶key r4, g4, b4这样梯度与抖动不会误读为精心创作的多彩成本也远低于成对计算。这些阈值是怀疑的触发器不是门禁。刻意极简的设计、夜景、空状态页面、白板都会诚实地触发它们。用途是决定往哪儿看然后说出这帧画面实际在做什么——永远不要为了抬高某个数字而调整采集这与裁掉差异是同一种失败。距离分数一个固定配对数字的默认公式当需要一个固定的单对数字时技能给出适用于结构变化默认公式distance 0.35 * diffRatio32 0.25 * pixelmatchRatio 0.25 * edgeDiffRatio32 0.15 * min(1, abs(log2(edgeEnergyRatio)))它衡量的是与另一张图的距离仅此而已。因为基准可能错距离 0 不是成功、大距离也不是失败——更丰富的场景、更清晰的模型、更强的标签、真实的深度、更好的光照都会合法地抬高它。用法是用这个分数找到图像移动的位置在第 4 步裁决谁对。脚本中报告字段命名为parityDistance报告注记明确写着This is a distance metric, not an acceptance gate并且输出会同时给出全帧分数和当 UI 主导画面时带标签的世界裁剪分数——用世界裁剪分数定位渲染器移动保留全帧分数让 UI/相机错误继续可见。实现细节值得一提edgeEnergyRatioOf为两个都没有边缘的帧设了1e-6下限并返回 1——两张完全没有边缘的平坦帧不是无限远而是同一帧如果直接做除法一对相同的空渲染正是这套指标要抓的情况会被送到非零距离。分数纪律每一轮迭代都引用同一对的上一次与本次距离然后说明移动方向朝目标、远离目标、还是诊断性噪声。缺内容类 bug 优先用边缘指标一张平坦的俯视地图可能展现出欺骗性的中等灰度差而边缘能量能证明树木、道路、城市轮廓或军队剪影确实不存在。当稳定 UI 主导画面而问题在场景渲染时先分割出稳定 UI同时保留一个带标签的全帧分数。相机错了像素分数只是诊断性的。先修相机意图再判断渲染。配套脚本实战visual-parity-diff.mjs技能规定对比脚本应保留在技能内部或临时工作区不要放进产品代码——除非产品确实需要在运行时做截图对比。本仓库内提供了现成的可复用助手# 成对模式需要 REFERENCE_DIR 与 CANDIDATE_DIR REFERENCE_DIRpng文件夹 CANDIDATE_DIRpng文件夹 OUT_DIR产物文件夹 node .agents/skills/compare-screenshots/scripts/visual-parity-diff.mjs # 固定配对顺序按 a,b,c 的顺序固定报告排序 REPORT_ORDERa,b,c # 带标签裁剪按图像 id 键控单位为像素或 { unit: ratio } 归一化边界 CROPS_JSONfile.json # 单图模式不设 REFERENCE_DIR只测量每张截图的自身指标 CANDIDATE_DIRpng文件夹 OUT_DIR产物文件夹 node .agents/skills/compare-screenshots/scripts/visual-parity-diff.mjs行为细节与 SKILL.md 及源码一致有REFERENCE_DIR时执行成对差异按文件名.png后缀匹配REFERENCE_DIR与CANDIDATE_DIR中的共同图片尺寸不一致直接抛错image sizes differ每对生成 8 类产物*-side-by-side.png、*-current-gray.png、*-candidate-gray.png、*-absdiff.png、*-pixelmatch.png、*-current-edges.png、*-candidate-edges.png、*-edge-diff.png并写入visual-parity-diff.json结果按parityDistance降序排列报告同时标注worstPair。有CROPS_JSON时对指定裁剪区域做同样的全套分析产物前缀为*-world-crop-*输出独立的parityDistance与同结构指标。不设REFERENCE_DIR时只写scene-metrics.json不含任何 diff 产物——用于孤立截图、任何人在评审前检查完整采集集、或判断大距离中哪一边才是空帧。透明像素先按 alpha 复合到 RGB 再测r png.data[o] * alpha因此不可见帧看起来丰富的陷阱会被transparentShare直接点名。灰度用 Rec. 601 亮度权重0.2126 * r 0.7152 * g 0.0722 * bSobel 用 3×3 邻域算子gx -a -2d -g c 2f i等边缘能量按像素归一。脚本从REPO_ROOT缺省为当前工作目录或其父目录解析web/package.json中的pngjs与pixelmatch依赖运行前需保证这些依赖在对应仓库中可解析。用 eval 脚本守住助手本身visual-parity-diff.eval.mjs 是助手的自检测试它用draw()逐像素生成正确性由构造即已知的夹具——空empty-solid、empty-transparent-noise、empty-transparent-white、empty-smooth-gradient、有内容content-noise、content-scene、图元主导primitive-dominant、半透明混合mixed-half-transparent、低对比度暗帧dim-lowcontrast、微小真实图small-but-real、退化图one-pixel-wide——然后断言场景指标能正确区分空与有内容colorEntropyBits 3.0 || dominantColorShare 0.6 || edgeDensity 0.04判空全透明帧报transparentShare 1、不透明帧报 0、半透明帧接近 0.5尺度不变性同一场景 1x 与 2x 分辨率的edgeDensity、colorEntropyBits接近与色调不变性纯红/纯蓝的平坦度指标完全相等透明黑覆在噪点上与其合成等价物flat-black指标完全一致成对模式相同对距离为 0、距离对称、两侧都带sceneMetrics以打破对称平局、仍写出 diff 产物而单图模式不写任何 diff 产物263 张批量图的管道化 stdout 完整可解析、与落盘报告一致失败路径响亮缺CANDIDATE_DIR、空目录都会非零退出并打印明确错误。运行方式REPO_ROOTrepo node visual-parity-diff.eval.mjs在修改脚本后用同一REPO_ROOT运行任一期望集失败即非零退出并打印所有检查项。纪律是绝不允许用放宽阈值来通过失败检查——除非先证明错的是夹具而不是代码。中立子代理评审防止历史偏差污染判断当对话历史或先前的结论可能影响主代理的视觉判断时使用 references/subagent-visual-review.md 中定义的独立评审配置生成配置agent_type: default、fork_context: false、把两张截图作为local_image附上、中性标签Image A/Image B或Reference/Candidate绝不告诉子代理哪张是候选、参考、期望、已接受、已失败、更新、更旧、更好或更差。提示词要点子代理对同一视觉目标的两张截图做无偏视觉评审无任何先验上下文报告① 是否显示相同的视口/状态/内容② 相机/视角、布局、内容、缺失细节、标签/文字、图标、颜色、光照、深度/层次、裁切、伪影、可读性、风格上的主要可见差异③ 对表面任务而言哪张更完整/可读为什么④ 关于图像是否保持预期视觉关系或需要再来一轮的简明裁决——不要假设任一张是期望目标只依据可见像素判断。结果的使用把子代理结果当作哪张更不错误的独立证据不是指标或你自己检查的替代品也不是支持基准的投票。若子代理指出相机错误、状态不匹配、内容缺失或可见伪影先修采集/渲染质量再判断其余当它改变或确认下一个实现目标时把裁决引述到工作笔记中。何时使用该技能按技能自身的触发条件当以下场景出现时启用UI、游戏、文档、渲染、图表或生成资产需要客观视觉遥测、并排检查、裁剪/缩放评审或在接受/拒绝一次视觉变更前需要一份全新的第二意见也适用于只有一张截图、没有对照的情况——用它测量该帧是否平坦、空洞或取景糟糕趁任何人评审之前。本文所有指标语义、公式、阈值与运行方式均以 SKILL.md 为准实现细节可对照 visual-parity-diff.mjs 与 visual-parity-diff.eval.mjs 两处源码验证。赞分享【免费下载链接】jevgrepFind code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.项目地址https://gitcode.com/gh_mirrors/je/jevgrep点击查看免费下载相关推荐Front-End-Checklist 视觉回归测试实战用 Playwright 截图对比拦截 CSS 回归Front End Checklist 视觉回归测试实战用 Playwright 截图对比拦截 CSS 回归 视觉回归测试Visual Regressionoh-my-claudecode 视觉裁决visual-verdict用结构化 JSON 驱动截图与参考图的逐轮比对oh my claudecode 视觉裁决visual verdict用结构化 JSON 驱动截图与参考图的逐轮比对 导读 在 Claude Code 驱人工智能AI Agent多智能体Agent 编排Agent 工作流AI 技能CLI开发工具Front-End-Checklist 视觉回归测试实践指南用 Playwright 截图对比与 Chromatic 守护页面外观Front End Checklist 视觉回归测试实践指南用 Playwright 截图对比与 Chromatic 守护页面外观 视觉回归测试Visual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考