lov-describe-image
给纯文本模型"看图":调用智谱 GLM-4V-Flash(免费)把图片转成文字描述。当用户要求描述/识别/读取图片,或任务里出现图片文件(截图/图表/照片)而当前模型无法直接看图时,优先调用本 skill。需要图片磁盘路径,可附带具体问题。
#vision
Install
npx skills add https://github.com/lovstudio/skills/tree/main/skills/describe-image
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lovstudio-skills@llmmart
git clone https://github.com/lovstudio/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lovstudio/skills collection as a plugin from our marketplace. Git is the plain clone.
README
看图说话 · Image Narrator
给纯文本模型"看图":把图片发送给视觉模型(智谱 GLM-4V-Flash,免费),返回文字描述,让本身不具备视觉能力的模型(如 deepseek-v4-flash)能间接"看到"图片内容。
解决的问题
在 Claude Code + 纯文本 DeepSeek(api.deepseek.com/anthropic)这类环境下,模型没有原生视觉能力,粘贴的图片无法被直接理解。本 skill 用一个免费视觉模型作为"眼睛":读入图片文件 → base64 编码 → 调 GLM-4V-Flash → 把文字描述转述回给调用模型。
安装
# 真源(Lovstudio 三层 symlink 约定)
mkdir -p ~/lovstudio/coding/skills
git clone <this-repo> ~/lovstudio/coding/skills/lov-describe-image-skill # 或直接拷贝目录
ln -sfn ~/lovstudio/coding/skills/lov-describe-image-skill ~/.agents/skills/lov-describe-image
ln -sfn ../../.agents/skills/lov-describe-image ~/.claude/skills/lov-describe-image
配置
设置智谱 API Key(注册地址 https://bigmodel.cn/apikey/platform,key 格式 id.secret):
export ZHIPU_API_KEY="你的key" # 建议写入 ~/.zshenv 长期生效
用法
python3 ~/.claude/skills/lov-describe-image/scripts/describe_image.py "<图片路径>" "[具体问题]"
<图片路径>必填:绝对路径,或相对当前工作区的路径。[具体问题]可选:想从图中知道的具体信息;省略则完整描述(物体/场景/布局/颜色/风格/所有文字)。
在 Claude Code 中,直接说"看看这张图 <路径>" 即可自动触发。
行为细节
- 超 5MB 图片自动用 macOS 自带
sips降采样到 2048px。 glm-4v-flash的max_tokens上限是 1024,脚本已固定,设大会被 API 400 拒绝。- 请求超时 60s;失败时输出明确错误(未设 key / 网络 / 格式 / 尺寸超限)。
已知限制
- 视觉后端是 GLM-4V-Flash(免费档),对细节核对(逐字转写、精确比对)置信度有限,多次调用可能给出前后不一致的答案;重要结论建议用更强的视觉模型(如 Gemini)交叉验证。
- 需要图片的磁盘路径;仅有
[Image #N]占位符而无可读路径时无法工作,需向用户索要路径。 - 只做图片→文字,不做图片生成、编辑或转换。
换视觉后端
改 scripts/describe_image.py 顶部的 BASE_URL / MODEL / apiKeyEnv 即可切换到任意 OpenAI 兼容视觉端点(如 SiliconFlow 的 Qwen-VL)。
License
MIT
Skill manifest
看图说话 · Image Narrator
给纯文本模型"看图":把图片发送给视觉模型(智谱 GLM-4V-Flash,免费),返回文字描述,让本身不具备视觉能力的模型(如 deepseek-v4-flash)能间接"看到"图片内容。
Triggers
Activate when
- 用户要求"看看/描述/识别/读懂/读取/识别这张图",或询问图片里写了什么。
- 任务上下文里出现图片文件(截图、图表、照片、海报、含文字的图),而当前模型无法直接看图。
- 需要从含文字的图片(界面截图、文档扫描、图表)中提取具体信息,例如检查异常、转录文字、核对内容。
Do not activate when
- 用户只是要求生成、编辑、压缩或转换图片,而不是理解图片内容。
- 当前模型本身具备视觉能力、能直接看到图片,无需转述。
- 用户明确要求走 dsh 的原生多模态管线、项目内置读图工具,或指定了其他视觉后端。
Usage
python3 ~/.claude/skills/lov-describe-image/scripts/describe_image.py "<图片路径>" "[具体问题]"
<图片路径>必填:绝对路径,或相对当前工作区的路径(建议绝对路径,避免歧义)。[具体问题]可选:想从图中知道的具体信息;省略则让视觉模型完整描述(物体/场景/布局/颜色/风格/所有文字)。
Behavior
- 读取文件 → 超 5MB 自动用
sips降采样到 2048px → base64 编码 → 调 GLM-4V-Flash(max_tokens上限 1024)。 - 返回的文本就是视觉模型的回答,直接向用户转述,不要添油加醋,也不要声称"看到了原图"。
- 失败时(未设 key / 网络 / 尺寸超限)会打印明确错误,按提示处理即可。
- 小模型对细节核对(逐字转写)置信度有限;重要结论建议用更强的视觉模型(如 Gemini)交叉验证。
Prerequisites
- 环境变量
ZHIPU_API_KEY(智谱 key,格式id.secret,注册地址:https://bigmodel.cn/apikey/platform)。 - macOS 自带
sips(大图降采样)与python3。
通用反馈闭环
用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行:
- 先判断意见是
task-specific(仅本次)还是reusable(可跨任务复用)。 task-specific只修改当前任务,不改 Skill。reusable先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。- 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。
reusable修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。
Files (skills)
-
scripts
-
describe_image.py 4.3 KB
#!/usr/bin/env python3 """see_image — 给纯文本模型看图:把图片发给智谱 GLM-4V-Flash,返回文字描述。 用法: describe_image.py <image_path> [question] 环境变量: ZHIPU_API_KEY 智谱开放平台 key(https://bigmodel.cn/apikey/platform,格式 id.secret) """ import base64 import json import os import shutil import subprocess import sys import tempfile import urllib.error import urllib.request BASE_URL = "https://open.bigmodel.cn/api/paas/v4/chat/completions" MODEL = "glm-4v-flash" MAX_TOKENS = 1024 # glm-4v-flash 的 max_tokens 上限就是 1024,设大会被 400 拒绝 MAX_BYTES = 5 * 1024 * 1024 # 超过则用 sips 降采样,避免尺寸/载荷拒绝 IMAGE_EXT = {".png", ".jpg", ".jpeg", ".webp", ".gif", ".bmp"} MIME_BY_EXT = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".webp": "image/webp", ".gif": "image/gif", ".bmp": "image/bmp", } DEFAULT_PROMPT = ( "请详细描述这张图片:主要物体、人物、场景、布局、颜色、风格,以及图中出现的所有文字(请完整转录)。" "如果图片是截图或图表,请说明其结构和关键信息。" ) def main() -> int: if len(sys.argv) < 2: print("用法: describe_image.py <图片路径> [具体问题]", file=sys.stderr) return 2 path = sys.argv[1] question = sys.argv[2] if len(sys.argv) > 2 and sys.argv[2].strip() else DEFAULT_PROMPT api_key = os.environ.get("ZHIPU_API_KEY", "").strip() if not api_key: print( "lov-describe-image: 未设置 ZHIPU_API_KEY。请到 https://bigmodel.cn/apikey/platform 注册," "然后执行 export ZHIPU_API_KEY='你的key'(写入 ~/.zshenv 长期生效)。", file=sys.stderr, ) return 1 if not os.path.isfile(path): print(f"lov-describe-image: 找不到文件 {path}", file=sys.stderr) return 1 ext = os.path.splitext(path)[1].lower() if ext not in IMAGE_EXT: print(f"lov-describe-image: 不支持的图片格式 {ext or '(无扩展名)'},支持 {sorted(IMAGE_EXT)}", file=sys.stderr) return 1 data = open(path, "rb").read() mime = MIME_BY_EXT[ext] if len(data) > MAX_BYTES: if shutil.which("sips") is None: print(f"lov-describe-image: 图片 {len(data)} 字节超过 {MAX_BYTES} 且无 sips 可降采样", file=sys.stderr) return 1 with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp: tmp_path = tmp.name try: subprocess.run(["sips", "-Z", "2048", path, "--out", tmp_path], check=True, capture_output=True) data = open(tmp_path, "rb").read() mime = "image/jpeg" finally: os.unlink(tmp_path) body = { "model": MODEL, "messages": [{ "role": "user", "content": [ {"type": "text", "text": question}, {"type": "image_url", "image_url": {"url": f"data:{mime};base64,{base64.b64encode(data).decode()}"}}, ], }], "max_tokens": MAX_TOKENS, } req = urllib.request.Request( BASE_URL, data=json.dumps(body).encode(), headers={"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}, ) try: with urllib.request.urlopen(req, timeout=60) as resp: payload = json.loads(resp.read().decode()) except urllib.error.HTTPError as e: print(f"lov-describe-image: 视觉 API 返回 HTTP {e.code}: {e.read().decode()[:500]}", file=sys.stderr) return 1 except Exception as e: # 网络/超时/解析 print(f"lov-describe-image: 请求失败: {e}", file=sys.stderr) return 1 content = payload.get("choices", [{}])[0].get("message", {}).get("content") if content is None: print(f"lov-describe-image: 视觉 API 返回空响应: {json.dumps(payload, ensure_ascii=False)[:300]}", file=sys.stderr) return 1 text = "".join(p.get("text", "") for p in content) if isinstance(content, list) else str(content) if not text.strip(): print("lov-describe-image: 视觉 API 返回了空文本", file=sys.stderr) return 1 print(text) return 0 if __name__ == "__main__": sys.exit(main())
-
-
.gitignore 29 B · in bundle
-
CHANGELOG.md 317 B
# Changelog All notable changes to this skill are documented here. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning: [SemVer](https://semver.org/) ## [0.2.0] - 2026-08-24 ### Added - add the shared feedback-classification and approval-invalidation gate used by every LovStudio Skill -
LICENSE 1 KB · in bundle
-
README.md 2.6 KB
# 看图说话 · Image Narrator  给纯文本模型"看图":把图片发送给视觉模型(智谱 GLM-4V-Flash,免费),返回文字描述,让本身不具备视觉能力的模型(如 `deepseek-v4-flash`)能间接"看到"图片内容。 ## 解决的问题 在 Claude Code + 纯文本 DeepSeek(`api.deepseek.com/anthropic`)这类环境下,模型没有原生视觉能力,粘贴的图片无法被直接理解。本 skill 用一个免费视觉模型作为"眼睛":读入图片文件 → base64 编码 → 调 GLM-4V-Flash → 把文字描述转述回给调用模型。 ## 安装 ```bash # 真源(Lovstudio 三层 symlink 约定) mkdir -p ~/lovstudio/coding/skills git clone <this-repo> ~/lovstudio/coding/skills/lov-describe-image-skill # 或直接拷贝目录 ln -sfn ~/lovstudio/coding/skills/lov-describe-image-skill ~/.agents/skills/lov-describe-image ln -sfn ../../.agents/skills/lov-describe-image ~/.claude/skills/lov-describe-image ``` ## 配置 设置智谱 API Key(注册地址 https://bigmodel.cn/apikey/platform,key 格式 `id.secret`): ```bash export ZHIPU_API_KEY="你的key" # 建议写入 ~/.zshenv 长期生效 ``` ## 用法 ```bash python3 ~/.claude/skills/lov-describe-image/scripts/describe_image.py "<图片路径>" "[具体问题]" ``` - `<图片路径>` 必填:绝对路径,或相对当前工作区的路径。 - `[具体问题]` 可选:想从图中知道的具体信息;省略则完整描述(物体/场景/布局/颜色/风格/所有文字)。 在 Claude Code 中,直接说"看看这张图 <路径>" 即可自动触发。 ## 行为细节 - 超 5MB 图片自动用 macOS 自带 `sips` 降采样到 2048px。 - `glm-4v-flash` 的 `max_tokens` 上限是 1024,脚本已固定,设大会被 API 400 拒绝。 - 请求超时 60s;失败时输出明确错误(未设 key / 网络 / 格式 / 尺寸超限)。 ## 已知限制 - 视觉后端是 GLM-4V-Flash(免费档),对**细节核对**(逐字转写、精确比对)置信度有限,多次调用可能给出前后不一致的答案;重要结论建议用更强的视觉模型(如 Gemini)交叉验证。 - 需要图片的**磁盘路径**;仅有 `[Image #N]` 占位符而无可读路径时无法工作,需向用户索要路径。 - 只做图片→文字,不做图片生成、编辑或转换。 ## 换视觉后端 改 `scripts/describe_image.py` 顶部的 `BASE_URL` / `MODEL` / `apiKeyEnv` 即可切换到任意 OpenAI 兼容视觉端点(如 SiliconFlow 的 Qwen-VL)。 ## License MIT -
SKILL.md 3.3 KB
--- name: lov-describe-image description: 给纯文本模型"看图":调用智谱 GLM-4V-Flash(免费)把图片转成文字描述。当用户要求描述/识别/读取图片,或任务里出现图片文件(截图/图表/照片)而当前模型无法直接看图时,优先调用本 skill。需要图片磁盘路径,可附带具体问题。 license: MIT metadata: author: mark version: "0.2.0" tags: - vision - image - describe - multimodal - glm-4v - ocr --- # 看图说话 · Image Narrator 给纯文本模型"看图":把图片发送给视觉模型(智谱 GLM-4V-Flash,免费),返回文字描述,让本身不具备视觉能力的模型(如 deepseek-v4-flash)能间接"看到"图片内容。 ## Triggers ### Activate when - 用户要求"看看/描述/识别/读懂/读取/识别这张图",或询问图片里写了什么。 - 任务上下文里出现图片文件(截图、图表、照片、海报、含文字的图),而当前模型无法直接看图。 - 需要从含文字的图片(界面截图、文档扫描、图表)中提取具体信息,例如检查异常、转录文字、核对内容。 ### Do not activate when - 用户只是要求生成、编辑、压缩或转换图片,而不是理解图片内容。 - 当前模型本身具备视觉能力、能直接看到图片,无需转述。 - 用户明确要求走 dsh 的原生多模态管线、项目内置读图工具,或指定了其他视觉后端。 ## Usage ```bash python3 ~/.claude/skills/lov-describe-image/scripts/describe_image.py "<图片路径>" "[具体问题]" ``` - `<图片路径>` 必填:绝对路径,或相对当前工作区的路径(建议绝对路径,避免歧义)。 - `[具体问题]` 可选:想从图中知道的具体信息;省略则让视觉模型完整描述(物体/场景/布局/颜色/风格/所有文字)。 ## Behavior - 读取文件 → 超 5MB 自动用 `sips` 降采样到 2048px → base64 编码 → 调 GLM-4V-Flash(`max_tokens` 上限 1024)。 - 返回的文本就是视觉模型的回答,直接向用户转述,不要添油加醋,也不要声称"看到了原图"。 - 失败时(未设 key / 网络 / 尺寸超限)会打印明确错误,按提示处理即可。 - 小模型对细节核对(逐字转写)置信度有限;重要结论建议用更强的视觉模型(如 Gemini)交叉验证。 ## Prerequisites - 环境变量 `ZHIPU_API_KEY`(智谱 key,格式 `id.secret`,注册地址:https://bigmodel.cn/apikey/platform)。 - macOS 自带 `sips`(大图降采样)与 `python3`。 ## 通用反馈闭环 用户在 Skill 驱动任务中提出修改意见时,继续当前产物前必须执行: 1. 先判断意见是 `task-specific`(仅本次)还是 `reusable`(可跨任务复用)。 2. `task-specific` 只修改当前任务,不改 Skill。 3. `reusable` 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。 4. 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。 5. `reusable` 修改会使此前的“确认”“继续”“发吧”失效;完成当前产物修改和回读后必须停下,等待用户下一步指示,不自动进入发布、提交或其他外部写入。
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.