dsh-timem-memory 底层原理(高中小白友好版)
August 18, 2026 · View on GitHub
目标读者:没有任何编程背景、只想弄懂「这个插件到底是怎么被安装、被启动、被使用的」的人。 读完这篇,你能向别人讲清楚三件事:包是什么、安装装到了哪里、DSH 是怎么把它「叫醒」的。
0. 一句话总览
npm 装的是「货物」,cordis 条目负责「开灯」。 装包只是把文件搬到你电脑上; 让 DSH 真正使用它,需要在配置文件里写一条「启动指令」。
1. 包(Package)是什么:App Store 里的一个 App
我们的插件本质是一个 npm 包——一个按照固定格式打包的文件夹。
dsh-timem-memory/
├── package.json ← 「商品说明书」:名字、版本、入口文件、随包附带的文件清单
├── lib/index.js ← 「发动机」:apply() 函数,DSH 叫醒它时执行的代码
├── skills/ ← 「附赠的说明书包」:5 份教 AI 何时搜记忆/写记忆的 SKILL.md
├── README.md ← 使用说明
└── LICENSE ← 授权协议
npm registry(registry.npmjs.org)就是软件界的 App Store。
npm install dsh-timem-memory 的含义 = 「从 App Store 下载这个 App」。
- 下载的方式有三种,货物都一样,只是「发货渠道」不同:
渠道 命令(由 DSH 转交给 pnpm) npm 官方商店(发布后) dsh plugin add dsh-timem-memoryGitHub 仓库 dsh plugin add git+https://github.com/auuduu/dsh-timem-memory.git本地打包文件 dsh plugin add ./dsh-timem-memory-0.1.0.tgz
dsh plugin add 内部其实就是把参数转交给 pnpm(另一个包管理器),
pnpm 负责下载、解压、放到正确位置。
2. 安装装到了哪里:node_modules 货架与「找包规则」
每个项目/每个 DSH profile 都有一个 node_modules 目录——货架。
pnpm 把包解压进货架:
~/.dsh/profiles/<profile>/node_modules/
├── dsh-timem-memory/ ← 我们的插件被放在这里
└── @deepseek-ai/… ← DSH 官方组件也在同一个货架
Node.js 找包的规则很像学校失物招领:你在 3 班丢了东西, 先查 3 班的失物柜,没有就查年级的,再查全校的。
- 插件代码里写
import '@deepseek-ai/dsh-mcp-client'(「我要用 MCP 客户端组件」)时, Node 从插件自己所在的目录开始,一层一层往上找node_modules,找到为止。 - 所以一个包里写了依赖什么,只要货架上(任意一层)有货,就能找到。
关键点:npm install 到此为止——货物上架了。但还没有人用它。
3. DSH 怎么「叫醒」它:cordis 条目 = 启动器里的勾选框
DSH 是一个基于 Cordis 的「插件启动器」。像游戏启动器管理 mod 一样, 它读一份配置文件,决定「哪些插件要启用、按什么顺序启用」。
我们在 cordis.patch.yml 里写的这条:
- insert:
- id: timem-memory # 起个内部名字
name: 'dsh-timem-memory' # 告诉启动器:去货架上找这个包
就是那个勾选框。启动时(或配置热更新时)启动器执行三步:
- 找货:按
name去node_modules里找到这个包; - 验货:读
package.json,找到入口文件(main: lib/index.js); - 点火:调用入口文件导出的
apply(ctx, config)函数,并给它一个「上下文遥控器」(ctx)。
apply() 一跑起来,插件就活了:
apply() 干两件事:
① 向「凭证管家」ctx.credentials 要 TiMEM 的钥匙(X-API-Key / X-TiMEM-User-Id)
→ 用钥匙拨通 TiMEM 云端 MCP 服务器
→ 把服务器的 17 个工具登记到 AI 的工具清单里(mcp__timem__search_memories …)
② 读包内 skills/*/SKILL.md
→ 把 5 份「记忆使用说明书」注册进 DSH 的 skill 体系
→ AI 看到它们后,学会「每回合先搜记忆、干完活写记忆」
4. MCP 是什么:给 AI 配的「统一遥控器接口」
AI 模型本身只会「说话」,不会做事。工具(tools) 是它的手。
- 每个工具都有名字和参数表。DSH 的 MCP 客户端把 TiMEM 服务器的工具
以
mcp__timem__搜索记忆的形式登记:mcp__timem__search_memories。 - 双下划线命名的含义:
mcp__<服务器名>__<工具名>——像「遥控器__空调__制冷」, 这样即使两个服务器都有叫search的按钮也不会混淆。 - AI 决定调用
mcp__timem__search_memories时,DSH 通过 MCP 协议 (一套标准化的 JSON 对话格式)把请求发到 TiMEM 服务器,拿到结果再喂回给 AI。
5. 密钥为什么安全:保险箱 + 管家模式
坏设计:把 API Key 直接写进配置文件 → 配置文件一分享就泄密。
我们的设计:
配置文件只写: 「钥匙名叫 TiMEM_API_KEY」(一句引用,不是钥匙本身)
真正的钥匙存在: ~/.dsh/.credentials.yaml(权限 0600 = 只有你本人可读写)
运行时有一个「凭证管家」服务 ctx.credentials:
插件问管家「我要 TiMEM_API_KEY」→ 管家按优先级查找 → 递上钥匙
优先级:启动时注入的环境变量 > 凭证保险箱 > 项目 .env > 用户 .env。
更妙的是:你在网页端改了钥匙,管家会广播「钥匙换了」事件, 插件听到后自动断开旧连接、用新钥匙重连——不用重启。
6. skill 是什么:贴在 AI 脸上的「工作流程便签」
17 个工具只是「手」。但 AI 需要知道什么时候用哪只手——这就是 skill 的作用。
- skill = 一份 Markdown 说明书(
SKILL.md),写着「何时触发、按什么步骤做、何时跳过」。 - DSH 的 skill 注册表(ctx.skills)把所有说明书汇总成一个目录发给 AI。
- 我们的插件用
ctx.skills.register()把 5 份说明书注册进去 (provider 标记为runtime,表示「由插件在运行时提供,而非散落在磁盘上」)。 - AI 看到
timem-coding-memory的说明后,编码时就会自动执行: 「回答前先search_memories→ 干活 → 回答后create_memory」。
7. 三个值得记住的坑(工程实践)
- 装包 ≠ 启用:npm install 只是上架;cordis 条目才是勾选框。两者缺一不可。
- ESM 模块缓存:运行中的 DSH 进程「记住」了旧插件代码;
改完插件要重启
dsh web冷启动才生效(配置热更新对已缓存的模块无能为力)。 - 一条命令的两半:
dsh plugin add <包>管「上架」,改cordis.patch.yml管「勾选」。 DSH 会热加载配置文件,所以改勾选不用重启——但新勾选的包如果进程里没缓存,稳妥起见也重启一次。
8. 把整个链路串起来(一句话版)
别人拿到你的仓库 →
dsh plugin add git+https://github.com/auuduu/dsh-timem-memory.git把货架上架 → 在cordis.patch.yml写一条dsh-timem-memory条目(勾选)→ 填好两把钥匙(TiMEM_API_KEY / TiMEM_USER_ID)→ 重启 → AI 就有了 17 只手(mcp__timem__* 工具)+ 5 张便签(记忆 skill),开始自动记忆。