# agentmemory
**Repository Path**: cymylive/agentmemory
## Basic Information
- **Project Name**: agentmemory
- **Description**: agentmemory是一个agent记忆系统
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-24
- **Last Updated**: 2026-05-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
English | 中文
# agentmemory
[](https://github.com/AutonomousResearchGroup/agentmemory/actions/workflows/test.yml)
[](https://badge.fury.io/py/agentmemory)
[](https://github.com/AutonomousResearchGroup/easycompletion/blob/main/LICENSE)
**AI Agent 的轻量级记忆管理库** — 语义搜索、知识图谱、事件记录、聚类分析
---
## 目录
- [简介](#简介)
- [安装](#安装)
- [快速开始](#快速开始)
- [部署配置](#部署配置)
- [ChromaDB(本地模式)](#chromadb本地模式)
- [PostgreSQL(生产部署)](#postgresql生产部署)
- [API 参考](#api-参考)
- [记忆 CRUD](#1-记忆-crud)
- [语义搜索](#2-语义搜索)
- [事件系统](#3-事件系统)
- [聚类分析](#4-聚类分析)
- [数据持久化](#5-数据持久化)
- [模型管理](#6-模型管理)
- [辅助工具](#7-辅助工具)
- [常见问题](#常见问题)
- [贡献指南](#贡献指南)
---
## 简介
`agentmemory` 是为 AI Agent 设计的记忆管理库,提供以下核心能力:
- **向量化存储** — 自动将文本转为向量嵌入,支持语义搜索
- **双后端支持** — 本地 ChromaDB 与生产级 PostgreSQL + pgvector
- **事件系统** — 基于纪元(epoch)的顺序事件记录
- **聚类分析** — 内建 DBScan 密度聚类算法
- **数据持久化** — JSON 导入/导出,方便备份与迁移
---
## 安装
```bash
pip install agentmemory
```
---
## 快速开始
```python
from agentmemory import create_memory, search_memory
# 创建一条记忆
create_memory(
"conversation",
"I can't do that, Dave.",
metadata={"speaker": "HAL", "some_other_key": "some value"}
)
# 语义搜索记忆
memories = search_memory("conversation", "Dave")
print(memories)
# 输出:
# [{
# "id": 0,
# "document": "I can't do that, Dave.",
# "metadata": {"speaker": "HAL", ...},
# "embedding": [0.001, 0.002, ...] # 可选
# }]
```
---
## 部署配置
### ChromaDB(本地模式)
默认使用 ChromaDB 本地持久化存储,数据保存在 `./memory` 目录:
```python
from agentmemory import create_memory
# 开箱即用,无需额外配置
create_memory("test", "hello world")
```
通过环境变量自定义存储路径:
```bash
export STORAGE_PATH="/path/to/memory"
```
### PostgreSQL(生产部署)
适用于大规模生产环境,使用 pgvector 扩展进行向量搜索:
```bash
export CLIENT_TYPE=POSTGRES
export POSTGRES_CONNECTION_STRING="postgres://user:password@host:5432/dbname"
export POSTGRES_MODEL_NAME="all-MiniLM-L6-v2" # 可选,默认值
export EMBEDDING_WIDTH=384 # 可选,默认值
```
代码中使用:
```python
import os
os.environ["CLIENT_TYPE"] = "POSTGRES"
os.environ["POSTGRES_CONNECTION_STRING"] = "postgres://..."
from agentmemory import create_memory
create_memory("conversation", "Hello, world!")
```
> 推荐使用 [Supabase](https://supabase.com/) 部署 PostgreSQL + pgvector,
> 参考教程:[OpenAI Embeddings & Postgres Vector](https://supabase.com/blog/openai-embeddings-postgres-vector)
---
## API 参考
### 1. 记忆 CRUD
#### `create_memory(category, text, metadata={}, embedding=None, id=None)`
创建一条新记忆。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类/集合名称 |
| `text` | str | — | 记忆内容文本 |
| `metadata` | dict | `{}` | 元数据,自动添加 `created_at`/`updated_at` 时间戳 |
| `embedding` | list | `None` | 预计算的向量嵌入(不传则自动生成) |
| `id` | str/int | `None` | 自定义 ID(不传则自动生成) |
**返回:** `str` 或 `int` — 新记忆的 ID
```python
create_memory("books", "百年孤独", metadata={"author": "马尔克斯", "year": 1967})
# 返回:0
```
---
#### `create_unique_memory(category, content, metadata={}, similarity=0.95)`
仅在无高度相似内容时创建新记忆,用于去重。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `content` | str | — | 记忆内容 |
| `metadata` | dict | `{}` | 元数据 |
| `similarity` | float | `0.95` | 相似度阈值(0~1),越高越严格 |
- 未找到相似内容:`metadata["novel"] = "True"`,创建新记忆
- 找到相似内容:`metadata["novel"] = "False"`,记录关联 ID
```python
create_unique_memory("books", "百年孤独", similarity=0.9)
```
---
#### `get_memory(category, id, include_embeddings=True)`
按 ID 获取单条记忆。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `id` | str/int | — | 记忆 ID |
| `include_embeddings` | bool | `True` | 是否包含向量 |
**返回:** `dict` 或 `None`
```python
memory = get_memory("books", 0)
print(memory["document"]) # 百年孤独
```
---
#### `get_memories(category, sort_order="desc", contains_text=None, filter_metadata=None, n_results=20, include_embeddings=True, novel=False)`
获取分类下的多条记忆,支持过滤和排序。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `sort_order` | str | `"desc"` | 排序方向:`"asc"` 或 `"desc"` |
| `contains_text` | str | `None` | 文档必须包含的文本 |
| `filter_metadata` | dict | `None` | 元数据精确匹配 |
| `n_results` | int | `20` | 返回条数 |
| `include_embeddings` | bool | `True` | 是否包含向量 |
| `novel` | bool | `False` | 是否只返回新记忆 |
**返回:** `list[dict]`
```python
memories = get_memories("books", sort_order="asc", n_results=5)
```
---
#### `update_memory(category, id, text=None, metadata=None, embedding=None)`
更新记忆内容或元数据。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `id` | str/int | — | 要更新的记忆 ID |
| `text` | str | `None` | 新文本 |
| `metadata` | dict | `None` | 新元数据 |
| `embedding` | list | `None` | 新向量 |
```python
update_memory("books", 0, text="霍乱时期的爱情", metadata={"author": "马尔克斯"})
```
---
#### `delete_memory(category, id)`
按 ID 删除单条记忆。
```python
delete_memory("books", 0)
```
---
#### `delete_memories(category, document=None, metadata=None)`
按文档内容或元数据批量删除记忆。
```python
# 删除作者为马尔克斯的所有记忆
delete_memories("books", metadata={"author": "马尔克斯"})
# 删除包含"百年"的记忆
delete_memories("books", document="百年")
```
---
#### `delete_similar_memories(category, content, similarity_threshold=0.95)`
查找并删除与指定内容相似的记忆。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `content` | str | — | 匹配内容 |
| `similarity_threshold` | float | `0.95` | 相似度阈值 |
**返回:** `bool` — 是否删除了任何记忆
```python
delete_similar_memories("books", "百年孤独", similarity_threshold=0.9)
```
---
#### `count_memories(category, novel=False)`
统计分类中的记忆数量。
```python
count = count_memories("books")
print(f"共有 {count} 本书")
```
---
#### `memory_exists(category, id, includes_metadata=None)`
检查指定记忆是否存在。
```python
if memory_exists("books", 0):
print("记忆存在")
```
---
#### `wipe_category(category)`
删除整个分类及其所有记忆。
```python
wipe_category("books")
```
---
#### `wipe_all_memories()`
删除所有分类下的全部记忆。
```python
wipe_all_memories()
```
---
### 2. 语义搜索
#### `search_memory(category, search_text, n_results=5, filter_metadata=None, contains_text=None, include_embeddings=True, include_distances=True, max_distance=None, min_distance=None, novel=False)`
基于语义相似度的记忆搜索。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `category` | str | — | 分类名称 |
| `search_text` | str | — | 搜索关键词 |
| `n_results` | int | `5` | 返回结果数量 |
| `filter_metadata` | dict | `None` | 元数据精确匹配 |
| `contains_text` | str | `None` | 文档必须包含的文本 |
| `include_embeddings` | bool | `True` | 是否返回向量 |
| `include_distances` | bool | `True` | 是否返回距离分数 |
| `max_distance` | float | `None` | 最大距离过滤(0=完全相同,1=完全不同) |
| `min_distance` | float | `None` | 最小距离过滤 |
| `novel` | bool | `False` | 是否只返回新记忆 |
**返回:** `list[dict]` — 每项包含 `{id, document, metadata, embedding?, distance?}`
```python
# 搜索关于"人工智能"的记忆
results = search_memory("conversation", "人工智能", n_results=3)
# 带元数据过滤
results = search_memory(
"conversation",
"人工智能",
filter_metadata={"speaker": "HAL"},
max_distance=0.5
)
```
> 注意:距离过滤在查询后应用,可能会减少结果数量,这是 ChromaDB 的当前限制。
---
### 3. 事件系统
事件系统提供基于纪元(epoch)的顺序事件记录,适用于对话轮次、循环迭代等场景。
#### `reset_epoch()`
重置纪元为 1。
```python
reset_epoch()
```
---
#### `set_epoch(epoch)`
设置指定纪元值。
```python
set_epoch(5)
```
---
#### `increment_epoch()`
纪元值 +1。
**返回:** `int` — 新的纪元值
```python
current = increment_epoch()
print(f"当前纪元: {current}")
```
---
#### `get_epoch()`
获取当前纪元值。
**返回:** `int`
```python
epoch = get_epoch()
```
---
#### `create_event(text, metadata={}, embedding=None)`
创建一条纪元事件,自动注入当前 epoch 到元数据中。
```python
create_event("用户询问天气", metadata={"intent": "weather"})
```
---
#### `get_events(epoch=None, n_results=10, filter_metadata=None)`
获取事件列表,支持按纪元筛选。
```python
# 获取所有事件
events = get_events()
# 获取特定纪元的事件
events = get_events(epoch=1)
```
---
### 4. 聚类分析
#### `cluster(epsilon, min_samples, category, filter_metadata=None, novel=False)`
对指定分类的记忆执行 DBScan 密度聚类。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `epsilon` | float | — | 邻域半径,决定两个样本被视为相邻的最大距离 |
| `min_samples` | int | — | 核心点的最小邻域样本数 |
| `category` | str | — | 要聚类的分类 |
| `filter_metadata` | dict | `None` | 聚类前的元数据过滤 |
| `novel` | bool | `False` | 是否只处理新记忆 |
聚类结果直接写入每个记忆的元数据中的 `"cluster"` 字段:
- 噪声点标记为 `"noise"`
- 正常簇标记为簇 ID(整数)
```python
from agentmemory import cluster
cluster(
epsilon=0.3,
min_samples=3,
category="conversation",
filter_metadata={"speaker": "HAL"}
)
```
> DBScan 算法参考:[原始论文](https://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf)
---
### 5. 数据持久化
#### `export_memory_to_json(include_embeddings=True)`
将所有记忆导出为字典。
**返回:** `dict` — `{collection_name: [memory_dict, ...], ...}`
```python
data = export_memory_to_json(include_embeddings=False)
```
---
#### `export_memory_to_file(path="./memory.json", include_embeddings=True)`
将所有记忆导出到 JSON 文件。
```python
export_memory_to_file(path="./backup.json")
```
---
#### `import_json_to_memory(data, replace=True)`
从字典导入记忆到数据库。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `data` | dict | — | `{category: [memory_dict, ...]}` 格式的数据 |
| `replace` | bool | `True` | 是否清空现有记忆后再导入 |
```python
import_json_to_memory(data, replace=False)
```
---
#### `import_file_to_memory(path="./memory.json", replace=True)`
从 JSON 文件导入记忆。
```python
import_file_to_memory(path="./backup.json", replace=True)
```
---
### 6. 模型管理
#### `check_model(model_name="all-MiniLM-L6-v2", model_path=None)`
检查并自动下载 ONNX 嵌入模型。
- 默认模型路径:`~/.cache/onnx_models`
- 下载来源:`https://chroma-onnx-models.s3.amazonaws.com/`
```python
from agentmemory import check_model
model_path = check_model()
```
---
#### `infer_embeddings(documents, model_path, batch_size=32)`
批量将文本转换为向量嵌入。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `documents` | list[str] | — | 文本列表 |
| `model_path` | str | — | `check_model()` 返回的模型路径 |
| `batch_size` | int | `32` | 批处理大小 |
```python
embeddings = infer_embeddings(["你好", "世界"], model_path)
```
---
### 7. 辅助工具
#### `get_client(client_type=None)`
获取后端客户端实例(单例模式)。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `client_type` | str | `None` | `"CHROMA"` 或 `"POSTGRES"`,默认从环境变量读取 |
```python
from agentmemory import get_client
client = get_client("CHROMA")
```
---
#### `chroma_collection_to_list(collection)`
将 ChromaDB 返回的字典格式转换为统一的对象列表。
```python
from agentmemory import chroma_collection_to_list
items = chroma_collection_to_list(chroma_result)
```
---
#### `list_to_chroma_collection(list)`
将对象列表转换回 ChromaDB 字典格式(`chroma_collection_to_list` 的逆操作)。
```python
from agentmemory import list_to_chroma_collection
chroma_dict = list_to_chroma_collection(items)
```
---
## 调试模式
有两种方式启用调试日志:
```python
# 方式一:传参
create_memory("test", "hello", debug=True)
# 方式二:环境变量
export DEBUG=True
```
调试模式下会输出详细的操作日志,向量值会被截断为 `[...]` 以便阅读。
---
## 常见问题
**Q: 如何切换存储后端?**
设置环境变量 `CLIENT_TYPE=POSTGRES` 并配置 `POSTGRES_CONNECTION_STRING`。
**Q: ChromaDB 数据存在哪里?**
默认存储在 `./memory` 目录,可通过 `STORAGE_PATH` 环境变量自定义。
**Q: 支持哪些元数据类型?**
ChromaDB 限制 metadata 值只能为字符串、数字、布尔。`dict`/`list`/`bool` 类型会自动转为字符串。
**Q: 如何备份记忆数据?**
使用 `export_memory_to_file()` 导出为 JSON,`import_file_to_memory()` 恢复。
---
## 贡献指南
欢迎贡献代码!本项目追求简洁和易用性,请保持代码风格一致。
- 提交 PR 前请确保测试通过
- 保持低依赖、高可读性
- 详细说明请参阅英文版 [README.md](README.md)
---
**agentmemory** — 让 AI Agent 拥有持久记忆