SAOS-3624/dsh-see-now · 上手攻略

  • 仓库:SAOS-3624/dsh-see-now
  • 链接:https://github.com/SAOS-3624/dsh-see-now
  • 分类:engineering / agent / multimodal(实时视觉插件)
  • 作者:spark
  • 更新:2026-11-04

§0 自检清单

  • [x] GitHub URL 已 fetch(README 全文,2026-11-04 抓取)
  • [x] 仓库卡信息核对:Apache-2.0、JavaScript、280 stars、周增 +546、最近提交 2026-11-04
  • [x] 关键子文档锚点:README 内引用 LICENSE / NOTICE / CONTRIBUTING.md / docs/images/*.png 已在正文中出现并核对
  • [x] 版本信息:README 未给出 release tag 号与 npm 版本号,仅说明「已发布到 npm」——已标 ⚠️ 待核
  • ⚠️ 待补:当前 commit hash 未取(README 与仓库卡均未暴露),无法核验子命令是否随最新提交变动
  • ⚠️ 待补:宿主 DeepSeek-V4 的 patch 网格口径来自 README 自述,非第三方独立核对
  • 说明:本文只读公开页面,未 clone、未运行代码,所有命令均为 README 原文转录

§1 它是什么

dsh-see-now 是给 DeepSeek 官方 CLI/桌面宿主 DSH(@deepseek-ai 系列)做的实时视觉插件。它把屏幕、摄像头或视频文件变成一串「按变化量筛选过」的帧,再把多帧拼进同一张图交给模型,从而让 AI「实时看见」你在看什么。

一句话概括它的设计哲学:先判断这一帧值不值得看,再决定传不传。静止画面几乎不出图,滚网页/切窗口留几帧,一镜到底视频靠「运动积分」攒帧,硬切幻灯片每切一次留一帧。

它不是独立应用,插件本体不依赖 DSH:capture / pipeline / pack / sheet 都是独立导出模块,理论上可以当库用在自己项目里。

§2 解决什么问题

传统「让 AI 陪你看屏幕」的做法是定时截全屏喂过去,README 给了两个死结:

做法 问题
每 2 秒截一张全屏 一分钟 30 张图,全是重复画面,token 直接烧穿
每隔 30 秒截一张 中间发生了什么全丢了,AI 只会说「看起来你在用电脑」

See Now 的取舍是:一张图里塞 4 帧还是 8 帧,价格一样(一张图固定成本摊到 4~8 帧上),所以「多留一帧」几乎免费,「漏掉一帧」才贵。README 给的实测口径是:同样一段 30 秒操作,别家烧 30 张图,这里常常只要 2~3 张。

成本口径:800×450 一张 ≈ 233 token(按宿主 DeepSeek-V4 的 patch 网格算:14px patch 向上对齐 → 42px 一格 → rows×(cols+1)+2)。README 明确说源码 SIZES 里的旧注释写 218 token 偏低,以 233 为准。

§3 快速安装

# 用 DSH 自带的插件管理器安装(本质是 profile 维度的 pnpm 包装器 + 插件登记器)
dsh plugin --profile web add dsh-see-now

# 桌面版换 profile(该 profile 需先开过一次桌面端才会初始化)
dsh plugin --profile desktop add dsh-see-now

# 卸载 / 升级
dsh plugin --profile web remove dsh-see-now
dsh plugin --profile web update dsh-see-now

装完必须重启 DSH(插件树在进程启动时组合)。但不用新开会话:工具表是每一步重新组装的,旧会话下一轮就能看到 see_now,宿主还会插一条 tool-addition 告诉模型多了这个工具。README 特别澄清「工具表在会话开头就定死了」这个说法不成立——挂不上多半是没重启,或装的是旧副本。

从源码装(改代码时用):

git clone https://github.com/SAOS-3624/dsh-see-now.git
cd dsh-see-now
node scripts/install-dev.mjs   # 拷进本机 DSH 的 desktop profile

install-dev 是复制不是软链——Node 解析裸包名要走真实路径,软链会找不到宿主的 @deepseek-ai/dsh-tools。装完同样要重启。

平台要求(README 表格):

平台 屏幕引擎 额外动作
Windows ddagrab,不行退 gdigrab(自动探测) 无
macOS avfoundation 系统设置 → 隐私与安全性 → 屏幕录制,勾上跑 DSH 的 App
Linux — 还没接(要补 x11grab / PipeWire),现在会直接报错,不假装能用

ffmpeg 不用进 PATH:插件按 DSH_FFMPEG_PATH → FFMPEG_PATH → DSH_FFMPEG_DIR → ~/.dsh/tools/ffmpeg/bin → ~/.dsh/bin 顺序自己找(DSH 桌面版把 ffmpeg 装在第四个位置)。

§4 核心用法

4.1 工具调用

see_now({ action: "watch" })                          // 阻塞到攒够一张图,然后把图交回来
see_now({ action: "watch", say: "…" })                 // 同时说一句话(只有 say 会进悬浮窗、会被念出来)
see_now({ action: "peek" })                           // 不阻塞,只看一眼
see_now({ action: "status" })                         // 查状态(含「收工线」当前生效值)
see_now({ action: "region" })                         // 让模型自己框一块区域

第一次调用约 1 秒返回当前屏幕;之后每次返回「这段时间里发生的事」。

4.2 常用参数

参数 说明
action watch(默认,阻塞取图)/ peek / start / stop / status / window / region
show 配 action:"window":true 叫回悬浮窗,false 隐藏,不传只报状态
region 只看屏幕一块:"x,y,w,h"(屏幕物理像素)或 "off" 取消。一般不用手填,说「框这块」让它自己框
say 唯一能进悬浮窗、能被念出来的通道
quality low(800×450) / standard / high / ultra。改它会重启采集(~0.6s),并立刻返回当前帧
pace 节奏:calm / normal(默认)/ dense
scene true = 逐场景模式,一张图只装一个画面、铺满
seconds watch 的阻塞上限(默认 300,封顶 860),攒够一张就提前返回
minFrames 少于这么多帧的图就别给了(省 token)
source / path / realtime 采集源:屏幕 / 摄像头 / 回放视频文件

4.3 三档节奏(pace)

档 换画面门槛 最多多久叫醒一次 适合
calm 20 分 30 秒 日常挂着,只想知道「大场面变了没」
normal(默认) 12 分 15 秒 滚网页、切窗口不会每下都留帧
dense 7 分 8 秒 幻灯片、逐帧播报——贵,别常开

觉得太吵就说「慢一点 / 省点钱」,模型会传 pace:"calm";觉得漏帧就说「不灵敏」,它会传 dense。

4.4 作为库独立使用

import { spawnFrames } from 'dsh-see-now/capture';
import { createPipeline } from 'dsh-see-now/pipeline';

const p = createPipeline({ width: 800, height: 450, fps: 12, queueDepth: 0 });
const run = spawnFrames({
  source: { kind: 'screen' },   // 或 { kind:'file', path:'x.mp4' }
  width: 800, height: 450, fps: 12,
  onFrame: (f) => p.push(f),
});

setInterval(() => {
  const sheet = p.take();       // 一张 PNG + 每帧的时间戳/档位/来源
  if (sheet) require('fs').writeFileSync(`sheet-${sheet.at}.png`, sheet.png);
}, 200);

4.5 悬浮窗控制

npx dsh-see-window            # 开窗(已经开着就什么都不做)
npx dsh-see-window --status   # 只看它在不在
npx dsh-see-window --force    # 杀掉重开
npx dsh-see-window --close    # 关掉

点 × 只是这一次不看,插件不会自己弹回来,得手动叫。

4.6 听声音(台词)· 仅 Windows

见 see_now 清单里多出来的一段台词,时间码和每帧的 24.1s 是同一个坐标系,模型能把一句话对到某一格画面上。

pip install pyaudiowatch numpy   # README 原文写的是 pyaudiowpatch

⚠️ 原文此处写作 pip install pyaudiowpatch numpy,按 PyPI 上包名应为 pyaudiowatch(Windows 音频回环库)。README 疑为笔误,实际安装以 pyaudiowatch 为准。

转写配置(DSH 桌面版自带 speechToText/SenseVoice,不用配;命令行则在 ~/.dsh/asr.json):

{ "baseUrl": "http://127.0.0.1:8000/v1", "key": "local-key", "model": "paraformer-zh-2024-03-09" }

找不到 Python 时写进 ~/.dsh/see-window.json:

{ "listenPython": "C:/Python313/python.exe" }

延迟实测(从最后一个字到文字可用):静音判定 450ms(大头)+ 写盘 5ms/扫目录平均 100ms + 转写 130–250ms ≈ 0.7–0.8 秒。README 说这不影响实际使用,因为图本身攒 15–40 秒才发一张,0.8 秒被淹没了。

4.7 TTS 适配器

核心不内置任何 TTS 引擎,只 dynamic import 你指定的模块。

// ~/.dsh/voice.json
{ "adapter": "/绝对路径/examples/voice-say-mac.mjs" }

自定义模型走 options,原样交给 attach(api, options):

{ "adapter": "D:/my-voice/index.mjs", "options": { "model": "D:/my/models/xxx" } }

macOS 自带示例 examples/voice-say-mac.mjs,音色/语速读 ~/.dsh/tts.json:

{ "voice": "Tingting", "rate": 185 }

每次调用工具前会比对配置指纹(适配器路径 + tts.json 内容摘要),变了就自动卸载重挂——改音色、换适配器,下一句就生效。

4.8 会话级偏好(不进 profile)

// ~/.dsh/see-now/preferences.json(路径按 README 描述推断,⚠️ 未逐字核对)
{
  "maxAutonomousWakes": 24,
  "idleStopMin": 10,
  "defaultPace": "calm"
}

maxAutonomousWakes 默认 8(连续这么多次自动叫醒都没人理 → 收工,1–200);idleStopMin 默认 3(没开悬浮窗时用户这么久没说话 → 收工,0 = 关掉);defaultPace 默认 normal。

§5 切点是怎么判的(机制)

两条判据,缺一不可:

① 切点(硬切)——分数又高又孤立:

score ≥ cutAbs(12)                    // 绝对地板
score > 2.5 × max(1, 前后帧)          // 尖峰
mc ≥ cutSpikeMcAbs(20)                // 尖峰也要有 mc 覆盖
距上一刀 ≥ 0.4 秒                     // 不应期

另有三条补充出口:运动补偿(score ≥ 6 && mc ≥ 60,整屏在动但邻域匹配不上 = 换镜头)、强台阶兜底(score ≥ 80)、相似构图压缩块(6 ≤ score < 12 && score > 3×邻居 && mc ≥ 8)。

② 积分(攒量)——分不高但一直有:

need = 4分 × 12fps × 3秒 = 144       // 固定绝对阈值,不跟着画面涨
每帧累加自己的分,累够就录、清零

为什么两个都要:尖峰是相对的,在低分区也会成立——README 举了「缓慢放大」的实测(帧 s=13.6、前后邻居只有 1.1/1.3),没有绝对地板就会被切成一块块。反过来只有地板也不行:一镜到底视频每帧 4 分,永远不会「跳」。

变化分刻度(0–255,同一套代码):静止桌面 0.00 / 光标在静止画面上移动 0.7 / 两张色调接近的照片切换 16~18 / 滚网页或切窗口 30~42 / 两张完全不同的照片切换 46~63。所以 cutAbs: 12 的默认值位置是:照片切换抓得住,光标和微小抖动碰不到。

mc 是运动补偿后的「变了多少格」占比,搜索半径默认 4 格:整屏平移 8 格时 radius=2 会误报 194,radius=4 只有 5。

§6 典型适用场景

  • AI 陪看屏幕:让模型盯着你的操作,遇到异常自动提醒或记录
  • 演示/录屏辅助:硬切幻灯片每切一次留一帧,scene:true 逐场景模式还能让模型「每翻一页说一句这是什么」
  • 视频内容分析:一镜到底视频靠积分攒帧,比全量抽帧省一个数量级
  • 摄像头实时问答:source:{kind:"camera"} 走 dshow 设备
  • OBS 抓后台窗口:source:{kind:"obs"},无物理屏的机器也能抓

§7 坑与注意

  1. Linux 不可用:x11grab / PipeWire 还没接,现在直接报错,不假装能用。
  2. macOS 屏幕录制权限不给不报错:exit 0、帧数正常,只是全黑。探针会算平均像素,发现全黑就在 start 返回里带提示,但权限只能你自己去点。
  3. 只支持主屏:负坐标表达不了,gdigrab 也不接受。
  4. 区域模式只能看到前台像素:这块被别的窗口挡住,看到的就是挡住它的那个窗口;默认不接 OBS,抓不到后台/最小化窗口。
  5. 抓屏整体失败时(锁屏、UAC 安全桌面、远程桌面)窗口会退成一块纯色底板,字还能读,但背后不是真实画面。
  6. 听声音只有 Windows:macOS 要装 BlackHole 之类虚拟声卡并手动配多输出设备,这一版没做,mac 上「听声音」直接报抓不到回环,画面功能照常。
  7. 它听得见自己:TTS 念台词时音箱出声,会被回环收回去。落盘前查 quiet-until.json,念的时候整段丢弃——否则 AI 会把自己的话当成「视频里说的」然后接着聊。
  8. 抓的是整个系统输出:QQ 提示音、BGM、游戏音效都会进台词;没人说话时转写多半是空的,偶有对着音乐吐幻觉歌词。
  9. 转写同音字会错(「技术维」/「技术为」)。README 说模型已被明确要求不要把它当原文引用。
  10. 只认「画面变了」,不认「语义变了」:同一句话的两个排版版本算变化;两段内容不同但长得很像的页面可能算没变。
  11. 没有跨帧去重(除 dupMin 那道粗筛),不保证每帧都有「新信息」。
  12. macOS -framerate 不压速:avfoundation 屏幕源实测 30 帧只用 0.73 秒(≈40fps),必须靠输出侧 -r 12 压回来——开发时少了这条管道被灌出过 240GB raw 文件。
  13. 参考背景会被长期前景污染:24 帧里前景占多数时模型会漂。
  14. 唤醒有节流:再密也不会超过 pace 里的间隔,语音播报是串行的。
  15. npm 版本号未在 README 给出:若需锁定版本,建议查 npm registry 或 release tag(本文未核对,⚠️)。

§8 与同类对比

方案 截帧策略 帧成本 跨平台 特色
dsh-see-now 变化分 + 切点/积分双判据 一张图摊 4~8 帧,约 233 token/张(low 档) Win / mac(Linux 未接) 逐场景模式、台词与画面对齐、TTS 浮窗、可当库用
定时截全屏(朴素做法) 固定间隔 每张单独计价,30s=30 张 任意 实现最简单,token 烧穿
Playwright / CDP 截图 按需触发 只在动作点截 Web 为主 适合网页自动化,不适合看桌面视频流
OBS + 虚拟摄像头源 持续推流 取决于下游自己抽帧 Win 为主 能抓后台窗口,但需另配抽帧逻辑
ffmpeg select='gt(scene,0.4)' ffmpeg 自带场景切分 每帧单独计价 全平台 生态成熟,但无积分兜底、无跨帧策略、无拼图

它的独特处在于「一张多帧图」这个计价结构:因为模型按图计费,把 4~8 帧拼成一张能显著摊薄固定成本——这是单纯 ffmpeg 抽帧方案得不到的。

§9 源码结构(便于定位)

src/:capture.js(唯一 spawn ffmpeg 的地方,一根 rawvideo 管道)、binaries.js(找 ffmpeg)、cuts.js(64×36 HSV 网格逐帧变化分)、pipeline.js(唯一有状态的地方:帧 → 打分 → 切点/积分 → 留帧 → 档位 → pack → 出图)、tiers.js、pack.js(DP 装箱)、sheet.js(合成 PNG)、runner.js、listen.js、loop.js、index.js。另有 examples/floating-chat/(悬浮窗 + listen.py + mic.py)、debug/(调试窗,不进 npm 包)、test/(181 条测试)。

开发期调试:

npm run debug:live
npm run debug:live -- --source=file --file=x.mp4 --realtime=1
npm run debug:live -- --source=file --file=x.mp4 --scene

Windows 上可直接双击 debug/调试窗.cmd。

§10 一句话推荐结论

如果你用 DSH(DeepSeek 官方 CLI/桌面端)并且想让 AI 实时陪看屏幕,这个插件是目前最值得试的方案——它用「变化分 + 切点/积分」双判据把 30 秒操作从 30 张图压到 2~3 张,且一张图塞 4~8 帧价格不变,token 结构性省一半以上;坑集中在平台覆盖(Linux 未接)、macOS 权限静默失败和「只认像素变化不认语义变化」三处,接受这些就直接上。

本文只读公开页面(GitHub README,2026-11-04 抓取)。未 clone、未运行代码,命令均转录自 README。⚠️ 标记处为待核项。