Skip to main content
Glama
moonandecho

origin-memorycore

by moonandecho

origin-memorycore

English | 简体中文

MemoryCore 是 LLM 代理的记忆治理层。

代理积累记忆的速度很快——偏好、事实、决策——而不加维护的记忆会悄然退化:重复内容堆积、陈旧事实残留、热层填满后开始拒绝写入。MemoryCore 就是为防止这种情况而设计的。

它作为一个两层记忆系统工作:

  • 热层 —— 频繁使用的行为知识(偏好、规则、纠正)存放在快速的本地文件中,始终处于上下文之中。

  • 冷层 —— 低频事实,自动迁移出去,存储在内嵌的 SQLite 引擎中(如果你配置了远程记忆服务,则存到那里)。

在两者之间,一个治理核心保持记忆的健康:

  • 写入时去重 —— 相似事实在存储前被合并,而不是重复存储。

  • 容量控制 —— 软/硬阈值会在热层填满之前触发溢出,因此热层永远不会拒绝写入。

  • 冷层治理 —— 周期性的去重/清理过程让冷层在增长时保持可查找性。

  • 回收站 —— 被删除的条目有 30 天宽限期;召回已删除的条目可将其复活。

结果是:热层保持在预算之内,冷层保持可查找,无论代理积累了多少记忆,记忆都始终可维护。

基于 MCP(模型上下文协议)streamable-http / stdio 标准构建。适用于任何 MCP 客户端,已通过 Hermes Agent 测试。

功能

  • 记忆治理(核心) —— 为冷层数据完整性提供的三层保护:

    • 冷写入去重:在写入冷层之前,语义召回 + LLM 评判会检查重复项,并更新现有条目,而不是创建冗余条目。

    • 容量硬门控:冷层强制软限制(6000 条,触发一次维护过程)和硬限制(10000 条,强制维护循环)——防止无界增长。

    • 回收站(trash_store.py):被删除的冷层条目被移动到 ~/.memorycore/trash.json,有效期为 30 天。使用新的语义证据召回已删除的条目即可恢复它(“召回即复活”)。

  • 冷/热路由 —— 每次写入都会被分类:高重要性或类偏好 → 热(本地);低频事实 → 冷(远程);陈旧状态记录 → 丢弃。

  • 六步溢出 —— 容量基线 → 去重 → 陈旧过滤 → 合并 → 安全写入(先写冷层,然后删除本地)→ 验证。

  • 冷层维护 —— 去重合并、陈旧清理、冲突解决、嵌入完整性检查。

  • 容量控制 —— 软阈值(写入前先溢出一次)/ 硬阈值(强制溢出)/ 目标比例。默认值:5000 字符限制的 60% / 80% / 40%。

  • 优雅降级 —— 冷层不可达?写入会响亮地失败(绝不静默丢弃),溢出会保留本地条目,健康检查返回带有 cold.error 的本地状态。

  • 零核心修改 —— 设计为即插即用的伴生组件;你的代理内置的记忆工具继续正常工作。

Related MCP server: AI Long-Term Memory MCP Server

架构

┌─────────────────────────────── Mac / local ──────────────────────────────┐
│  LLM agent (e.g. Hermes)                                                 │
│    │  MCP client                                                         │
│    ▼                                                                     │
│  MemoryCore MCP server                                                   │
│    ├─ local_store.py        hot tier: MEMORY.md / USER.md (chars-based)  │
│    ├─ classifier.py         cold/hot/stale routing rules                 │
│    ├─ overflow.py           six-step overflow                            │
│    ├─ maintenance.py        cold-tier governance                         │
│    └─ cold_store_client.py  →  LocalBackend (SQLite, in-process)         │
│                               or RemoteBackend (MCP streamable-http)     │
└──────────────────────────────────────────────────────────────────────────┘
                     LocalBackend: mnemosyne-memory (in-process engine)
                     RemoteBackend: remote MCP memory service

Optional (Hermes Agent only): hermes-plugin/memorycore-prefetch
  ┌───────────────────────────────────────────────────────────────────────┐
  │ MemoryProvider plugin (single-model qwen3, enabled by default)        │
  │   system_prompt_block → static index (always active)                  │
  │   prefetch → ColdStoreClient.recall_results(top_k=20)                 │
  │            → dense ranking → session + hot-tier dedup → top-5         │
  │   Disable: MEMORYCORE_PREFETCH_ENABLED=0                              │
  └───────────────────────────────────────────────────────────────────────┘

快速开始

前提条件

  • ollama —— 嵌入 API(安装:https://ollama.com)

  • qwen3-embedding:0.6b —— 推荐的嵌入模型(1024 维)

# Install ollama (macOS/Linux)
curl -fsSL https://ollama.com/install.sh | sh

# Pull the embedding model
ollama pull qwen3-embedding:0.6b

安装与运行

pip install "origin-memorycore @ git+https://github.com/moonandecho/origin-memorycore.git"

# That's it! MemoryCore runs with ollama for embeddings:
#   - Hot tier:  MEMORY.md / USER.md (default ~/.hermes/memories)
#   - Cold tier: SQLite via mnemosyne-memory (default ~/.memorycore/data/)
#   - Embedding: qwen3-embedding:0.6b via ollama (http://localhost:11434/v1)
python -m memorycore.server          # stdio transport (default)

数据目录结构(全部位于 ~/.memorycore/ 下):

~/.memorycore/
├── data/          # SQLite database (MNEMOSYNE_DATA_DIR)
└── ...

使用 MNEMOSYNE_DATA_DIR 覆盖。

模型切换

默认嵌入模型是 qwen3-embedding:0.6b(1024 维)。通过设置环境变量使用任何 ollama 模型:

export MEMORYCORE_EMBED_URL="http://localhost:11434/v1"
export MEMORYCORE_EMBED_MODEL="nomic-embed-text"   # or your preferred model

或者指向任何兼容 OpenAI 的嵌入 API:

export MEMORYCORE_EMBED_URL="https://api.openai.com/v1"
export MEMORYCORE_EMBED_MODEL="text-embedding-3-small"

在你的 MCP 客户端中注册它(以 Hermes Agent config.yaml 为例):

mcp_servers:
  memorycore:
    command: python
    args: ["-m", "memorycore.server"]

远程模式(可选)

如果你更倾向于共享远程 Mnemosyne MCP 服务而不是本地引擎,请设置 MEMORYCORE_COLD_BACKEND=remote:

export MEMORYCORE_COLD_BACKEND=remote
export MNEMOSYNE_URL="http://your-memory-service:9000/mcp"
python -m memorycore.server

暴露的工具:

工具

用途

memorycore_store_fact(content, importance, scope, target)

统一写入入口:将冷 / 热 / 陈旧路由

memorycore_recall(query, top_k)

主动召回冷层记忆(只读,补充每轮预取)

memorycore_trigger_overflow(target)

运行六步溢出,target ≤40%

memorycore_run_cold_storage_maintenance()

冷层治理过程

memorycore_get_memory_usage()

热层使用情况 + 冷层统计 + 阈值

Hermes 集成——每轮预取

MCP 服务器与客户端无关。对于 Hermes Agent,有一个可选的伴生插件,提供双通道冷层访问:

双通道设计

  • 静态索引通道(始终激活,零开销) —— 一个系统提示块,列出可用主题(可通过 MEMORYCORE_INDEX_TOPICS 配置,逗号分隔),并指导使用 memorycore_recall(query) 进行按需召回。

  • 每轮预取通道(默认启用) —— 每轮召回冷层,按稠密得分排序,并将前 5 条注入上下文,使代理在说话之前“记住”相关内容。设置 MEMORYCORE_PREFETCH_ENABLED=0 可禁用,仅使用按需召回。

预取流水线

query → preprocess → cold-tier recall (20 candidates)
  → dense ranking (qwen3) → top-5
  → session dedup → hot-tier dedup → inject into context

MemoryCore 使用单模型 qwen3 架构(无重排序器)。来自 qwen3 的稠密得分用于批次内的相对排序;没有绝对阈值——按稠密得分排序的前 5 个候选在去重后总是被注入。

优雅降级

当 ollama 不可达(未安装、未运行或模型未拉取)时,预取静默返回空字符串——对话继续进行,不注入记忆,也不会向用户显示任何错误。DEBUG 级别的日志记录探测失败。

部署(Hermes Agent)

# 1. install origin-memorycore (provides the cold tier + ColdStoreClient)
pip install "origin-memorycore @ git+https://github.com/moonandecho/origin-memorycore.git"

# 2. put the plugin in Hermes' user plugin dir
mkdir -p ~/.hermes/plugins
cp -r hermes-plugin/memorycore-prefetch ~/.hermes/plugins/

# 3. activate (takes effect next session)
hermes config set memory.provider memorycore-prefetch

部署后的三种形态:

形态

配置

行为

默认(推荐)

无额外配置

静态索引 + 每轮预取,注入前 5 条候选

仅按需

MEMORYCORE_PREFETCH_ENABLED=0

仅静态索引,代理通过 memorycore_recall 查询冷层

自定义嵌入

MEMORYCORE_EMBED_URL + MEMORYCORE_EMBED_MODEL

指向不同的 ollama 实例或兼容 OpenAI 的 API

插件配置

变量

默认值

描述

MEMORYCORE_PREFETCH_ENABLED

(未设置)

设置为 0 以禁用每轮预取

MEMORYCORE_EMBED_URL

http://localhost:11434/v1

Ollama 或兼容 OpenAI 的嵌入 API 基础 URL

MEMORYCORE_EMBED_MODEL

qwen3-embedding:0.6b

嵌入模型名称(推荐 1024 维)

MEMORYCORE_INDEX_TOPICS

(未设置)

用于系统提示索引块的逗号分隔主题

要求与注意事项:

  • Hermes 专用:该插件导入 Hermes 运行时模块(agent.memory_provider),不能作为独立包使用——它是 MemoryCore 的 Hermes 集成侧。完整细节:hermes-plugin/memorycore-prefetch/README.md。

  • 每次召回保持 5 秒超时;失败会静默降级为空注入,绝不会阻塞对话。

热层治理

热层(MEMORY.md / USER.md)每轮都被注入上下文,因此必须保持小巧和最新。MemoryCore 在六步溢出之上叠加了三种机制,使历史记录以确定性的方式退役,而不是不断堆积:

热层元数据老化

  • 边车元数据:MEMORY.meta.json / USER.meta.json 位于 .md 文件旁边,以条目内容的 SHA-256 作为键。原子写入加上文件锁确保它们跨进程安全;§ 分隔的 .md 格式保持不变,因此宿主记忆工具可以继续正常工作。

  • 每个条目都被归类为 state(历史决策 / 状态记录)或 rule(准则 / 偏好):

    • state:写入 7 天后退役到冷层(可配置:STATE_TTL_DAYS)

    • rule:永不会因为年龄而退役;在 30 天未更新后,长条目(>200 字符)成为 LLM 压缩候选(可配置:RULE_COMPRESS_DAYS)。规则还通过下面的失效信号阶梯获得可持续的退出方式——绝不会错误地退役一个有效偏好。

  • 当条目的内容改变时,其键也会改变——下一次对账会重新对新内容进行归类,并垃圾回收孤立键。

双重写入入口治理

  • store_fact 写入入口:看起来像已完成决策/状态记录的内容(包含日期和完成标记,如 拍板/已配置,且没有行为指令)会被直接路由到冷层——它永远不会进入热层。

  • 插件 on_memory_write 直接写入通道:每次内置记忆工具添加/替换后,条目会被立即归类。state 条目在后台迁移到冷层(去重 → 冷写入确认 → 从热层移除;冷写入失败时,条目保留并带有状态戳作为 7 天后备)。这运行独立于使用阈值之外。单个工作线程排空一个有界队列(大小 128);当队列满时,写入被跳过,下一次溢出对账会将其标记为后备。

元数据优先的溢出

每次溢出运行首先对账元数据(为未归类的旧条目打上戳,垃圾回收孤立项),然后按元数据退役条目——关键词仅作为未归类条目的回退路径。边车故障会降级到关键词路径,绝不会阻塞溢出。

规则失效信号(分级保护)

一个完全由 rule 条目组成的热层在设计上就没有退出路径(“绝不会让偏好沉没”),因此那些从未被编辑的短规则会永远留存,最终填满热层。MemoryCore 用一个压力阶梯来填补这个缺口:每次溢出运行都会测量真实使用量(基线),并随着压力升高打开更深的退出路径(响应)。五个可观察信号决定资格和顺序——压力决定是否行动:

信号

观察对象

动作

S1 空闲时间

sidecar 中的 updated_at

压缩(30d)与 stub-sink(45d)的资格门槛

S2 完成度复查

嵌入日期 ≥ 60d + 至少 2 个完成标记 + 零行为词

被误标为 rule 的历史记录重新标记为 state → 进入常规 7 天 TTL sink

S3 同主题聚类

词汇相似度(可选嵌入通道)

同主题条目合并为一条;合并后的长条目稍后成为压缩候选

S4 主题活跃度

本地查询活动日志(prefetch/recall,滚动 45 天,可选)+ LLM 休眠判定

处于高压力下的休眠 B 类规则:全文进入冷层(先确认),保留 ≤40 字符的指针 stub 在热层

S5 跨层冗余

冷层 recall 命中

已存在等价冷副本 → 删除热副本(零信息丢失)

分层保护:A 类元规则(行为 / 交互 / 写作风格准则)、红线规则以及 importance ≥ 0.9 的条目永远不会被 S2/S4/S5 处理——它们只会合并或压缩。Stub 指针有自己的生命周期(高压力下按最旧优先 GC;冷层永不触碰),因此指针不会二次填满热层。每次退出都是先写冷层:只有在冷层确认之后本地条目才会变更,任何失败都保留原条目。当某个信号不可用(无活动日志、无 LLM key)时,阶梯机制会降级为之前的行为,而不是猜测。

常量(memorycore/core/config.py):RULE_RETYPE_DAYS=60、 RULE_STUB_IDLE_DAYS=45、ACTIVITY_WINDOW_DAYS=30、MAX_STUB_PER_RUN=3、 STUB_MAX_CHARS=40、IMPORTANCE_PROTECT=0.9。

健康检查:memorycore_memory_audit

一个只读工具,列出热层每个条目及其类型、年龄、退役计划和保留/sink 分类——这是诊断“溢出却找不到可 sink 条目”的可观测性锚点。

规模测试与优化结果

MemoryCore 在万条冷层规模下进行了压力测试和召回优化(隔离测试环境,与生产数据零接触,结果可复现)。

写入与容量

指标

结果

写入吞吐

10k 条目耗时 467s,约 21.4 条目/s(受嵌入计算限制)

数据库大小

300MB / 10k 条目

内存占用

进程 RSS 仅 +19MB,全程平稳——无泄漏特征

查询延迟 —— top_k=5 时中位数 48ms;万条规模与百条规模一致,无延迟回退。

召回质量 —— 三项探测:

  1. 精确匹配(自召回):20/20 命中 top-1——精确匹配完好。

  2. 噪声抑制(无关查询):top-1 稠密得分均值 0.056,大多数返回 0.0——无关内容几乎不会泄漏到结果中。

  3. 短查询召回(优化前 → 优化后) —— 关键优化成果:

阶段

短查询命中率

优化前

0/8

优化后

5/8(62.5%)

优化内容:在高主题密度下,固定候选截断 k=max(top_k, 20) 将详细记忆挤出候选池,导致短查询无法召回它们。修复将候选截断扩大到 k=max(top_k*4, 300),并在召回入口点内部扩展候选,然后再截断返回——所有召回通道(每轮 prefetch + 按需召回)都从这一处修复中受益。修复仅限于召回阶段;排序逻辑未改动,行为可预测且可回退。

注意:测试使用合成 10k 条目数据库(80 条“黄金”记忆 + 9920 条日常日志语气的填充记忆,配置与生产一致);生产数据未受影响。

面向 sqlite-vec 用户的说明

如果你为 Mnemosyne 冷层启用 sqlite-vec 向量索引,请注意 beam.py 的 _wm_vec_search_sqlite 使用了原始相似度公式 sim = 1 - distance / (2 * EMBEDDING_DIM),该公式会将 float32 距离压缩到约 1.0,使动态阈值实际上失效(所有结果都会通过)。

补丁:在 float32 分支中,将公式替换为 sim = 1 - d² / 2——这为归一化向量提供精确的余弦相似度,并恢复正确的阈值行为。

冷存储契约

任何暴露以下五个 MCP 工具的服务都可以充当冷层:

工具

语义

remember(content, importance, scope)

存储一条记忆,返回 memory_id

recall(query, top_k)

语义召回

update(memory_id, content)

合并更新现有记忆

forget(memory_id)

删除一条记忆

stats()

total + 嵌入完整性

完整契约和参考客户端见 examples/cold-store-contract.md。

配置

环境变量

默认值

含义

MEMORYCORE_COLD_BACKEND

local

冷层后端:local(进程内)或 remote(MCP)

MNEMOSYNE_URL

(空)

冷层 MCP 端点(remote 模式必需)

MNEMOSYNE_DATA_DIR

~/.memorycore/data

本地 SQLite 数据目录

MEMORYCORE_EMBED_URL

http://localhost:11434/v1

Ollama 或 OpenAI 兼容的嵌入 API 基础 URL

MEMORYCORE_EMBED_MODEL

qwen3-embedding:0.6b

嵌入模型名称(1024 维)

MEMORY_DIR

~/.hermes/memories

热层目录(MEMORY.md / USER.md)

ACTIVITY_LOG_ENABLED

1

用于主题活跃度信号的查询活动日志;0 完全禁用日志和 S4 stub-sink

MNEMOSYNE_TIMEOUT

10.0

冷层请求超时(remote 模式,秒)

容量常量位于 memorycore/core/config.py(CHAR_LIMIT_*、SOFT_THRESHOLD、HARD_THRESHOLD、TARGET_RATIO)。

工作原理

  1. 写入 —— store_fact 对内容进行分类:

    • importance ≥ 0.8 或匹配热关键词(偏好 / 规则 / 修正 / 红线)→ 热,保留在本地

    • 过期标记(短条目,例如“已修复 / fixed”)→ 丢弃(不迁移)

    • 其他情况 → 冷,直接写入远端服务

  2. 溢出 —— 当热层使用量超过软阈值时,溢出机制将低频条目迁移到冷层;达到硬阈值时强制溢出,直到 ≤ 目标值。顺序始终是先写冷层,验证,再删除本地——冷层失败时不会丢失任何数据。

  3. 维护 —— 定期对冷层执行合并重复项、移除过期条目、解决冲突,并验证嵌入完整性。

许可证

MIT © 2026 moonandecho

第三方许可证

  • mnemosyne-memory — MIT, 作者 AxDSan。LocalBackend 使用的进程内记忆引擎。

  • MCP Python SDK — MIT。

  • ollama — MIT。本地嵌入 API 服务器。

  • qwen3-embedding — Apache-2.0, 作者 Alibaba Cloud。默认嵌入模型(未捆绑;通过 ollama 拉取)。

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Open-source AI memory layer for LLM agents. Importance scoring, temporal decay, hierarchical memory (facts, summaries, themes), YMYL prioritization, and active retrieval with contradiction detection. Supports OpenAI, Anthropic, Ollama. Local-first with SQLite + FAISS.
    51 PyPI
    49
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    Provides persistent, self-optimizing memory for AI agents, enabling them to remember preferences and context across sessions and share knowledge across multiple agents.
    4
    9 npm
    ISC