dsh-knit
Manifest valid★ 2Agent 一天产出 20 篇文档,你找不到刚才那篇。Knit:DeepSeek Harness(DSH)Web 插件,把工作区最近的 Markdown 文档与图片/视频放到对话旁边的侧边栏,按与当前对话的相关性排序,点开就地预览。零模型调用。 | Recent docs, images & video in the DSH sidebar, ranked by relevance, with inline preview.
Knit
Agent 一天产出 20 篇文档,你找不到刚才那篇。 Knit 把它们放到对话旁边 —— 你正在聊什么,相关的那篇就在最上面。
你的 agent 也一样。 同一份排序也给它当工具用 —— 它问「哪几篇相关」,拿回排名加每篇里命中的那段原文。

真机截图(不是原型):一个含 36 篇文档的工作区 —— 列表 + 就地预览 + 引用条。 引用条是 v0.12 加的:展开就能看到「这篇被谁引用」,点一项直接跳过去。 顶行会跟着你正在聊什么变;对话内容还不足时它退回按时间排,并如实说明依据。

排序跟着对话走(同一个工作区、同一个会话):先问「排序算法用的 BM25 是怎么加权的?」, 顶上换成排序那几篇;再问「插件市场收录和下载量怎么查?」,顶上又换成市场调研那几篇。 ⚠️ 面板是每 5 秒轮询一次的,所以重排落在发消息之后的 0–5 秒内、不是瞬时;动图比真实时间快。
扫整个项目文件夹的 Markdown / 图片 / 视频 · 排序跟着对话走 · 不调模型、不联网
dsh plugin --profile web add dsh-knit
这不就是个「最近文件列表」吗?
是的,但有两个关键区别:
- 范围:最近打开列表只记你点开过的文件;Knit 扫整个项目文件夹。 重启 DSH、新开会话、跨天回来,它都还在。
- 排序:它按时间排;Knit 按你正在聊什么排。
三句话说完它是什么:
- 扫整个项目文件夹的 Markdown,不只是这一轮生成的那几篇 —— 重启、换会话、跨天都还在
- 排序跟着你正在聊什么走:聊架构,架构文档浮上来;聊竞品,竞品分析浮上来
- 不调模型、不联网:全是本地字符串运算,零延迟、零成本、文档不出本机
「相关」是怎么算出来的
没有玄学,就是字符串运算。三步:
1. 读当前会话。 取最近 6 条用户 / 助手消息,只认真人输入的用户消息
(agent.inject() 塞进来的合成上下文不算,那会把话题带偏)。越新的消息权重越高:3 / 2 / 1 / 1 …
2. 抽关键词。
- 英文词:取值很高,出现 1 次就要(
chokidar、mtime这种精确词) - 中文 2/3-gram:出现 2 次,或出现在最新那条消息里
- 丢掉跨词边界的碎片:中文没有词边界,n-gram 会把相邻两个词的字粘起来 (「图片和」「个插」「的排」)。这类碎片有个共同特征 —— 首字或尾字是纯虚词, 一律丢掉。不丢的话它们会占满候选位,把「图片」「排序」这些真词全挤出去
- 虚词表过滤 + 贪心去重叠(选了「相关性排序」就不再算「相关性」和「排序」)
3. 给文档打分 —— BM25。
每个词先算 IDF:在语料里越罕见越值钱 ln(1 + (N - df + 0.5) / (df + 0.5))
再按字段加权求和:标题 ×4 + 摘要 ×2 + 正文前 2500 字 ×1
每个字段都按 BM25 饱和 + 长度归一化(k1 = 1.2,b = 0.3 / 0.5 / 0.75)
再叠 10% 的时间新鲜度微调(主排序仍是相关性)
为什么是 BM25 而不是「命中次数 × 权重」(那是最初的做法,已换掉):
- 没有 IDF 时,语料里到处都是的词(比如项目名)和罕见词一样值钱, 于是高频词不产生任何区分度,还稀释掉罕见词的分辨力
- 没有长度归一化时,长文档靠堆词就能赢
- 命中次数封顶 6 次是个手写硬拐点;
k1/b才是为这件事设计的
实测(test/eval/fixture.mjs,21 个用例,两版引擎跑同一套语料):
| top-1 命中 | MRR | |
|---|---|---|
| 旧做法(加权命中) | 76.2% | 0.830 |
| BM25 | 95.2% | 0.976 |
这套评测在 npm test 里跑,基线由 test/eval/legacy.mjs 冻结的旧引擎现算,
所以「新引擎必须显著更好」是自动验证的,而不是引用一个写死的数字。
跟「自己数关键词」比(knit/tools/scale-benchmark.mjs,N = 20/60/180/540):
语料刻意做成有真实陷阱的 —— 12 篇短而聚焦的主题文档,加上一堆「每条主题各提 5 次、
但哪一件都没讲」的长干扰文档(真实项目里的 CHANGELOG 就长这样)。
主题文档一半用描述性文件名,一半看不出内容。
| 路线 | 文件名说得清 | 文件名看不出 | MRR 随规模 |
|---|---|---|---|
| Knit(BM25) | 100% | 100% | 1.000(不随规模变) |
自己 grep -c 数关键词 | 17% | 0% | 0.313 → 0.089 |
| 只看文件名 | 100% | 0% | 0.602 |
三件事:排序强于自己数关键词(所以让 agent 重算是不理性的); 文件名匹配只在名字描述内容时好使,Knit 是唯一两种都 100% 的; 自己数的可靠性随规模单调下降。
关于那行「按「xxx」排序」:显示的是命中词在原文里覆盖的那一段,不是词表里的碎片。
中文没有词边界,候选里必然有跨词的碎片(「项目文档」会切出 项目文 / 目文档),
直接显示就成了乱码 —— 把它们的区间合并再切原文,正好还原出 项目文档。
标签是你自己打的字,所以大小写原样保留(打 BM25 就显示 BM25)。
全是字符串运算 —— 没有 embedding,没有模型调用。
并且老实说边界:
- 对话只有一两句时关键词太少,它会退回按修改时间排,并在面板上说明这一点 —— 不假装排了个序
- 语料只有三五篇时 IDF 几乎不起作用:
df的取值范围太窄,动态范围被压扁。 文档越多这个排序越准 —— 这正是它该有的样子 - 它只能排「和对话有共同词汇」的文档:如果一个词都没命中,所有文档同分, 名次就退化成按时间排
安装
dsh plugin --profile web add dsh-knit
装完重启 DSH,然后硬刷新浏览器(Cmd + Shift + R)。
怎么打开:
- 会话头部右侧的 Knit 图标按钮(就在右侧栏展开按钮旁边)—— 一键开面板
- 或右侧栏 tab 条上的「+」→「Knit 最近文档」
可选:装了 dsh-better-sidebar 的话,面板也会注册成它的一个 tab;
没装不受影响,两边是各自独立的可选依赖。
功能
| 能力 | |
|---|---|
| 按当前对话相关性排序(BM25 + IDF,纯本地,零模型) | ✅ |
给 agent 用的 knit_docs 工具:让模型自己查「这个项目里跟当前话题最相关的文档」 | ✅ |
| 相关性 / 修改时间双模式一键切换(偏好记在 localStorage) | ✅ |
扫描会话工作区里的 .md(递归,深度 ≤ 6,跳过 node_modules / .git / dist) | ✅ |
| 每项显示:H1 标题(无则文件名)+ 相对时间 + 首段摘要 | ✅ |
| 面板拖宽后文档列表自动排成 2 列(<420px 保持 1 列);多列时字段一个不少,只是排版改成纵向、标题与路径折两行 | ✅ |
| 单击就地展开预览,再点收起 | ✅ |
相对路径图片真正渲染(./img/a.png、../assets/b.png) | ✅ |
| 文档 / 图片与视频 / 全部 三类一键切换(偏好记住,默认仍是文档,老体验不变);选中态是中性灰填充,不带品牌色描边 | ✅ |
| 图片与视频:方形缩略图网格,格子基准固定 104px、列数由宽度连续数出来(320px → 2 列 / 632px → 5 列 / 1200px → 10 列),格子大小基本不变;纵向有多少行就铺多少行,超出交给列表滚动;视频自动取首帧、叠播放三角与时长角标(零依赖、不转码) | ✅ |
| 点图片 / 视频在面板内就地预览:图片大图、视频可播放可拖动(HTTP Range 流式,不全量下载) | ✅ |
| 「全部」视图分上下两区:文档最多 4 条(超出给「查看全部 →」);图片视频不截断,只给计数 | ✅ |
预览面板可拖高度(20%–80%,位置记住)、可全屏,Esc 退出 | ✅ |
| 「在本地打开」:用系统默认应用打开当前预览的这篇文档(预览头的路径面包屑同样可点) | ✅ |
| 双击在新标签页打开(官方文档预览,带 PDF 渲染器与渲染方式切换) | ✅ |
| 过滤框:按标题 / 摘要 / 路径实时过滤 | ✅ |
| 点工作区路径:用系统文件管理器打开项目文件夹 | ✅ |
| 悬停入口按钮偷看:弹只读浮层列最近 5 篇,点击才进右边栏(不推挤布局) | ✅ |
键盘导航:↑ ↓ 移动即预览 / Enter 切换 / Esc 收起;多列时 ← → 按屏幕位置跨行,Home / End 到首尾 | ✅ |
| 每 5 秒自动刷新 + 手动刷新;2 分钟内改动过的文档打 🆕 | ✅ |
| 中英双语,跟随 DSH 语言实时切换(不用重载插件) | ✅ |
列表是标准 listbox/option 语义,选中项用 aria-activedescendant 播报;多列时键盘焦点有可见描边 | ✅ |
| 零模型调用、零网络出口 | ✅ |
相关度不做可视化(不显示百分比、不画长条)—— 排序本身就是答案,名次即相关度。
另外两档长什么样

图片与视频:方形缩略图,列数跟着面板宽度连续变 —— 这一屏是 6 列,格子约 112px。 视频取首帧当海报,中央叠播放三角、右下角叠时长。列出的就是工作区里真实的图片与 SVG 文件 —— 这个工作区里正好有几张截图和两个图标,所以看起来像一屏文件缩略图。

全部:上区文档(最多 4 条,超出时右侧给「查看全部 →」)、下区图片与视频(不截断,只给计数)。 文档在这一档排成 2 列,标题 / 时间 / 摘要 / 路径四个字段一个不少 —— 列数只改排版,不砍数据。
也给 agent 用:knit_docs 工具
同一份排序,除了给你看,也开了一个口子给模型。
装好之后,agent 的工具列表里会多一个 knit_docs:它可以问
「这个项目里跟当前话题最相关的文档是哪几篇」,拿到按相关性排好序的
路径 + 标题 + 摘要,再用它自己的 read 打开其中一篇。
为什么有用:agent 想引用项目里已有的文档时,只能靠猜路径、或者把 glob
出来的路径一个个 read 试过去 —— 费 token 又慢。而这份排序 Knit 每一轮已经算好了,
这个工具只是把它交出去。
只读,且不存储任何东西:它读的是项目里现成的文件,不是「记忆」。 和记忆类插件的区别是:它们起点是空的(agent 得先记过才有东西可召回), Knit 一装上就有整个项目的历史文档可用。
三个细节:
- 不返回相关度分数。它是相对分数(永远有一篇 100%,每次刷新可能换人当), 给模型看会被当成绝对置信度去推理。顺序即相关度 —— 与面板同一条规矩。
- 不返回正文。agent 有自己的
read工具;Knit 负责发现,不负责搬运。 - 拿不到会话就报错,不兜底。HTTP 路由在会话查不到时会兜底到进程 cwd (兼容不带 sessionId 的老客户端),工具没有这个包袱 —— 兜底只会扫到一个不相干的项目并返回它的文档。宁可报错,也不返回错的东西。
⚠️ 代价要说清楚:工具描述会进每一次请求的系统提示词。 装 Knit 的用户每个会话都会多占一点 token。这是「让 agent 有能力」的必要成本。
它读什么,不读什么
- 扫描当前会话工作区内的
.md、图片与视频(路径越出工作区一律拒绝);媒体只取元信息,不读画面内容 - 只读当前会话的对话事件(用来排序)
knit_docs工具只读:不写任何文件、不落盘任何索引- 不发起任何对外网络请求:客户端的
fetch都指向插件自己的同源路由 - 没有安装期脚本(无
install/postinstall) - 零依赖 —— 装完不需要构建授权,也没有构建步骤
- 按路径读文件的接口只放行图片 / 视频扩展名白名单(图片 ≤ 12MB、视频 ≤ 256MB),
视频走 HTTP Range 按需取字节,响应带
nosniff与default-src 'none'; sandbox
面板里那份「相关度」只影响排序,不显示也不外传。
上面每一条都有自动化检查守着,逐条列在 SECURITY.md 里 —— 每条属性都指向一个真实存在的测试。
npm test会校验那张表本身没腐烂。
已知限制
- 对话太短时排序会退化:只有一两句时关键词不足,退回按修改时间,并在面板上说明
- 中文分词是 n-gram 近似:没有引入分词库(那会带来依赖)。跨词边界的碎片已经按 「首尾是虚词」丢掉、并按原文区间合并还原成真词,但仍可能有孤立碎片 (比如「视频上」这种没有重叠伙伴的)出现在「按「xxx」排序」那行里 —— 匹配不上任何文档的碎片不参与打分
- 语料太少时 IDF 作用有限:只有三五篇文档时,
df的取值范围被压扁, 排序更接近按命中次数排;文档越多越准 - 右侧栏默认页会变成 guide:DSH 的规则是「guide 入口只有一个才直接开那一页」, 内置 Files 占了一个,所以展开右侧栏先看到 guide,需要点一下胶囊
- 媒体只认常见格式与大小:图片
png/jpg/jpeg/gif/webp/avif/bmp/ico/svg、 视频mp4/m4v/webm/mov/ogv;图片 ≤ 12MB、视频 ≤ 256MB,超出不列出 - 媒体只按文件名参与相关性匹配:不解析画面 / 语音内容,截图与录屏建议用可检索的文件名
- 右侧栏状态是 memory-only:刷新或新会话会回到收起状态
开发
git clone https://github.com/PolinniZhong/dsh-knit.git
cd dsh-knit
npm test # 215 项,零依赖,不需要先 npm install
改动生效方式:宿主半边(src/host/)改了必须重启 DSH(实测不热加载);
客户端半边(src/client/)改了硬刷新浏览器即可。
没有构建步骤:客户端半边是手写的 window.__ModuleLoader__.load({...}),
用 React.createElement 而不是 JSX,所以不需要 tsdown / tsc。
静态资源也是内联的 —— 改图标要同时改 assets/ 源文件和 src/client/client.js 里的
KNIT_ICON_PATH,test/icon.test.mjs 会核对两者逐字一致。
knit/
├── package.json # dsh.bundle.patch + dsh.client
├── cordis.patch.yml # 挂进 plugin tree 的 insert 行
├── assets/ # 图标源文件(path 已内联进 client.js)
├── src/
│ ├── host/index.js # /knit/api/recent · /doc · /raw
│ ├── host/relevance.js # 相关性引擎:BM25 + 关键词抽取(纯函数)
│ ├── host/tool.js # agent 文档工具 knit_docs(手写 ToolDefinition)
│ └── client/client.js # 双宿主注册 + 面板 UI
└── test/ # 215 项测试
└── eval/ # 离线质量评测:语料 + 用例 + 冻结的 v0.5.2 基线
细节和取舍写在源码注释里;贡献流程见 CONTRIBUTING.md, 版本变更见 CHANGELOG.md。
版本策略:
0.x表示功能还在动,可能有破坏性变更。1.0.0留给「真实留存被验证之后」,不因为功能做完就发。
协议
MIT © Polinni
Versions
| Latest version | Published | Size |
|---|---|---|
| 0.4.0 | — | — |
| 0.5.0 | — | — |
| 0.5.1 | — | — |
| 0.9.0 | — | — |
| 0.11.0 | — | — |
| 0.12.0 | — | — |
| 0.12.1 | — | — |
| 0.13.0 | — | — |
Comments
Loading…
Similar plugins
by Anionex
[dsh]为纯文本模型设计更强大的视觉工具箱:一行安装使用、粘贴图片直接识别、多张图片问答、截图到前端UI 还原等|DeepSeek Harness-native integration for agent-vision-toolkit: image Q&A, long-screenshot OCR, UI restoration, grounding, pixel diff, Artifacts
★ 820
↓ 3.2k/wk
MIT
TypeScript
Aug 25, 2026
dsh plugin --profile web add @anionex/dsh-vision-toolkitby jh1016248
DSH(DeepSeek Harness)插件:会话标题栏一键导出当前会话 —— 「保存 MD」下载纯净 Markdown,「保存 HTML」下载带左侧目录、表格与代码块渲染的网页。自动过滤模型思考过程与工具调用记录,只保留用户与助手的正文,适合归档、分享与撰写报告。安装:dsh plugin --profile web add dsh-save-session
★ 0
↓ 690/wk
MIT
JavaScript
Sep 11, 2026
dsh plugin --profile web add dsh-save-sessionby EternalNight996
🧑💼为 DeepSeek Harness Web 主窗口添加「工作角色」页签 + 「像素办公室」浮层:内置 508 张完整角色卡(The Agency 255 + agency-agents-zh 253),支持搜索 / 中英切换 / 分部分类选人;Canvas 2D 像素小人可站立、打字、踱步,浮层可拖动折叠缩放,选人即入列;闲聊台词可接 AI(内置或外部接口,20 字内中文)。npm 双
★ 3
↓ 114/wk
MIT
JavaScript
Sep 3, 2026
dsh plugin --profile web add dsh-ui-agents-pixeby leanderli
DSH Web UI 的文件与变更面板插件:为当前会话的工作区目录提供一体化的 文件浏览 / 搜索 / 预览 / 编辑与 Git 操作(状态、暂存、提交、拉取、推送、 分支、历史、diff 等),在浏览器里以居中模态面板呈现,无需离开 WebUI 即可完成 日常文件与版本控制操作。
★ 2
MIT
JavaScript
Sep 14, 2026
dsh plugin --profile web add dsh-files-gitby Cheyeah
DeepSeek Harness (DSH) Web 插件:拖放文件预览 / Markdown 渲染 / 文件盒 / 智能桌面截图(全屏·区域·窗口)/ 外挂识图与识别文本入库。完整开发历史含 21 个快照标签。
★ 0
JavaScript
Aug 28, 2026
dsh plugin --profile web add dsh-drop-previewby Kr-ATG
DSH 对话流增强插件(零 DSH 源码改动,纯插件注入)。回合呈现:思考 chip(实时走秒 + 实时文字滚动)· 工具调用聚合 chip · 对话流卡片(步骤卡/总结卡)· 共享活动抽屉。正文增强:proto-tabs 可交互卡片 · diagram 流程图围栏 · 本地 HTML 内嵌预览(识别正文里的 .html 路径,host 读文件 + 同目录资源,iframe 沙箱隔离,高度自适应,
★ 3
JavaScript
Sep 17, 2026
dsh plugin --profile web add dsh-chat-flow