dsh-plugin-long-term-memory
Đã xác minhdsh-plugin-long-term-memory · v1.1.3 · MIT
Long-term memory and self-learning plugin for DeepSeek Harness (DSH) - observe, learn, and remember across sessions. Also supports OpenCode.
Cài đặt
dsh plugin add dsh-plugin-long-term-memory Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.
Mã nguồn
Phát hành lên npm mà không có repository công khai. Hãy kiểm tra nội dung package trước khi cài.
Thẻ
Tác giả
Readme
DSH 长期记忆插件
观测、学习、记忆。为 DeepSeek Harness (DSH) 打造的自进化记忆系统,同时也支持 OpenCode。
这个插件让 AI 助手拥有跨会话记忆能力——它会观测你的工具使用方式、提炼行为模式(「本能」),并在对话中召回相关记忆,提供上下文感知的智能辅助。
核心能力
功能概览
| 能力 | 说明 |
|---|---|
| 工具观测 | 自动捕获每次工具调用的输入和输出,记录行为数据 |
| 模式提炼 | 结合统计分析和语义分析,自动发现你的工作习惯和偏好 |
| 记忆注入 | 在对话中自动召回相关记忆,并注入到系统提示中 |
| 规则进化 | 高置信度的行为模式会自动生成 auto-evolved.md 规则文件 |
| 对话持久化 | 将完整对话历史存入 LanceDB,支持后续检索和分析 |
| 项目隔离 | 记忆按项目作用域隔离,避免跨项目污染 |
双记忆系统
┌────────────────────────────────────┐ ┌────────────────────────────────────┐
│ Instinct 系统(行为记忆) │ │ Memory 系统(知识记忆) │
├────────────────────────────────────┤ ├────────────────────────────────────┤
│ 数据来源:工具调用观测记录 │ │ 数据来源:用户与 AI 的对话内容 │
│ 提炼方式:统计 + AI 语义分析 │ │ 提炼方式:AI 语义判断 │
│ 存储格式:instincts.jsonl │ │ 存储格式:memories.jsonl │
│ 作用范围:全局(所有项目共享) │ │ 作用范围:项目级(含全局记忆) │
│ 生命周期:置信度演化 + 衰减 │ │ 生命周期:按类型 TTL 过期 │
│ 注入方式:auto-evolved.md │ │ 注入方式:会话预加载 + 实时召回 │
└────────────────────────────────────┘ └────────────────────────────────────┘
安装与使用
DSH 插件命令安装(推荐)
npx @deepseek-ai/dsh plugin --profile web add dsh-plugin-long-term-memory@latest
一条命令完成安装与注册:DSH 加载 bundle 时自动读取包内
dsh.bundle.patch声明的 cordis.patch.yml,将插件挂载为 profile layer。无需手动在项目根创建cordis.yml或指向构建产物路径。
验证安装:
npx @deepseek-ai/dsh plugin --profile web list
关于 peer dep 警告:DSH 自身的 web profile 自带
@deepseek-ai/[email protected],期望的[email protected]与本插件用[email protected]期望的[email protected]不兼容。pnpm 会同时装两个 minor-rc 版本(无害),最终日志里会出现Conflicting peer dependencies。这是 DSH 生态自身的版本漂移,与本插件无关——dsh web仍可正常启动,本插件按[email protected]的 API 编写,无法也不应降级。 此外apache-arrow@17的 bin 路径已从.cjs改为.js/.mjs,pnpm 的Failed to create bin at ... arrow2csv是无害警告(不影响 lancedb 运行时 require)。
- 配置文件:
~/.config/dsh/long-term-memory.jsonc(首次启动自动生成模板) - 数据目录:默认
~/.local/share/dsh/long-term-memory/ - 验证加载:
export LONG_TERM_MEMORY_DEBUG=1后启动 DSH,查看~/.local/share/dsh/long-term-memory/plugin.log应出现plugin loaded (tools + hooks + prompt registered) - 沙箱兼容:若终端沙箱(TRAE/EDR)拦截
~/.dsh写入,可用HOME=$PWD/.fake-home npx @deepseek-ai/dsh plugin --profile web add dsh-plugin-long-term-memory@latest临时重定向
已知限制:DSH preview API 易变(锁
@deepseek-ai/[email protected]);turn/end触发的本能分析带 5 分钟防抖。
从源码构建
git clone https://github.com/yuqiangcn/dsh-plugin-long-term-memory.git
cd dsh-plugin-long-term-memory
pnpm install
pnpm build:dsh
OpenCode — 兼容
本插件也保留了 OpenCode 入口(src/index.ts),与 DSH 共享同一套引擎。
pnpm build
配置方式与 DSH 侧类似,配置文件位于 ~/.config/opencode/opencode-plugin-long-term-memory.jsonc。
配置方式
插件支持两种配置方式:
| 方式 | 适用场景 | 难度 |
|---|---|---|
| 什么都不配 | 想快速体验,默认 TF-IDF + 全功能开 | ⭐ |
| JSONC 配置文件(推荐) | 日常使用,团队统一配置 | ⭐⭐ |
配置文件位置
DSH 侧:
~/.config/dsh/long-term-memory.jsonc
OpenCode 侧:
~/.config/opencode/opencode-plugin-long-term-memory.jsonc
- Linux/macOS 遵循 XDG 规范,可用
XDG_CONFIG_HOME环境变量覆盖基目录 - JSONC 格式(支持
//注释、尾随逗号、${ENV_VAR}环境变量引用) - 任何字段缺失或类型错误 → 降级到默认值 + error 日志,不影响插件启动
顶层字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dataDir |
string | ~/.local/share/dsh/long-term-memory |
数据存储目录。更改后旧数据不自动迁移,需手动复制 |
observationEnabled |
bool | true |
开启工具观测。记录每次工具调用的输入/输出到 observations.jsonl |
autoInject |
bool | true |
自动将相关记忆注入系统提示(会话预加载 + 实时召回) |
autoAnalyze |
bool | true |
会话结束后自动分析行为模式,生成 Instinct |
autoExtractMemory |
bool | false |
从对话内容自动提炼记忆。需要配置 ai 块 |
semanticAnalysis |
bool | false |
启用 LLM 语义分析提炼行为模式。需要配置 ai 块 |
maxRecallCount |
number | 5 |
每次对话最多召回多少条记忆 |
recallThreshold |
number | 0.3 |
召回最低相似度(0=不召回,1=完全匹配) |
injectPosition |
enum | "system" |
注入位置:"system" 注入系统提示 / "user" 注入用户消息 |
statisticalMinOccurrences |
number | 3 |
行为模式最少出现几次才被统计检测为 Instinct |
analyticsEnabled |
bool | true |
启用 Analytics 埋点。memory_analytics 工具可生成质量报告 |
ai |
object | - | AI 模型配置(控制语义分析 / 记忆提炼 / 沉淀整理)。见下 |
embedding |
object | - | Embedding 配置(控制语义检索质量)。不配则用本地 TF-IDF(零依赖)。见下 |
autoMaterialize |
object | - | 项目知识沉淀配置(把决策/Bug/模式沉淀到 docs/)。见下 |
ai 块 — AI 模型配置
控制三个 AI 行为:语义分析、记忆提炼、沉淀整理。只要开启 semanticAnalysis 或 autoExtractMemory 或 autoMaterialize.organization.enabled,就必须配置此块。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
provider |
enum | "openai" |
"openai" / "zhipu"(智谱,国内推荐)/ "custom"(OpenAI 兼容端点) |
model |
string | "gpt-4o-mini" |
模型名。OpenAI 例:gpt-4o-mini / gpt-4o;智谱例:glm-4-flash / glm-4-plus |
apiKey |
string | - | API key。建议用 "${ENV_VAR}" 引用环境变量 |
baseUrl |
string | - | 自定义端点。custom 必填;openai/zhipu 留空则用默认值 |
temperature |
number | - | 生成温度(0-2)。建议 0.1-0.3 保持稳定 |
maxTokens |
number | - | 最大输出 tokens |
embedding 块 — 向量嵌入配置
控制语义检索质量。留空 = 本地 TF-IDF(关键词匹配,零依赖)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
provider |
enum | "openai" |
"openai" / "zhipu" / "custom" |
model |
string | "text-embedding-3-small" |
模型名 |
apiKey |
string | - | API key。写法同 ai 块 |
baseUrl |
string | - | 自定义端点。custom 必填 |
dimensions |
number | - | 输出向量维度。仅智谱 embedding-3 有效(256/512/1024/2048) |
autoMaterialize 块 — 项目知识沉淀配置
把高价值记忆(决策 / 项目 / Bug / 模式)沉淀到 docs/project-context.md,作为团队共享文档。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mode |
enum | "assisted" |
"disabled" 纯手动 / "assisted" 会话结束提示候选(默认) / "auto" 满足阈值自动写入 |
types |
array | ["decision", "project", "bug", "pattern"] |
允许沉淀的记忆类型。不能包含 user / profile / feedback(隐私保护) |
thresholds.minConfidence |
number | 0.85 |
auto 模式的最低置信度门槛 |
thresholds.minAccessCount |
number | 3 |
auto 模式的最低访问次数门槛 |
output.path |
string | "docs/project-context.md" |
输出文件路径(相对项目根目录) |
output.autoGeneratedMark |
string | "[Auto-generated]" |
自动生成条目的前缀标记 |
organization.enabled |
bool | true |
是否用 LLM 整理。关闭后直接拼接。需要 ai 块 |
organization.temperature |
number | 0.2 |
LLM 整理温度 |
autoReferenceInAgents |
bool | true |
沉淀成功后是否在项目根 AGENTS.md 中追加 ## Project Knowledge 章节 |
完整配置示例
最小可用(啥都不配):
{}
推荐配置(语义检索 + 自动沉淀,国内环境):
{
"dataDir": "~/.local/share/dsh/long-term-memory",
"observationEnabled": true,
"autoInject": true,
"autoAnalyze": true,
"semanticAnalysis": true,
"autoExtractMemory": true,
"maxRecallCount": 5,
"recallThreshold": 0.3,
"ai": {
"provider": "zhipu",
"model": "glm-4-flash",
"apiKey": "${ZHIPU_API_KEY}",
"temperature": 0.2
},
"embedding": {
"provider": "zhipu",
"model": "embedding-3",
"apiKey": "${ZHIPU_API_KEY}",
"dimensions": 1024
},
"autoMaterialize": {
"mode": "assisted",
"types": ["decision", "project", "bug", "pattern"],
"autoReferenceInAgents": true
}
}
海外环境(OpenAI):
{
"ai": {
"provider": "openai",
"model": "gpt-4o-mini",
"apiKey": "${OPENAI_API_KEY}"
},
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small",
"apiKey": "${OPENAI_API_KEY}"
}
}
常见坑点
apiKey用"${ENV_VAR}":插件启动时同步解析,环境变量没设 →undefined→ 请求失败并打 error 日志。建议用direnv/.env/1Password CLI管理- 开了
semanticAnalysis/autoExtractMemory但没配ai块:AI 调用会失败,相关功能静默失效(不报错也不生效) - 改了
dataDir旧数据不迁移:需要手动复制旧目录下的memories/observations/instincts/dialogues.lance/到新目录 - Embedding 模型换了后旧记忆不兼容:新模型的向量维度和旧的可能不同,旧记忆会自动 fallback TF-IDF 检索
- LanceDB 对话表维度固定:
dialogues.lance表的embedding维度是建表时定的。换 Embedding 模型后,需要删除~/.local/share/dsh/long-term-memory/dialogues.lance/让插件重建 - Monorepo 项目标识冲突:多个子包共用 git remote,会被识别为同一个项目。插件支持自动检测 monorepo 并生成
rootId:leafName的作用域 ID - JSONC 字段类型写错:插件不会崩溃,会打 error 日志并降级默认值
提供的工具
安装后,插件会注册以下工具供 AI 使用:
| 工具 | 用途 |
|---|---|
memory_save |
将知识、偏好或决策保存到长期记忆。支持 scope 参数指定作用域 |
memory_search |
搜索已存储的记忆内容 |
memory_list |
列出所有记忆(可按类型过滤) |
memory_delete |
按 ID 删除指定记忆 |
memory_restore |
恢复软删除的记忆(30 天内可恢复) |
memory_set_scope |
在 monorepo 中切换子包作用域;独立项目中传入项目名可确认当前项目作用域 |
memory_status |
查看系统状态、当前作用域与配置 |
memory_open |
打开 MEMORY.md 摘要文件 |
memory_demo |
保存测试记忆并验证端到端管道 |
memory_analytics |
生成记忆质量报告(命中率、误存候选) |
instinct_list |
查看已学习的行为模式 |
memory_analyze |
手动触发行为模式分析 |
memory_evolve |
从高置信度模式生成进化规则 |
memory_export_rules |
将学习到的规则导出到 AGENTS.md(人工审核+确认) |
memory_materialize |
预览项目知识候选清单 |
memory_materialize_stage |
暂存候选记忆,返回 id+摘要清单;含内容级重复预检 |
memory_materialize_apply |
写入选中的记忆到 docs/project-context.md |
memory_materialize_discard |
清空 staging 区 |
架构设计
┌──────────────────────────────────────────────────────────────┐
│ 宿主适配层 │
├──────────────────────────────────────────────────────────────┤
│ ┌───────────────────┐ ┌───────────────────────────────┐ │
│ │ DSH (Cordis) │ │ OpenCode (Hooks) │ │
│ │ src/dsh/ │ │ src/index.ts │ │
│ └────────┬──────────┘ └────────┬──────────────────────┘ │
│ │ │ │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 引擎层 (共享) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │ 观测引擎 │─▶│ 本能引擎 │─▶│ 记忆引擎 │ │ │
│ │ │(observation) │ │ (instinct) │ │ (memory) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │observations │ │ instincts │ │ memories │ │ │
│ │ │ .jsonl │ │ .jsonl │ │ .jsonl │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ dialogue-store.ts (LanceDB 向量表) │ │ │
│ │ │ └─ 持久化对话历史 │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
文件结构
src/
├── index.ts # OpenCode 插件入口(兼容)
├── dsh/
│ ├── index.ts # DSH Cordis 插件入口(主入口)
│ ├── tools.ts # 工具注册(DSH DSL)
│ ├── hooks.ts # 事件桥接
│ └── prompt.ts # 系统提示注入
├── observation-engine.ts # 观测引擎:Hook 捕获 + 会话追踪
├── instinct-engine.ts # 本能引擎:模式提炼(统计 + AI 语义)
├── memory-engine.ts # 记忆引擎:召回 + 上下文注入
├── memory-store.ts # 存储层:JSONL + TF-IDF/Embedding + 检索
├── dialogue-store.ts # LanceDB 向量表:对话历史持久化
├── embedding-provider.ts # 可插拔 Embedding 层(TF-IDF / Remote / Local)
├── ai-provider.ts # 声明式 AI/Embedding 配置 → fetch 调用函数
├── config-loader.ts # 独立配置加载器(JSONC → Zod 校验)
├── project-utils.ts # 项目标识符推断
├── materializer.ts # 项目知识沉淀(docs/project-context.md)
├── agents-exporter.ts # 规则导出到 AGENTS.md
├── analytics.ts # 埋点与质量报告
└── logger.ts # 日志系统
Monorepo 作用域
插件会自动检测 git 仓库下的 package.json 数量。若存在多个被 git 追踪的 package.json,则视为 monorepo:
- 项目 ID 格式:
rootId:leafName,例如acme:acme-web、acme:acme-shared - 根作用域:
rootId(如acme)下的记忆可被所有子包召回 - 子包作用域:
rootId:leafName下的记忆默认只在该子包召回 - 全局作用域:不绑定 project 的记忆在所有项目召回
显式切换
memory_set_scope name=acme-web
独立(非 monorepo)项目中没有子包概念,作用域始终是项目自身。传入项目名(如 package.json 的 name)即可确认并锁定当前项目作用域:
memory_set_scope name=wallet-h5
memory_save 的 scope 参数
| 取值 | 含义 |
|---|---|
current |
写入当前作用域(默认) |
leaf |
写入当前子包作用域(同 current) |
root |
强制写入根作用域,所有子包共享 |
global |
不绑定 project,全局共享 |
Embedding 提供者
插件支持三种语义检索后端,默认使用本地 TF-IDF(零依赖)。
| 提供者 | 配置方式 | 适用场景 | 维度 |
|---|---|---|---|
| TF-IDF(默认) | 无需配置 | 零依赖、隐私安全、关键词匹配 | 词汇维度 |
| 远程 API | 配置文件 embedding 块(推荐) |
语义质量最优 | 模型决定 |
| 本地模型 | 预留接口 | 未来接入 transformers.js / ollama | 模型决定 |
方式一:配置文件(推荐)
{
"embedding": {
"provider": "openai" | "zhipu" | "custom",
"model": "...",
"apiKey": "明文key 或 ${ENV_VAR}",
"baseUrl": "...", // 可选,custom 必填
"dimensions": 1024 // 可选,仅 zhipu embedding-3 有效
}
}
1. OpenAI
{
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small",
"apiKey": "${OPENAI_API_KEY}"
}
}
2. 智谱 AI(Zhipu)— 中国大陆友好
{
"embedding": {
"provider": "zhipu",
"model": "embedding-3",
"apiKey": "${ZHIPU_API_KEY}",
"dimensions": 1024
}
}
默认端点:https://open.bigmodel.cn/api/paas/v4/embeddings,自动路由。
3. Custom(任何 OpenAI-compatible 端点)
{
"embedding": {
"provider": "custom",
"model": "any-model",
"apiKey": "${CUSTOM_API_KEY}",
"baseUrl": "https://my-proxy.example.com/v1"
}
}
如何选择
| 场景 | 推荐 |
|---|---|
| 不想折腾,关键词匹配够用 | 啥都不配(默认 TF-IDF) |
| 国内 + 中文场景 | 智谱 embedding-3(国内访问稳、价格便宜) |
| 海外 + 追求质量 | OpenAI text-embedding-3-small |
| 企业内部代理 / 私有部署 | Custom + baseUrl 指向代理 |
数据存储
所有数据均存储在本地数据目录(默认 ~/.local/share/dsh/long-term-memory/,可通过 dataDir 配置):
| 文件/目录 | 内容 |
|---|---|
memories/memories.jsonl |
知识记忆(含可选的 _embedding 稠密向量) |
observations/observations.jsonl |
工具调用观测记录 |
instincts/instincts.jsonl |
行为模式(本能) |
dialogues.lance/ |
LanceDB 向量表:对话历史 |
auto-evolved.md |
自动生成的高置信度规则 |
隐私说明:默认情况下所有数据保存在本地,不需要任何云服务。只有显式配置远程 Embedding API 时才会向外部发送数据。
技术栈
- 运行时: Bun(构建) / Node.js ≥ 22.19(DSH 加载)
- 语言: TypeScript 5.8.2(严格模式)
- Schema: Zod 4.1.8
- 向量数据库: LanceDB 0.30.x
- 宿主框架: Cordis 4.0.1(DSH)/ @opencode-ai/plugin(OpenCode 兼容)
开发
# 安装依赖
pnpm install
# 类型检查
pnpm typecheck # npx tsc --noEmit
# 构建 DSH 插件(主入口)
pnpm build:dsh # bun build src/dsh/index.ts --outdir dist-dsh --target node
# 构建 OpenCode 插件(兼容)
pnpm build # bun build src/index.ts --outdir dist --target bun
# 开发运行
pnpm dev # bun run src/index.ts
重要:生产构建使用
bun build。tsc仅用于类型检查(--noEmit),不要用它编译代码。
项目级上下文隔离
记忆系统支持项目级作用域隔离:
- 自动推断:从当前目录自动推断项目标识
- 优先级:git remote URL → package.json name → 目录名
- 检索过滤:
searchMemories优先召回同项目记忆(分数 +0.15 提升)- 全局记忆 +0.05,跨项目 +0
- 同项目不足 topK 时自动 fallback 跨项目 + 全局
- 配置覆盖:
defaultProject?: string可覆盖自动推断(用于 monorepo 子包)
项目知识沉淀
高价值的项目知识可以通过 memory_materialize_* 工具沉淀到 docs/project-context.md,作为团队共享的可读文档。
三步流程
# 1️⃣ 暂存:列出所有候选
memory_materialize_stage
# 2️⃣ 选你想沉淀的
memory_materialize_apply ids=["mem_xxx", "mem_zzz"]
# 3️⃣ (可选)不想沉淀了?清空 staging
memory_materialize_discard
重复预检(团队协作防护)
memory_materialize_stage 阶段会自动做内容级相似度预检,使用字符级 3-gram + Jaccard 相似度,零外部依赖:
similarity ≥ 0.7→🔴 strong match(强烈建议排除)0.5 ≤ similarity < 0.7→🟡 warning match(关注)
隐私保护
docs/project-context.md 通常提交到 git 并团队共享,因此个人类型不允许沉淀:
| 类型 | 是否允许沉淀 | 原因 |
|---|---|---|
decision project bug pattern |
✅ 允许 | 项目相关知识 |
workflow tool-usage reference |
✅ 允许 | 项目相关行为/资源 |
custom |
✅ 允许 | 兜底类型 |
user profile feedback |
❌ 禁止 | 隐私泄露风险 |
许可
MIT