给纯文本模型外挂读图能力(ModLens)

ModLens 是 TypeScript 写的视觉插件,把粘贴进对话的图片转成含 OCR 转写、版面区域与实体关系的 JSON 证据,让 DeepSeek、GLM 这类纯文本模型也能读图。它可装进 DeepSeek Harness,也支持 Claude Code、Codex、OpenCode、Pi。这篇梳理它的功能、安装命令、配置项与真实 Issue 里暴露的坑,帮读者判断自己的宿主与模型组合值不值得装。

DeepSeek 的旗舰对话模型和 GLM-5.3 本身是纯文本的,读不了图。把报错截图、设计稿或者一张图表粘进对话,模型要么直接忽略,要么回一句不支持图片输入。绕开的常见做法是先把图片存成文件,再把路径贴进对话,多一道手续,路径写错还得重来。

ModLens 是 TypeScript 写的视觉插件,把粘贴进对话的图片转成结构化 JSON 证据(OCR、版面、语义),交给 DeepSeek、GLM 等纯文本模型作答。

它挂在宿主 harness 里工作。插件启动后自动发现每一条承载合格纯文本模型的路由,给每条路由包一个带 (modlens vision) 后缀的条目;图片进入对话后由 modlens_read_image 工具接走,送进视觉引擎,回来的是一份可以被逐条引用的证据,模型基于它作答。

ModLens 项目横幅,展示给纯文本模型外挂视觉能力的功能定位

仓库地址是 https://github.com/liustack/modlens ,采用 MIT License,主要语言 TypeScript(占 81.5%,另有 16.6% 的 JavaScript)。截至抓取时 Star 4166、Fork 130、开放 Issue 4 个,最近一次提交是 2026-10-04。

主要功能

  • 直接粘贴图片。在纯文本模型下粘贴的图片会落到一个私有临时文件,路径进入输入框,然后交给 modlens_read_image 工具处理。README 说这套交互与 OpenCode、Pi 提供的一致,不需要先存盘再手动传路径。
  • 模型选择器里的 (modlens vision) 条目。在模型选择器中挑一条 (modlens vision) 条目,插件会记住这次选择,之后粘贴的图片缩略图留在消息里,观感更接近 Codex app;图片在请求时被转成结构化证据,仍由同一条底层路由作答。两种粘贴路径走的是同一套引擎。
  • 自动发现并包装纯文本路由。库存安装会得到 DeepSeek-V4-Flash (modlens vision) 与 DeepSeek-V4-Pro (modlens vision),opencode-go、zai 这类额外路由各自获得自己的条目。这些家族里的原生视觉模型,包括 GLM-5.3-Flash,会被自动排除。接管与否由宿主按模型的元数据判断,只有被正面确认为纯文本的模型才会被接管,未确认的一律不动。
  • 输出结构化证据而不是观感描述。结果包括完整转写、按阅读顺序排布的版面区域、实体与关系列表。README 的说法是模型可以引用其中的具体内容。
  • 十个视觉来源组成一条失效链。六个内置 provider 任意一个即可工作,另有四个本地 agent CLI 的登录可被复用。内置的 gemini-api 走免费 Gemini API key,单次读取 5-10 秒,README 把它列为推荐默认;openai 接受任何 OpenAI 兼容端点。复用某条 CLI 登录时,每次读取会标注这次消耗的是谁的配额。
  • 逗号分隔的多 key 轮换。把多个 key 用逗号分隔,遇到鉴权、限流或配额失败时轮换;其他类型的失败会跳过剩余 key,并保留既有的 provider failover 逻辑。
  • 零配置启动。安装时会先盘点本机已有的东西。Claude Code、Codex、OpenCode、Pi 里的登录可以复用,复用前会先征求同意;本机已有的多模态模型也在盘点范围内。什么都没装的话,Antigravity CLI 是免费的免 key 通道。
  • 轻量,卸载就是删文件夹。没有 hooks、没有 wrapper、没有本地代理守护进程,不改动宿主配置的任何一行。skill 宿主上它就是一个 skill 文件夹,dsh 上它就是一个插件。

安装与依赖

运行需要 Node.js,npm 徽章指向 nodejs.org。DeepSeek Harness 上一条命令装完:

npx -y @deepseek-ai/dsh plugin --profile web add @liustack/[email protected]

其他 harness 用 skills.sh 装到用户级:

npx -y skills add liustack/modlens --skill modlens --global

也可以把安装直接交给你的 AI,把这句话发给它:

Install and configure the modlens skill following https://github.com/liustack/modlens/blob/main/INSTALL.md, then run the health check and tell me the result.

装完重启宿主,让它做一次健康检查。只有当健康检查结果为空时,才需要配一个免费引擎。推荐做法是申请免费 Gemini API key,在 Google AI Studio 大约三分钟,不需要信用卡,配好后每次读取 5-10 秒。想完全跳过注册,可以改装 Antigravity CLI:

curl -fsSL https://antigravity.google/cli/install.sh | bash
agy                                                           # sign in, then exit

仓库里没有说明从源码构建的步骤,目录里有 package.json、vite.config.ts、vitest.globalSetup.ts,但 README 节选未展开这部分。

最短能跑通的用法

装好之后不需要额外启动命令,正常聊天即可。把图片粘贴进对话,或者丢一个文件路径进去,然后照常提问,skill 会自己触发:图片送进视觉引擎,回答基于它读到的东西生成。

同一张图粘贴一次就够了,之后针对这张图的追问不需要重新粘贴。如果用的是 dsh,也可以在 Settings → Plugins → Plugin config 的 ModLens 卡片里先选好引擎再开始用。

关键参数

  • ~/.modlens/config.json 是配置文件。README 提到配置卡在读取失败时会在旁边显示 Retry 控件,举例的失败原因是这个文件格式错误。
  • dsh 侧有图形化配置入口。dsh 0.1.7 之前它在 Settings → Plugins → Plugin config 里;从 0.1.7 起,配置被移到侧边栏的 Plugins 页面,选中 Installed 下的 @liustack/modlens。
  • 卡片里可以切换引擎、勾选 auto 模式允许复用哪些本地 CLI,保存后立即生效。
  • 多个 API key 用逗号分隔写在一起,触发轮换的条件是鉴权失败、限流或配额耗尽。
  • 模型选择器中的 (modlens vision) 条目决定粘贴行为走哪条路径;选择会被记住。

更细的字段说明指向 skills/modlens/references/configure.md,README 节选没有逐项展开每个字段,需要精确配置时得去翻那份文件。

结果在哪里看

一次读取产出的是结构化 JSON 证据,包含 OCR 转写、按阅读顺序排列的版面区域、以及实体与关系列表。这份证据进入对话上下文,由模型在回答里引用,所以你能从模型的复述和引文中判断它读到了什么。

如果复用了某条本地 CLI 的登录,每次读取都会带上标签,标明这次消耗的是哪个来源的配额。运行过程中出问题时,README 指向 docs/troubleshooting.md,那里列出了 modlens 会打印的每一条消息及其原因与修法。

实际使用中的坑

仓库里的 Issue 大多是真实环境暴露出来的问题,且基本都已关闭。挑几条有代表性的:

  • Windows 上 claude-cli 提供方起不来。现象是 spawn EINVAL 或 claude not found,原因指向 Windows 下的 .CMD shim。同一类问题也影响 opencode 的复用探测。该 Issue 状态为已解决。
  • Codex 里粘贴的图片没被接管。当模型是通过 OpenAI 兼容网关提供的纯文本模型时,用户直接附加或粘贴的图片会先作为原生视觉输入发给上游,请求被上游拒绝,ModLens 来不及接手。该 Issue 状态为已解决。
  • 插件更新后需要重新配置。有用户反馈每次更新 modlens 都要让 dsh 重新自动更新一次配置,在多模型场景下尤其明显。该 Issue 状态为已解决。
  • 已安装的 skill 副本不自动更新。skill 包在两个地方钉住了版本号,升级后副本仍停在安装时的版本,用户需要手动改 run.ps1 与 SKILL.md。该 Issue 状态为已解决。

另外还有一条值得注意的历史问题是 CJK 证据变成替换字符,起因是子进程把 stdout 的每个分块单独解码,多字节字符被切开;以及同一会话里已经包含图片后无法切换到纯文本模型的报错 does not accept image input, but this session already contains images。这两条也都已解决。

和同类放在一起看

项目适合谁部署方式主要限制什么情况下选它更合适项目地址
ModLens在 dsh、Claude Code、Codex、OpenCode 或 Pi 上用 DeepSeek、GLM 等纯文本模型,又需要读截图、设计稿和图表的人一条 npx 命令装成 dsh 插件,或用 skills.sh 装成 skill;不改宿主配置行,卸载就是删文件夹至少需要一个视觉来源,本机没有现成登录时要配免费 Gemini key 或装 Antigravity CLI;已安装的 skill 副本不随版本自动更新;Open Issue 4 个宿主正好是它支持的几个 harness,且希望保持宿主原样、随时能干净卸掉liustack/modlens
ZhuXinAI/sidesight在终端里跑纯文本 coding agent,想用命令行方式调视觉的开发者仓库没有说明部署方式项目规模小(Star 2),功能覆盖未逐一核实;它走的是 CLI 侧车形态,不提供 harness 插件式集成你的流程本来就以命令行脚本为主,不需要把能力挂进某个 harnessZhuXinAI/sidesight
liustack/modsearch同样用 dsh,但需要的是联网检索而不是读图的人同为 liustack 的 dsh 插件,装法属于同一套它解决的是网页搜索,和读图不是同一件事,两者不能互相替代你的缺口是让模型查到互联网上的信息liustack/modsearch

ModLens 把自己绑定在宿主 harness 上,离开 dsh、Claude Code、Codex、OpenCode、Pi 这些宿主就不工作。如果你的流程是纯命令行的批处理,或者在不支持这些宿主的自研 agent 框架里调用,CLI 形态的 sidesight 更直接。如果缺的其实是联网搜索能力,那该装的是 modsearch,两个插件各管一头,装错了不会报错,只是问题依然没解决。

适合谁

已经在用 DeepSeek、GLM 这类纯文本模型,而且宿主是 dsh、Claude Code、Codex、OpenCode 或 Pi 的开发者,是这个插件最直接的目标用户。手上经常要处理截图、设计稿、界面图、图表,又不想每次都手动存盘再贴路径的人,能立刻感受到区别。

已经在用原生多模态模型的人不需要它。宿主不在支持列表里的团队也不适合,README 没有提供独立的命令行入口或可嵌入的 SDK。不想在本机配置任何外部 API key、也不愿意装 Antigravity CLI 的人,装完会卡在健康检查那一步。

焚评:这个项目的量化评分

本项目的选题来自 焚.com(一个按公开公式给 GitHub 项目打分的站)。焚评当前总分 9.2 分(满分 10)。下表是各维度的得分:

评分维度得分
热度动量(权重 25%)10.0 / 10
开发活跃(权重 25%)7.0 / 10
社区响应(权重 15%)10.0 / 10
文档质量(权重 15%)9.4 / 10
发布节奏(权重 10%)9.9 / 10
风险控制(权重 10%)10.0 / 10

评分口径、权重与计算方式见焚.com 的评分方法页;数据随 GitHub 指标刷新,具体数值以焚.com 当前页面为准。本文正文为诀.com 独立撰写,评分数据由焚.com 授权引用。

内容核验说明

它的价值在装前判断:宿主支持列表、健康检查、免费引擎与卸载方式都摆明了,还附上 Issue 里 Windows spawn 失败、Codex 附件未被接管、会话隔离、skill 副本不随版本更新这些真实坑。适合拿 DeepSeek、GLM 等纯文本模型又需要读截图的人;已用原生多模态或走命令行批处理的不用看。

文中的 Star、Fork、Issue 数、版本号与时间戳来自仓库公开页面,诀.com 未独立验证;功能描述与安装命令转述自 README,未实际安装测试;Issue 现象为提交者报告,状态以仓库标注为准;焚评评分引自焚.com,随 GitHub 指标刷新。

项目来源与说明

开源项目:liustack(liustack)

本文由诀.com 编辑基于该项目的公开信息独立撰写,属原创解读,不是对项目文档的翻译或转载;文中提到的功能与参数以官方仓库为准,代码与文档版权归原作者所有。

查看项目仓库