核心问题: 给纯文本代理加视觉桥的同时,能不能保证 API 密钥和会话数据不被泄露?
RepoDaily 采用评分
RepoDaily 将该项目的采用分评为 91/100(强):分数来自文章来源、安装路径、生产风险、差异化、许可证清晰度以及 AI/Agent 适配度。
包含 6 个来源、覆盖 4 类来源;如有 RepoDaily 独有模块,会进一步提高证据分。
检测到 5 个工作流步骤、4 个下一步动作,以及 5 个命令/安装信号。
趋势热度为 +536 stars;如内容中有 release、issue 或维护信号,会提高维护可信度。
采纳风险标记为 medium,并包含 6 条安全说明与 4 条跳过条件。
3 个机会视角、3 个替代方案,以及 4 个类型化模块支撑差异化判断。
文章中包含许可证来源或许可证表述。
文章正文和元数据中检测到 6 个 AI/Agent 相关信号。
项目概览
ModLens(liustack/modlens,TypeScript,MIT 协议)是一个插件式视觉引擎,作用是给纯文本模型装上眼睛。旗舰 DeepSeek 与 GLM 对话模型读不了图片,而 ModLens 正是在用户最能感知的痛点上下手:直接读取粘贴进对话的图片,不需要先存成文件再传路径。装进 DeepSeek Harness(dsh)只需一条命令,且刻意钉在 3.16.7 版本。插件暴露一个原生 `modlens_read_image` 工具,把粘贴的图片转成覆盖 OCR、布局与语义的结构化 JSON 证据,输出契约写在 docs/output-schema.md。本周期内该仓库获得 536 颗星,2026-08-16 当天排在趋势榜第 8 位。
它的接入方式比一句口号更讲究。ModLens 会自动发现所有承载纯文本 DeepSeek 或 GLM 模型的 provider 路由,并为每条路由加一个 `(modlens vision)` 包装入口;README 写明原版安装会得到 `DeepSeek-V4-Flash (modlens vision)` 和 `DeepSeek-V4-Pro (modlens vision)`,opencode-go、zai 这类额外路由各有自己的入口。只有元数据明确确认是纯文本的模型才会被接管,视觉模型保持原生粘贴。粘贴有两条路:普通粘贴会把图片落到一个私有临时文件、路径进入输入框(与 OpenCode 和 Pi 的交互一致);或者选一次 `(modlens vision)` 入口,缩略图留在消息里,更接近 Codex 应用的手感。网页搜索与抓取明确不在范围内,放在兄弟项目 ModSearch 里。
用安全工具的视角看它,是因为这个插件踩在敏感管道上,而不是因为它是个扫描器。SECURITY.md 直说:modlens 在你的机器上对图片运行视觉引擎,并能从本地会话存储恢复粘贴图片的字节,图片内容被视为不可信输入。2026-08-15 发布的 3.16.7 大部分都在处理这块:网页设置卡只接受回环写入、宿主绝不把已存密钥发给浏览器(只告知是否存在)、密钥录入不经过 argv、shell 历史或聊天内容。
为什么现在变热
- 占据「DeepSeek Harness(dsh)第一个视觉插件」的位置,一条钉版本的命令即可安装:`npx -y @deepseek-ai/dsh plugin --profile web add @liustack/[email protected]`
- 单人维护的 TypeScript CLI,npm 包名 @liustack/modlens,本周期 536 颗星、趋势榜第 8
- 2026-08-15 一天连发三个补丁(3.16.5、3.16.6、3.16.7),分别对应 issue #36、#37、#39
- README 徽章把多数仓库藏着的信息直接亮出来:「Not backed by Y Combinator」「users unknown」
- 粘贴优先的交互借鉴 OpenCode、Pi 与 Codex 应用,而不是存文件绕路
解决什么问题
- 旗舰 DeepSeek 与 GLM 对话模型是纯文本的,完全读不了图片
- 常见变通——先存图片、再传路径——破坏了聊天界面养成的粘贴习惯
- 截图里的布局与图表结构(坐标轴、对数刻度、高亮区域)在随手转写中会丢失
- 3.16.6 之前模型侧契约执行代价高:可选字段为 `null`(如 `visual.notes`)会让整次读取失败(#37),严格 json_schema 还得手写
- 3.16.0 到 3.16.5 之间,普通纯文本路由上的粘贴在所有默认安装里都是坏的,因为服务端判定误判了插件自己的包装入口(#36)
工作原理
- 运行 `npx -y @deepseek-ai/dsh plugin --profile web add @liustack/[email protected]` 安装;版本号是刻意钉住的,因为 pnpm 11 会扣住最近 24 小时内发布的版本,用 `@latest` 会装到一天前的版本。更新就再跑一遍同一条命令。
- 插件扫描 provider 路由,为每条承载纯文本 DeepSeek 或 GLM 模型的路由加一个 `(modlens vision)` 包装入口;这两个家族自带的视觉模型被自动排除。
- 粘贴图片:普通纯文本路由上,图片落为私有临时文件、路径进入输入框;走 `(modlens vision)` 入口则缩略图保留在消息里,请求时转换为结构化证据。
- `modlens_read_image` 工具在你机器上用配置好的视觉引擎处理图片字节。
- 读取结果返回结构化 JSON 证据(OCR、布局、语义),并按运行时 schema 校验;3.16.6 起可选字段为 `null` 会在校验前被丢弃,必填字段为 `null` 仍然算违规。
产品演示与界面预览




命令面:你实际要敲的命令
- 安装或更新:`npx -y @deepseek-ai/dsh plugin --profile web add @liustack/[email protected]`——按 docs/harness-setup.md 的说明钉版本而非 `@latest`,原因是 pnpm 11 的 24 小时扣留
- 密钥录入:`modlens config set gemini-api.apiKey` 省略值会以隐藏回显提示输入,也接受一行管道输入——密钥不进 argv、shell 历史或聊天
- 严格输出模式:`modlens config set openai.structuredOutput true` 会以 `response_format: json_schema` 发送,所有属性必填、`additionalProperties: false`;默认关闭,因为不支持的网关会返回 400
- CONTRIBUTING.md 的开发流水线:`pnpm install`、`pnpm test`(vitest)、`pnpm typecheck`(tsc --noEmit)、`pnpm build`(必须产出单个 dist/main.js)、`pnpm lint`(Biome);要求 Node 22.19+
接入面:它插在哪里
ModLens 挂进 dsh 插件系统后,自动发现所有承载纯文本 DeepSeek 或 GLM 模型的 provider 路由,并为每条加一个包装入口。原版安装会得到 `DeepSeek-V4-Flash (modlens vision)` 和 `DeepSeek-V4-Pro (modlens vision)`;opencode-go、zai 等路由各有自己的入口。走哪种粘贴由宿主按模型决定:只有元数据明确确认为纯文本的模型才被接管,视觉模型保持原生粘贴。
配置只有一个家:共享的 `~/.modlens/config.json`。3.16.7 起,dsh 网页 UI 在 Settings 的 Plugins 下多了一张设置卡(引擎、API 密钥、端点、模型,以及读取可借用哪些本地登录态),它读写一条拥有该文件的回环路由,因此不会复制出第二份存储,其他 harness 看到的也是同一份改动。网页搜索与抓取留在兄弟仓库 ModSearch(github.com/liustack/modsearch),CONTRIBUTING.md 的范围一节把这条线划得很清楚。
维护风险:单人维护、一天三补丁
2026-08-15 的更新日志能看出这个项目的形状。3.16.5 修复了纯文本模型上的普通粘贴——自 3.16.0 把判定移到服务端后,它在所有默认安装里都是坏的:只要选择器标签下任一模型声明了图片输入,判定就拒绝,这对真视觉模型是对的,对插件自己原样复用上游模型 id 的包装入口是错的(#36)。3.16.6 把可选字段里的 `null` 合法化——上报的失败点名 `visual.notes`——模型没话说时伸手够 `null` 也不再害死整次读取(#37)。3.16.7 交付了只允许回环写入的网页设置卡(#39)。
CONTRIBUTING.md 说得很直白:ModLens 不接受 pull request。它是一个刻意保持小型的工具,由一位审查并拥有每一行代码的维护者维护。被认可的贡献方式有两种:提 issue(它决定做什么)和 fork——MIT 协议让副本完全属于你。SECURITY.md 补充:修复只落在 npm 最新版上,所以保持更新不是可选项,而 README 的徽章也老实标着用户数未知。
上手路径:十分钟拿到第一次读图
- 把钉版本的安装命令跑进 dsh(`--profile web`)
- 在一条纯文本 DeepSeek 路由上打开对话,把截图直接粘进输入框——不用文件、不用路径
- 或者在模型选择器里选一次 `(modlens vision)`(会记住你的选择),再粘贴,让缩略图留在消息里
- 检查 `modlens_read_image` 的返回:OCR 文本、布局、语义,并确认可选 `null` 不再让读取失败
- 录入任何密钥之前,先读 docs/security.md,再用隐藏回显形式的 `modlens config set gemini-api.apiKey`
谁适合关注
适合关注
- 你在 dsh 里跑纯文本 DeepSeek 或 GLM 路由,经常往编码对话里粘截图、图表或 UI 截图
- 你希望 OCR 加布局加语义装进一份模型可以直接引用的 JSON,而不是一大段散乱文字
- 你在意密钥卫生:隐藏回显录入、仅回环写入、宿主不把已存密钥发给浏览器,这些都已在 3.16.7 里
- 你能接受始终跑 npm 最新版,因为 SECURITY.md 说修复只落在最新版
可以先跳过
- 你的路由已经在用视觉模型——插件会放任不管,也不会为它们增加任何东西
- 你需要一个多人维护、接受 pull request 的项目;CONTRIBUTING.md 明确不接受
- 你跑不了 Node 22.19+,这是开发环境声明的下限
- 你的网关不支持结构化输出却想开 `openai.structuredOutput`——更新日志说这类端点会返回 400
风险与注意事项
一个纪律严明、文档扎实的单人项目,同日补丁的节奏既快速修复回归,也在快速增加新的受攻击面。
- 单一维护者审查每一行代码;CONTRIBUTING.md 明确不接受 pull request
- 2026-08-15 一天三个补丁(3.16.5–3.16.7):修复坏掉的粘贴接管(#36)、`null` 契约缺口(#37)、新增网页设置卡这个新面(#39)
- README 自己就挂着「users unknown」徽章——没有任何采用规模数据
- 修复只落在 npm 最新版,按 SECURITY.md 的要求,每个安装都必须跟最新版
- SECURITY.md 要求通过 GitHub Security Advisories 私下报告,并附上确切命令、完整输出、modlens 与 Node 版本
- 明示的威胁面:modlens 在你的机器上对图片运行视觉引擎,并能从本地会话存储恢复粘贴图片的字节;图片内容被视为不可信输入,完整安全模型写在 docs/security.md
- 3.16.7 网页设置卡:宿主绝不把已存密钥发给浏览器,只告知是否存在;密钥栏留空表示不动已存值;跨源或非回环写入会被拒绝,方式与 dsh 给自己 API 设的围栏一致
- 一次保存只携带它自己的事——切换本地登录态授权不会移动引擎钉选,也不会改写引擎设置
- 省略值执行 `modlens config set gemini-api.apiKey` 可让密钥不进 argv、shell 历史和聊天;文档写明了每种录入形式真正守住的边界
- MIT 协议,fork 被明确鼓励:改名、改线、发布,无需许可
替代方案比较
| 方案 | 适用场景 | 代价 |
|---|---|---|
换用视觉模型路由 | 读图是你的核心需求,你更愿意换模型而不是给纯文本模型搭桥 | 按 token 计费的多模态 API;同时放弃现有的 DeepSeek/GLM 路由 |
存文件再传路径 | 你很少粘图,能忍受 README 明确点名的这段绕路 | 免费,每张图多几次点击,布局上下文照样丢失 |
| 你需要无 PR 政策不会收进上游的改动 | 维护责任归你;MIT 已把权利完整给你 |
这个趋势说明了什么
把剩余纯文本路由都包起来
自动发现已覆盖承载纯文本 DeepSeek 或 GLM 模型的路由,README 还说 opencode-go、zai 这类额外路由各有自己的包装入口。把一条 GLM 路由完整跑通是最具体的下一步验证。
在 dsh 装 3.16.7,列出插件新增的 `(modlens vision)` 入口,确认机器上每条纯文本 DeepSeek 与 GLM 路由都能读取一张粘贴的截图。
免手写的严格 schema 执行
3.16.6 从运行时校验的同一份 schema 派生出严格 json_schema(所有属性必填、`additionalProperties: false`、可选字段改为可空),省掉了 #37 报告者为关思考的 qwen 手写整套 schema 的代价。
把支持 `response_format` 的网关接上插件,执行 `modlens config set openai.structuredOutput true`,确认网关多塞的 `null` 键不会害死读取。
值得抄走的密钥录入模式
省略值、隐藏回显、接受一行管道输入——这套做法让密钥不进 argv 和 shell 历史,文档还写明每种录入形式各自守住哪条边界。
不带值运行 `modlens config set gemini-api.apiKey`,检查 `history` 和 shell 配置有无泄漏,再确认已存密钥只能通过回环设置卡读取。
RepoDaily 判断
ModLens 解决的是一个窄而真实的问题——纯文本 DeepSeek 与 GLM 模型读不了你粘贴的截图——而且用一种单人项目里少见的纪律在做:钉版本安装、运行时强制输出契约、仅回环的配置写入、不碰 shell 历史的密钥录入。如果你日常在 dsh 的纯文本路由上工作、并且愿意跟 npm 最新版,就采用它;如果你需要委员会式的多人维护、或者已经在用视觉模型,就跳过。