deepseek-eyes

by fryghost

1 工具与能力github收录于 08-23

给 DeepSeek Harness 里的纯文本模型视力——然后直接粘贴图片就行

Give a text-only model in DeepSeek Harness sight — then just paste the image.

安装

dsh plugin --profile web add github:fryghost/deepseek-eyes

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗

安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。

README

目录

给 DeepSeek Harness 里的纯文本模型装上眼睛——然后直接粘贴图片就行。

在 DeepSeek Harness 中,只要当前模型是纯文本模型,粘贴或拖入的图片会在消息进入 agent 之前就被拒绝——工具、skill、插件统统没有机会介入。deepseek-eyes 在模型选择器里新增一个 DeepSeek(视觉桥) 入口:选它,底层模型仍然是你的纯文本模型,粘贴图片的体验和原生视觉模型完全一样。一次设置、全部在界面里完成——不用写 YAML、不用换服务商、不用下载新模型,之后就一直是"粘了就能看"。

社区插件声明:本项目由社区维护,是第三方插件,与 DeepSeek(深度求索)官方无任何隶属、赞助或背书关系,也不属于官方 @deepseek-ai npm scope 下的包。

English: README.md。

快速上手

三步,基本全程点鼠标:

1. 安装

git clone https://github.com/<you>/deepseek-eyes.git
dsh plugin --profile web add "file:$PWD/deepseek-eyes"

重启正在运行的 Web Profile 并刷新页面。Windows PowerShell 下直接把 checkout 的绝对路径传给 dsh plugin 即可——记得保留 file: 前缀,它很关键(见安装)。

2. 在界面里配置一次。 打开 设置 → DeepSeek Eyes,只需要填两样:

  • 视觉端点 —— 任意 OpenAI 兼容视觉 API 的 base URL + 模型 id(OpenRouter、阿里云百炼、自托管视觉模型……都行)。
  • API key —— 粘进 API key 输入框,点 保存 key。它走 DSH 凭证体系存储,绝不回传浏览器。

点 测试连接 验证一下,完事——设置保存即热生效,无需重启。

3. 选桥、粘贴。 在模型选择器里选 DeepSeek(视觉桥),模型 id 照常用纯文本模型(如 deepseek-v4-pro),往输入框粘贴/拖入图片,在同一条消息里顺带写下问题,发送。

就这样。不含图片的请求原样透传,只有带图的消息才会被改写。卡住了?看故障排查。

你只需要自备两样东西:一个视觉端点、一个 key。 其余一切——provider 接线、设置页、凭证存储、图片准入——插件全包了。

界面一览

在设置页把视觉端点配置一次——填写、测试连接、保存 key:

DeepSeek Eyes 设置页

然后在模型选择器里选 DeepSeek(视觉桥),照常粘贴图片:

带 DeepSeek(视觉桥)入口的模型选择器

下面是桥的实际使用效果:直接将图粘贴进对话,由 DeepSeek-eyes 解析图片、交给纯文本模型读取并逐项分析:

用 DeepSeek-eyes 读取 GitHub Topics 页面

工作原理

flowchart LR
    A[粘贴/拖入图片<br/>已选桥 provider] --> B[DSH 入口准入<br/>inputModalities: text + image]
    B --> C[桥 adapter 的 stream]
    C -->|含图片| D[从用户文本提取 focus hint]
    D --> E[视觉 API<br/>OpenAI 兼容]
    E --> F[图片块 → 文字描述]
    F --> G[转发纯文本请求]
    C -->|不含图片| G
    G --> H[目标 provider<br/>如 deepseek-official]
  • 桥 provider 声明 inputModalities: ['text', 'image'],于是宿主放行图片内容,不再返回 Web UI 里那个 Model "..." does not support image input.(attachment-error)。
  • stream() 里,adapter 遍历请求消息(包括工具结果里的嵌套内容),从消息自身文本或最近一条用户文本中提取 focus hint,再问视觉模型:"agent 看这张图是因为:<hint>"。返回的描述替换掉图片块,并以"证据"形式包装(图中文字只是数据,绝不当作指令)。
  • 改写后的请求通过 ctx.llm.stream 按目标 provider 路由委托出去,真实 adapter 的序列化、流式、重试与遥测全部原样保留。无图请求消息零改动。
  • 图片描述有进程内缓存(按 附件 + 视觉模型 + 语言 + hint 做 key)。

安装

git clone https://github.com/<you>/deepseek-eyes.git
dsh plugin --profile web add "file:$PWD/deepseek-eyes"
# 如果也跑 headless:
dsh plugin --profile headless add "file:$PWD/deepseek-eyes"

# 通过凭证体系保存视觉 API key:
dsh credentials set VISION_API_KEY

然后重启正在运行的 Web Profile、刷新页面,并配置视觉端点(见上)。Windows PowerShell 下直接把 checkout 绝对路径传给 dsh plugin 即可。

务必使用 file: 前缀。 直接传目录路径会让 pnpm 装成 link: 依赖——一条从 profile 指向 checkout 的符号链接。发布版 DSH 运行时用原生 Node ESM 加载插件,会把该符号链接解析到 profile 树之外的真实位置,于是插件对 peer 包的导入(@deepseek-ai/dsh-settings、@deepseek-ai/dsh-llm 等)再也找不到 profile 的模块 fallback,harness 启动即报 Cannot find package '@deepseek-ai/dsh-settings' 而失败。file: 前缀让 pnpm 把 checkout 复制进 profile(真实目录,解析始终留在 profile 内),任何运行时都能正常启动。裸路径只在源码 checkout 的开发版 harness(tsx)下看起来能用。打 tarball 安装等效:pnpm pack 后执行 dsh plugin add ./deepseek-eyes-0.1.0.tgz。

由于 file: 安装的是副本,改动 src/ 后需重新 pnpm run build 并重新执行 dsh plugin add "file:…"。

配置

推荐:在 Web 界面里配置。 重启后打开 设置 → DeepSeek Eyes:那里有完整表单(视觉端点、模型、Credential 引用与配置状态、输出语言、超时与图片限制、描述缓存),保存即热生效,还有测试连接按钮(对配置的端点发 GET /models,不上传图片、不创建 completion)。同一页面还有 API key 输入框:粘贴视觉 API key 后点 保存 key,即通过 DSH 凭证体系按当前引用存储,值不会回传浏览器(清除已存 key 按钮可移除)。模型设置页也会出现 DeepSeek Eyes 一行,展示桥路由的模型列表与凭证状态。

底层是同一个 deepseek-eyes settings 节;手写 YAML 与其等价——在 profile patch 行里用相同 id 覆盖(例如 %DSH_HOME%\profiles\web\cordis.patch.yml):

- id: deepseek-eyes
  config:
    provider: deepseek-vision          # 模型选择器里的桥路由
    displayName: 'DeepSeek(视觉桥)'
    targetProvider: deepseek-official  # 真正承载请求的纯文本 provider 路由
    apiKeyEnv: VISION_API_KEY          # 凭证引用,不是 key 本身
    vision:
      baseUrl: https://your-vision-provider.example.com/v1   # 任意 OpenAI 兼容端点
      model: your-vision-model
      language: zh                      # zh | en
      timeoutMs: 60000
      maxTokens: 2048
      maxImageBytes: 10485760
      maxImagePixels: 40000000
      cacheSize: 16
字段 默认值 含义
provider deepseek-vision 桥路由 id;在模型选择器中选择它。
displayName DeepSeek(视觉桥) 选择器中展示的 provider 名称。
targetProvider deepseek-official 改写后请求转发到的路由。必须与 provider 不同。
apiKeyEnv VISION_API_KEY 凭证引用;每次调用先查凭证体系,再回落进程环境变量。
vision.baseUrl 空 OpenAI 兼容端点 base URL;首次描述图片前必须配置。
vision.model 空 视觉模型 id;首次描述图片前必须配置。
vision.language zh 生成描述的语言。
vision.timeoutMs 60000 单次调用截止时间(1000–600000)。
vision.maxTokens 2048 单次描述的输出 token 上限。
vision.maxImageBytes 10485760 单张图片编码字节上限。
vision.maxImagePixels 40000000 单张图片解码像素上限。
vision.cacheSize 16 进程内描述缓存条数;0 关闭。

API key 绝不写进 patch:在 DeepSeek Eyes 页面的 API key 输入框粘贴保存,或用 dsh credentials set VISION_API_KEY(或在启动环境中导出)。设置页保存后热生效;provider 变更会就地重注册路由。

使用

  1. 在模型选择器中选 DeepSeek(视觉桥)(或你配置的 displayName),模型 id 照常用纯文本模型(如 deepseek-v4-pro)。
  2. 在输入框粘贴/拖入图片,可以顺带提个问题("这个按钮为什么是灰的?")。
  3. 发送。文本模型会收到以"证据"形式包装的视觉描述,像真的看到了图一样作答。

小贴士:把问题写在同一张图片所在的同一条消息里——它就是 focus hint,对描述质量的提升非常明显。

环境要求与依赖

deepseek-eyes 是一层薄封装:它不带任何模型、也不自带任何服务商。它依赖的内容分四类。

1. 由消费它的 DSH profile 提供(peer 依赖——任何标准 profile 都已安装):

包 作用
@deepseek-ai/dsh-llm ≥ 0.1.0-rc.1 本插件所扩展的 LLM 注册表与 adapter 基类(在 0.1.0-rc.5 线上开发验证)
@deepseek-ai/dsh-attachment ≥ 0.1.0-rc.1 持久化图片存储,请求时读回
@deepseek-ai/dsh-settings ≥ 0.1.0-rc.1 热更新配置节
@deepseek-ai/cordis ≥ 4 插件框架
@deepseek-ai/schemastery ≥ 3.18 配置 schema

2. 本机环境:

依赖 说明
Node ≥ 22.19(或 ≥ 24) 与 harness 运行时一致(engines)
pnpm dsh plugin 安装 bundle 时使用

3. 你需要自备的外部服务:

服务 说明
OpenAI 兼容视觉端点(/chat/completions + image_url)+ API key 不内置——任意兼容服务商均可(OpenRouter、阿里云百炼、自托管视觉模型等)。粘贴的图片会上传到该端点,请选择你信任的服务。
目标文本 provider 路由(默认 deepseek-official) 真正作答的模型;profile 里任何文本路由都行,但必须与桥路由不同。

4. 仅开发期(运行时不需要):TypeScript、Vitest、@types/node、React 类型——另需 deepseek-harness checkout 作为同级目录(其构建产物 lib/ 的类型声明把类型检查钉死在准确的 harness API 线上;见"开发")。

与 dsh-vision-toolkit 的关系

deepseek-eyes 和 dsh-vision-toolkit 解决的是同一问题的不同一半,可以同时安装:

deepseek-eyes dsh-vision-toolkit
粘贴图片、模型"看到" ✅ 无缝 ❌ 纯文本模型会被拒绝
目标定位、元素盘点、精确像素坐标 ❌ ✅(vision_ground / vision_detect)
长截图 OCR、SVG 描摹、像素 diff ❌ ✅
选择器中多一个 provider 路由 ✅ —

桥给模型的是一份描述;toolkit 给 agent 的是像素级工具。工程级视觉任务建议两者都装,测量用 toolkit,日常看图用桥。

错误码

失败以稳定的错误码浮出为终结性 LLM 错误:

错误码 含义
VISION_CONFIG vision.baseUrl / vision.model 未配置。
VISION_CREDENTIAL 没有 API key:执行 dsh credentials set <credential>。
VISION_HTTP 视觉端点返回非 2xx(携带 status)。
VISION_RATE_LIMIT 视觉端点返回 429。
VISION_TIMEOUT 单次调用超时。
VISION_NETWORK 未收到任何 HTTP 响应的传输失败。
VISION_INVALID_RESPONSE 载荷不可用或内容为空。
VISION_IMAGE_TOO_LARGE 图片超出 maxImageBytes / maxImagePixels。
VISION_IMAGE_READ 持久化图片读取失败。
ABORTED 调用方在描述过程中取消了请求。

故障排查

现象 处理
安装后 harness 启动失败:failed to import loader entry deepseek-eyes … Cannot find package '@deepseek-ai/dsh-settings'(或 -llm/-credentials) 插件是用裸路径安装的,pnpm 会以符号链接(link:)方式安装。改用 file: 前缀重装(dsh plugin add "file:<checkout>")或从 tarball 安装,然后重启。
粘贴仍提示"does not support image input" 模型选择器里没有选桥 provider——插件无法改变纯文本路由的准入。选中 deepseek-vision。
选择器里没有桥 provider dsh plugin add 之后重启 Web Profile 并刷新页面;用 dsh --profile web --dump-config | grep deepseek-eyes 确认 bundle 行已挂载。
VISION_CONFIG 在 profile patch 里配置 vision.baseUrl 与 vision.model。
VISION_CREDENTIAL 在 DeepSeek Eyes 页面的 API key 输入框保存 key,或执行 dsh credentials set VISION_API_KEY(或 apiKeyEnv 指向的名字)。
VISION_HTTP 401/403 凭证值或端点不对;错误正文已截断脱敏。
VISION_RATE_LIMIT 等限流窗口过去,或换端点。
目标路由 NO_ADAPTER targetProvider 指向了未注册(或加载更晚)的路由,检查 id。

限制

  • 文本模型拿到的是描述而非像素:精细几何、精确颜色、像素级布局不在范围内(配合 dsh-vision-toolkit 使用)。
  • 委托调用刻意不带 agent-loop 标记,因此走桥路由的会话会失去 adapter 的 replay state(影响缓存响应重放,正确性不受影响,重放会回退为真实调用)。
  • 只处理 DSH 附件通道接纳的 PNG / JPEG / WebP / GIF;视觉端点需接受所选格式。
  • 描述在请求路径内按图片块串行生成:请为 vision.timeoutMs 留足预算。
  • 进程内缓存在重启后清空。

安全

  • 图片内容按不可信数据处理:视觉提示词被要求、注入的描述被包装,保证图中文字绝不作为指令执行。
  • key 每次调用经 DSH 凭证体系解析,绝不进入配置、日志或错误信息。设置页的 API key 输入框单向写入凭证体系(与官方模型页同款路径);已存值绝不回传浏览器。
  • 上游错误正文截断到 300 字符后才可能出现在消息里。
  • 上传前有尺寸围栏(maxImageBytes、maxImagePixels)。

开发

pnpm install      # 仅 devDependencies;harness 侧 peer 由消费 profile 提供
pnpm typecheck    # tsc 检查 src + tests(host 侧)
pnpm build        # 产出 lib/(host)与 lib/client.js(浏览器设置卡片)
pnpm test         # vitest 单元测试(重写逻辑、视觉客户端、配置)
  • lib/ 有意提交入库:dsh plugin add "file:<path>" 安装 checkout 后加载的是 main: lib/index.js;Web 前端通过 dsh.client 声明与 exports["./client"] 发现浏览器 bundle。
  • 类型检查钉在 harness API 线上:各 tsconfig 把 @deepseek-ai/dsh-* 的类型导入映射到同级 deepseek-harness checkout 的构建产物 lib/ 声明(npm 发布版早于部分 API)。把 github.com/deepseek-ai/deepseek-harness 克隆到本仓库旁边并构建一次即可;CI 也假设这一布局。
  • 改动 src/ 后、安装进 profile 前,记得 pnpm run build;file: 安装的是副本,需重新执行 dsh plugin add "file:…" 才能让重建后的 lib/ 生效。
  • CI 执行 install 与 test;存在 harness 同级 checkout 时另行执行 typecheck/build——见 .github/workflows/ci.yml。

许可证

MIT — 见 LICENSE。

致谢

focus hint 的思想(把"模型为什么看这张图"带给视觉模型,而不是要一段泛泛描述)来自 Anionex/agent-vision-toolkit。本插件把这一思想原生实现进了 DeepSeek Harness 的 LLM adapter 层。

原始 README: https://github.com/fryghost/deepseek-eyes/blob/main/README.zh.md ↗