7.6 KiB
7.6 KiB
OpenClaw 对话和记忆优化初步方案
研究日期:2026-02-17
研究者:Ami + 阿米狗
状态:已实施并上线
背景与目标
OpenClaw 默认配置下存在两个核心痛点:
- 对话 context 超限会直接中断会话,体验割裂
- 记忆搜索被禁用(需要 OpenAI/Gemini/Voyage API key,成本高)
本方案目标:在不依赖任何外部 API key 的前提下,实现:
- 对话 context 的主动管理(不被动等爆)
- 本地向量语义搜索(完全离线)
- 跨会话记忆自动恢复
核心约束
我们假设暂时解决不了对话 context 上限这一概念和顶层限制(200k token 硬上限由模型决定,无法改变)。 因此,所有优化都是在这个硬上限内做最大化利用。
三步方案
Step 1 — Token 优化 + 自动压缩
问题:context 默认无上限地增长,直到 API 报错才触发压缩,体验差。
解决:
| 配置项 | 值 | 作用 |
|---|---|---|
contextTokens |
120000 |
软上限,到达后触发剪枝(低于模型 200k 硬上限,留出安全边际) |
contextPruning.mode |
cache-ttl |
在 Anthropic 缓存 TTL 到期前删除老 tool output,减少 cacheWrite 费用 |
contextPruning.keepLastAssistants |
3 |
保留最近 3 条 assistant 消息,删除更早的 |
compaction.mode |
safeguard |
确保 Pi runtime 的 compaction 有足够预留空间 |
compaction.reserveTokensFloor |
20000 |
compaction 预留底线 20k token(防止压缩时空间不足) |
原理:把原来的"被动爆仓"改成"主动管理",在 context 超限前就开始清理。
Step 2 — 新会话自动恢复历史(QMD 本地向量搜索)
问题:memory_search 工具默认需要 OpenAI/Gemini/Voyage embedding API,没有 key 则完全禁用。
解决:安装并启用 QMD(Quick Markdown / 本地向量搜索引擎)
QMD 是什么
- GitHub: tobi/qmd
- OpenClaw 官方支持的实验性本地搜索后端
- 技术栈:BM25 + 向量(node-llama-cpp)+ reranking
- 完全本地运行,GGUF 模型首次自动下载,无 API key 需求
安装步骤
# 1. 安装 Bun(QMD 运行时)
curl -fsSL https://bun.sh/install | bash
# 2. 安装 QMD
bun install -g https://github.com/tobi/qmd
# 3. 解锁 postinstall(bun 默认阻止)
cd ~/.bun/install/global && bun pm trust --all
# 4. 补充缺失的 @types/node 并 build
cd ~/.bun/install/global/node_modules/@tobilu/qmd
bun add -d @types/node && bun run build
# 5. 验证
qmd --version # → qmd 1.0.6
注意:bun install -g 安装的 qmd 包没有预编译 dist,需要手动 build TypeScript 源码。这是一个安装坑,已记录。
OpenClaw 配置
{
"memory": {
"backend": "qmd",
"citations": "auto",
"qmd": {
"command": "/Users/mini/.bun/bin/qmd",
"includeDefaultMemory": true,
"sessions": {
"enabled": true,
"retentionDays": 30
},
"update": {
"interval": "5m",
"debounceMs": 15000
},
"limits": {
"maxResults": 6,
"timeoutMs": 4000
},
"scope": {
"default": "deny",
"rules": [{ "action": "allow", "match": { "chatType": "direct" } }]
}
}
}
}
关键配置说明:
backend: "qmd"— 切换为本地引擎(替代内置 SQLite 索引)sessions.enabled: true— 自动导出 session 对话记录到 QMD 索引(实现跨会话搜索)retentionDays: 30— 保留 30 天历史scope.rules— 仅限直接私聊可搜索(不在群组里暴露私人记忆)citations: "auto"— 搜索结果自动附带来源文件路径
效果:新会话开始时,memory_search 可以检索过去 30 天的对话历史摘要和记忆文件,自动恢复上下文。
Step 3 — Context 快满时自动提醒
问题:用户不知道 context 什么时候快满,只能被动等待中断。
解决:在压缩前的"软阈值"触发主动通知
工作流程
context 使用量
↓
[120k 软上限] → contextPruning 开始清理老消息
↓
[还剩 ~5k token] → memoryFlush 触发(比 compaction 更早)
↓
├── 1. 把重要上下文写入 memory/YYYY-MM-DD.md
└── 2. 发 Telegram 通知:⚠️ 对话快满了,建议发 /new
↓
[用户发 /new 开启新会话]
↓
[新会话] → memory_search 自动检索历史 → 无缝续接
配置
{
"agents": {
"defaults": {
"compaction": {
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 5000,
"prompt": "Context is nearing the compaction limit. Do TWO things:\n1. Write important context/decisions from this conversation to memory/YYYY-MM-DD.md (today's date).\n2. Use the message tool to send a Telegram notification to the user (target: 5588544200, channel: telegram) saying: '⚠️ 对话快满了,建议发 /new 开启新会话,我会自动从历史记忆中恢复上下文。'\nReply with NO_REPLY after completing both steps.",
"systemPrompt": "Pre-compaction housekeeping: persist memories and notify user. Silent turn."
}
}
}
}
}
原理:
softThresholdTokens: 5000— 在 Pi runtime 触发 compaction 之前 5000 token 就介入prompt中的双任务:写记忆 + 发通知NO_REPLY— 对话中不显示任何内容(静默操作),但 tools 仍然执行(Telegram 消息照常发)
整体架构图
用户对话
│
▼
[OpenClaw Gateway]
│
├── contextTokens: 120k → 软上限保护
├── contextPruning: cache-ttl → 清理老 tool output
│
├── [context 剩 5k] → memoryFlush 触发
│ ├── 写 memory/YYYY-MM-DD.md
│ └── 发 Telegram 通知 → 用户
│
├── compaction: safeguard → 自动压缩摘要(最后防线)
│
└── [用户 /new 开新会话]
│
▼
QMD 本地向量索引
├── MEMORY.md(长期记忆)
├── memory/*.md(日志)
└── sessions/*.jsonl(30天对话历史)
│
▼
memory_search → 自动恢复上下文
当前局限性
- QMD 首次搜索较慢:需要自动下载 GGUF 模型(reranker + query expansion),约几百 MB
- session 索引延迟:对话结束后才导出,不是实时的
- 根本上限无法突破:200k token 硬上限由 Anthropic 决定,所有优化只是更好地利用这 200k
- QMD build 依赖:安装时需要手动 build TypeScript(bun 全局安装的包缺少 dist 目录,已知坑)
文件位置
| 文件 | 说明 |
|---|---|
~/.openclaw/openclaw.json |
所有配置的实际存储位置 |
/Users/mini/clawd/MEMORY.md |
长期记忆(每次主会话加载) |
/Users/mini/clawd/memory/YYYY-MM-DD.md |
每日日志 |
~/.openclaw/agents/main/qmd/ |
QMD 索引数据库 + 缓存 |
~/.openclaw/agents/main/sessions/*.jsonl |
对话历史(被 QMD 索引) |
后续可探索方向
- 3层记忆架构(@Ktaohzk 方案):Fact/Belief 分层 + 衰减评分,进一步减少 token 占用
- session memory search 实验性功能:
memorySearch.experimental.sessionMemory: true(内置 SQLite 版的 session 索引,与 QMD sessions 二选一) - 混合搜索调优:调整
vectorWeight/textWeight比例优化检索精度 - embedding 缓存:
memorySearch.cache.enabled: true避免重复 embedding
本文档由 Ami + 阿米狗共同研究整理,2026-02-17