Skip to main content
M

cyber-self

mrlsss/cyber-self

Per-workspace personal knowledge base for DeepSeek Harness: each identity gets an isolated local library — import PDF, Word, Excel, Markdown, text, HTML and images, auto-chunk and embed into SQLite with FTS5 + vector hybrid retrieval, then ask questions in chat with numbered citations back to the source. Local-first, no cloud upload; vector embeddings need a local Ollama (default bge-m3), and without it retrieval degrades to FTS5 keyword search.

Install

dsh plugin --profile web add github:mrlsss/cyber-self

README

CyberSelf——赛博镜像

一个人可以有多重身份,每种身份一套只属于自己的资料库。把资料收进来,自动整理、建立索引,之后用说话的方式提问,回答会注明出处。

这是一个 DSH 插件:一个身份对应一个 DSH 工作区,工作区里挂着它自己的本地资料库。

适合什么场景

  • 喜欢听歌的人(身份 A):录入歌单、乐评、歌词笔记。之后说"下雨天、一个人在家,想听安静的",从自己的资料里筛出符合的歌。
  • 数据整理工作者(身份 B):录入工作中的数据。之后按条件让它整理出符合需求的条目。
  • 学生(身份 C):录入各科资料、学习笔记。之后直接问某个知识点、某一道题。
  • 销售、服务人员(身份 D):录入多名客户的聊天记录。之后问"某个客户推进到哪一步了"。

A、B、C、D 可以是同一个人的多重身份。身份之间互相隔离,互不影响。

实际的角色五花八门,但用法始终是同一条线:

  1. 收集这个身份的相关数据;
  2. 整理归纳、向量化、建立索引;
  3. 提问,复用这些数据。

身份怎么隔离

一个身份 = 一个 DSH 工作区 = 一个资料库。库文件就放在工作区目录里的 .cyberself/kb.db,全部内容只在本机。

检索只在当前工作区的库里进行,没有跨身份检索。删掉这个工作区,它的资料库也一起删掉。

安装

需要 Node.js 22.5 以上(资料库用 node:sqlite)、pnpm、DSH 0.2.1-rc 系列。向量化用本机的 Ollama;扫描件和图片转写需要一个能看图的对话模型。

ollama pull bge-m3
pnpm install
pnpm build

构建产物是 lib/index.js(Host 侧)和 lib/client.js(浏览器侧),仓库里带着构建好的文件,从 GitHub 安装时不需要再构建。

两种安装方式

应用内(desktop)命令行(自己建的 profile)
怎么装DSH Desktop 的插件市场dsh plugin add
工作区桌面应用里的全部工作区,挑需要的设为资料库该 profile 下的工作区
其他工具全部保留可以关掉,只留资料库
适合日常使用只读资料库的专用入口、本地改代码调试

两个 profile 可以同时存在。资料库跟着工作区目录走,两个 profile 打开同一个工作区时用的是同一个库,不需要重新导入。

装进 DSH Desktop

桌面应用的 desktop profile 由应用自身管理,命令行的 dsh plugin 写不进去,会报 profile "desktop" is managed exclusively by the Electron application。在 DSH Desktop 的插件市场里搜索 cyber-self 安装。

也可以自己建一个命令行 profile,见下一节。

装进自己建的 profile

命令行 profile 有两种用法:市场还没收录时的安装方式,以及一个只让模型看到资料库的入口。后一种要在第 3 步关掉读文件、联网、执行命令。

1. 新建
dsh --profile kb --from-default-profile web

--from-default-profile 只接受 DSH 自带的模板(web、headless、tui)。desktop 由桌面应用自己管理,不能拿来当模板,也不能用 dsh plugin 往里写。

2. 装插件
dsh plugin --profile kb add github:MrLsss/cyber-self

改本地代码时在项目根执行 dsh plugin --profile kb add link:"$PWD",改完 pnpm build 再重启。

然后检查 ~/.dsh/profiles/kb/package.json,dsh.profile.bundles 里要有 cyberself:

"dsh": {
  "profile": {
    "bundles": [
      "@deepseek-ai/dsh-base",
      "@deepseek-ai/dsh-web-app",
      "cyberself"
    ]
  }
}
3. 关掉不需要的工具

编辑 ~/.dsh/profiles/kb/cordis.patch.yml,按 id 把对应条目设为 disabled: true:

- id: tool-bash
  disabled: true
- id: tool-pwsh
  disabled: true
- id: tool-fs
  disabled: true
- id: tool-fs-search
  disabled: true
- id: tool-web
  disabled: true
- id: tool-subagent
  disabled: true
- id: tool-workflow
  disabled: true
id关掉的工具作用
tool-bashbash、后台任务执行命令
tool-pwshpwsh在 Windows 上执行命令
tool-fsread、write、edit读写工作区里的文件
tool-fs-searchglob、grep按文件名或内容搜索文件
tool-webweb_search、web_fetch联网搜索和抓取网页
tool-subagent子任务相关工具另起一个助手干活
tool-workflow编排脚本批量调度多个子任务

tool-todo、tool-goal、tool-skill、tool-result-pruner 不影响资料库的封闭性,可以留着。插件自己的 cyberself_search、cyberself_read 不受影响,资料库的读取走插件自己的工具。

4. 重启
dsh --profile kb

patch 层在启动时合成,改完 cordis.patch.yml 必须重启才生效。改 Host 代码也要重启;改客户端代码要重新 pnpm build 再刷新页面。

为什么关掉工具

「回答范围」里的「仅资料库」是提示词约束,模型手里仍然有 bash、read、web_search,只是被要求别用;在 profile 里关掉之后,这些工具根本不会出现在模型面前,问答只能围着资料库进行。

桌面应用里的日常对话不受影响,两边用的还是同一批工作区和同一份资料库。

使用四步

1. 收集录入

打开身份对应的工作区,点顶栏的「资料库」按钮(或右栏的「资料库」页签),点「设为资料库」,然后上传文件,或填入 Host 上的目录绝对路径整目录导入。

数据格式
文档.pdf .docx(Word 内嵌的图片也会解析)
表格.xlsx .xls .csv(每行一段,工作表名作为小节标题)
笔记、纯文本.md .markdown .txt .text .log(自动识别 UTF-8 与 GBK)
网页.html .htm(取正文、标题和表格)
图片、扫描件.png .jpg .jpeg .webp .gif(视觉模型转写)
聊天记录从聊天软件导出为 txt、Markdown 或 html 后导入

单个文件最大 64 MB。目录导入会先递归扫描,列出文件数量、总体积、其中多少张图片要交给视觉模型,确认之后才开始导入;扫描时跳过隐藏目录和 node_modules、.git、.cyberself、dist、build、lib。.doc 不支持,先另存为 .docx 或 PDF。

2. 结构化整理(自动)

导入时自动完成:按格式解析出正文,按标题、表格行、段落切成块,按内容 hash 去重。同一份文件再导一次,直接提示「这个文件已经导入过」;换个文件名、内容一样,也认得出来。

3. 向量化、索引(自动)

切块进入 SQLite,同时建两份索引:全文索引(trigram)和向量(默认 Ollama bge-m3)。向量在后台补齐,面板上能看到「已向量化 K 段 / 共 M 段」。向量还没跑完也能提问,此时只按关键词匹配。

4. 资产复用

在对话里直接问。插件先检索资料,把命中的片段交给对话模型,回答里每句结论后面带 [1]、[2] 编号,编号对应面板里能查到的原文块。资料里没有的内容,回答会直说缺什么,不猜。

举个例子。身份 D 的「客户跟进」工作区里导入了 客户-林总.txt:

3月12日 林总:报价收到,内部还要过一遍采购流程。
3月20日 我:发了第二版方案,增加了分期付款。
3月27日 林总:方案可以,约下周三下午当面签合同。

问:「和林总推进到哪一步了?」

回答:

已到签约阶段。3 月 27 日林总确认第二版方案可行,约好下周三下午当面签合同。[1]

此前 3 月 12 日报价进入对方采购流程,3 月 20 日发出了增加分期付款的第二版方案。[1]

面板上的检索框可以只查资料、不调用模型,用来核对原文和分数。

面板功能

  • 统计:几份资料、几段、已向量化几段、占用大小。
  • 导入:上传文件,或填一个目录路径,扫描后先看数量、体积和图片张数,再决定是否导入。
  • 文档列表:点开一份能看到每一段的原文、页码、小节标题,可以单独删除。
  • 检索框:只查资料库,不调用模型。
  • 操作:向量化全部、清空资料、删除数据。

「清空资料」删掉全部文档、分块和向量,保留资料库标记;「删除数据」删掉整个 .cyberself 目录,这个工作区不再算资料库。

回答范围

每个身份单独设置:

  • 仅资料库:只依据检索到的原文回答,资料里没有就说明缺哪类资料。
  • 允许补充:先查资料库,没覆盖的部分可以补充,补充内容单独成句并注明「(资料库外)」。

这是对模型的指令约束,模型手里仍然有其他工具。要让它在能力上就没有这些工具,按装进自己建的 profile 的第 3 步关掉。

设置

设置 → 资料库:

字段说明
服务地址Ollama 地址,默认 http://127.0.0.1:11434
模型嵌入模型名称,输入框会列出已安装的模型
单次超时单次嵌入请求的超时,默认 120 秒
每批条数每次送给模型的文本条数,默认 8
每块字符上限0 表示整块送入;设小可以加快向量化,代价是每块后半段不参与语义匹配
表格分块去重打开后,Excel 和 CSV 里只有数字不同的行共用一个向量

改动模型、每块字符上限或去重开关,会清空已有向量并在后台重新生成。保存之前先探测新的嵌入服务,连不上或者模型没装,设置不会保存,向量也不会被清掉。设置保存在 $DSH_HOME/cyberself/settings.json。

其余参数(分块长度、每次检索几条、回答温度等)写在 profile 的 cordis.patch.yml 里,全部字段和默认值见 src/host/config.ts:

- id: cyberself
  config:
    retrieval:
      topK: 8
    answer:
      model: deepseek-chat
      verify: true

数据

内容位置
资料库数据库<工作区>/.cyberself/kb.db
资料库标记与回答范围<工作区>/.cyberself/config.json
嵌入服务设置$DSH_HOME/cyberself/settings.json

资料库目录就在工作区里面,所以如果你会把这个工作区提交到 Git,记得把它加进自己的 .gitignore:

.cyberself/

开发

pnpm install
pnpm build      # 生成 lib/index.js 与 lib/client.js
pnpm typecheck
pnpm test       # node:test,94 个用例,需要本机 Ollama 与 bge-m3

其中两个用例要把问题真正发给对话模型(测试走 127.0.0.1:3425 的模型网关),CI 没有这个网关,会跳过这两个用例跑其余 92 个。

lib/ 跟着源码一起提交,安装侧不会执行构建。改完 src/ 记得重新 pnpm build 再提交,CI 会检查 lib/ 与源码是否一致。

目录内容
src/host/解析、分块、SQLite、检索、问答、HTTP 路由、模型工具、会话规则
src/client/右栏面板、设置页、样式、数据请求
src/shared/前后端共享的类型与路径
test/测试用例、网关客户端、样例文件
test-docs/各种格式的样本文件与测量脚本

限制

  • .doc 不支持。
  • 扫描件和图片依赖能看图的模型,模型不支持图片时导入会失败。
  • 扫描版 PDF 的页面要渲染成图片,依赖 @napi-rs/canvas 的预编译包;平台没有预编译包时,这类页面会报错并说明原因,文字版 PDF 不受影响。
  • 向量检索在 JavaScript 里逐块计算,耗时随分块数量线性增长,1 万段约 0.8 秒。
  • Word 转出来的分块可能比章节更碎,检索粒度比 Markdown 差一些。
  • 一个工作区一个库,没有跨身份检索。
  • 同一时间每个库只跑一个向量化任务。

常见问题

连不上 Ollama。 先确认服务在跑:curl http://127.0.0.1:11434/api/tags。

提示 Ollama 里没有模型。 执行 ollama pull bge-m3,然后点设置页的「重新检测」。

导入成功但搜不到。 看面板统计里「已向量化」是不是 0。向量没生成时只按关键词匹配,可以换个更贴近原文的说法。

回答没有编号。 先确认 answer.verify 是打开的;重答一次仍无编号会附警告。也可以把 answer.model 换成更强的模型。

Related plugins