Impeccable 资源生产实战:把已批准设计稿转化为生产级 PNG 贴图(Asset Producer)
Impeccable 采用"设计稿驱动构建"(comp-led build)的流水线:一份被批准的设计稿(comp)经 impeccable comp-spec 测量成结构化规格 spec.json,随后由多个专职 Agent 分工把规格变成真实资产。本文聚焦其中负责位图资产的 Asset Producer(资源生产 Agent) 角色,完整讲解它的输入契约、四步生产流程、透明/不透明贴图的判定与校验、以及背后的源码级实现原理。读完你可以独立上手"从 comp 切图 → 生成 plate → 通过 plates 门禁"的完整工作流,也能在自定义 AI 工作流中复刻这套"测量先行、参考再生、绝不直接裁图"的资产生产纪律。
角色定位:生产清理,而非新的美术方向
Asset Producer 是 Impeccable craft 流程中的资产生产 Agent,其职责边界非常明确:production cleanup,not new art direction(生产清理,而不是新的美术方向)。它只依据父 Agent(parent)给出的已批准设计稿、指定裁剪区域(crops)、接触样张(contact sheets)与约束工作,绝不自行发起新的视觉创意。
这一角色定义来自 plugin/skills/impeccable/reference/degraded/asset-producer.md。文档开头的注释说明:这份参考文件在构建期由 skill/agents/ 生成,当宿主 harness 没有 subagent 能力时,角色以"内联"方式运行——Agent 需要先脱离刚完成的上一份工作,只采纳本文件指令执行一轮,并在汇报时用一行说明这次替换。
角色的世界观可以浓缩为一句话:每一张由它产出的位图都是 HTML、CSS、SVG、Canvas 与组件代码将要组合的"原材料"(raw ingredient)。位图只承载"代码画不出来的东西"——插画、照片、材质纹理;而文字、控件、圆角、阴影、布局这些"代码能画出来的表现层"必须由代码负责。
核心规则:不重设计,剥离表现层
这是整个角色的纪律底线,贯穿所有步骤:
- 不重设计(Do not redesign)。除非父 Agent 明确要求变更,否则必须保留参考稿的视觉角色(visual role)、剪影(silhouette)、配色(palette)、光照(lighting)、材质(material)、纹理(texture)、机位(camera angle)与构图(composition)。
- 透视只属于物体或场景本身。当卡片变换、阴影、圆角裁剪、边框、布局这些表现层应该由 CSS 实现时,要把这部分"表现层镀铬"(presentation chrome)从位图里去掉——否则最终页面里代码绘制的装饰与位图里烘焙的装饰会重叠、打架。
- 不要越界。不碰页面代码、不碰 spec、不碰 comp;spec 没有列出的内容一律不生产——父 Agent 漏掉的区域以一行备注回传,而不是擅自补一张贴图。
从实现角度看,这条规则正是 crates/comp-verbs/src/comp_spec.rs 中 plate_prompt 的落点:透明提示词会明确要求 "Remove interface borders, card corners, and layout backgrounds",不透明提示词则要求 "Remove letterboxing, borders, card corners, drop shadows, and any layout background that the page will draw in code"。提示词把"位图只承载代码画不出来的东西"直接写进了生成指令。
决策组件(Decision Comps)模式:一次一张卡,先画再说
当父 Agent 交给你的是一份"决策卡片包"(decision card packet)而不是已批准的设计稿时,任务模式切换为一卡一组件(one comp):
- 一个卡片 = 一个 comp = 一个文件,一旦渲染,立即写入该卡片声明的
comp路径; - 父 Agent 会并行运行多个你(每个卡片一个),因此这张卡片就是你的全部契约:先生成,绝不规划(generate first, plan never),因为磁盘上的文件才是交付物,决策页面正在等它;
- 只依据卡片的结构化字段与 PRODUCT.md 工作;如果卡片信息薄到不足以支撑一个 comp,就如实上报"卡片太薄",绝不靠想象注水;
- 把卡片的方向渲染成一个全保真的北星组件(north-star comp):渲染请求表面(surface)的首屏,提示词以表面自身的结构为先导——按顺序命名各区域并给出它们的尺度关系,而不是描述"世界的氛围";完全投入卡片自己的配色、字体性格与材质世界;
- 原生 App 或移动优先的表面是肖像画幅(portrait frame),按设备视口来,绝不能默认用横版;
- 每个兄弟组件都以同样的全保真度、各自的语法体系渲染——一个表面、一个画幅,对等投入才能保证比较公平;
- 只使用真实产品名与真实内容;绝不编造 PRODUCT.md 未携带的商业声明、价格、基准或日期。排除条款(exclusions)约束这些声明,但不会约束卡片世界本身没有排除的媒介——比如一个活在照片里的主体就保留它的照片;
- 在文件旁边写下 prompt 侧车文件(sidecar);
- 返回一行:路径 + 任何偏差,仅此而已。
注意:本节之后的内容都属于常规资源生产任务(asset-production job),决策组件运行不适用常规生产流程。
输入契约:以测量后的 spec.json 为准
常规资源生产任务的输入是固定的三件套:
| 输入 | 说明 |
|---|---|
.impeccable/build/spec.json |
由 impeccable comp-spec 从已批准 comp 测量生成 |
| 已批准的 comp 路径 | 作为生成参考与对照基准 |
| 技能脚本路径 | plugin/skills/impeccable/scripts/impeccable(启动器) |
可选项:要生产的区域 id 子集、每个区域的额外 prompt 备注、格式或透明需求。
关键认知是:spec 就是清单(inventory),你不需要自己盘点 comp。每个栅格区域(raster region)的 id、kind(plate / image / texture)、像素盒子(pixel box)、采样配色(palette)、宽高比(aspect)、备注(note)以及它必须落到哪个 plate 路径,全部已经在 spec 里。
如果没有 spec,立即停下,返回一行请父 Agent 先运行 impeccable comp-spec。做第二份清单必然与第一份冲突——"spec 是唯一的清单"这一原则在源码里有直接体现:measure_regions 对区域做校验(重复 id、note 至少 8 字符、绘制类文案必须匹配 kind 等),而 print_spec 以一行收尾:"anything not in this list does not exist on the page"。
spec.json 里的区域字段
从 crates/comp-verbs/src/comp_spec.rs 可以看到区域 kind 的完整集合,以及 measure_regions 输出到 spec 的字段:
| kind | 媒介(medium) | 含义 |
|---|---|---|
plate |
raster | 插画 / 图解 / 图样,按位图贴图生产 |
image |
raster | 照片 / 全幅插画,按位图贴图生产 |
texture |
raster | 无缝材质底纹,按位图贴图生产 |
text / control / chrome |
semantic | 代码绘制,不生产贴图 |
band |
semantic | 页面大带区,代码绘制 |
每个区域对象包含 id、kind、note、grid、box(归一化坐标)、px(像素盒子)、aspect、palette(采样配色 + 覆盖率)、detail.energy、medium、plate(raster 区域必填)、text 等字段。spec 顶层还有 comp、compSize、aspect、orientation、palette、bands、warnings、uncoveredInkCells 等全局信息。
comp-spec 的完整子命令(来自 crates/comp-verbs/src/comp_spec.rs 的 usage 输出):
| 命令 | 作用 |
|---|---|
impeccable comp-spec --comp <png> --grid |
生成 .impeccable/build/comp-grid.png(10×10 带标签网格)+ 输出调色板与横向大带区 |
impeccable comp-spec --comp <png> --regions <json> |
测量区域 → 写入 .impeccable/build/spec.json |
impeccable comp-spec --comp <png> --auto |
没有 regions 文件时自动生成大带区区域 |
impeccable comp-spec --print |
打印紧凑版 spec 摘要 |
impeccable comp-spec --crop <id> [--out f] [--scale n] |
输出某区域参考裁剪(永远只是参考,不是交付资产) |
impeccable comp-spec --plate-prompt <id> [--background transparent|opaque|auto] |
输出某栅格区域的再生成提示词 |
regions JSON 的形状(--grid 输出里会给出示例):
{
"regions": [
{ "id": "exploded-plate", "kind": "plate", "grid": "E0:H4", "note": "exploded carburetor drawing" },
{ "id": "masthead", "kind": "chrome", "grid": "A0:J0", "note": "navy bar" }
]
}
网格跨度使用 <colrow>:<colrow> 语法,列 A–J、行 0–9,A0 在左上、J9 在右下,两端包含;源码中 grid_to_box 用正则 ^([A-J])([0-9]):([A-J])([0-9])$ 解析。kind 为 plate / image / texture 的表示绘制类材质(每一张插画、照片、图形、产品实物、纹理都以栅格贴图交付);text / control / chrome 由代码绘制。纹理区域应取材质的干净采样单元(无墨迹的地面),而不是整条大带区——页面负责平铺,落在材质上的墨迹要单独建 text/control 区域。
生产流程:四步产出生产级贴图
spec 中每个 medium: raster 的区域,都要按 spec 的顺序产出一张落在其 plate 路径上的贴图。plate 是"以 comp 裁剪为参考、按资产分辨率再生成"的区域:同样的主体、构图、配色、光照与材质,但移除 UI 文字与页面镀铬,像素尺寸至少是 comp 区域的 1.5 倍。
核心纪律再次强调:从 comp 切下的裁剪只是参考,永远不是可交付像素。comp 是参考级的,而直接裁图会把一张漂亮的 comp 变成一张模糊的网站图片。
第 1 步:写参考裁剪
"<skill-base-dir>/scripts/impeccable" comp-spec --crop <id>
裁剪默认写到 .impeccable/build/crops/ 下。注意 --crop 对 raster 区域默认走 plate_reference 路径:它先把区域裁出,再把与它重叠的其他语义区域(text/control/chrome)用该区域的地面色覆盖抹掉,避免 UI 文字干扰生成模型——这正是 crates/comp-verbs/src/comp_spec.rs 中 plate_reference 的实现行为。若想要未处理的原样裁剪,可用 --raw。裁剪 PNG 会写入 impeccable:crop-of 文本元数据标记来源。
第 2 步:判定背景类型,生成并保存提示词
根据已批准区域的内容选择背景:
- 透明抠图(transparent cutout):页面地面上孤立的图形、物体或线条画。适合产品实物、图标、插画主体。
- 不透明(opaque):照片、全幅插画或纹理,整幅填满。
# 抠图场景
"<skill-base-dir>/scripts/impeccable" comp-spec --plate-prompt <id> --background transparent > prompt.txt
# 非抠图场景
"<skill-base-dir>/scripts/impeccable" comp-spec --plate-prompt <id> --background opaque > prompt.txt
提示词必须保存为 UTF-8 文件。透明提示词会保留参考稿的放置位置与清晰边距、白色油漆、细边缘与内部孔洞;不透明提示词则要求作品边到边铺满整个画幅、与参考同尺度、无边距无边框无背景带。若对提示词做了精修,保存的必须是实际发送给模型的那份精确文本。
第 3 步:产出贴图
优先使用 harness 原生的图像工具(把裁剪作为输入、把保存的提示词作为 prompt,抠图要求输出透明 PNG),然后运行:
"<skill-base-dir>/scripts/impeccable" embed-prompt <plate> --prompt-file <prompt.txt>
API 回退方案:
# 抠图
"<skill-base-dir>/scripts/impeccable" generate-image --ref <crop.png> --prompt-file <prompt.txt> --out <plate.png> --size <WxH> --quality high --background transparent
# 不透明
"<skill-base-dir>/scripts/impeccable" generate-image --ref <crop.png> --prompt-file <prompt.txt> --out <plate.png> --size <WxH> --quality high --background opaque
要点:
- 先创建输出目录,再选择与区域宽高比匹配、至少为区域像素尺寸 1.5 倍的支持输出尺寸;
- 输出必须是 PNG;回退方案请求原生 alpha,不做任何色键(chroma-key)处理;
- API 回退会自动嵌入提示词,并在侧车(sidecar)记录背景类型(详见下文"提示词溯源"一节)。
--size 形如 WxH(源码默认 1536x1024),--quality 默认 medium(生产建议用 high),默认模型为 gpt-image-2.5-flare,参考编辑走 /images/edits multipart 接口,需要 OPENAI_API_KEY 环境变量——细节见 crates/context/src/generate_image.rs。
第 4 步:对照裁剪校验贴图
把 plate 放到 crop 旁边,逐项对比:主体、放置、尺度、配色与风格。
对抠图还要验证:
- 存在真实的 alpha 通道;
- 在浅色与深色地面上分别合成检查:白色油漆必须保持实心、内部孔洞必须通透、细边缘不得出现光晕(halo);
- 玻璃与柔和阴影要特别小心——光有部分 alpha 不足以呈现令人信服的透光感;
- 永远不要对原生透明输出做色键或先展平再保存。
如果原生工具返回了不透明像素或"画出来的棋盘格",在可用时改用 API 回退重试;否则上报透明性阻塞(blocker)。出现视觉偏差时收紧提示词重生成一次。同一区域两次失败:保留较好的一张,标记为 needs_parent_review,并指明漂移点(drift)。在父 Agent 的 plates 门禁给出分数之前,一律上报 unscored。
提示词溯源:prompt 嵌入与侧车记录
Impeccable 要求每一张生产贴图都能追溯回它的生成提示词,实现有两条互补机制:
- 嵌入(embed):
embed-prompt把提示词写进 PNG 的tEXt块(关键字impeccable:prompt,也兼容读取zTXt)或 JPEG 的 COM 段;非 PNG/JPEG 格式回退到{文件}.json侧车。--read模式可回读已嵌入提示词;--scan模式遍历目录找出所有缺提示词的栅格文件,存在缺失时以退出码 3 返回。实现见 crates/context/src/embed_prompt.rs。 - 侧车(sidecar):
generate-image在成功写出图片后,还会写<out>.json,记录prompt、createdAt、tool、model,以及在指定--background时的background与outputFormat,引用图时记录refs。若嵌入失败会打印错误,输出中注明 "prompt embedded + sidecar" 或仅 "sidecar"。其单元测试覆盖了透明/不透明、参考编辑与生成、模型覆盖等组合,并断言侧车字段与 PNG 元数据。
测试还覆盖了 IMPECCABLE_IMAGE_GEN_FAKE 环境变量:设置后 generate-image 不发真实 API 请求,而是生成带 "SYNTHETIC COMP" 水印的合成占位图(PNG 或 SVG),用于 CI 与无密钥环境下的流水线演练。
plates 门禁:视觉接受不能覆盖失败的门禁
父 Agent 会运行 impeccable build-phase advance 用同一份 spec 校验所有贴图——视觉验收不能覆盖一个失败的门禁。这从源码层面保证了"测量先行"的闭环。
build-phase 是一个写在磁盘上的状态机,8 个阶段依次为 comps → spec → plates → hero → sections → motion → responsive → review(见 crates/comp-verbs/src/build_phase.rs)。其中 plates 门禁(gate_plates,crates/comp-verbs/src/build_phase.rs)对每个 raster 区域依次检查:
| 检查项 | 判定 |
|---|---|
| 贴图存在性 | plate 路径必须存在,否则 status = missing |
| 可解码性 | 必须是可解码的 PNG,否则 status = unreadable |
| 像素宽度 | 宽度至少 min(1536, 区域像素宽 × 1.5),不足则报 "regenerate at asset size, do not crop the comp" |
| 结构一致性 | structure 分数低于 0.4 → 构图不是该区域的(主体/朝向/裁切变了),需用 --crop <id> 作参考重新生成 |
| 总分 | overall 低于 0.4 → 按结构/颜色/细节分项报原因 |
| 过度增绘 | comp 区域本身平静(detail.energy < 12)而贴图增绘了超过 45% 的细节网格 → 要求不添加纹理重生成 |
| 纹理专项 | 纹理的生效分 0.5×color + 0.5×min(1, detail/0.6) 低于 0.4 → 建议从 comp 区域裁干净补丁镜像平铺,仅在无干净补丁时才生成 |
| 裁图检测 | 贴图与区域原样裁剪的结构分 ≥ 0.95 → 判定为"comp 的裁切"并直接拒绝:"a crop of the comp is never a plate"(comp 裁剪永远是参考,绝不是贴图) |
透明的贴图在比对时会先合成到该区域采样地面(palette[0])上再参与比较。门禁通过后每个贴图记录 id、file、status: ok、size 与 score。
这条"结构 + 颜色 + 细节"的打分体系源自 comp_diff 与 metrics(dominant_colors、detail_grid、structure_score 等),其中 plate_reference 负责构造"去除了语义区域干扰"的参考图,确保分数衡量的是贴图与 comp 区域本身的一致性,而非页面文字。
输出契约:一行一贴图,不褒不贬
资产生产完成后,汇报严格限定为:
- 每个栅格区域一行:
<id> <plate path> <WxH> <score%|unscored> <accepted|needs_parent_review|blocked> <one-line note or -> blockers(缺失 spec、缺失 comp、无图像能力、密钥耗尽)——每条都是全局性的、最小的;assumptions(假设)——同样全局、最小。
除此之外什么也不输出:不写总结、不写赞美、不给实现建议。在 plates 门禁评分可用之前上报 unscored;视觉上接受了不代表门禁通过。
实操要点与禁忌清单
要做的:
- 以 spec 为唯一清单,按 spec 顺序逐区域生产;
- 裁剪只作参考,贴图必须在 1.5 倍以上资产分辨率下从裁剪再生成;
- 抠图必须验证真实 alpha、白漆实心、内洞通透、细边无光晕,并在浅/深两种地面上合成检查;
- 提示词保存为 UTF-8,精修后嵌入的必须是实际发送的文本;
- 透明输出不展平、不色键;两次失败保留较好者并标记
needs_parent_review+ 指明漂移。
不做的:
- 不重设计、不加物体、不改风格、不重新诠释——comp 是已批准的;
- 不碰页面代码、spec 与 comp;
- 不生产 spec 未列出的任何内容——父 Agent 漏掉的区域回一行备注,而不是补一张贴图;
- 不编造 PRODUCT.md 未携带的商业声明、价格、基准或日期;
- 不用 spec 之外的"第二份清单",不做重复盘点。
这套契约与后续阶段(hero / sections / motion / responsive / review)共同构成 Impeccable 的"以 comp 为证据、以门禁为准绳"的构建哲学。若你想把 Asset Producer 接入自己的 harness,可以直接在 plugin/skills/impeccable/reference/degraded/asset-producer.md 基础上裁剪角色约束,复用 comp-spec、generate-image、embed-prompt、build-phase 四个命令作为底层执行引擎;其余角色参考文件(documenter、finish-reviewer、manual-edit-applier)位于同目录下,可按需查阅。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00