图片内容识别与结构化批量重命名
把「杂乱命名的图片文件夹」变成「按内容结构化命名的图库」。核心思路:用并行子代理逐张看图提元数据 → 合并 → 按命名规则批量改名 → 出对照表。
> 关键经验:大量图片直接在主会话里逐张 Read 会撑爆上下文。必须分批发派子代理,且子代理把结果写入 JSON 文件而非靠返回值回传(并行子代理常无法可靠回传大段结构化数据,会返回空结果)。
适用场景
- 摄影素材/旅行照片/监控截图等需要按内容重新归档。
- 文件名全是无意义编号(001.jpg、DSC_2082.JPG、空白文件名)、需要语义化。
- 数量大(几十到几百张),需要并行处理。
命名规则(可配置,默认模板)
默认采用四段式(可改成任意维度顺序):
[场景]-[主体]-[特征]-[序号].[扩展名]
示例:草场-芦苇荡-逆光剪影-01.jpg
约束条件(写进校验脚本):
- 单文件名长度 ≤ 30 字符(含扩展名),可配置
MAX_LEN。 - 半角连字符
-分隔,避免空格与特殊字符(/\ : * ? " < > |)。 - 序号统一两位,组内从
01起;超过 99 时自动升三位(100)保证唯一。 - 地标特殊处理:若图片含可辨认地理标识(招牌/观景台/石碑/标志性建筑),用
地标-[具体名称]-[角度/时间]-[序号](如地标-鸳鸯石-秋-01.JPG)。 - 无法明确内容的图片:
待分类-[大致描述]-[序号]。 - 扩展名保留原样(
.jpg/.JPG并存亦可,可后处理统一小写)。
> 可读性原则:当特征位为「静态」这类弱信息时,可把「季节/时间」并入特征位让名字更可读(如 山峦-地貌-夏-01 而非 山峦-地貌-静态-01)。此合并逻辑在 scripts/rename.py 的 BUILD_NAME 中可开关。
标准工作流
步骤 1 — 收集文件清单
ls -1 "/path/to/folder/" > files.txt # 仅图片:*.jpg *.jpeg *.png *.JPG ...
确认总数,并确认没有与目标命名冲突的残留旧文件。
步骤 2 — 分批发派并行子代理做视觉识别(核心)
- 把图片切成 5 批左右,每批 30–45 张(按总数定),用
Agent工具并行启动general-purpose子代理。 - 每个子代理用
Read工具逐一真正打开每张图,基于实际画面判断维度(文件名中文可作线索,但以图为准)。 - 维度建议(可按需增删):
scene场景:草场/山峦/天空/道路/建筑/水域/空镜subject主体:人物/动物/植物/地貌/空镜feature特征/状态:静态/动态/日出/日落/云雾/逆光/特写(取 1–2 个,中文顿号连接)season季节·时间:春/夏/秋/冬/晨/昏/夜(无法判断用「待分类」)color色彩基调:金黄/翠绿/蔚蓝/暖调/冷调(无法判断用「待分类」)is_landmark+landmark是否含地标及名称desc一句话事实描述(≤20 字)- 必须让子代理用
Write把结果写入文件,例如.workbuddy/analysis_a.json,内容为 JSON 数组,每条含orig, scene, subject, feature, season, color, is_landmark, landmark, desc。 - 子代理
max_turns设为图片数 + 余量(约 每张 1 turn + 10),图片多则调高;步数不足会失败,需重跑该批。 - 提示词模板见下方「子代理提示词模板」。
步骤 3 — 合并 JSON
读取全部 analysis_*.json,拼成一个列表(注意去重:以 orig 为键)。用 Python 或脚本合并即可。
步骤 4 — 生成新名 + 组内两位序号
按 场景-主体-特征(或地标/待分类)分组,组内两位流水。逻辑见 scripts/rename.py 的 build_name()。
步骤 5 — 执行重命名 + 输出对照表
scripts/rename.py 会:加载合并 JSON → 生成新名 → 校验长度/冲突 → 执行 rename → 输出 重命名对照表.csv(UTF-8 BOM,Excel 直接打开)与 重命名对照表.md。
python scripts/rename.py --src /path/to/folder --json merged.json --out /path/to/folder
步骤 6 — 校验
cd /path/to/folder
ls -1 | awk '{ if (length($0) > 30) print "OVER:", length($0), $0 }' # 应无输出
# 确认旧编号文件已清除、总数一致
子代理提示词模板(复制改路径即可)
你是一名视觉内容分析助手。请用 Read 工具逐一打开并真正查看每张图片,基于实际看到的内容判断字段:
- scene:从 [草场/山峦/天空/道路/建筑/水域/空镜] 中选最贴切的一个
- subject:从 [人物/动物/植物/地貌/空镜] 中选最贴切的一个
- feature:从 [静态/动态/日出/日落/云雾/逆光/特写] 中选最贴切 1–2 个,中文顿号连接;无明显特征用「静态」
- season:从 [春/夏/秋/冬/晨/昏/夜] 中选;无法判断用「待分类」
- color:从 [金黄/翠绿/蔚蓝/暖调/冷调] 中选;无法判断用「待分类」
- is_landmark:清晰出现可辨认地理标识填 true 并给 landmark 名称,否则 false、landmark 留空字符串
- desc:一句话(≤20字)事实描述
文件名中文可作线索,但必须以图像为准。
需要分析的图片(绝对路径):
<逐行列出本批图片绝对路径>
完成后用 Write 工具写入:<本批输出路径,如 .workbuddy/analysis_a.json>
内容为 JSON 数组,每个文件一个对象,键:orig、scene、subject、feature、season、color、is_landmark、landmark、desc。
最后回复一句话:「已写入 analysis_a.json,共 N 条」。
关键陷阱 / 经验(踩过的坑)
- 并行子代理返回空结果:第一轮我们用返回值回传结构化 JSON,5 个全部返回空。改为「子代理写文件」后 100% 成功。这是本 Skill 最重要的经验。
- 子代理步数不足:
max_turns给太低会导致还没读完所有图就中断(尤其 >40 张的批)。失败就单独重跑那一批,提高上限即可。 leftover误报:改名后脚本若按「旧名是否仍存在」统计「残留」,会误把已改好的新名算成残留。应以「旧名清单是否全清空」为准。- 文件名里有空格/全角破折号(如
018——刘寿福.jpg):新名一律半角-,旧名保留原样做 rename 源。 - 扩展名大小写:
.jpg与.JPG并存时保留原样;如需统一小写,跑一次rename.py --lowercase-ext。
参考脚本
scripts/rename.py:合并 JSON → 生成新名 → 校验 → 改名 → 输出 CSV/MD 对照表。规则变量集中在文件顶部,便于按项目调整。