# 🧵 ChainMem(链忆)— 让 AI Agent 拥有像人一样的联想式回忆

> **给它一个"线头",它还你一件"毛衣"。**

---

## 一、一个困扰我很久的问题

你有没有这样的经历?

你用 AI Agent 聊了一整个下午,把需求、方案、代码都讨论清楚了。第二天打开新会话,它一句"你好,请问有什么可以帮你的?"——**全忘了**。

这就是当下 AI Agent 最尴尬的短板:**没有记忆**。

当然,现在已经有向量数据库(Pinecone、Chroma、Milvus)来做记忆存储。但你试试搜"上次关于股票投资的想法"——返回 10 个孤立片段的,凑不出"当时到底说了什么"。就像图书馆查资料,搜得到碎片,**但拼不回一本书**。

所以我自己写了一个:**ChainMem(链忆)**。

---

## 二、人的记忆 vs AI 的"记忆"

先想想人的记忆是什么样:

> 你听到一首歌的前奏 → 想起整首歌 → 想起那个夏天 → 想起那个人...

人的记忆是**链式的**——一个线索能引出整段完整的记忆。你不需要"搜索"过去,你只需要一个**线头**,轻轻一扯,整件"毛衣"就出来了。

而现有的 AI 记忆系统本质上是**图书馆模式**:

```
你搜"股票" → 返回 10 个孤立片段:
  [片段A] "...股票..."
  [片段B] "...股票投资..."
  [片段C] "...关于股票..."
  ...
  但凑不出"当时到底说了什么"
```

每条记忆是独立的**点**——能搜到碎片,但**凑不出一段完整的、前后连贯的记忆**。

ChainMem 用**链式结构**模拟人脑的联想回忆:

```
你搜"股票" → 找到链头 → 沿指针遍历 → 整段对话一字不差重现:
  "其实我的想法是股票投资..."
  "应该分散风险"
  "所以我选了消费、科技、医疗三个板块..."
  "每个板块配比大约是..."
```

**不是搜索碎片,而是还原整段记忆。**

---

## 三、核心设计:链式 + 向量混合架构

ChainMem 的核心架构只有两层,却巧妙解决了"检索精度"和"上下文完整性"之间的矛盾。

### 3.1 结链(Ingestion)

当你把一段文本存入 ChainMem 时,它做了三件事:

```
原始文本 → ① 语义切块 → ② 向量嵌入 → ③ 链式串联
```

**① 语义切块:** 按标点将文本切成 6~18 字的短语块。太短的块(≤5 字)会自动合并到前一块,因为 sentence-transformers 对超短文本的编码质量很差(不同短文本可能产生完全相同的向量)。

**② 向量嵌入:** 每个块用 sentence-transformers 编码为 384 维的向量,用于后续语义搜索。

**③ 链式串联:** 用双向指针(prev_id / next_id)把所有块串成一条链。这样,找到任意一个节点,就能沿着指针恢复整条链——完整无遗。

### 3.2 追溯(Retrieval)

当你输入查询时,ChainMem 走了三条路径:

```
         用户查询
             │
             ▼
  ┌─────────────────┐     ┌──────────────────────┐
  │  FAISS 语义搜索   │     │  子串精确匹配          │
  │  (TOP 10 候选)    │────▶│  +0.20 加分           │
  └────────┬─────────┘     └──────────────────────┘
           │
           ▼
  ┌─────────────────┐
  │  候选排序         │  语义分 + 子串分 + 标签分
  └────────┬─────────┘
           │
           ▼
  ┌─────────────────┐     ┌──────────────────────┐
  │  指针双向遍历      │────▶│  ... → Node_A → Node_B │
  │  prev + next     │      │  → Node_C → ...      │
  │  忠实还原全部     │     │  → 完整上下文输出      │
  └─────────────────┘     └──────────────────────┘
```

**为什么需要三条路径?**

- **纯语义搜索不够准:** 384 维向量中,语义接近但不同内容的文本可能撞到同一区域,准确率仅 85~90%
- **子串匹配精但不广:** 能把查询文本"钉"在包含它的节点上,但查不到同义词或意译
- **标签分类辅助排优:** 限定搜索域,排除无关领域

三者结合,实测检索准确率达到 **100%**。

### 3.3 关键优化

在生产环境中还踩了几个坑,分享一下:

**坑 1:短文本退化**

sentence-transformers 对 ≤5 字的短文本会产生完全相同的嵌入向量。修复:结链时自动合并短块。

**坑 2:短查询失效**

≤3 字的查询嵌入质量极差,容易被高维空间的无关节点吸走。修复:查询 ≤3 字时自动补齐 `query = query + " " + query`。

**坑 3:FAISS 索引重建太慢**

全量重建 13,000 个节点的索引要 50~60 秒。优化:索引持久化到磁盘(启动 1 秒加载),增量添加只编新节点(130ms)。

**坑 4(v0.5.2+):单向遍历丢上下文**

单向向前遍历只能获得匹配节点之后的内容,之前的内容丢失。修复:改用双向遍历(prev_id + next_id),回忆覆盖率从 60% 提升到 **97%**。

**坑 5(v0.5.3+):拼写错误零召回**

英文查询 `Taiyuan campain`(拼错)查不到 `campaign`。修复:加入 Levenshtein 编辑距离兜底,阈值 ≤2 的拼写错误自动纠正。

---

## 四、性能对比

| 指标 | 传统向量搜索 | ChainMem | 提升 |
|:-----|:----------:|:--------:|:---:|
| **检索速度** | ~50ms | **~22ms** | 2.3x |
| **结果完整性** | 碎片 | **100% 原始记忆** | ∞ |
| **启动时间** | ~60s(全量重建) | **~1s**(磁盘加载) | 60x |
| **增量添加** | 全量重建 | **~132ms** | 455x |
| **中文支持** | 一般 | **优秀**(trigram FTS5) | — |
| **检索精度** | 语义近似 | **语义+子串+标签** 混合 | 更高 |
| **英语查询** | 差(跨语言分<0.4) | **✅ 精确+分词+拼写纠错** | 显著 |
| **上下文覆盖** | 片段 | **双向遍历 97%** | — |

测试环境:单核 CPU + 7.5GB 内存,13,000+ 节点数据库。

---

## 五、快速开始

ChainMem 采用**分层依赖**设计,按需选择:

| 安装方式 | 命令 | 大小 | 功能 |
|:---------|:-----|:----:|:-----|
| 🪶 **核心版** | `pip install chainmem` | **~2 MB** | CLI、SQLite存储、文本检索 |
| 🔥 **完整版** | `pip install chainmem[full]` | ~1.5~2 GB | 以上 + 语义搜索 + FAISS |
| 🔐 **加密版** | `pip install chainmem[secure]` | ~5 MB | 凭证自动检测 + Fernet 加密 |
| 🚀 **全功能** | `pip install chainmem[full,secure]` | ~1.5~2 GB | 全部功能 |

### Python SDK

```python
from chainmem import ChainMemory

# 初始化
cm = ChainMemory(db_path="~/.chainmem/data.db").open()

# 结链:把一段对话存为记忆
chain = cm.ingest(
    "其实我的想法是把每一次的记忆包括一次对话全部变成一个链条",
    source="demo",
    tags=["讨论", "记忆系统", "架构"],
)
print(f"链 ID: {chain.id}, 节点数: {chain.node_count}")

# 追溯:输入几个字,拉出整段记忆
result = cm.retrieve("其实我的想法")
print("".join(result))  # → 完整记忆复原

# 统计
print(cm.stats())

cm.close()
```

### CLI 模式

```bash
# 结链
chainmem ingest "其实我的想法是把每一次的记忆..." --source demo --tags 讨论,记忆系统

# 追溯
chainmem retrieve "其实我的想法"

# 统计
chainmem stats

# 启动 MCP 服务器
chainmem serve --socket /tmp/chainmem.sock
```

---

## 六、与 AI Agent 集成

ChainMem 原生支持 **MCP(Model Context Protocol)**,可直接作为 AI Agent 的记忆插件。

### Hermes Agent 配置

```yaml
# ~/.hermes/config.yaml
mcp_servers:
  chainmem:
    command: chainmem
    args: ["serve", "--socket", "/tmp/chainmem.sock"]
```

配置后,Agent 自动获得三个工具:

| 工具 | 功能 |
|:-----|:-----|
| `chainmem_ingest(text, source, tags)` | 结链:存储重要对话 |
| `chainmem_retrieve(query, tags)` | 追溯:检索完整记忆链 |
| `chainmem_stats()` | 统计:查看记忆库状态 |

### 实际使用场景

**场景 1:跨会话记忆**

用户在新会话中说:"还记得上次我们讨论的那个股票策略吗?"

Agent 调用 `chainmem_retrieve(query="股票策略", tags="股决")`,拉出上次的完整讨论,就好像昨天刚聊过一样。

**场景 2:自动记录**

讨论中用户说"这个记下来",Agent 调用 `chainmem_ingest(tags="架构设计")`,把刚才的讨论存入长期记忆。

**场景 3:知识库查询**

Agent 收到一个问题,先查 ChainMem 看看有没有相关记忆,有则引用完整上下文作答,无则从零推理。

---

## 七、项目架构

```
chainmem/
├── pyproject.toml           # 项目配置
├── README.md                # 中文文档
├── README.en.md             # English version
├── LICENSE                  # MIT License
├── CONTRIBUTING.md          # 贡献指南
├── assets/                  # Logo + 架构图
├── src/chainmem/
│   ├── __init__.py          # ChainMemory 主入口
│   ├── core/node.py         # 数据模型(ChainNode, Chain)
│   ├── store/sqlite_store.py # SQLite 持久化
│   ├── pipeline/
│   │   ├── ingester.py      # 结链(切块 → 嵌入 → 串联)
│   │   └── retriever.py     # 追溯(FAISS + 子串 + 指针)
│   └── cli/app.py           # Typer CLI + MCP server
├── scripts/
│   ├── chainmem_server.py   # 持久化 MCP 服务
│   └── benchmark.py         # 性能基准测试
└── tests/
    └── test_core.py         # 核心测试(16 个用例全部通过)
```

---

## 八、开源与未来

ChainMem 是一个**开源项目**,采用 MIT 协议。仓库在 GitHub:

> **[https://github.com/yabolee-kkk/chainmem](https://github.com/yabolee-kkk/chainmem)**

PyPI 地址:[https://pypi.org/project/chainmem/](https://pypi.org/project/chainmem/)

当前处于 **Alpha 阶段(v0.5.3)**,核心闭环已完成:

- ✅ 结链(文本 → 切块 → 嵌入 → 存储)
- ✅ 追溯(语义搜索 + 子串匹配 + 指针遍历)
- ✅ **双向遍历**(匹配节点上下文 97% 还原)
- ✅ **模糊分词兜底**(短查询、重组查询零召回)
- ✅ **Levenshtein 拼写纠错**(拼写错误自动纠正)
- ✅ MCP 服务器持久化
- ✅ FAISS 索引持久化(秒级启动)
- ✅ 增量索引(毫秒级添加)
- ✅ 凭证自动加密(v0.5.0)
- ✅ 标签分类
- ✅ Python SDK + CLI

### 路线图

```
Phase 2 🏗️ 类人记忆机制
  ├─ 衰减曲线(Forgetting Curve)
  ├─ 联想增强(检索A时推荐相关链)
  ├─ 自动结链(对话中自动记忆)
  └─ 分支消歧(相同前缀不同下文)

Phase 3 🎯 真正的"人脑记忆"
  ├─ 分层记忆(工作记忆 + 短期 + 长期)
  ├─ 记忆整合(多条记忆→知识归纳)
  ├─ 跨 Agent 记忆共享
  └─ 睡眠压缩(像人脑睡觉时整理记忆)
```

欢迎任何形式的贡献!无论是修 Bug、加功能、写文档,还是提 Issue 讨论,"链忆"的未来由社区共同构建。

---

## 写在最后

ChainMem 的灵感来自一个简单的观察:**AI Agent 说一句话就要翻一次向量数据库,但人类翻的是一本线装书——找到线索,顺着线,拉出整段记忆。**

链式结构不是什么新技术——链表是每个程序员学数据结构第一课就接触的东西。但有时候,最简单的数据结构,恰好能解决最复杂的问题。

**"回忆"不是搜索碎片。回忆,是把整件毛衣从头到尾拿出来。**

---

> **GitHub:** [https://github.com/yabolee-kkk/chainmem](https://github.com/yabolee-kkk/chainmem)
>
> **PyPI:** [https://pypi.org/project/chainmem/](https://pypi.org/project/chainmem/)
>
> **安装命令:**
> - 🪶 核心版:`pip install chainmem`
> - 🔥 完整版:`pip install chainmem[full]`
> - 🔐 加密版:`pip install chainmem[secure]`
> - 🚀 全功能版:`pip install chainmem[full,secure]`

*如果这篇文章对你有帮助,欢迎 Star、Fork、分享!*

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐