Web 素材自动化 Agent
把"这个页面缺图片"这件事,变成前端代码可以直接引用的项目级素材——
不需要用户手动一张一张搜索和下载。
Agent 负责判断(需要什么图、哪张候选最合适、版权是否可用)。
scripts/ 只做确定性的工程操作(调 API 下载字节流、做优化、计算哈希、
组织目录、写清单)。这是本 Skill 的核心设计原则——动手之前先看
"Scripts 与 Agent 的边界"一节。
关于本 Skill 的设计思路
开发者构建 UI 时,从"我需要一个 Banner"到
"这个文件已经在 src/assets/images/banner/home-banner.webp 并被组件引用"
之间,往往是一堆琐碎、重复、易出错的步骤。本 Skill 把这段距离压缩成:
- 理解真正需要什么图:从用户需求 + 项目上下文推断(不要求用户逐项描述)。
- 多源检索候选图:通过各来源的官方/公开 API。
- 筛选每个图片槽位的最佳候选(语义相关度、尺寸、比例、构图、水印、版权),
而不是简单地"返回第一张"。 - 安全下载到项目里,绝不破坏已有文件。
- 组织与命名:贴合项目真实结构,按语义命名。
- 按需优化(WebP、压缩),不盲目转码。
- 去重:对照项目已有素材,避免重复下载。
- 记录:写入素材清单与许可证文件,来源清晰可查。
- 清晰汇报:包括任何版权不确定的素材。
最终目标:让本 Skill 真正成为 Agent 软件开发流程的一部分,而不是一个
"图片下载器"。
Scripts 与 Agent 的边界(动手前必读)
Agent 做决策。Scripts 只执行确定性操作。
Scripts 绝不能自行决定:
- 用户真正需要什么图
- 哪张图最合适
- 哪张图可以安全商用
- 用户应该用哪种视觉风格
Agent 通过上下文 + references/ 中的指南做这些判断。Scripts 仅用于
执行 Agent 已经决定好的工作,例如:
"把这组 URL 下载到 src/assets/images/banner/ 并汇报结果"、
"为这些文件计算感知哈希找重复"、
"把这份清单写入 manifest"。
| Agent 决定(判断) | Script 执行(工程) |
|---|---|
| 需要哪些图片 | — |
| 哪张候选胜出 | — |
| 版权是否可商用 | — |
| 把此 URL 下载到此目录 | image_downloader.py |
| 组织与重命名这些文件 | asset_organizer.py |
| 是否优化这些文件(以及如何优化) | image_optimizer.py |
| 查找重复 | image_deduplicator.py |
| 记录 manifest 与 licenses | asset_manifest.py |
| 按关键词找候选 | image_search.py(仅返回候选) |
工作流
每次任务都按以下步骤执行,每一步标注谁决策。
第 1 步 — 理解图片需求(Agent)
结合用户需求与项目上下文来理解。读项目里的实际内容:package.json、
README.md、当前正在编辑的页面/组件、目录树。从组件/文件名可以推断
可能需要的素材,例如:
- ProductCard.vue / ProductCard.tsx → 商品缩略图
- CategoryCard.vue → 分类图标/图片
- HomeBanner.vue → 首页 Banner
- EmptyState.vue、Avatar.vue、BgWrapper.vue → 装饰/背景
将需求拆解为一张张图片槽位清单,每个槽位包含:
- 用途(Banner / 商品 / 分类 / 图标 / 背景 / 缩略图 / 装饰)
- 数量
- 类型(照片 / 插画 / 图标 / Logo)
- 主题/关键词
- 风格(高端、商务、极简、活泼……)
- 尺寸/宽高比(Banner ≈ 16:9 或 21:9,商品 ≈ 1:1 或 4:3)
- 是否需要透明背景?(图标/Logo 通常是)
- 是否需要高清?、是否适合移动端?、是否适合 Web?(几乎都是"是")
不要强迫用户逐项指定这些。Agent 做合理推断。只有那些会显著影响搜索结果、
且无法从上下文推断的关键属性才向用户确认。详见
references/project-asset-convention.md(命名/槽位)与
references/image-search-strategy.md(Query 构建)。
> 边界:项目上下文仅用于推断图片需求,不要凭空创造用户没有要求的
> 业务内容。如果需求确实模糊,就问一个聚焦的问题——绝不要靠猜测批量下载。
第 2 步 — 构建搜索关键词(Agent)
把每个槽位对应的用户真实视觉意图,转换成有效的搜索关键词。补充同义词、
英文、场景描述,但不能改变用户原本的视觉需求。例如
"白酒商城首页图片"可展开为:
white liquor、Chinese baijiu、premium Chinese liquor bottle、
baijiu product、liquor store shelf。
详见 references/image-search-strategy.md。
第 3 步 — 检索候选(Script + Agent)
按 references/image-source-guide.md 选择来源(Unsplash、Pexels、Pixabay、
Openverse、Wikimedia Commons 或用户指定来源),调用 image_search.py:
传入来源 + 关键词 + 数量。脚本返回候选列表(URL、缩略图、尺寸、作者、
来源、许可证、来源页)。Agent 审阅候选——脚本本身不做排序。
# 方式一:零 Key 开箱即用(自动走匿名来源 openverse / wikimedia)
python scripts/image_search.py --source openverse --query "premium chinese baijiu bottle" --count 10
# 方式二:高质量官方图源(需免费申请 Key,环境变量传入)
python scripts/image_search.py --source unsplash --query "premium chinese baijiu bottle" --count 10 --api-key "$UNSPLASH_KEY"
Key 与开箱即用:openverse 与 wikimedia 匿名即可搜索,无需任何 Key;
unsplash / pexels / pixabay 需要对应官方 Key(免费申请)。当用户未提供
Key 却指定了这三者时,脚本会自动降级到 openverse(再失败则降级到
wikimedia),并在 stderr 给出提示,不会直接报错中断——保证 Skill 零配置也能
跑通。若用户明确想要官方图源,引导其设置 UNSPLASH_KEY / PEXELS_KEY /
PIXABAY_KEY 环境变量(或 --api-key)。
若某来源失败或返回过少,按 references/image-search-strategy.md 降级:
改关键词 → 换来源 → 放宽约束 → 询问用户。
> 版权防线:优先选择能返回明确许可证元数据的来源。
> 任何脚本读不到许可证的图片一律标为"版权状态未知"——绝不声称"可商用"。
> 不要伪造作者、许可证或来源 URL。
第 4 步 — 每个槽位选出最佳(Agent)
按 references/image-selection-guide.md 的标准(语义相关度、清晰度、尺寸、
比例、构图、主体、背景、风格、水印、重复、设计契合度、版权清晰度)从候选
中选出最佳,优先许可证清晰、来源明确的素材。
第 5 步 — 对照项目去重(Script + Agent)
下载前先跑 image_deduplicator.py 扫描已有素材目录与候选 URL/哈希,
跳过已存在的资源。Agent 决定哪些近重复应当跳过。
python scripts/image_deduplicator.py --scan-dir src/assets/images --candidates candidates.json
当用户说"再要几张同类图"时,主动寻找不同的素材(不同的 URL + 不同的
感知哈希),不要重复下载。
第 6 步 — 安全下载(Script)
把最终确定的 URL 列表交给 image_downloader.py 下载到目标目录。脚本负责
处理重定向、Content-Type 检测、扩展名推断、重试/超时、文件名生成、文件名
冲突(重名则改名),绝不覆盖已有文件,也绝不删除或移动目标目录外的文件。
python scripts/image_downloader.py --urls urls.txt --out src/assets/images/banner --manifest-tmp candidates.json
目标目录如何选取见 references/framework-asset-guide.md(Vue 用 src/assets,
React/Next 用 public 或 src/assets,Nuxt 用 static/assets,uni-app 用
static,微信小程序用 images/,纯 HTML 用 assets//images/)。
第 7 步 — 组织与命名(Script + Agent)
使用 asset_organizer.py 把文件按用途移动/重命名到合适的子目录。Agent 提供
用途→目录映射(或沿用项目现有约定)。命名遵循语义化 ASCII:
home-banner.webp、baijiu-product-01.webp、category-beer.webp,不要
IMG_928371.jpg。如果项目已使用中文命名约定,则沿用之。绝不改造用户项目
目录以套模板。
python scripts/asset_organizer.py --src src/assets/images/_tmp --map purposes.json --root src/assets/images
第 8 步 — 优化(Script + Agent,可选)
仅在确实有益时跑 image_optimizer.py(大文件、WebP 有收益、移动端目标)。
脚本会检查尺寸、按需压缩、按需转 WebP——但绝不无条件压缩所有图:
保留透明通道、保留原始格式(当转码会损伤质量时)、由 Agent 决定策略。
保留原始文件信息和来源/许可证信息。
python scripts/image_optimizer.py --dir src/assets/images/products --webp --max-long-edge 1600 --keep-original-meta
第 9 步 — 写入清单与许可证(Script)
运行 asset_manifest.py 写 asset-manifest.json(每个素材一条:name、type、
keyword、source、source_url、author、license、downloaded_at),当素材有署名或
使用限制时再写 licenses.md。
python scripts/asset_manifest.py --root src/assets --candidates candidates.json --downloaded downloaded.json
第 10 步 — 汇报(Agent)
按"最终汇报"模板清晰总结本次处理:列出所有写入与改动的文件、每个素材的
来源与版权状态;明确标注"版权状态待确认"的素材;面向商业项目时显式提醒
用户核验每个素材的最终使用许可。
Source Adapter 架构
image_search.py 基于可插拔的 Source Adapter 模式。每个来源实现同一接口
(search(query, count) -> list[Candidate])。新增来源 = 新增一个适配器模块
并注册;本 Skill 不会被绑定到任何单一网站。默认优先级(可配置):
- 带官方 API + 许可证元数据的来源(Unsplash、Pexels、Pixabay)
- Openverse(聚合 CC 协议作品)
- Wikimedia Commons(署名清晰)
- 用户指定的来源
详见 references/image-source-guide.md。
失败处理
- 搜索失败:改写关键词 → 换来源 → 放宽约束 → 询问用户。
- 下载失败:重试 → 换候选 URL → 换一张图。
- 版权不明:标记"版权状态未知"并告知用户,绝不可声称可商用。
- 需求不明:问一个聚焦的问题;不要靠猜测批量下载。
最终汇报
每次处理完成后,按下面这种结构汇报:
本次处理:
✓ 下载 6 张图片
✓ 发现并跳过 2 张重复图片
✓ 优化 5 张图片
✓ 生成 WebP 4 张
✓ 已放入项目资源目录
资源位置:src/assets/images/
素材:
- banner/home-banner.webp
- products/baijiu-01.webp
- products/baijiu-02.webp
...
来源:
- Unsplash: https://unsplash.com/photos/xxx
- Pixabay: https://pixabay.com/photos/xxx
版权:
- baijiu-01.webp:许可证明确(Unsplash License)
- category-beer.webp:版权状态待确认
修改的文件:
- src/assets/images/banner/home-banner.webp (新增)
- src/assets/asset-manifest.json (新增)
- src/assets/licenses.md (新增)
凡是有"版权状态待确认"的素材,必须在文字上明示。商业项目附加一行:
"建议核验上述素材的最终使用许可。"
硬性约束(必须始终遵守)
- 不得默认认为互联网图片可以自由使用。
- 优先选择来源明确、许可证明确的素材。
- 不得伪造图片作者、许可证或版权信息。
- 不得伪造图片来源 URL。
- 不得覆盖用户已有的图片。
- 不得改造用户项目结构,优先适配项目现状。
- 不确定图片需求时进行必要的询问。
- 图片搜索、筛选与版权判断由 Agent 最终决策。
- Scripts 只执行确定性的下载、处理、检测与组织任务。
- 涉及商业项目时,显式提醒用户核验素材的最终使用许可。
- 不要凭空创造用户没要求的业务内容——上下文只用来推断图片需求,
不创造功能。 - 不要盲目转码/重编码所有图片;优化按需逐图决定。
参考文档(按需加载,不要一次全读)
references/image-source-guide.md— 支持的来源、各自适用场景、API 用法、
Adapter 设计、来源优先级。references/image-search-strategy.md— 需求→Query、关键词扩展、多源搜索、
候选筛选、失败降级。references/copyright-and-license-guide.md— 版权基础、免费与免费商用的
区别、常见许可证、署名要求、不确定时的处理。references/image-selection-guide.md— 图片质量、尺寸、比例、构图、
水印检测、重复检测、用途与选择策略。references/project-asset-convention.md— 命名规范、目录组织、Banner /
商品 / 图标等分类、清单管理、资源引用方式。references/framework-asset-guide.md— Vue、React、Next.js、Nuxt、uni-app、
微信小程序、纯 HTML/CSS/JS 等项目中的静态资源管理方式。
参考文档用于引导 Agent 的判断,不是绝对规则。