内容
# memlife
渐进式退化的记忆。 不再是无限增长的记忆堆。
[](https://pypi.org/project/memlife/)
[](https://pypi.org/project/memlife/)
[](https://github.com/EzyRider/memlife/blob/main/LICENSE)
**当前版本:0.5.4**
memlife 是一个为人工智能代理设计的四层生命周期记忆系统。 与其将记忆视为单调增长的数据库,不如让每个记忆条目都有生命周期——事实会消退,日志条目会退休,过期数据会被修剪,任何东西都不会永远积累。
四个层级:
- **事件** —— 原始事件(发生了什么)
- **事实** —— 持久的真相(我所知道的)
- **日志** —— 反思后的信念(我所相信的)
- **衰退/修剪** —— 置信度消退,过时条目退休,垃圾回收清理
## 为什么选择 memlife
其他记忆系统都会积累。 事实永远不会过期。 置信度从不会衰退。 过时的惯例变成不容置疑的真相。 随着时间的推移,记忆质量会下降。
memlife 解决了这个问题。 记忆应该像人类的记忆一样——它会消退,会被修订,会被修剪。 而不是一个不断增长直到崩溃的数据库。
## 安装
```bash
pip install memlife
```
使用适配器(可选):
```bash
pip install memlife[ollama] # Ollama 嵌入器 + 聊天
pip install memlife[openai] # OpenAI 嵌入器 + 聊天
pip install memlife[sentence-transformers] # 本地嵌入
pip install memlife[mcp] # MCP 服务器
```
## 快速入门(30 秒,无依赖)
```python
import asyncio
from memlife import MemoryStore, MemoryConfig, DummyEmbedder
async def main():
store = MemoryStore(
config=MemoryConfig(db_path="./memlife.db", embedding_model="dummy"),
embedder=DummyEmbedder(),
)
# 存储一个事件(发生了什么)
store.remember(task="用户询问部署问题", outcome="成功")
# 存储一个事实(持久的真相)
await store.store_fact("用户通过 GitHub Actions 部署", confidence=0.8)
# 存储实体关系(类似事实,但结构化)
store.store_triple("用户", "通过", "GitHub Actions", confidence=0.8)
# 检索相关记忆(所有层级的统一评分)
context = await store.retrieve("部署")
print(context)
store.close()
asyncio.run(main())
```
无需 Ollama,无需 OpenAI,无需 API 密钥。 `DummyEmbedder` 使用词袋向量——相似的句子具有正的余弦相似度。 完整的生命周期——存储、检索、衰退、垃圾回收和实体图——无需任何大型语言模型。 只有结构化提取和反思需要模型。
## 生命周期
```
┌───────────┐ 反思 ┌───────────┐
│ 事件 │ ──────────────────▶│ 日志 │
│ (事件) │ 大型语言模型综合 │ (信念) │
└─────┬─────┘ 观察和 └─────┬─────┘
│ 提取三元组 │
│ │
│ store_fact() / store_triple() │ 置信度衰退
▼ │ (可配置)
┌───────────┐ 回忆提升 ┌─────▼─────┐
│ 事实 │ ◀──────────────── │ 退休 │
│ (真相) │ 置信度 +0.05 │ (下限) │
└─────┬─────┘ └─────┬─────┘
│ │
│ │ 实体图(三元组)
│ ▼
┌───────────────┐
│ 三元组/图│
│(主题-谓语- │
│ 对象 + 提供者)│
└───────┬───────┘
│
│ 修订/取代 │ 垃圾回收修剪
▼ ▼
┌───────────┐ ┌───────────┐
│ 被取代 │ 可配置 │ 已修剪 │
│ (被取代)│ ──────────────────▶│ (已删除) │
└───────────┘ 保留 └───────────┘
统一评分 = 相关性 × 置信度 × 最近度
在每次响应之前应用于所有层级。
无需大型语言模型模式:存储 + 检索 + 衰退 + 垃圾回收 + 实体图无需任何模型。 只有反思和结构化提取需要大型语言模型。
```
## 无大型语言模型模式
存储、检索、衰退、垃圾回收、实体图和嵌入版本控制都无需任何大型语言模型。 只有反思循环和结构化提取需要模型。
```python
from memlife import MemoryStore, MemoryConfig
store = MemoryStore(config=MemoryConfig(db_path="./memlife.db"))
store.remember(task="发生了什么", outcome="成功")
# retrieve() 是异步的 - 使用 SyncMemoryStore 或 asyncio.run():
import asyncio
context = asyncio.run(store.retrieve("什么"))
store.close()
```
这使得 memlife 适用于测试、离线代理和轻量级部署,您不希望管理模型访问。
## 核心概念
### 事件
事件是原始事件。 它们存储成本低廉,对于回忆有用,但系统并不将它们视为持久的真相。 随着时间的推移,反思可以将事件从观察中提升为事实或日志条目。
```python
store.remember(
task="用户询问部署问题",
outcome="成功",
confidence=0.9,
)
```
### 事实
事实是具有明确置信度的持久真相。 它们在不使用时会衰退,在回忆时会提升,并且可以被修订或取代。
```python
await store.store_fact("用户通过 GitHub Actions 部署", confidence=0.8)
```
### 实体图(三元组)
实体之间的结构化关系。 三元组的行为类似于事实,但参与图遍历。
```python
store.store_triple("用户", "通过", "GitHub Actions", confidence=0.8)
```
### 日志
日志保存反思后的信念——系统在反思过程中从事件和事实中综合得出的高级观察结果。
```python
await store.reflect() # 或调度它
```
### 衰退、退休和垃圾回收
置信度会随着时间的推移而衰退。 置信度低于阈值的条目将退休。 被取代的条目会老化。 垃圾回收会根据保留策略修剪它们。 所有这些都是可配置的。
## 检索
`retrieve()` 使用统一函数对所有四个层级进行评分:
```
分数 = 相关性 × 置信度 × 最近度
```
这意味着一个相关性高但置信度低的记忆不会淹没一个相关性适中、置信度高、最近的记忆。 结果是一个混合的上下文字符串,可以直接输入到提示中。
```python
context = await store.retrieve("部署")
```
## 配置
```python
from memlife import MemoryConfig
config = MemoryConfig(
db_path="./memlife.db",
embedding_model="dummy", # 或 "nomic-embed-text" 等
vector_backend="json", # json | binary | sqlite_vec
reflection_interval=3600, # 秒
decay_half_life_days=30,
confidence_floor=0.3,
namespace="default",
)
```
参见 `MemoryConfig` 以获取完整的选项集。
## MCP 服务器
memlife 附带一个 MCP 服务器,因此任何兼容 MCP 的客户端都可以使用它:
```bash
memlife-mcp-server --db-path ./memlife.db --vector-backend binary
```
暴露的工具包括 `memory_store`、`memory_search`、`memory_retrieve`、`memory_reflect`、`memory_contradictions`、`memory_revise`、`memory_expire`、`memory_recall` 等。
## 版本 0.5.4 中的新功能
- **MCP 反思超时控制。** `memlife-mcp-server` 现已公开 `--reflection-timeout` 和 `--reflection-total-timeout`,以便反思保持在 MCP 客户端窗口内,适用于较慢的大型语言模型端点。
- **README 工具列表已刷新。** MCP 服务器工具列表现在与实际实施的工具相匹配,包括 `memory_recall`、`memory_revise` 和 `memory_expire`。
- **Memorias 和 polyphonic 功能标志。** `--memorias-extraction` 和 `--polyphonic-recall` 现在可以从 MCP 服务器 CLI 启用。
- **按工具名称搜索事件。** `memory_search_episodes` 现在接受 `tool_name` 过滤器,使得审计特定工具的使用更加容易。
- **向量后端默认清理。** `--vector-backend` 现已明确默认为 `json`,并在提供旧标志时具有更清晰的优先级。
## 版本 0.5.3 中的新功能
- **修复配置验证回归。** `MemoryConfig.validate()` 现运行所有不变式检查,即使 `vector_backend` 保留其默认自动值。 以前,`None` 的默认值导致验证过早返回,跳过衰退和阈值检查。
- **二进制后端不再丢失 JSON 存储的向量。** `BinaryVectorBackend` 反序列化现在为存储在后端切换之前存储的行回落到 JSON 格式,因此从 `json` 更改为 `binary` 现有存储不会使旧向量对搜索不可见。
## 版本 0.5.2 中的新功能
- **二进制向量后端现用于检索。** 以前后端可以选择,但回忆仍然使用内联余弦。 事实、事件和日志向量回忆现在通过配置的后端路由,因此 `binary` 使用汉明距离搜索,`sqlite_vec` 使用 sqlite-vec KNN。
- **向量后端优先级集中。** `MemoryConfig.resolved_vector_backend()` 提供明确的顺序:显式 `vector_backend` > `use_binary_vectors` > `use_sqlite_vec` > 默认 `json`。 同时使用两个旧标志现在解析为 `binary` 并带有警告,而不是静默依赖于 if/else 顺序。
- **MCP 服务器关闭是干净的。** 关闭路径现在关闭存储、嵌入器、聊天适配器和反射器,并在清理后通过 SIGTERM 退出进程,而不是挂起。
- **Ollama 适配器不再在存在循环之前创建会话。** 会话在第一次异步调用时延迟创建,避免在事件循环外实例化嵌入器/聊天时出现 `RuntimeError`。
## 版本 0.5.1 中的新功能
- `memlife-mcp-server` 现接受 `--vector-backend {json,sqlite_vec,binary}`。
- **可插拔的向量后端。** 在 JSON、二进制和 `sqlite-vec` 后端之间切换,只需更改一个配置。 新的二进制后端以位打包的向量存储嵌入,体积减小约 32 倍,而 sqlite-vec 在可用时提供快速的近似最近邻。
- **公共 `Metrics` 快照。** `store.metrics()` 返回结构化的计数、嵌入覆盖率、反射聚合、回忆计数、DB 元数据和模式迁移健康状况的快照。 通过 `memlife://stats` MCP 资源公开。
- **模式迁移状态。** `store.migration_status()` 检查数据库是否具有所有预期的表和列,标记缺失的项目,并报告 SQLite 版本和页面统计信息。 在 `Metrics` 中公开,以便操作员可以在模式过时之前检测到它。
- **sqlite-vec 的 pysqlite3 备用方案。** 在标准库 `sqlite3` 编译器未加载扩展的情况下,memlife 透明地回落到 `pysqlite3`,以便 sqlite-vec 仍然可以加载。
- **反思审计轨迹。** 反思过程记录建议的、保留的和丢弃的项目,以及计时和模型元数据。 分页审计查询有助于调试反思循环的实际操作。
- **命名空间默认值和验证强化。** 默认命名空间现在为 `_default`,名称在打开任何数据库之前进行验证/规范化,并且配置在未知向量后端或不安全的路径时快速失败。
## 许可证
MIT