🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

本地知识库 imaused/dsh-kb-lite

DeepSeek Harness
imaused15 天前有提交已提供中文文档扫描:含敏感能力

把文档入库,按原文段落检索并给出可引用的出处

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add imaused/dsh-kb-lite
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · search
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令发起外部网络请求
查看扫描证据(共 3 处,展示前 3 条)
  • 发起网络请求
    lib/plugin.js:355
    const result = await engine.request(op, params, {
  • 发起网络请求
    lib/plugin.js:540
    ingest = await engine.request(
  • 执行外部命令来自配置/变量
    lib/rpc.js:295
    const result = spawnSync(
扫描于 2026/11/1(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

dsh创建的记忆库插件

README

由 DeepSeek 最新模型翻译生成
dsh-kb-lite DeepSeek Harness 的本地知识库:把 Markdown、纯文本和 PDF 入库,用 BM25 或可选的稠密检索取回原文段落,并把模型能直接引用的出处交给它——文件、标题、行号或页码。 MIT。宿主侧插件,五个工具,没有浏览器界面,引擎不打开任何 socket。BM25 只依赖 Python 标准库。 为什么还要另做一个 dsh-kb-rag 是现有插件里最接近的一个,它在 DSH 0.2.0-rc.2 上装不上。它声明了指向 @deepseek-ai/dsh-client-runtime 的 dsh.client.inject,而 0.2.0-rc.2 的客户端基线里没有这个包。同时它把 @deepseek-ai/dsh-tools 钉在 ^0.1.0-rc.6,宿主是 0.2.0-rc.2 时 DSH 自己的版本闸门拒绝的正是这个范围。迄今发布的 22 个版本都带同一个 peer 范围,没有可以退回去的旧版本。 本插件站在这条取舍的另一边:只有宿主侧,不带客户端包,不做客户端注入,peer 范围写成带显式预发布分支的形式,让 0.2.0-rc.x 真的能匹配上。dsh-kb-rag 的思路本身没有问题——卡住它的是客户端依赖和 peer 范围,不是功能。
展开完整文档(README 剩余 1 节)
dsh-kb-lite

DeepSeek Harness 的本地知识库:把 Markdown、纯文本和 PDF 入库,用 BM25 或可选的稠密检索取回原文段落,并把模型能直接引用的出处交给它——文件、标题、行号或页码。

MIT。宿主侧插件,五个工具,没有浏览器界面,引擎不打开任何 socket。BM25 只依赖 Python 标准库。

为什么还要另做一个

dsh-kb-rag 是现有插件里最接近的一个,它在 DSH 0.2.0-rc.2 上装不上。它声明了指向 @deepseek-ai/dsh-client-runtime 的 dsh.client.inject,而 0.2.0-rc.2 的客户端基线里没有这个包。同时它把 @deepseek-ai/dsh-tools 钉在 ^0.1.0-rc.6,宿主是 0.2.0-rc.2 时 DSH 自己的版本闸门拒绝的正是这个范围。迄今发布的 22 个版本都带同一个 peer 范围,没有可以退回去的旧版本。

本插件站在这条取舍的另一边:只有宿主侧,不带客户端包,不做客户端注入,peer 范围写成带显式预发布分支的形式,让 0.2.0-rc.x 真的能匹配上。dsh-kb-rag 的思路本身没有问题——卡住它的是客户端依赖和 peer 范围,不是功能。如果将来出现面向 0.2.x、且不再注入 dsh-client-runtime 的版本,它覆盖的范围和这个插件大部分重叠,没有理由优先选这个。

范围是有意做小的:五个工具、一个本地索引目录、一条在从没装过 torch 的机器上也能跑的 BM25。

特性

- 五个工具:kb_ingest、kb_search、kb_ask、kb_stats、kb_clear。
- 没有浏览器界面,也没有客户端包。package.json 里刻意不写 dsh.client 字段:插件只加宿主侧工具,所以 DSH 改客户端 API 时弄不坏已经装好的副本。这一点重要,因为客户端那一半一旦坏了会把整个 Web 界面一起带下去——DSH 的启动是全或无。
- 输入:.md、.markdown、.txt、.pdf。PDF 需要 pymupdf;没有时每个 PDF 作为逐文件错误返回,批次其余文件照常入库。其它扩展名不读:目录遍历会跳过,显式点名的文件会以 unsupported_extension 报错。
- 支持递归目录——隐藏目录以及 .git、node_modules、.venv、__pycache__ 一类的目录会跳过。按 sha256 增量:未变化的文件跳过,内容变化的重新索引,force: true 无条件重解析。
- max_files 限制单次调用处理的文件数;超出的部分作为 pending 返回,下次调用接着做。
- BM25 不依赖任何第三方库,含汉字二元组分词。
- 可选的稠密检索走 sentence-transformers 和 BAAI/bge-small-zh-v1.5;hybrid 用倒数排名融合(RRF)合并两路结果。
- 引用信息:path、title、heading,Markdown 与纯文本有 start_line/end_line,PDF 有 page,matched_by 说明这一块是哪一路检回的。
- kb_ask 在字符预算内返回原文,不改写、不摘要、不润色。
- 一个知识库一个目录。没有数据库服务,没有守护进程,不占端口。

安装

dsh plugin --profile web add dsh-kb-lite

或者直接从 GitHub 装:

dsh plugin --profile web add github:imaused/dsh-kb-lite

把 imaused 换成发布这个仓库的 GitHub 账号。如果你的 profile 不叫 web,换成自己的名字(例如 --profile desktop)。

装完重启 DSH,并开一个新会话。工具是在会话创建时绑定的;已经开着的会话看不到它们。

工具

| 工具 | 做什么 | 参数 |
| kb_ingest | 索引文件或目录 | paths、recursive、force、max_files、with_embeddings、kb_root |
| kb_search | 返回带片段的打分结果 | query、top_k、mode(auto、bm25、dense、hybrid)、kb_root |
| kb_ask | 在字符预算内返回可供模型引用的原文段落 | query、top_k、max_chars、kb_root |
| kb_stats | 文档数、块数、kb_root、占用大小、updated_at,最多 50 条已索引路径 | kb_root |
| kb_clear | 删除索引 | confirm: true、kb_root |

每个工具都接受可选的 kb_root,只对本次调用生效。传给 kb_ingest 的路径必须是绝对路径。

默认值:recursive: true、force: false、max_files: 50(限制在 1–500)、with_embeddings: "auto",kb_search 的 top_k 默认 8、kb_ask 默认 5(都限制在 1–50),max_chars 默认 6000。with_embeddings 接受 "auto"(有稠密依赖时算向量)、"on" 和 "off";只想用 BM25 时传 "off" 可以跳过这次入库的向量计算。

快速开始

下面都是对话里直接输入的提示词。每条都点名了工具和参数,这是拿到确定性调用最可靠的方式。

1. 索引一个文档目录:

用 kb_ingest 把 D:/docs 入库:paths ["D:/docs"],recursive: true,max_files: 50。

返回里会有 added/updated/skipped 计数、逐文件的 errors;如果目录里的受支持文件超过 50 个,还会有 pending。路径必须是绝对路径:相对路径不会按工作目录解析,只会尝试拼到你的主目录上,好让报错说清楚到底试了哪个路径。

2. 提问并拿到可引用的段落:

用 kb_ask 从知识库回答:query "重试策略是怎么退避的",top_k: 5,max_chars: 6000。引用原文,并标出 path 和行号。

3. 只用 BM25 检索——对比两种模式时很有用:

用 kb_search 检索:query "BM25 k1 b",top_k: 8,mode: "bm25"。

4. 看看索引里到底有什么:

运行 kb_stats,告诉我 kb_root、文档数、块数、dense 是否可用,以及已索引的路径。

5. 清掉一个临时索引:

用 kb_clear 清空 kb_root "D:/kb/scratch",confirm: true。

这会删掉该 kb_root 下的索引文件——manifest.json、chunks.jsonl 以及可能存在的向量文件。不会动你的原始文档;engine.log 会留下。

配置

| 设置 | 默认值 | 作用 |
| KB_LITE_PYTHON | 未设置——依次尝试 python、python3、py | 启动引擎进程用的解释器。找到的不是装了 pymupdf 或 sentence-transformers 的那个,或者这些名字都解析不到时,设它。 |
| KB_LITE_ROOT | ~/.kb-lite | 调用没有传 kb_root 时使用的默认目录。~ 是用户主目录(os.homedir()),Windows 上例如 C:/Users/you/.kb-lite。 |
| KB_LITE_MODEL | BAAI/bge-small-zh-v1.5 | 稠密检索可用时使用的嵌入模型。 |
| kb_root(单次调用) | — | 覆盖 KB_LITE_ROOT,只对本次调用生效。 |

优先级:单次调用的 kb_root > KB_LITE_ROOT > ~/.kb-lite。

环境变量要在启动 DSH 之前设好,在会话里设不生效。

检索是怎么工作的

BM25。 纯 Python 实现,不用任何库。分词是拉丁词(转小写,[a-z0-9_]+)加汉字二元组(相邻两字),再加单字兜底,参数为 k1 = 1.2、b = 0.75。这是永远可用的模式:什么都没装,BM25 仍然是一套完整的、带排序的关键词检索。

稠密检索。 当 numpy 可导入、sentence-transformers 能加载时,引擎用 BAAI/bge-small-zh-v1.5(可用 KB_LITE_MODEL 改)给块算向量,并在查询侧加上该模型训练时用的指令前缀 为这个句子生成表示以用于检索相关文章:。稠密检索能找到与原文不共用一个词的改写问法。向量是在入库时算的,所以在装这些可选依赖之前建的索引没有向量——装好之后重新入库(force: true,或者先 kb_clear)才会有稠密结果。

混合检索。 倒数排名融合,k = 60:两路各取 top_k * 4 个候选,按融合分排序。每条命中的 matched_by 记录它是被 BM25、稠密检索还是两者一起找到的。

mode: "auto" 在有稠密时走 hybrid,否则走 bm25,每条结果都带 mode_used,不用猜实际跑的是哪条路。显式模式也按同样方式降级:机器上没有那套依赖,或者索引里没有向量时,dense 或 hybrid 会退回 BM25 而不是报错,并在 mode_used 里说明。kb_ask 没有 mode 参数,选择方式相同,也会报 mode_used。

几百份文件以内,单靠 BM25 通常够用。稠密检索值得装的理由是:你的问题是对原文的改写(「上传为什么老是断」),而不是原文里出现过的词(「上传超时」),或者语料中英混杂。为了检索 40 个 Markdown 文件去拉 torch 那一套并不划算。要判断自己的语料该用哪个,同一个查询跑两遍——mode: "bm25" 和 mode: "hybrid"——对比命中即可。

分块决定了引用能不能落地。Markdown 按 ATX 标题切节,单节超过 1200 字符再按空行或句末切,重叠 120 字符。纯文本按空行切分,贪心合并到不超过 1200 字符,重叠同样是 120。PDF 按页取文本,再用同样的规则切,page 从 1 开始。每块都记录 start_line 和 end_line——md/txt 是原文行号,PDF 是该页内的行号——kb_ask 的输出之所以能直接引用,靠的就是这两个字段。

存储布局

所有东西都在一个目录里,即 kb_root(默认 ~/.kb-lite,也就是放在用户主目录下,而不是当前工作目录——以桌面方式启动时 cwd 并不可靠):

kb_root/
manifest.json # {version, docs: {<doc_id>: {path, sha256, mtime, size, title, kind, pages, chunks}}, updated_at}
chunks.jsonl # 每行一个 JSON:{chunk_id, doc_id, ordinal, heading, start_line, end_line, page, text} vectors.npy # 可选;行序与 chunks.jsonl 一致;float32 vectors.json # 没有 numpy 时的降级存储;与 .npy 二选一,不会同时存在 engine.log # 引擎日志;引擎的 stderr 也镜像到这里

doc_id = 规范化路径 sha1 的前 16 位;chunk_id = <doc_id>:<ordinal>。manifest.json 和 chunks.jsonl 都是纯文本——可以直接读、直接 diff,也可以拿来核对到底入库了什么。

索引是派生数据。要重置就删掉 kb_root 再重新入库,不要手改这些文件;kb_clear 就是替你删。改了 KB_LITE_MODEL 之后,已存的向量来自旧模型,应当重建(kb_clear,再入库)。

环境要求

- Node.js 18 或更新——插件的宿主侧。
- Python 3.9 或更新——运行引擎。
- 跑 BM25 不需要别的东西。
- 可选项,PDF 需要:pymupdf(pip install pymupdf)。
- 可选项,稠密检索需要:numpy 和 sentence-transformers(pip install numpy sentence-transformers),装进插件实际启动的那个解释器(见 KB_LITE_PYTHON)。
- 不需要数据库、不需要服务、不需要 API key。

已知限制

以下都是已知的,没有藏在配置项后面:

- 没有重排器。 hybrid 只是把 BM25 与稠密两路排序融合,融合之后不再重新打分。
- 不处理 DOI,也不生成可点击的引用。 PDF 里的 DOI 就是普通文本。kb_ask 给你 path、行号和页码,不是一个能点开的文献链接。
- 不能导入 Zotero(或任何文献管理库)。 入口只有磁盘上的文件,把 kb_ingest 指过去。
- 没有 OCR。 扫描版 PDF 没有文本层,抽不出任何东西。先自己做 OCR,再入库文本。
- 向量文件整体重写,不做增量更新。 每次入库都会按新的块列表重写 vectors.npy/vectors.json;未变化的块复用已有向量,但没有追加写,也没有后台压缩。
- BM25 索引是每次查询时重建的,不做缓存。 目标规模(几百个文件、几千个块)下没问题,换来的是磁盘格式足够简单;它不是为十万级块设计的。本机实测:25 个块的语料查询在毫秒级返回,代价随语料增长,而不是随查询增长。
- 块大小固定。 1200 字符、重叠 120,没有单次调用或单文件的覆盖开关。
- 只认四种扩展名。 .md、.markdown、.txt、.pdf。DOCX、HTML、EPUB 不读。
- 引擎是每个插件实例一个进程,不是共享守护进程。 每个加载了插件的 DSH 实例都会起自己的 python engine/kb_engine.py。两个 profile 就是两个进程;开着稠密检索时,各自加载一份嵌入模型,不是一个共享服务。

隐私

- 引擎不打开任何 socket,不发网络请求。没有遥测,没有更新检查,没有远程索引。
- 它唯一常驻的进程是每个插件实例一个本地 python engine/kb_engine.py;启动前还会跑一次一次性的解释器探测,详见 SECURITY.md。
- 读什么:你传给 kb_ingest 的文件,以及它自己的 kb_root。
- 写什么:只写 kb_root 里面。
- 不读也不存任何凭据。没有 key、没有 token、没有账号。

有一个容易搞错的例外要讲清楚:如果装了可选的稠密依赖,第一次运行时从 Hugging Face 下载 BAAI/bge-small-zh-v1.5 的是 sentence-transformers(不是本插件),除非模型已经在本机缓存里。在不能出网的机器上,要么先把缓存准备好,要么不要装稠密那一套。

SECURITY.md 里有精确的 argv、完整的读写边界,以及你可以自己跑的核对命令。

状态

版本 0.1.0。在 Windows 11、DSH 0.2.0-rc.2、Node 24、Python 3.14 上测过。Linux 与 macOS 未测试。

这个插件怎么提交到插件列表,写在 docs/submission.md 里。

排错

工具报 python_not_found、python_start_failed 或 engine_dead。 python_not_found 表示所有候选解释器都没应答;python_start_failed 表示找到了一个但退出码非零。启动引擎之前,插件会先跑 python -c "import sys; sys.stdout.write('ok')" 做一次探测,所以解释器存在但坏掉的情况会卡在这一步。先确认解释器:

python --version

然后用 KB_LITE_PYTHON 指到一个确定可用的解释器,重启 DSH。Windows 上如果 python 打开的是微软商店而不是解释器,写真实路径:

KB_LITE_PYTHON=C:/Users/you/AppData/Local/Programs/Python/Python314/python.exe

想知道引擎本身能不能跑,手工起一次并发一条请求:

echo '{"id":"1","op":"ping","params":{}}' | python engine/kb_engine.py

应该先看到一个 ready 行,然后是 {"id":"1","ok":true,"result":{"pong":true,...}}。这一步能过,问题就在插件使用的路径上,不在引擎;过不去,就看 kb_root 下的 engine.log。

PDF 被忽略或报错。 PDF 支持需要同一个解释器里有 pymupdf:

python -c "import fitz; print(fitz.__doc__)"

缺模块会以逐文件错误出现在 errors[] 里,错误码 pdf_unavailable,批次其余文件照常入库。能导入、但切出 0 个块的 PDF,多半是扫描件——没有文本层,也没有 OCR。

稠密检索不可用。 kb_stats 会报 dense: false,mode: "auto" 就停在 BM25。把依赖装进插件实际启动的那个解释器:

python -m pip install numpy sentence-transformers

然后重启 DSH。模型第一次使用可能需要下载,见上面「隐私」。没有这套依赖时,mode: "dense" 和 mode: "hybrid" 会静默退回 BM25,并在 mode_used 里报 "bm25"——不会出错,但也不会有稠密检索。

索引不在我以为的地方。 kb_stats 会返回当前使用的 kb_root。默认是 ~/.kb-lite;KB_LITE_ROOT 或单次调用的 kb_root 可以改。拿不准就传绝对路径。

中文回来是乱码。 在中文 Windows 控制台下,Python 的 stdout 默认是 GBK 而不是 UTF-8:

python -c "import sys; print(sys.stdout.encoding)"

输出 gbk 是正常的,这也正是引擎不信任控制台的原因:它在启动时把自己的 stdin/stdout/stderr 重设为 UTF-8,插件启动它时也带上了 PYTHONIOENCODING=utf-8 和 PYTHONUTF8=1。所以出现乱码说明你面对的不是插件启动的那个引擎——查 engine.log,并确认 KB_LITE_PYTHON 指的就是你以为的那个解释器。

入库没做完就停了。 是 max_files 截断的。返回里的 pending 是剩下的数量;对同样的路径再调一次 kb_ingest(已入库的文件会按 sha256 跳过,代价很小)。

许可证

MIT,见 LICENSE。
预览分享卡片长什么样 ↓imaused/dsh-kb-lite
分享 · DeepSeek Harness Hub
imaused/dsh-kb-lite

把文档入库,按原文段落检索并给出可引用的出处

回到顶部