dsh-mem0-memory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.en.md +270 -0
- package/README.md +272 -0
- package/bin/dsh-mem0-import.mjs +211 -0
- package/bin/dsh-mem0-search.mjs +124 -0
- package/cordis.patch.yml +4 -0
- package/excluded-workspaces.example.json +4 -0
- package/lib/index.js +299 -0
- package/package.json +38 -0
- package/scripts/.env.example +22 -0
- package/scripts/excluded-workspaces.json +4 -0
- package/scripts/g1-session-parser.mjs +816 -0
- package/scripts/mem0-server.py +743 -0
- package/scripts/setup.py +188 -0
- package/scripts/start-server.bat +47 -0
- package/scripts/start-server.sh +44 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本项目遵循语义化版本(SemVer)。DSH 处于 Developer Preview(rc 系列),
|
|
4
|
+
插件随 DSH rc 发版节奏跟进;破坏性变更记录于此。
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
### 0.1.0(发布候选,待外部审查后发布)
|
|
9
|
+
|
|
10
|
+
- **2026-08-20 定名**:包名由 dsh-mem0-bridge 更名为 **dsh-mem0-memory**(发布前改名,无外部影响;插件 id mem0-memory,与 OpenClaw 侧插件命名一脉相承)。
|
|
11
|
+
|
|
12
|
+
首个公开版本(alpha)。三件套捆绑:插件 + 通用化 server + 导入命令。
|
|
13
|
+
|
|
14
|
+
**能力**:
|
|
15
|
+
- 插件:`agent/pre-step` 同步召回注入(limit/scoreThreshold/timeout/source/probePath/autoImport 全配置化);`session/disposed` 自动增量导入
|
|
16
|
+
- server:hybrid 混合检索(top_k 修复)+ 关键词补捞 topup + embedding 故障降级;G4 source 后置过滤;`/search` `/add` `/import` `/health`
|
|
17
|
+
- G1 解析器:zstd 多帧扫描、两级清洗、user 锚点分组、per-session checkpoint 增量、工作区排除(0_ 前缀 + 名单,fail-closed)
|
|
18
|
+
- `dsh-mem0-import`:`--since-last`(默认)/`--full`/`--session`/`--dry-run`;全部成功才落 checkpoint;锁文件 PID 存活检测
|
|
19
|
+
- setup.py:`--check`/`--init`/`--install` 一键初始化 + .env 模板;start-server.bat/.sh 跨平台启动(健康自检)
|
|
20
|
+
|
|
21
|
+
**内置补丁(monkey-patch,不修改 mem0 安装)**:
|
|
22
|
+
- jieba 中文分词 BM25(×3 引用点:lemmatization/main/scoring)
|
|
23
|
+
- 提取语言 use_input_language=True(中文事实不被翻译成英文)
|
|
24
|
+
- DeepSeek thinking 关闭 + 去 response_format(防 0 事实入库 / v4-flash 空内容)
|
|
25
|
+
- API client 超时 120s
|
|
26
|
+
|
|
27
|
+
**去本机化**:零私有路径/数据/名单残留;API key 走 env/.env;mem0 依赖声明(mem0ai>=2.0)。
|
|
28
|
+
|
|
29
|
+
**已知边界**:DSH rc 破坏性变更未跟踪;mem0 上游 API 变化需跟进;DeepSeek 之外 LLM 未逐一适配。
|
|
30
|
+
|
|
31
|
+
### 上游致谢
|
|
32
|
+
|
|
33
|
+
- 召回后处理逻辑移植自 OpenClaw `mem0-memory` 插件(recall.js)
|
|
34
|
+
- zstd 帧解析移植自 DSH 官方 persistence 源码
|
|
35
|
+
- mem0(MIT)—— 向量记忆库
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-mem0-memory contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# dsh-mem0-memory — DSH conversation memory → mem0 vector store
|
|
2
|
+
|
|
3
|
+
> **🌐 Language**: [中文](README.md) | English
|
|
4
|
+
|
|
5
|
+
> **Status**: alpha (experimental). **In one line**: a DSH plugin + a CLI tool + a local service that automatically stores your DSH conversation memory into a mem0 vector store and recalls it in new sessions — **no more amnesia between conversations**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What problem does it solve
|
|
10
|
+
|
|
11
|
+
Every new DSH session starts with a model that is like an **employee on day one**: the plans you settled yesterday, the preferences you stated repeatedly, the pitfalls you hit last month — it knows none of it, and everything has to be explained from scratch. The longer you use sessions, the heavier this "amnesia tax" becomes — switch sessions and your accumulated context resets to zero.
|
|
12
|
+
|
|
13
|
+
Agent memory is not a new problem, and open source already has a battle-tested answer — **Mem0**: a memory layer built for AI agents that turns "conversation → fact extraction → semantic + keyword retrieval → context injection" into a standard pipeline. It is one of the most popular agent-memory projects on GitHub, and many agent products are built directly on it. We chose it because the path is proven and the ecosystem keeps evolving — **we don't need to reinvent memory, we just need to install it into DSH properly**.
|
|
14
|
+
|
|
15
|
+
**dsh-mem0-memory — a DSH memory plugin with deep Mem0 integration, built for the Chinese ecosystem**: it plugs mem0 memory into the DSH conversation loop and manages your conversation memory:
|
|
16
|
+
|
|
17
|
+
- **No more amnesia**: new sessions automatically carry relevant memories, no manual lookup
|
|
18
|
+
- **Chinese works out of the box**: jieba tokenization + Chinese fact extraction, precise Chinese keyword matching
|
|
19
|
+
- **Data stays on your machine**: fully local; in the most privacy-sensitive scenario it can run completely offline
|
|
20
|
+
|
|
21
|
+
Diagram:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Your DSH sessions (raw logs)
|
|
25
|
+
↓ memory ingestion
|
|
26
|
+
↓
|
|
27
|
+
mem0 vector store (Qdrant + SQLite, semantic search)
|
|
28
|
+
↑ auto-recall search results before each turn
|
|
29
|
+
Your new session (answers with recalled memories)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What it looks like after installation
|
|
33
|
+
|
|
34
|
+
**Before installation**, a fresh session asks:
|
|
35
|
+
|
|
36
|
+
> What exactly was that rule about "diagnose first, weigh options, get confirmation" I mentioned last time?
|
|
37
|
+
|
|
38
|
+
DSH answers: *Sorry, no relevant record in this conversation...*
|
|
39
|
+
|
|
40
|
+
**After installation**, the same question:
|
|
41
|
+
|
|
42
|
+
DSH automatically injects `<relevant-memories>` (a few related memories recalled from mem0) before replying, then answers accurately — it can even proactively cite last time's conclusions and lessons. Below is a **real recall transcript** (2026-08-20, content anonymized) — what gets injected for the query "diagnose first, weigh options, get confirmation before changing":
|
|
43
|
+
|
|
44
|
+
```xml
|
|
45
|
+
<relevant-memories>
|
|
46
|
+
The following memories were recalled from the Mem0 long-term memory store. Refer to them when answering the user's question.
|
|
47
|
+
<memory id="c445c0d1-...">The user decided not to rush changes to the plan document; align on the approach first.</memory>
|
|
48
|
+
<memory id="2a47dd0d-...">The user explicitly required: diagnose the problem first, present options, wait for confirmation before changing, and report what changed afterwards — never change things silently.</memory>
|
|
49
|
+
<memory id="736895ad-...">The user's preference "taking an extra step without confirmation even when the direction is right" was recorded as a signal to correct.</memory>
|
|
50
|
+
</relevant-memories>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The three memories rank in decreasing relevance (0.84 → 0.83 → 0.37) — hybrid retrieval injects by relevance, weak matches are still surfaced but ranked last, and the LLM decides what to use. This is a real recall from the actual memory store (anonymized), not a fabricated demo.
|
|
54
|
+
|
|
55
|
+
**Core capabilities**:
|
|
56
|
+
1. **Hybrid retrieval** — semantic vectors + BM25 keywords **fused and ranked together**: related meanings hit (vectors), exact names/IDs/paths hit (keywords); neither replaces the other
|
|
57
|
+
2. **Cross-session sharing** — all sessions write to the same memory store; a conclusion in session A is available in session B
|
|
58
|
+
3. **Automatic injection** — recall runs automatically before every real turn, zero manual work
|
|
59
|
+
4. **Incremental import** — only new messages are processed, no re-burning of tokens (per-session checkpoint)
|
|
60
|
+
5. **Workspace isolation** — workspaces whose names start with `0_` are never ingested (anti-pollution convention)
|
|
61
|
+
|
|
62
|
+
> Plain-language version: traditional retrieval is **matching words** (exact keyword match), while mem0 is **matching meaning** (semantic vectors) + **matching words** (keywords) on two channels — so even if you forgot the exact wording ("that conclusion from last time"), something semantically close still gets retrieved.
|
|
63
|
+
|
|
64
|
+
## Requirements (check before installing)
|
|
65
|
+
|
|
66
|
+
| Item | Requirement | Notes |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| DeepSeek Harness | rc.6+ (Developer Preview) | plugin host |
|
|
69
|
+
| Node.js | **≥ 23** (G1 tool uses node:zlib native zstd) | same install as DSH; check `node --version` |
|
|
70
|
+
| Python | 3.10+ | mem0 runtime |
|
|
71
|
+
| LLM API Key | DeepSeek (or any OpenAI-compatible) | fact extraction (memory ingestion) |
|
|
72
|
+
| Embedding API Key | any vector model service (Qwen, Jina, or any OpenAI-compatible endpoint); **local vector models also supported** (e.g. Ollama + bge-m3, zero API cost) | vectorization (memory retrieval) |
|
|
73
|
+
| Disk | ~1GB+ | memory store (vectors + history) |
|
|
74
|
+
|
|
75
|
+
> What you do **not** need: no GPU, no Docker, no self-hosted Qdrant server (local embedded mode), **no Mem0 cloud service**, **no pre-installed mem0** (the mem0 library and its dependencies are installed automatically by setup steps ②/④).
|
|
76
|
+
|
|
77
|
+
### Architecture in one sentence: a mem0 "custom-built machine" for DSH, with a setup service included
|
|
78
|
+
|
|
79
|
+
| Actual component | Metaphor | Notes |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| mem0 open-source library | Motherboard | official standard part, stable and reliable |
|
|
82
|
+
| Vector store = **Qdrant local mode** | Hard drive | mem0 supports several vector stores; we picked and configured Qdrant local (zero Docker, pip-installable, data on local disk) |
|
|
83
|
+
| LLM extraction = DeepSeek | CPU | default standard part, swappable with any OpenAI-compatible model |
|
|
84
|
+
| Embedding = Qwen3-8B | RAM | default standard part, recommended for Chinese, swappable with local models |
|
|
85
|
+
| **jieba Chinese tokenization** (BM25 keyword channel) | Chinese IME (custom part) | Chinese customization — stock mem0 is essentially unusable for Chinese keyword search |
|
|
86
|
+
| **G1 parser** (DSH sessions → memory batches) | Dedicated data interface card (custom part) | DSH customization — translates DSH conversation logs into memories |
|
|
87
|
+
| Degraded mode + keyword top-up + retrieval fixes | Circuit breaker (custom part) | custom retrieval hardening — offline recall even when the embedding model fails |
|
|
88
|
+
|
|
89
|
+
**A "full machine" needs every part — monitor, display, keyboard/mouse — or the whole thing is a paperweight**: the value loop (conversation → memory → retrieval → injection → conversation) is broken if any link is missing. That is also this project's delivery shape: **plugin + local service + dependency manifest, bundled as a three-piece set**.
|
|
90
|
+
|
|
91
|
+
- **Why not just buy the branded machine (Mem0 cloud)?**: ① you can't patch the Chinese fixes into a branded machine (no opening it up) — for Chinese use cases a custom-built machine is the only path that works ② memory data lives on a remote server, not locally ③ it costs money.
|
|
92
|
+
- **Setup service included** — one command installs every part (`setup.py`), and this README documents how to swap each part.
|
|
93
|
+
|
|
94
|
+
### Deployment shape & data sovereignty (important)
|
|
95
|
+
|
|
96
|
+
- **Runs fully local**: the memory store, vector store (Qdrant local), and fact history (SQLite) are all files on your disk — **data never leaves your machine**. The BM25 keyword model is also local (fastembed cache, works offline) — the keyword channel still recalls when the embedding API fails (automatic degradation).
|
|
97
|
+
- **The "mem0 service" is a thin local service shipped with the plugin**: it wraps the open-source mem0 library as HTTP endpoints (`/search` `/add` `/import` `/health`) — not an official cloud service, no dependency on Mem0 Cloud.
|
|
98
|
+
- **Only two outbound API calls**: ① LLM API (DeepSeek or any OpenAI-compatible, for fact extraction during ingestion) ② Embedding API (any vector model service). **Both can be swapped for local models** (e.g. Ollama + bge-m3 embedding, local LLM) — the most privacy-sensitive setup can be **fully offline**.
|
|
99
|
+
- **Chinese support**: works out of the box (see "Built-in patches" below).
|
|
100
|
+
|
|
101
|
+
## Quick install (~15-25 minutes first time)
|
|
102
|
+
|
|
103
|
+
> 5 steps total: **install plugin → install parts → set keys → power on → boot** (in machine terms: ① monitor + keyboard/mouse ② parts ③ power cable ④ chassis ⑤ power on). The slow parts are only the first model downloads in steps 2 and 4 — that's "waiting for a download", not hands-on work.
|
|
104
|
+
|
|
105
|
+
### Step 1: Install the plugin (pick one, ~1-2 min)
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
dsh plugin --profile web add github:kittitys/dsh-mem0-memory # GitHub source (recommended)
|
|
109
|
+
# or
|
|
110
|
+
dsh plugin --profile web add dsh-mem0-memory # npm source
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Step 2: Install dependencies (~5-10 min, mostly the embedding model download)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install mem0ai qdrant-client fastembed jieba flask
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Step 3: Set API keys (~1 min)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
export MEM0_LLM_API_KEY=xxx # LLM API, fact extraction (memory ingestion)
|
|
123
|
+
export MEM0_EMBEDDING_API_KEY=xxx # embedding API, vectorization
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> Keys can also go into a `.env` file at the project root (template: `scripts/.env.example`).
|
|
127
|
+
|
|
128
|
+
### Step 4: Initialize and start the memory service (~3-5 min, first run includes model download)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Enter the plugin directory first (npm install location: $DSH_HOME/profiles/web/node_modules/dsh-mem0-memory/)
|
|
132
|
+
cd "$DSH_HOME/profiles/web/node_modules/dsh-mem0-memory"
|
|
133
|
+
python scripts/setup.py --init --install # install deps + create the store
|
|
134
|
+
python scripts/mem0-server.py --port 18200 # start the service
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
> Windows users can use the bundled `scripts/start-server.bat`; consider registering it to auto-start on login.
|
|
138
|
+
|
|
139
|
+
### Step 5: Restart to activate (~2 min)
|
|
140
|
+
|
|
141
|
+
The plugin's own `cordis.patch.yml` is **merged into the profile configuration automatically** at install time (no need to add an enable entry manually). To tune parameters (e.g. memories injected per turn), append an override entry to `$DSH_HOME/profiles/web/cordis.patch.yml`:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
- id: mem0-memory
|
|
145
|
+
config:
|
|
146
|
+
limit: 5 # max memories injected per turn (default 5)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Then restart the DSH web profile (plugins have no hot reload) — **done ✅**
|
|
150
|
+
|
|
151
|
+
> After the restart, **run the first import once (next section)** and your history is in the memory store — from then on it's automatic and incremental, nothing else to manage.
|
|
152
|
+
>
|
|
153
|
+
> **Peer dependency warnings are safe to ignore**: pnpm may print `missing peer @deepseek-ai/cordis` / `@deepseek-ai/dsh-agent-loop` during install — this is a declarative warning; at runtime the plugin resolves these from the DSH bundle installation, nothing to do.
|
|
154
|
+
|
|
155
|
+
## First import: load your historical sessions into the memory store
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Incremental import (default; reads checkpoint; first run is automatically full)
|
|
159
|
+
dsh-mem0-import --since-last
|
|
160
|
+
# Common variants:
|
|
161
|
+
# --full full re-import (ignores checkpoint)
|
|
162
|
+
# --session <file> import only a specific session
|
|
163
|
+
# --dry-run show stats without writing anything
|
|
164
|
+
# --server <url> custom mem0-server address
|
|
165
|
+
# --dsh-home <dir> custom DSH data root (default $DSH_HOME)
|
|
166
|
+
# (After npm install, dsh-mem0-import is a global command; from a source checkout use the full path
|
|
167
|
+
# node <package-dir>/bin/dsh-mem0-import.mjs, same arguments)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The first full import calls the LLM for fact extraction (token-billed; roughly a few cents to a few dollars per thousand sessions); after that, incremental imports are handled by the three-tier mechanism (below) with no manual management.
|
|
171
|
+
|
|
172
|
+
> **Can I skip the manual first import?** Yes — when the first session ends (dispose), auto-import runs a full import because there is no checkpoint yet. But note: **web sessions live a long time**, and dispose usually only happens on process exit/restart — meanwhile the store stays empty (your first conversation only enters the store when that session ends). **A manual first import is recommended** (the one command above) for immediate effect; after that it's fully automatic.
|
|
173
|
+
|
|
174
|
+
> **How long does the first import take?** Experience: **~1-2 min per batch** (vectorization + LLM fact extraction). New users (few historical sessions) ~**10-30 min**; heavy history (dozens of sessions) ~**1 hour+**. The biggest variable is API state — flaky vector/extraction APIs can double the time (just re-run later to resume). Interruptions are not scary: re-running only repeats the interrupted batch (mem0 hash dedup catches it), not from scratch.
|
|
175
|
+
|
|
176
|
+
## Daily use (invisible context injection while chatting)
|
|
177
|
+
|
|
178
|
+
- **During conversations**: the plugin recalls and injects automatically (~5-10s per turn, configurable skip)
|
|
179
|
+
- **Memory ingestion: three tiers, zero config by default** —
|
|
180
|
+
- **① Auto (default)**: incremental import when the session ends (plugin hooks `session/disposed`, only processes messages since the last import, no repeated token burn)
|
|
181
|
+
- **② Manual**: sync anytime with one command: `dsh-mem0-import --since-last` (command name works directly after npm install)
|
|
182
|
+
- **③ Scheduled** (advanced): for a fixed cadence, use your OS scheduler (Windows Task Scheduler / cron / systemd timer) to run `dsh-mem0-import --since-last`
|
|
183
|
+
- **Tuning / inspecting config**: edit the `config` section in `$DSH_HOME/profiles/web/cordis.patch.yml` (see Step 5); to see the full composed configuration, use `dsh --profile web --dump-config`
|
|
184
|
+
|
|
185
|
+
> **Note**: this project only imports "in-conversation memory" (your DSH sessions); it does not process SESSION-STATE / other persistent files (e.g. USER, IDENTITY).
|
|
186
|
+
|
|
187
|
+
## Active search (query your memory like a search engine)
|
|
188
|
+
|
|
189
|
+
Auto-injection is "memory with no effort"; to **explicitly query** what's in the store, use `dsh-mem0-search` (shares the same store as auto-injection; hybrid/top-up/degraded all available):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
dsh-mem0-search "上次说的消息格式规范" # default top 5, all sources
|
|
193
|
+
dsh-mem0-search "项目技术栈" --source DSH --limit 10 # only a specific source
|
|
194
|
+
dsh-mem0-search "8月的决定" --from 2026-08-01 --to 2026-08-31 # date window
|
|
195
|
+
dsh-mem0-search "关键词" --json # raw JSON (script-friendly)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> Date-window queries use scroll + re-rank and normally take 20-60s (plain queries are much faster).
|
|
199
|
+
|
|
200
|
+
## Config reference
|
|
201
|
+
|
|
202
|
+
| Option | Default | Notes |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| `serverUrl` | `http://127.0.0.1:18200` | mem0 service address |
|
|
205
|
+
| `limit` | 5 | max memories injected per turn |
|
|
206
|
+
| `scoreThreshold` | 0.15 | relevance threshold (below → not injected) |
|
|
207
|
+
| `timeoutMs` | 20000 | recall timeout (on timeout, skip recall — conversation unaffected, only this turn's injected results are missing) |
|
|
208
|
+
| `source` | (empty) | recall only a specific source (multi-source setups) |
|
|
209
|
+
| `probePath` | (empty = off) | troubleshooting probe log path (only written when set) |
|
|
210
|
+
| `autoImport` | true | auto incremental import at session end (off = manual/scheduled only) |
|
|
211
|
+
|
|
212
|
+
## How it works
|
|
213
|
+
|
|
214
|
+
```mermaid
|
|
215
|
+
flowchart LR
|
|
216
|
+
A[DSH session logs<br/>zstd append-only] -->|G1 parser<br/>clean + extract per turn| B[conversation batches]
|
|
217
|
+
B -->|POST /import| C[(mem0 vector store<br/>Qdrant + SQLite)]
|
|
218
|
+
D[new session question] -->|agent/pre-step hook| E[dsh-mem0-memory plugin]
|
|
219
|
+
C -->|hybrid retrieval<br/>dense semantic + BM25 keywords| E
|
|
220
|
+
E -->|inject relevant-memories| F[LLM answer]
|
|
221
|
+
F -->|session end dispose| A
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Mechanism details (ingestion, recall, incremental, anti-pollution) live in the feature sections above and the source (`lib/`, `bin/`, `scripts/`).
|
|
225
|
+
|
|
226
|
+
### Built-in patches (key customized capabilities, applied as patches)
|
|
227
|
+
|
|
228
|
+
The capabilities in the diagram — "hybrid retrieval", "Chinese support" — are delivered as **four patches**, applied automatically when the server starts:
|
|
229
|
+
|
|
230
|
+
> All customizations are applied via **monkey-patch (runtime replacement)** — **no files in the mem0 installation are modified**, `pip install -U mem0ai` upgrades won't lose the patches, and uninstalling the plugin leaves no trace. Any patch failure degrades gracefully (WARN log), conversations and imports are unaffected.
|
|
231
|
+
>
|
|
232
|
+
> Of the four patches, **the first three together make Chinese work out of the box**: jieba covers the **retrieval side** (Chinese keywords hit), extraction language keeps facts in Chinese on the **write side**, and the DeepSeek patch keeps the **extraction side** from spinning uselessly.
|
|
233
|
+
|
|
234
|
+
<details>
|
|
235
|
+
<summary>Patch details (click to expand)</summary>
|
|
236
|
+
|
|
237
|
+
| Patch | What it does | If it fails (WARN degradation only) |
|
|
238
|
+
|---|---|---|
|
|
239
|
+
| **jieba Chinese tokenization** (`lemmatize_for_bm25` ×3 call sites) | mem0's default spaCy English tokenizer fails on Chinese (continuous Chinese has almost no tokens under SPLADE encoding → the BM25 keyword channel is crippled). With jieba, both the **write side** (fact `text_lemmatized`) and the **query side** tokenize correctly, so Chinese keywords (proper nouns/IDs/paths) hit exactly across hybrid/top-up/degraded channels | Chinese keyword retrieval degrades (semantic retrieval still works) |
|
|
240
|
+
| **Extraction language** (`use_input_language=True`) | mem0 by default extracts facts into **English** — Chinese conversations get translated into English facts, breaking Chinese keyword retrieval. Forcing input-language extraction (Language Requirement section appended to prompt) | Facts extracted in English (cross-lingual semantic recall still works) |
|
|
241
|
+
| **DeepSeek patch** (thinking off + no response_format) | New DeepSeek models burn max_tokens on thinking by default (`finish_reason=length, content=""`) → mem0 silently ingests 0 facts; and v4-flash returns empty content on json_object + long prompts. Forcing it off makes mechanical extraction faster, cheaper, and always productive | DeepSeek users may extract 0 facts (no impact with other LLMs) |
|
|
242
|
+
| **API timeout** (embedding/deepseek 120s) | The official client sets no timeout; a hung API can block request threads | None (only prevents hangs) |
|
|
243
|
+
|
|
244
|
+
</details>
|
|
245
|
+
|
|
246
|
+
## Limitations & FAQ
|
|
247
|
+
|
|
248
|
+
| Question | Answer |
|
|
249
|
+
|---|---|
|
|
250
|
+
| How much slower will each reply be after install? | Measured: ~5-10s per turn for recall (synchronous injection). Occasional cold-start turns may exceed 15s. Set `timeoutMs` or disable the plugin for manual recall only |
|
|
251
|
+
| What if the embedding API goes down? | **The hybrid channel degrades automatically to keyword-only**: BM25 search is a local model (works offline), recall falls back to pure keyword matching with a `degraded` flag; if that also fails, recall is skipped for this turn and conversation continues unaffected |
|
|
252
|
+
| **How do the mem0 service and DSH relate? Are they independent?** | **Two completely independent processes**: DSH = Node process (conversation + plugin host); mem0 service = separate Python process (HTTP service, port 18200). Neither needs the other to start; the plugin only calls it over HTTP. **DSH crash/restart doesn't affect mem0**; **mem0 down doesn't affect DSH conversations** (recall is skipped automatically) |
|
|
253
|
+
| Does the mem0 service need to stay running? | Yes — it's the "brain" of memory; keep it running. If it's down: ① recall is skipped on the conversation side (chatting is fully normal, just amnesia across sessions) ② imports fail, that day's memory isn't updated (re-runnable later, no data loss) ③ manual queries error. **Data is never lost** — the store is disk files; the service recovers on restart |
|
|
254
|
+
| Can the memory store leak? | Local Qdrant + SQLite, never leaves the machine; API keys are only used for embedding/LLM extraction calls |
|
|
255
|
+
| Relation to "official memory"? | DSH has no built-in memory yet; this plugin is the community route |
|
|
256
|
+
| Can bad data be written into my session? | Injection follows the DSH message spec (id + content blocks); failed recall skips automatically, sessions are never corrupted |
|
|
257
|
+
| How does "auto incremental import" know where it stopped? | One checkpoint per session (`lastSeq`). No matter how often a session ends, it's never re-processed; a mid-run crash repeats at most one window, absorbed by mem0's exact-hash dedup |
|
|
258
|
+
| Windows support? | Core is cross-platform; bundled scripts work on Windows/Linux (Windows: `scripts/start-server.bat`, Linux/macOS: `scripts/start-server.sh`) |
|
|
259
|
+
| Plugin installed but not working? | ① Confirm `dsh plugin --profile web add` succeeded (plugin is in the profile bundles list) ② server-side plugins have no hot reload — restart DSH web after changes ③ enable `probePath` for probe logs to diagnose |
|
|
260
|
+
|
|
261
|
+
## Project status
|
|
262
|
+
|
|
263
|
+
- Experimental (alpha). Evaluate before production use.
|
|
264
|
+
- Known boundaries: DSH Developer Preview upgrades may break compatibility; mem0 v2 semantics (ADD-only + hash dedup); LLMs other than DeepSeek are not individually adapted (the DeepSeek patch only applies to it).
|
|
265
|
+
- Development history (including incident post-mortems and isolated verification) lives in the project docs; recall post-processing is ported from the OpenClaw `mem0-memory` plugin; zstd frame parsing is ported from DSH's official persistence source.
|
|
266
|
+
- **Feedback**: issues / PRs welcome (GitHub Issues). Updates may be slow, but recall quality and install issues get priority — the pits you hit are our tests.
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT (see LICENSE). *This project is not affiliated with DeepSeek.*
|
package/README.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# dsh-mem0-memory — DSH 会话记忆 → mem0 向量库
|
|
2
|
+
|
|
3
|
+
> **🌐 语言/Language**: 中文 | [English](README.en.md)
|
|
4
|
+
|
|
5
|
+
> **状态**:alpha(实验性质)。**一句话**:一个 DSH 插件 + 一个命令行工具 + 一个本地服务,把你的 DSH 对话记忆自动存进 mem0 向量库,并在新会话里自动召回——**换对话不再失忆**。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 解决什么问题
|
|
10
|
+
|
|
11
|
+
DSH 的每个新会话,模型都像**第一天上班**:昨天敲定的方案、反复强调的偏好、踩过的坑,它一概不知,一切从头解释。会话用得越久,这笔「失忆税」越明显——换一个会话,之前的积累全部归零。
|
|
12
|
+
|
|
13
|
+
Agent 记忆不是新问题,开源社区早有被大规模验证的答案——**Mem0**:专为 AI Agent 设计的记忆层,把「对话 → 事实提取 → 语义+关键词检索 → 上下文注入」整条链路做成标准件,是 GitHub 上最流行的 agent memory 项目之一,大量 agent 产品直接基于它构建。选它,是因为这条路被验证过、生态持续演进——**我们不需要重新发明记忆,只需要把它正确地装进 DSH**。
|
|
14
|
+
|
|
15
|
+
**dsh-mem0-memory——深度集成 Mem0、面向中文生态的 DSH 记忆插件**:把 mem0 记忆能力接入 DSH 对话循环,管理你的会话记忆:
|
|
16
|
+
|
|
17
|
+
- **换对话不失忆**:新会话自动带上相关记忆,不用手动查
|
|
18
|
+
- **中文开箱即用**:jieba 分词 + 中文事实提取,中文关键词精确命中
|
|
19
|
+
- **数据不出机器**:全本地运行,极致隐私场景可完全离线
|
|
20
|
+
|
|
21
|
+
示意图:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
你的 DSH 会话(原始日志)
|
|
25
|
+
↓ 记忆入库
|
|
26
|
+
↓
|
|
27
|
+
mem0 向量记忆库(Qdrant + SQLite,语义检索)
|
|
28
|
+
↑ 每轮对话前自动召回搜索结果
|
|
29
|
+
你的新会话(自动带上召回记忆回答问题)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 安装后的效果
|
|
33
|
+
|
|
34
|
+
**安装前**,新会话提问:
|
|
35
|
+
|
|
36
|
+
> 我上次说的那个「先诊断、多方案对比、确认后再怎样怎样」的规矩具体是怎么回事来着?
|
|
37
|
+
|
|
38
|
+
DSH 答:*抱歉,这个对话里没有相关记录……*
|
|
39
|
+
|
|
40
|
+
**安装后**,同样的问题:
|
|
41
|
+
|
|
42
|
+
DSH 会在回复前自动注入 `<relevant-memories>`(从 mem0 召回的数条相关记忆),然后给出准确回答,甚至能主动引用上次的结论和教训。下面是**真实召回实录**(2026-08-20,内容已脱敏)——查询「动手前先诊断、多方案对比、确认后再改」时注入的内容:
|
|
43
|
+
|
|
44
|
+
```xml
|
|
45
|
+
<relevant-memories>
|
|
46
|
+
以下是从 Mem0 长期记忆中召回的相关记忆,优先参考这些内容回答用户问题。
|
|
47
|
+
<memory id="c445c0d1-...">用户决定不急着修改方案文档,先对齐方案再动手。</memory>
|
|
48
|
+
<memory id="2a47dd0d-...">用户明确要求:助手必须先诊断问题、给出多方案对比、等用户确认再改,改完告知变更内容,不准悄无声息地改。</memory>
|
|
49
|
+
<memory id="736895ad-...">用户偏好「方向对但未经确认就多走一步」被记录为待修正信号。</memory>
|
|
50
|
+
</relevant-memories>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
三条记忆相关度依次递减(0.84 → 0.83 → 0.37)——混合检索按相关度排序注入,弱相关也带出但排在末尾,由 LLM 自行取舍。以上内容来自真实记忆库(脱敏),非虚构演示。
|
|
54
|
+
|
|
55
|
+
**核心能力**:
|
|
56
|
+
1. **混合检索召回**——语义向量 + 关键词 BM25 **双通道融合排序**:意思相近能命中(向量),名字/ID/路径精确命中(关键词),互不替代
|
|
57
|
+
2. **跨会话共享**——所有会话写同一个记忆库,A 会话的结论在 B 会话可用
|
|
58
|
+
3. **自动注入**——每轮真实对话前自动召回,零手动操作
|
|
59
|
+
4. **增量导入**——只处理新增消息,不重复烧 token(per-session checkpoint)
|
|
60
|
+
5. **工作区隔离**——名字以 `0_` 开头的工作区自动不入库(防污染约定)
|
|
61
|
+
|
|
62
|
+
> 通俗版:传统检索是**按字找**(关键词精确匹配),mem0 是**按意思找**(语义向量)+ **按词找**(关键词)双通道——哪怕你忘了原话(「上次那个啥结论」),意思相近也能被捞回来。
|
|
63
|
+
|
|
64
|
+
## 基础要求(安装前请确认)
|
|
65
|
+
|
|
66
|
+
| 项 | 要求 | 说明 |
|
|
67
|
+
| ----------------- | --------------------------------------------------------------------------- | ------------------------------ |
|
|
68
|
+
| DeepSeek Harness | rc.6+(Developer Preview) | 插件宿主 |
|
|
69
|
+
| Node.js | **≥ 23**(G1 工具用 node:zlib 原生 zstd) | 与 DSH 同装即可,检查 `node --version` |
|
|
70
|
+
| Python | 3.10+ | mem0 运行环境 |
|
|
71
|
+
| LLM API Key | DeepSeek(或任意 OpenAI 兼容) | 用于事实提取(记忆入库) |
|
|
72
|
+
| Embedding API Key | 任意向量模型服务(千问、Jina,或任意 OpenAI 兼容端点);**也兼容本地向量模型**(如 Ollama + bge-m3,零 API 成本) | 用于向量化(记忆检索) |
|
|
73
|
+
| 磁盘 | ~1GB+ | 记忆库(向量 + 历史) |
|
|
74
|
+
|
|
75
|
+
> 不需要的东西:不需要 GPU、不需要 Docker、不需要自建 Qdrant server(用本地嵌入式模式)、**不需要任何 Mem0 云服务**、**不需要预装 mem0**(mem0 库及其依赖由**安装步骤②/④自动安装**)。
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
### 一句话架构:这是一台专门用于 DSH 的 mem0 定制化「组装机」+ 搭配装机服务
|
|
79
|
+
|
|
80
|
+
| 实际部件 | 比喻 | 说明 |
|
|
81
|
+
| -------------------------- | ------------ | -------------------------------------------------------------- |
|
|
82
|
+
| mem0 开源库 | 主板 | 官方标准件,稳定可靠 |
|
|
83
|
+
| 向量库 = **Qdrant 本地模式** | 硬盘 | mem0 支持多家向量库,我们选定并配置好 Qdrant local(优势:零 Docker、pip 即用、数据在本地磁盘) |
|
|
84
|
+
| LLM 提取 = DeepSeek | 处理器 | 默认标准件,可换任意 OpenAI 兼容模型 |
|
|
85
|
+
| Embedding = Qwen3-8B | 内存条 | 默认标准件,中文效果推荐配置,可换本地模型 |
|
|
86
|
+
| **jieba 中文分词**(BM25 关键词通道) | 中文输入法(定制件) | 中文定制化——mem0 原版对中文关键词搜索基本不可用 |
|
|
87
|
+
| **G1 解析器**(DSH 会话 → 记忆批次) | 专属数据接口卡(定制件) | DSH 定制化——把 DSH 的对话日志翻译成记忆 |
|
|
88
|
+
| 降级模式 + 关键词补捞 + 检索修复 | 电路保护器(定制件) | 定制化检索增强——embedding 模型失效也能离线召回记忆 |
|
|
89
|
+
|
|
90
|
+
**「一整套硬件」主机、显示器、键鼠缺一不可**——价值闭环(对话 → 记忆 → 检索 → 注入 → 对话)少一环整机就是摆设。这也是本项目的交付形态:**插件 + 本地服务 + 依赖清单,三件套捆绑**。
|
|
91
|
+
|
|
92
|
+
- **为什么不直接用品牌机(Mem0 云服务)**:① 中文补丁打不进去(品牌机不让拆机),对中文场景组装机是唯一能跑通的路 ② 记忆数据在远程服务器上,非本地 ③ 付费。
|
|
93
|
+
- **随包提供装机服务**——一条命令装好所有部件(`setup.py`),说明书(README)写清楚每个部件怎么换。
|
|
94
|
+
|
|
95
|
+
### 部署形态与数据主权(重要)
|
|
96
|
+
|
|
97
|
+
- **全部本地运行**:记忆库、向量库(Qdrant local)、事实历史(SQLite)都是用户磁盘上的文件——**数据不出机器**。BM25 关键词模型也是本地模型(fastembed 缓存,离线可用)——embedding API 故障时关键词通道仍可召回(自动降级)。
|
|
98
|
+
- **「mem0 服务」= 插件自带的本地薄服务**:把开源 mem0 库包装成 HTTP 端点(`/search` `/add` `/import` `/health`),不是官方云服务,也不依赖 Mem0 Cloud。
|
|
99
|
+
- **出网仅两个 API 调用**:① LLM API(DeepSeek 或任意 OpenAI 兼容,用于记忆入库时的事实提取)② Embedding API(任意向量模型服务)。**两者都可换本地模型**(如 Ollama + bge-m3 embedding、本地 LLM)——极致隐私场景可以做到**完全不出网**。
|
|
100
|
+
- **中文支持**:开箱即用(见下方「内置补丁」)。
|
|
101
|
+
|
|
102
|
+
## 快速安装(首次约 15-25 分钟)
|
|
103
|
+
|
|
104
|
+
> 一共 5 步:**装插件 → 装零件 → 配密钥 → 开机 → 通电**(对应组装机:① 显示器+键鼠 ② 零件 ③ 电源线 ④ 主机 ⑤ 通电)。慢的只有步骤 2 和步骤 4 的首次模型下载——那是「等下载」,不是操作。
|
|
105
|
+
|
|
106
|
+
### 步骤 1:安装插件(二选一,约 1-2 分钟)
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
dsh plugin --profile web add github:kittitys/dsh-mem0-memory # GitHub 源(推荐)
|
|
110
|
+
# 或
|
|
111
|
+
dsh plugin --profile web add dsh-mem0-memory # npm 源
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 步骤 2:装依赖(约 5-10 分钟,主要花在搜索模型下载)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pip install mem0ai qdrant-client fastembed jieba flask
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 步骤 3:配密钥(约 1 分钟)
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
export MEM0_LLM_API_KEY=xxx # LLM API,负责提取(记忆入库)
|
|
124
|
+
export MEM0_EMBEDDING_API_KEY=xxx # embedding API,负责向量化
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
> 密钥也可以写入项目根 `.env`(模板见 `scripts/.env.example`)。
|
|
128
|
+
|
|
129
|
+
### 步骤 4:初始化并启动记忆服务(约 3-5 分钟,首次含模型下载)
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# 先进入插件目录(npm 安装位置:$DSH_HOME/profiles/web/node_modules/dsh-mem0-memory/)
|
|
133
|
+
cd "$DSH_HOME/profiles/web/node_modules/dsh-mem0-memory"
|
|
134
|
+
python scripts/setup.py --init --install # 装依赖 + 建库
|
|
135
|
+
python scripts/mem0-server.py --port 18200 # 启动服务
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> Windows 用户可直接用随附的 `scripts/start-server.bat`;建议注册开机自启。
|
|
139
|
+
|
|
140
|
+
### 步骤 5:重启生效(约 2 分钟)
|
|
141
|
+
|
|
142
|
+
插件自带的 `cordis.patch.yml` 在安装时会**自动并入** profile 配置(无需手动添加启用条目)。如需调整参数(如每轮注入条数),在 `$DSH_HOME/profiles/web/cordis.patch.yml` 追加覆盖条目:
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
- id: mem0-memory
|
|
146
|
+
config:
|
|
147
|
+
limit: 5 # 每轮注入上下文的搜索条数上限(默认 5)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
然后重启 DSH web profile(插件无热重载)——**完成 ✅**
|
|
151
|
+
|
|
152
|
+
> 重启后,**跑一次首次导入(见下节)**,历史会话就进记忆库了——之后自动增量,不用再管。
|
|
153
|
+
>
|
|
154
|
+
> **peer 依赖警告可忽略**:安装时 pnpm 可能提示 `missing peer @deepseek-ai/cordis` / `@deepseek-ai/dsh-agent-loop`——这是声明性警告,插件运行时会从 DSH 的 bundle 安装处解析这些依赖,无需处理。
|
|
155
|
+
|
|
156
|
+
## 首次导入:把你的历史会话装进记忆库
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# 增量导入(默认,读 checkpoint;首次自动全量)
|
|
160
|
+
dsh-mem0-import --since-last
|
|
161
|
+
# 常用变体:
|
|
162
|
+
# --full 全量重导(忽略 checkpoint)
|
|
163
|
+
# --session <file> 只导指定 session
|
|
164
|
+
# --dry-run 先看统计不落盘
|
|
165
|
+
# --server <url> 自定义 mem0-server 地址
|
|
166
|
+
# --dsh-home <dir> 自定义 DSH 数据根(默认 $DSH_HOME)
|
|
167
|
+
# (npm 安装后 dsh-mem0-import 为全局命令;源码方式安装时用完整路径
|
|
168
|
+
# node <包目录>/bin/dsh-mem0-import.mjs,参数相同)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
首次全量导入会调用 LLM 提取事实(按 token 计费,千条会话约几毛~几块钱量级);之后的增量交给三档机制(见下),不需要手动管理。
|
|
172
|
+
|
|
173
|
+
> **可以不手动跑首次导入吗?** 可以——第一次会话结束时(dispose),自动导入会因为没有 checkpoint 而自动全量。但注意:**Web 会话是长期存活的**,dispose 通常要等进程退出/重启——期间记忆库是空的(你第一段对话的内容要等这段对话结束后才进库)。**建议首次手动跑一次**(上面一条命令),立即生效;之后全自动。
|
|
174
|
+
|
|
175
|
+
> **首轮导入要多久?** 经验值:**每批约 1-2 分钟**(含向量化 + LLM 事实提取)。新用户(历史会话不多)约 **10-30 分钟**;历史会话很多(几十个)约 **1 小时+**。最大变量是 API 状态——向量/提取 API 服务抽风时耗时可能翻倍(可稍后重跑续传)。中断不可怕:重跑只会重复断点那一批(mem0 hash 去重兜底),不是从头再来。
|
|
176
|
+
|
|
177
|
+
## 日常使用(对话过程中无感注入记忆上下文)
|
|
178
|
+
|
|
179
|
+
- **对话时**:插件自动召回注入(每轮 ~5-10 秒,可配置跳过)
|
|
180
|
+
- **记忆入库:三档机制,默认零配置**——
|
|
181
|
+
- **① 自动(默认)**:会话结束时自动增量导入新消息(插件挂 `session/disposed` 钩子,只处理上次导入后的增量,不重复烧 token)
|
|
182
|
+
- **② 手动**:任何时候想同步,一条命令:`dsh-mem0-import --since-last`(npm 安装后可直接用命令名)
|
|
183
|
+
- **③ 定时**(进阶):想要固定节奏,用系统定时任务(Windows 任务计划 / cron / systemd timer)定时跑 `dsh-mem0-import --since-last` 即可
|
|
184
|
+
- **调参/查看配置**:改 `$DSH_HOME/profiles/web/cordis.patch.yml` 里的 `config` 段(见步骤 5);想看成稿后的完整合成配置,用 `dsh --profile web --dump-config`
|
|
185
|
+
|
|
186
|
+
> **说明**:本项目只导入「对话内记忆」(你的 DSH 会话),不处理 SESSION-STATE / 其他持久性文件(如USER、IDENTITY 等)。
|
|
187
|
+
|
|
188
|
+
## 主动搜索(像用搜索引擎一样主动查记忆)
|
|
189
|
+
|
|
190
|
+
自动注入是「无感带记忆」;想**明确查**记忆库里有什么时,用 `dsh-mem0-search`(与自动注入共用同一个记忆库,混合检索/补捞/降级全能力都在):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
dsh-mem0-search "上次说的消息格式规范" # 默认 top 5,全部来源
|
|
194
|
+
dsh-mem0-search "项目技术栈" --source DSH --limit 10 # 只搜指定来源
|
|
195
|
+
dsh-mem0-search "8月的决定" --from 2026-08-01 --to 2026-08-31 # 日期窗口
|
|
196
|
+
dsh-mem0-search "关键词" --json # 原始 JSON(脚本友好)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> 日期窗口查询走 scroll + 重排,耗时 20-60s 属正常(普通查询远快于此)。
|
|
200
|
+
|
|
201
|
+
## 可配置参数表
|
|
202
|
+
|
|
203
|
+
| 配置项 | 默认 | 说明 |
|
|
204
|
+
| ---------------- | ------------------------ | ----------------------------------- |
|
|
205
|
+
| `serverUrl` | `http://127.0.0.1:18200` | 标准 mem0 服务地址 |
|
|
206
|
+
| `limit` | 5 | 每轮注入记忆条数上限 |
|
|
207
|
+
| `scoreThreshold` | 0.15 | 相关度阈值(低于则不注入) |
|
|
208
|
+
| `timeoutMs` | 20000 | 召回超时(超时自动跳过,不影响对话推进,只影响本轮回答的搜索结果注入) |
|
|
209
|
+
| `source` | (空) | 只召回指定来源(多源场景) |
|
|
210
|
+
| `probePath` | (空=关) | 排障探针日志文件路径(设置后才写文件) |
|
|
211
|
+
| `autoImport` | true | 会话结束自动增量导入(关 = 只用手动/定时) |
|
|
212
|
+
|
|
213
|
+
## 工作原理
|
|
214
|
+
|
|
215
|
+
```mermaid
|
|
216
|
+
flowchart LR
|
|
217
|
+
A[DSH 会话日志<br/>zstd append-only] -->|G1 解析器<br/>清洗+按轮提取| B[对话批次]
|
|
218
|
+
B -->|POST /import| C[(mem0 向量库<br/>Qdrant + SQLite)]
|
|
219
|
+
D[新会话提问] -->|agent/pre-step 钩子| E[dsh-mem0-memory 插件]
|
|
220
|
+
C -->|混合检索<br/>dense 语义 + BM25 关键词| E
|
|
221
|
+
E -->|注入 relevant-memories| F[LLM 回答]
|
|
222
|
+
F -->|会话结束 dispose| A
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
写入、召回、增量、防污染等机制细节见各功能章节与源码(`lib/`、`bin/`、`scripts/`)。
|
|
226
|
+
|
|
227
|
+
### 内置补丁模式(关键定制化功能点以补丁方式生效)
|
|
228
|
+
|
|
229
|
+
流程图里的「混合检索」「中文支持」等能力,落地为**四个补丁**,在 server 启动时自动应用:
|
|
230
|
+
|
|
231
|
+
> 所有定制都以 **monkey-patch(运行时替换)** 方式应用——**不修改 mem0 安装目录的任何文件**,`pip install -U mem0ai` 升级不会丢失补丁,卸载插件不留痕迹。任何补丁应用失败都只降级不中断(日志 WARN),对话/导入不受影响。
|
|
232
|
+
>
|
|
233
|
+
> 四个补丁中,**前三个共同构成「中文开箱即用」能力**:jieba 保证**检索侧**中文关键词可命中,提取语言保证**写入侧**事实保持中文,DeepSeek 补丁保证**提取侧**不空转。
|
|
234
|
+
|
|
235
|
+
<details>
|
|
236
|
+
<summary>四个补丁明细(点击展开)</summary>
|
|
237
|
+
|
|
238
|
+
| 补丁 | 作用 | 失败后果(仅 WARN 降级) |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| **jieba 中文分词**(`lemmatize_for_bm25` ×3 引用点) | mem0 默认 spaCy 英文分词对中文失效(连续中文在 SPLADE 编码下几乎无 token,BM25 关键词通道残废)。替换为 jieba 后:**写入侧**(事实的 `text_lemmatized`)与**查询侧**都正确分词,中文关键词(专有名词/ID/路径)在 hybrid/topup/降级全通道精确命中 | 中文关键词检索退化(语义检索仍可用) |
|
|
241
|
+
| **提取语言**(`use_input_language=True`) | mem0 默认把输入内容提取成**英文**事实——中文对话会被 LLM 翻译成英文落库,中文关键词检索随之失效。强制按输入语言提取(prompt 追加 Language Requirement 段) | 事实被提取为英文(语义跨语言检索仍可召回) |
|
|
242
|
+
| **DeepSeek 补丁**(thinking 关闭 + 去 response_format) | DeepSeek 新模型默认 thinking 会把 max_tokens 全部烧在推理上(`finish_reason=length, content=""`)→ mem0 静默视为 0 事实入库;且 v4-flash 在 json_object+长 prompt 下返回空内容。强制关闭后机械提取任务更快更省且必有产出 | DeepSeek 用户提取可能 0 事实(换其他 LLM 无影响) |
|
|
243
|
+
| **API 超时**(embedding/deepseek 120s) | 官方不设 client 超时,API 长时间无响应会拖住请求线程 | 无(仅防挂起) |
|
|
244
|
+
|
|
245
|
+
</details>
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
## 限制及 FAQ
|
|
249
|
+
|
|
250
|
+
| 问题 | 回答 |
|
|
251
|
+
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
252
|
+
| 安装后每轮对话回复会慢多少? | 实测召回日常约 5-10 秒/轮(同步注入)。偶尔冷启动轮次可能超过15 秒。可设 `timeoutMs` 或关闭插件按需手动召回 |
|
|
253
|
+
| Embedding API 挂了会怎样? | **混合通道自动降级为纯关键词通道**:BM25 搜索是本地模型(离线可用),召回降级为纯关键词匹配并标注 degraded;仍不可用则本次跳过召回,不影响对话 |
|
|
254
|
+
| **mem0 服务和 DSH 是什么关系?独立吗?** | **完全独立的两个进程**:DSH = Node 进程(对话 + 插件宿主);mem0 服务 = 独立 Python 进程(HTTP 服务,端口 18200)。互不依赖对方才能启动,插件只是通过 HTTP 调用它。**DSH 崩溃/重启不影响 mem0**;**mem0 挂了也不影响 DSH 对话**(召回自动跳过) |
|
|
255
|
+
| 需要一直开着 mem0 服务吗? | 是的——它是记忆的「大脑」,建议常开。不开/服务崩溃的后果:① 对话侧召回自动跳过,聊天完全正常(表现为换对话失忆回归)② 导入失败,当日记忆不更新(可后续补跑,不丢数据)③ 手动查询报错。**数据不会丢**——记忆库是磁盘文件,服务重启即恢复 |
|
|
256
|
+
| 记忆库会泄露吗? | 本地 Qdrant + SQLite,不出机器;API Key 仅用于 embedding/LLM提取调用 |
|
|
257
|
+
| 与「官方记忆」什么关系? | DSH 官方无内置记忆;本插件是社区路线 |
|
|
258
|
+
| 会不会把坏数据写进会话? | 注入遵循 DSH 消息规范(id + 块数组),召回失败自动跳过,绝不破坏会话 |
|
|
259
|
+
| 「自动增量导入」是如何实现的? | 每个会话一个 checkpoint(`lastSeq`)。同一会话反复结束多少次都不会重复处理;中途崩溃最多重复一次窗口,由 mem0 精确 hash 去重吸收 |
|
|
260
|
+
| 支持 Windows 吗? | 核心跨平台;随附脚本 Windows/Linux 均可(Windows 用 `scripts/start-server.bat`,Linux/macOS 用 `scripts/start-server.sh`) |
|
|
261
|
+
| 插件装了但没生效? | ① 确认 `dsh plugin --profile web add` 已成功(插件在 profile bundles 清单里)② 服务端插件无热重载——改完必须重启 DSH web ③ `probePath` 开启探针日志可定位 |
|
|
262
|
+
|
|
263
|
+
## 项目状态
|
|
264
|
+
|
|
265
|
+
- 实验性(alpha)。生产环境使用前请自行评估。
|
|
266
|
+
- 已知边界:DSH Developer Preview 版本升级可能破坏兼容;mem0 v2 语义(ADD-only + hash 去重);DeepSeek 之外的 LLM 未逐一适配(DeepSeek 补丁仅对其生效)。
|
|
267
|
+
- 开发过程记录(含事故复盘、隔离验证)见项目文档;召回后处理逻辑移植自 OpenClaw `mem0-memory` 插件;zstd 帧解析移植自 DSH 官方 persistence 源码。
|
|
268
|
+
- **反馈**:欢迎提 issue / PR(GitHub Issues)。更新可能不及时,但会优先处理召回质量问题、安装问题——你踩的坑就是我们的测试。
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
MIT(见 LICENSE)。*This project is not affiliated with DeepSeek.*
|