dsh-visionary
by zhuiyueya
在图片抵达 LLM 前透明地转成 OCR 文本 + 视觉模型描述——让 DeepSeek API 终于能「看见」聊天图片
A DeepSeek Harness plugin that transparently turns chat images into OCR text + vision-model descriptions before they reach the LLM — so DeepSeek API can finally see…
安装
dsh plugin --profile web add github:zhuiyueya/dsh-visionaryGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗
安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。
README
目录
👁️ dsh-visionary
给纯文本的 DeepSeek 模型装上眼睛。
一个 DeepSeek Harness 插件:在图片到达模型之前,透明地把聊天中的图片转换成 OCR 精确文字 + 视觉模型结构化描述 —— 从此 DeepSeek API 也能看懂截图、文档、照片和图表。
✨ 为什么需要它
DeepSeek API 是纯文本模型。在对话里粘贴一张图片,Harness 会直接拒绝(UNSUPPORTED_CONTENT)——截图看不了、文档看不了、照片看不了。
dsh-visionary 恰好守在被拒绝的那道边界上,在适配器看到图片之前把请求改写:每个图片块变成一个结构化文本块(精确 OCR 转写 + 详细的视觉模型描述)。用户侧的聊天记录保留原图,只有模型侧的请求被转换。
⚡ 特性
- 🔌 透明、框架级 —— 挂在所有 LLM 调用的唯一汇合点(
streamWithRegistration)上;web、headless、子代理全部生效 - 🖥️ 在「设置 → 模型」页配置 —— 预置 6 个视觉提供商(GLM-4V、Qwen-VL、硅基流动、OpenRouter、Gemini、Ollama),像添加 DeepSeek 一样点几下即可,零配置文件
- 🔁 多后端回退链 —— 按 免费 → 付费 → 本地 Ollama 依次尝试,谁先成功用谁;失败原因聚合,绝不中断对话
- 🔤 OCR + VLM 混合 —— 截图/文档走本地精确 OCR;自然图片走结构化 VLM 描述(并附上 OCR 文本互为印证)
- 🧠 能力感知 —— 目标模型声明支持图片输入时原样放行,零开销
- 🗃️ 双层缓存 —— 会话级(
vision/describe事件)+ 全局 KV(~/.dsh/storages):同一张图跨轮次、跨会话都只转换一次 - 🛡️ 防刷屏护栏 —— 每条描述
maxChars硬截断、单请求图片预算、超大图送 VLM 前自动缩小 - 💪 失败不阻塞 —— 转换失败变成明确的占位文本,模型会如实告知用户;可选严格模式直接报错
🔧 工作原理
flowchart LR
U[用户粘贴图片] --> S[附件存储<br/>字节 + 元数据]
S --> M[用户消息<br/>含 image block]
M --> B{dsh-visionary<br/>守在 LLM 边界}
B -->|模型支持图片| P[原样放行]
B -->|纯文本模型| T[转换每个图片块]
T --> C{命中缓存?}
C -->|是| F[复用转换文本]
C -->|否| O[OCR - 本地 tesseract / HTTP 服务]
O --> V[VLM 回退链<br/>GLM-4V → Qwen-VL → Ollama...]
V --> F
F --> R[纯文本模型作答<br/>如同亲眼所见]
- 拦截点:
LlmRuntime.streamWithRegistration——llm.stream()与prepareCall().stream()的共同出口 - 模型侧 / 用户侧分离:会话日志保留原图(界面不变),仅模型请求被改写
- 图片 → 文本格式:
[用户上传的图片 <attachmentId>, 1024x768, image/png]
── OCR 识别文本 ──
<图中精确文字>
── 视觉模型描述(glm-4v-flash)──
<结构化描述>
🚀 快速开始
# 1. 安装插件到 profile
dsh plugin --profile web add dsh-visionary
# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 激活
- insert:
- id: visionary
name: dsh-visionary
重启 dsh web 即生效 —— 发截图零配置可用(内置 tesseract OCR)。想获得完整效果,再加一个视觉模型:
🖥️ 在设置页「模型」里配置视觉模型
打开 设置 → 模型,与配置 DeepSeek 的操作完全一致:
点击 添加模型,从目录里选一个:
目录项 默认端点 说明 GLM-4V-Flash(智谱,免费) https://open.bigmodel.cn/api/paas/v4免费、中文强,首选 Qwen-VL(阿里云百炼) https://dashscope.aliyuncs.com/compatible-mode/v1中文效果顶级 Qwen2.5-VL(硅基流动) https://api.siliconflow.cn/v1注册送额度 OpenRouter 视觉模型(含 :free)https://openrouter.ai/api/v1一个 key 多模型 Gemini 视觉模型(Google) https://generativelanguage.googleapis.com/v1beta/openai免费层额度大 Ollama 本地视觉模型 http://localhost:11434/v1离线、隐私、无需 key 粘贴 API key(存入 DSH 凭据库,可直接点 获取模型 自动探测模型列表)。
确认 baseURL 与模型 id,保存。完成——全程不碰 YAML。
配置了多个视觉模型时,自动按目录顺序组成有序回退链(目录顺序 = 优先级);已配置的模型随时可在页面编辑/删除。任何提供商路由下声明了 image 输入模态的模型都会被自动纳入。
OCR 调优、模式、缓存属于
vision:命名空间的高级配置——默认值已开箱即用。
🧭 模式与回退链
| 模式 | 行为 | 适用场景 |
|---|---|---|
auto(默认) |
先 OCR;OCR 达到 ocr.minChars 字数视为"文本图"→ 仅 OCR。否则 VLM 描述(附 OCR 上下文互证) |
一切 |
ocr |
仅 OCR | 截图、文档、代码、表格 |
vlm |
仅视觉模型 | 照片、自然图片、示意图 |
both |
OCR 和 VLM 都要(VLM 纠正/补充 OCR) | 需要语义理解的文档 |
每张图的回退顺序:设置页配置的提供商 → vlm.backends —— 逐个尝试直到成功;超时/API 错误自动换下一个;全部失败变成可见占位符(严格模式则报错)。
⚙️ 高级配置
全部可选,写在 settings.yaml 的 vision: 段(热更新):
vision:
mode: auto # auto | ocr | vlm | both
ocr:
engine: auto # auto(http→rapid-json→tesseract) | tesseract | http | rapid-json | none
languages: [chi_sim, eng] # tesseract 语言包
minChars: 20 # auto 模式:OCR 达到该字数视为"文本图",不再调 VLM
# http: { url: "http://127.0.0.1:8000/ocr" } # 自托管 PaddleOCR/RapidOCR 服务
# binaryPath: "/path/to/RapidOCR-json" # Windows/Linux 高精度 OCR
vlm:
enabled: true
maxChars: 2000 # 每条描述硬上限(提示词约束 + 输出截断双保险)
maxPixels: 1500000 # 超过该像素数先等比缩小再送 VLM(需 sharp)
prompt: | # 默认中文明细描述提示词,可自由覆盖
请以中文详细描述这张图片……
backends: # 传统有序回退链(设置页配置的提供商优先)
- name: local-ollama
baseUrl: http://localhost:11434/v1
model: qwen2.5vl
skipVisionModels: true # 目标模型支持图片时原样放行
cache: { session: true, global: true, maxAgeMs: 2592000000 }
concurrency: 4 # 单请求图片并行转换数
maxImagesPerRequest: 10 # 单请求图片预算(超出用省略标记)
placeholderOnError: true # false = 转换失败直接让 LLM 请求报错
OCR 引擎
| 引擎 | 说明 |
|---|---|
tesseract |
内置,纯 JS + WASM,零原生依赖;语言包自动下载(设 langPath 可完全离线) |
http |
对接任意自托管 OCR 服务(PaddleOCR/RapidOCR FastAPI、Dify OCR 节点)—— 中文精度最佳路径;POST {"image":"data:…"} 期望 {"text":"…"} |
rapid-json |
RapidOCR-json 二进制(Windows/Linux,中文高精度) |
none |
关闭 OCR(纯 VLM 模式) |
API key 解析
apiKey(字面量)→ apiKeyEnv 环境变量 → DSH 凭据服务。本地服务(Ollama)允许无 key;云端无 key 会 401 并自动回退到下一个后端。
🗃️ 缓存
- 会话层:会话日志里的
vision/describe事件 —— 同一会话内同一张图跨轮次零重复调用 - 全局层:
~/.dsh/storages的 KV 单元 —— 新会话里遇到同一张图也不会重新转换 - 缓存键对转换配置做指纹(模式、OCR 引擎、后端端点/模型、提示词、各项上限),更换模型后旧缓存自动失效
❓ 常见问题
用户还能看到自己的图片吗? 能。聊天记录保留原图,只有模型侧的请求携带文本。
会花钱吗? OCR 本地免费;默认 VLM(GLM-4V-Flash)官方免费;回退链(免费 → 付费 → 本地 Ollama)由你掌控。
图片会发给第三方吗? 只有当你配置了云端 VLM 才会。mode: ocr(或本地 Ollama)时一切都在本机完成。
为什么不用工具式方案? 工具式插件依赖模型记得去调工具(通常还要写硬规则兜底)。本插件是推式:转换发生在适配器之前、无条件执行——模型连"看不了"的选项都没有。
一条消息多张图? 并行转换(受 concurrency 限制)、缓存、预算封顶。
🧪 开发
git clone git@github.com:zhuiyueya/dsh-visionary.git
cd dsh-visionary && npm install
# 端到端测试(真实 tesseract OCR + mock VLM 服务 + 转换断言)
node test/e2e.mjs # 20/20 PASS
# 真实 DeepSeek API 集成验证(在 profile 目录运行,见脚本头注释)
📌 Topics
Recommended GitHub tags for discoverability:
deepseek-harness dsh-plugin vision-bridge image-understanding
multimodal ocr vlm text-only-llm llm-plugin glm-4v qwen-vl ollama
📜 许可证
🙏 致谢
架构参考了 OpenClaw 的媒体理解(推式预处理)、opencode 的图片规范化、block/goose 的本地推理模态门控,以及 vision-bridge-mcp 的回退链——融汇成一个 DeepSeek Harness 原生插件。
原始 README: https://github.com/zhuiyueya/dsh-visionary/blob/main/README.zh-CN.md ↗
同类插件
查看全部 →
modlens
为纯文本模型架起视觉桥梁:粘贴图片,输出结构化 JSON 证据(OCR、版面、语义)。

dsh-vision-toolkit
让纯文本模型更好地做视觉任务:带意图的图片问答、长截图 OCR、UI 还原等。

dsh-vision-router
为纯文本 Agent 提供视觉能力:内置免 Key 视觉链 + 像素级视觉工具(看图问答、定位、裁剪、像素对比、取色、OCR、矢量化、抠图、截图);粘贴图片即可用。

dsh-vision-complete
给 DeepSeek 补上「眼睛和耳朵」的多模态视觉插件:看图 / OCR / 物体检测 / 视频理解 / 语音转写 / 截图直读,一键安装(DSH 插件)。

dsh-media-skills
面向纯文本模型的免费视觉桥与生图:粘贴读图、GLM-4V-Flash 与 Gemini 引擎故障转移、modlens 同款结构化证据输出,并自动播种免费视觉模型路由。

dsh-vision-opencode
给纯文本主模型加可配置识图模型:vision_read_image 工具、输入框识图模型选择器,以及纯文本路由的图片自动转文字。