BingoAgentTouch/Personal_MCP2

@bingo_touth/memory-mcp-server

分层长期记忆 MCP 服务器:本地 MiniLM 或 OpenAI 兼容嵌入 API,供 LLM Agent(DeepSeek Harness / Claude Code)做可语义检索的长期记忆

包名
@bingo_touth/memory-mcp-server
版本
0.9.2
许可证
AGPL-3.0
最近更新
2026年8月23日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:BingoAgentTouch/Personal_MCP

从 candidate-report.json 提取 candidate_artifact 后,使用 untouched hold-out:

node bench/run-multiview-eval.mjs validate
--artifact
--output

node bench/run-multiview-eval.mjs evaluate
--threshold
--output


`validate` 只有在 hold-out 满足冻结目标时才会输出 `validated` artifact;失败时报告 `no_go`,不得手动把 candidate 标为 validated。artifact 绑定 model/tokenizer、recipe、窗口策略、aggregation/raw-similarity mode、development/hold-out dataset hash 和 canonical artifact hash。

新的 multiview generation、activation、delta 写入与 compaction 都必须携带并校验该 immutable validated snapshot;compaction 的 artifact 还必须与 active generation 的 snapshot 完全一致。历史 policy-less multiview generation 仍可读取,并在 search 中保持 summary-only shadow;它们不能重新激活或创建/重置/写入 delta。

本项目采用简单、手动维护优先的落地策略,不把大规模生产级 calibration、长时间 shadow observation 或复杂自动运维作为首次启用的前置条件。真实库首次启用时只需在维护窗口完成 multiview build → validate → switch,保留旧 generation,并用少量真实查询做 sanity check;必要时手动回切旧 generation。fixture artifact 不能冒充真实生产阈值,但不再阻塞首次使用。

## Compaction 日常维护流程(手动维护)

日常写入走 **delta 增量层**(generation 是不可变快照,写入只更新 `memory/embedding_delta/`)。delta 条目数 D 增长后:① 每次 `create_fragment` 重写 `delta_index.json` 的写放大 ≈ O(D²);② 检索多一层校验。**compaction** 把 base + delta 合并进一个全新 generation 并清空 delta(两层变一层)。

**什么时候做**:delta 条目数(`memory/embedding_delta/delta_index.json` 的键数)≥ 100~300、`create_fragment`/`memory_search` 明显变慢、或按使用强度定期(如每月/每 200 片段)。**全程在维护窗口执行,先备份 memory 根**。

```bash
cd           # 存储根相对 CWD,必须
node /compact_embeddings.mjs preflight --generation gen_YYYYMMDD_compaction --representation multiview --evidence-policy 
node /compact_embeddings.mjs build --generation gen_YYYYMMDD_compaction
node /compact_embeddings.mjs validate --generation gen_YYYYMMDD_compaction
node /compact_embeddings.mjs switch --generation gen_YYYYMMDD_compaction
  • --representation 必须与当前 active generation 一致;multiview 时必须携带 validated evidence policy(run-multiview-eval.mjs validate 产出,candidate 不可用)。
  • preflight 会上 compaction 锁 + 封存 delta + 写 merge contract;validate 不通过不得 switch;异常中断先用 compact_embeddings.mjs unlock 确认解锁,不要把 unlock 当通用恢复手段。
  • switch 后旧 generation 保留在 previous_generation_id,可手动回切。
  • 换模型/换表示请用 migrate_embeddings.mjs,不要用 compaction 顶替。
  • 详细判定信号、故障处理与操作前检查清单见《项目维护/memory-mcp-server_compaction维护手册_20260809.md》;archive 恢复场景见下一节。

Compaction archive recovery(维护者手动流程)

此流程只用于恢复一个 C3-3B v2 compaction archive:把 archive 中的 sealed delta 和记录的 base active pointer 原样恢复。它不是通用 JSON 修复、migrate_embeddings.mjs 的 rollback、orphan reconcile,也不是面向日常用户的操作。

当前没有公开的 restore CLI 或 MCP tool;仅维护者可在受控环境中调用内部 API:verifyArchivedDelta(archivePath)restoreArchivedDelta(archivePath)recoverDeltaRestoreTransaction()不要手动复制 archive 文件、改写 embedding_active.json、删除 transaction,或把 compact_embeddings.mjs unlock 当作通用恢复手段。

恢复前按顺序完成:

  1. 停止 MCP server 和全部写入方,记录绝对 memory root、候选 archive 路径、当前 active pointer、delta manifest/index 摘要、compaction lock,以及 memory/embedding_delta/transactions/restore-* 目录。
  2. 对整个 memory root 做独立的字节级备份;恢复流程不会替代这一份操作前备份。
  3. 只选择 memory/embedding_delta/archive/-into-/ 下的 archive。它必须包含 merge_receipt.jsonmerge_contract.jsonmanifest.jsondelta_index.json;有 materialized record 时还必须有对应 vectors/ payload。
  4. 先执行 verifyArchivedDelta(archivePath),只有返回 valid: true 才能继续。v1 receipt、任意 payload/receipt/contract/pointer 校验失败都必须停止,不能尝试“修好” archive 后继续。
  5. restoreArchivedDelta(archivePath) 会再次拒绝 source inventory 漂移、active pointer 不等于 receipt target pointer、非空的 post-compaction target delta、或已有未完成 restore transaction。满足条件后它才会恢复 archive 的 sealed delta,并最后写入 receipt base pointer。
  6. 成功后确认:active pointer 等于 receipt.pointer_snapshots.base;live delta 的 ID/payload 等于 archive、状态为 sealed、兼容性正常;target generation 与 archive 均仍存在;没有遗留 restore-* transaction。

正常调用返回 { restored: true, idempotent: false };若已经完全处于 archive 记录的 base+sealed-delta 状态,会返回 { restored: false, idempotent: true }。若出现 recovery_failed: true,保留其 transaction_path、archive、pointer/manifest 快照和错误输出,不要重跑 restore 或手动清理;由维护者先调用一次 recoverDeltaRestoreTransaction()。多个 restore transaction、未知 transaction schema、archive 验证失败或 recovery 再次失败都属于停止并人工检查的条件,不能 force-unlock。

当没有有效 archive、source 已变化或 pointer 状态不满足恢复前提时,走受控 rebuild:

node /migrate_embeddings.mjs build --generation gen_YYYYMMDD_xxx
node /migrate_embeddings.mjs validate --generation gen_YYYYMMDD_xxx
node /migrate_embeddings.mjs switch --generation gen_YYYYMMDD_xxx

对真实 memory root 的复制副本演练、自动启动恢复、公开 restore CLI 和 MCP restore tool 都是后续独立授权事项;本文档不启用它们。


MCP 工具一览

工具作用
memory_store_turn追加一轮对话到 raw(全量原文)
memory_create_fragment把若干轮打包成 L1 片段,自动算 embedding
memory_create_daily_summary写 L2 每日总结
memory_upsert_topic创建/更新 L3 跨天主题索引
memory_search语义检索 → 命中 L1 并回填 L2/L3 上下文
memory_get_fragment / memory_get_daily / memory_get_topic按 ID 读取完整内容
memory_list_dates列出所有有记录的日期
memory_get_raw_turns按 exact/range/recent/all 四种互斥模式读取 L0 逐轮原文,可先按 agent_id 过滤
memory_consolidate_topics检测中文相似 Topic;经审阅后支持 dry-run、整批预检、执行合并与 fragment 回指修复

Topic 合并说明

memory_consolidate_topics(action="execute") 会先做整批校验。任一 active 合并组存在 source/target 冲突、非法 fragment ID、路径越界、fragment 缺失或旧 Topic 回指不唯一时,整批返回 validated: false 和 MCP isError: true,不会改写 live 文件。

dry_run: true 使用与正式执行相同的计划和预检,只返回 changes,不写文件。正式执行会更新 target、改写 fragment 回指,并把 source 主题备份到 .trash 后删除。

这是面向个人项目的简化维护模型:优先保证行为直白、出问题后可人工检查;不承诺工业级自动恢复或复杂维护编排。


和宿主自带记忆的分工(避免双写)

很多 Agent 宿主(如 Claude Code)自身已有一套"始终加载进上下文"的轻量记忆。本 MCP 与它职责不同,不要重复存:

  • 宿主自带记忆 = 蒸馏后的常驻规则/偏好,需要每个会话都在上下文里、无需检索。少而精,一条一行。
  • 本 MCP = 可检索的情节档案:完整对话、任务片段、每日/主题脉络。按需 memory_search 取用,不常驻。

一条经验值得记时问自己:它需要每个会话都在场,还是只在我去翻的时候才要? 前者进宿主记忆(一行),后者进本 MCP(带证据的片段)。宿主里的那一行可以引用 MCP 的主题名做下钻,但不要复制正文。


仓库卫生

memory/ 里是原始对话逐字记录。若把本服务器的记忆库放在某个 git 项目内,记得在该项目 .gitignore 忽略它,别把对话原文和向量提交进版本库:

/memory/

记忆重要性评分

新建 fragment 时请保守填写 importance,不要把普通记忆默认评为 0.7 以上:

  • 0.35~0.4:临时、局部、低复用信息
  • 0.5:普通可复用记忆
  • 0.6~0.7:持续有帮助或明确重要
  • 0.8:关键架构、重要约束
  • 0.9~1.0:核心事实,错误代价高,应该很少使用

历史 fragment 的 importance 不因这次规则调整而批量改写。P3 Phase 1c 检索时使用 max(importance, earned_importance),earned 只提升有效重要性,不会降低已有权重。

已知取舍

  • MiniLM 的相似度整体偏低,0.2–0.35 就是可靠命中,不要按 0.8 的直觉设阈值。
  • 检索质量高度依赖写入方给的 task_desc/result_desc/片段浓缩质量——工具负责结构与召回,浓缩得好不好看用的人。
  • embedding 文本 = task_desc + result_desc + turns_text(查询多针对结论,纳入后召回更准)。

开发

npm run dev      # tsx 直跑 src/index.ts
npm run check    # tsc --noEmit 类型检查
npm run watch    # 文件监听(如启用 watcher)