返回 Skill 列表
extension
分类: 内容与媒体无需 API Key

图片索引与文章自动插图

本地照片索引与文章自动插图系统。扫描照片库,调用视觉 AI 生成中文描述和向量索引,写文章时根据上下文语义匹配并插入照片,支持关键词和自然语言搜索。

person作者: sunny31221hubOpenAPI

图片索引与文章自动插图

安装位置要求(重要)

本技能只安装到项目级,不要安装到全局目录(~/.claude/skills/~/.agents/skills/ 等):

  • 多数工具(Codex、Kimi Code、Cursor 等):解压到项目根目录的 .agents/skills/image-indexer/(Agent Skills 开放标准 universal 目录,工具自动发现)
  • Claude Code:解压到项目根目录的 .claude/skills/image-indexer/

安装方式:从技能中心页面下载 zip 解压到上述项目目录;或安装 content-system-setup 技能后运行 python3 scripts/setup.py --install-skills,自动下载安装全部配套技能(项目级)。

Overview

这是一个本地照片管理与写作辅助工具。核心能力是将你的本地照片库转化为可语义搜索的向量索引,然后在写 Markdown 文章时,自动分析段落内容,从你的照片库中匹配最合适的照片插入。

核心原理:

  1. 视觉模型看懂每张照片 → 生成中文描述 + 标签 + 场景 + 氛围
  2. Embedding 模型将描述转为 1024 维向量 → 存为索引
  3. 搜索时将查询文本同样转为向量 → 余弦相似度匹配 → 返回 Top-K

与华为相册缓存的类比:华为用缩略图做"替身"快速预览,这个系统用向量描述做"替身"快速搜索。

Usage

/image-indexer index              # 构建图片索引
/image-indexer search "日落海边"   # 搜索照片
/image-indexer insert 文章.md     # 文章自动配图
/image-indexer status             # 查看索引状态

每次使用前需确保 SILICONFLOW_API_KEY 环境变量已设置。

Example

从头构建索引到文章配图的完整示例:

# 1. 构建索引(先测试 20 张)
cd scripts && python3 scan_images.py --limit 20
SILICONFLOW_API_KEY="sk-xxx" python3 generate_descriptions.py --limit 20
SILICONFLOW_API_KEY="sk-xxx" python3 build_embeddings.py

# 2. 搜索照片
SILICONFLOW_API_KEY="sk-xxx" python3 search_images.py "木桌上的茶具" --top-k 3

# 3. 为文章配图
SILICONFLOW_API_KEY="sk-xxx" python3 insert_images.py ~/article.md ~/article_illustrated.md

When to Use

  • 写完一篇 Markdown 文章,想从自己的照片库里配图(而非网上找图)
  • 想搜索手机里有没有某个场景的照片:"有没有日落的照片"
  • 第一次使用或新增照片后,需要构建/更新索引
  • 查看索引状态和统计

When NOT to Use

  • 从网上搜索图片 → 用浏览器或图库网站
  • 批量修图/管理照片 → 用照片管理软件
  • 文章排版/发布 → 用配套的排版/发布技能
  • 只需要一篇文章的快速配图且不关心图片来源 → 直接用 Pexels/Unsplash

Quick Reference

| 操作 | 命令(在 skill 根目录下执行) | 说明 | |------|------|------| | 构建索引(全量) | cd scripts && python3 scan_images.py && python3 generate_descriptions.py && python3 build_embeddings.py | 首次使用,约需 30-60 分钟 | | 构建索引(测试) | 同上,加 --limit 20 | 先跑 20 张验证流程 | | 搜索照片 | cd scripts && SILICONFLOW_API_KEY="sk-xxx" python3 search_images.py "日落海边" --top-k 5 | 自然语言搜索 | | 文章配图 | cd scripts && SILICONFLOW_API_KEY="sk-xxx" python3 insert_images.py 文章.md 输出.md | 自动在段落间插入照片 | | 查看状态 | python3 -c "import json; d=json.load(open('$HOME/image-indexer/data/image_descriptions.json')); print(f'已索引: {len(d)} 张')" | 索引进度查询 |

环境要求

API Key

需要 SiliconFlow API Key(免费注册 https://cloud.siliconflow.cn),设为环境变量:

export SILICONFLOW_API_KEY="sk-xxxxxxxx"

Python 依赖

pip3 install numpy Pillow requests

目录结构

image-indexer/
├── SKILL.md                          # 本文件
└── scripts/
    ├── config.py                     # 配置(路径、API、过滤规则)
    ├── scan_images.py                # 步骤1:扫描图片,过滤缓存
    ├── generate_descriptions.py      # 步骤2:AI 生成描述
    ├── build_embeddings.py           # 步骤3:构建向量索引
    ├── search_images.py              # 步骤4:语义搜索(含 ImageSearcher 类)
    └── insert_images.py              # 步骤5:文章自动插图

~/image-indexer/data/                 # 索引数据(不随 skill 走)
├── image_inventory.json              # 图片清单
├── image_descriptions.json           # AI 生成的描述
├── image_embeddings.npy              # 向量数组 (N×1024)
├── image_paths.json                  # 路径列表(与向量对应)
└── error_log.json                    # 处理失败记录

Workflow

操作 1:构建图片索引(一次性)

用户说"索引照片"、"构建图片索引"时执行。

Step 1: 确认 API Key

echo $SILICONFLOW_API_KEY

如果为空,引导用户设置。

Step 2: 扫描图片

cd scripts && python3 scan_images.py --limit 20

过滤规则:

  • 必须为 jpg/jpeg/png/heic/webp/bmp 格式
  • 宽或高 < 200px 的缩略图不收录
  • 纯数字名、hash 名、_compv2.tmp/.dat/.xml/.bak 等缓存文件过滤

Step 3: 生成描述

SILICONFLOW_API_KEY="sk-xxx" python3 generate_descriptions.py --limit 20
  • 图片压缩到最长边 512px,转 base64 发给 SiliconFlow
  • 5 线程并发,每 50 张保存进度
  • 支持断点续传(重新运行自动跳过已处理)
  • 失败记录写入 error_log.json

Step 4: 构建向量索引

SILICONFLOW_API_KEY="sk-xxx" python3 build_embeddings.py
  • 拼接 caption + tags + scene + mood → 输入 BAAI/bge-m3
  • 输出 1024 维向量,批量 32 条,存为 numpy 数组

测试验证后,去掉 --limit 跑全量。

操作 2:搜索照片

用户说"找一张...的照片"、"搜索我的照片"、"有没有...的图"时执行。

cd scripts && SILICONFLOW_API_KEY="sk-xxx" python3 search_images.py "用户的自然语言查询" --top-k 5 --min-score 0.2

返回结果包含:文件名、描述、标签、场景、氛围、相似度分数。

在对话中直接展示匹配结果表格,让用户确认选哪张。

操作 3:文章自动配图

用户说"给这篇文章配图"、"插图"、"把我的照片插到文章里"时执行。

cd scripts && SILICONFLOW_API_KEY="sk-xxx" python3 insert_images.py /path/to/article.md /path/to/output.md --density 3 --max-images 6 --min-score 0.3

参数说明:

  • --density 3:每 3 个段落插入一张图(默认 4)
  • --min-score 0.3:最低相似度阈值,低于此分数宁可不插图
  • --max-images 10:单篇文章最多插图数

系统会:

  1. 解析文章段落结构,跳过标题/列表/代码块
  2. 提取每个候选位置的上下文(上下各 2 段)
  3. 语义搜索最匹配的照片
  4. 同一文章不重复使用同一张图
  5. 分数低于阈值的位置主动跳过

完成后展示匹配结果表格:

| 位置 | 照片 | 分数 | 说明 |
|------|------|------|------|
| 段落2 | 沙朴树.jpg | 0.59 | 匹配"树林"上下文 |

配置说明

scripts/config.py 中的关键配置:

| 配置项 | 默认值 | 说明 | |--------|--------|------| | PHOTOS_DIR | ~/Pictures/照片 | 照片目录(需自行修改;内容创作系统建议指向 07_视觉与排版/图片库/) | | DATA_DIR | ~/image-indexer/data/ | 索引数据目录 | | VISION_MODELS | GLM-4.1V-9B → Qwen3-VL-8B → Qwen3-VL-30B | 视觉模型优先级 | | EMBEDDING_MODEL | BAAI/bge-m3 | 向量模型 | | CONCURRENCY | 5 | 并发数 | | SAVE_INTERVAL | 50 | 断点保存间隔 | | MIN_SCORE | 0.3 | 搜索最低相似度 |

Common Mistakes

| 错误 | 原因 | 修复 | |------|------|------| | API 超时 | SiliconFlow 免费额度限速 | 已内置 3 次重试 + 60s 超时 | | 描述生成中断 | 网络波动/API 异常 | 重新运行,自动断点续传 | | 插图不匹配 | 索引照片太少 | 索引照片足够多后匹配度大幅提升 | | 找不到合适的图 | 候选照片与文章主题无关 | 系统会主动跳过(分数低于阈值),不会强行插入 | | ModuleNotFoundError | 缺少 Python 依赖 | pip3 install numpy Pillow requests |

Resources