Claude Skill

lov-describe-image

给纯文本模型"看图":调用智谱 GLM-4V-Flash(免费)把图片转成文字描述。当用户要求描述/识别/读取图片,或任务里出现图片文件(截图/图表/照片)而当前模型无法直接看图时,优先调用本 skill。需要图片磁盘路径,可附带具体问题。

LLM Mart · 0 points · 13 views 14 listing impressions 0 install-command copies

#vision

Virus-scanned Reviewed automatically before listing.

Full trust report

Download lovstudio-skills-skills_describe-image-0b16007.zip · 7 KB
Part of lovstudio/skills — 83 skills
This skill couldn't be refreshed from GitHub on the last check — you're seeing the last imported snapshot.

Install

skills CLI npx skills add https://github.com/lovstudio/skills/tree/main/skills/describe-image
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lovstudio-skills@llmmart
Git 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

Version

给纯文本模型"看图":把图片发送给视觉模型(智谱 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 驱动任务中提出修改意见时,继续当前产物前必须执行:

  1. 先判断意见是 task-specific(仅本次)还是 reusable(可跨任务复用)。
  2. task-specific 只修改当前任务,不改 Skill。
  3. reusable 先确定作用域:领域规则先更新对应 canonical Skill;适用于所有 Skill 的规则先更新共享规范。
  4. 完成规则更新、版本、lint 与分发核验后,再把修改应用到当前任务。
  5. 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
    
    ![Version](https://img.shields.io/badge/version-0.2.0-CC785C)
    
    给纯文本模型"看图":把图片发送给视觉模型(智谱 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.

No comments yet.

Reviews (0)

No reviews yet.

Related