Metadata-Version: 2.4
Name: huimemory
Version: 0.1.0
Summary: Lightweight, pluggable AI memory runtime system
Author: HuiMengAI
License: MIT
Keywords: memory,ai,agent,embedding,vector-search,rag
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0
Requires-Dist: tiktoken>=0.7
Provides-Extra: full
Requires-Dist: openai>=1.0; extra == "full"
Requires-Dist: zstandard>=0.20; extra == "full"
Requires-Dist: numpy>=1.24; extra == "full"
Requires-Dist: requests>=2.28; extra == "full"
Requires-Dist: jieba>=0.42; extra == "full"
Requires-Dist: tiktoken>=0.7; extra == "full"
Provides-Extra: embedding
Requires-Dist: FlagEmbedding>=1.2; extra == "embedding"
Requires-Dist: torch>=2.0; extra == "embedding"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://img.shields.io/badge/Python-3.9+-blue.svg" alt="Python 3.9+">
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
  <img src="https://img.shields.io/badge/Phase%203-Complete-green.svg" alt="Phase 3 Complete">
</p>

<h1 align="center">HuiMemory</h1>

<p align="center">
  <b>轻量级、可插拔的 AI 对话记忆系统</b><br>
  <i>让 AI 记得清、找得快、不废话。</i>
</p>

---

## 简介

AI 对话的上下文窗口终有尽头——聊着聊着，前面说的全忘了。HuiMemory 的核心目标就是**突破这个限制**：通过持久化的记忆管理层，让 AI 在单次对话窗口内"记住"跨越数周甚至数月的历史，把短对话变成真正意义上的长期协作。

HuiMemory 是一个独立的对话记忆管理层，为 AI Agent 应用提供**分层记忆、自适应压缩、语义检索、增量演化**等核心能力。从量化系统的记忆模块中独立出来，抽象为通用库，与具体向量数据库和嵌入模型完全解耦，支持零外部依赖的轻量部署。

**核心设计理念**：检索系统 = 搜索引擎，LLM = 看网页找答案的用户。记忆管理的核心是**策略**，而非特定的向量库或嵌入模型。

---

## 核心特性

| 特性 | 说明 |
|------|------|
| **对话轮次感知** | 以 user+assistant 轮次为原子单位切分和检索，命中返回完整上下文 |
| **三层检索架构** | LLM 提炼关键词+时间 → 检索系统找内容 → LLM 组织答案 |
| **自然语言时间解析** | 零依赖规则引擎，"上周三"、"前天下午" → 精确日期范围 |
| **渐进式记忆扫描** | 模糊查询时由近及远逐周扫描，支持过程反馈和深度上限 |
| **上下文窗口扩展** | 命中轮次自动扩展 ±N 邻轮，提供完整对话语境 |
| **BGE-M3 Reranker** | 复用 BGE-M3 compute_score 精细重排序，按需启用 |
| **分层记忆** | 短期对话 → 长期摘要 → 高层原则，三级存储自动流转 |
| **增量演化** | 语义相似度驱动的增量摘要，避免重复计算；记忆演化引擎自主重组索引 |
| **人类可读** | 核心记忆以 Markdown 平铺存储，可审计、可编辑、可手动干预 |
| **可插拔架构** | 所有组件通过抽象接口解耦，支持任意替换向量库、嵌入模型、LLM |

---

## 架构总览

```
┌──────────────────────────────────────────────────────────────────────┐
│                          HuiMemory Facade                             │
├──────────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐               │
│  │  会话管理器   │  │  记忆检索器   │  │  压缩归档器   │               │
│  │ TopicManager │  │  Retriever   │  │  Archiver    │               │
│  └──────────────┘  └──────┬───────┘  └──────────────┘               │
│  ┌──────────────┐  ┌──────┴───────┐  ┌──────────────┐               │
│  │ 上下文监控器  │  │  查询扩展器   │  │  记忆演化器   │               │
│  │ContextMonitor│  │QueryExpander │  │ MemoryEvolver│               │
│  └──────────────┘  └──────────────┘  └──────────────┘               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐               │
│  │  摘要生成器   │  │ 增量摘要器    │  │  Reranker    │               │
│  │  Summarizer  │  │  IncSumm     │  │ (BGE-M3)     │               │
│  └──────────────┘  └──────────────┘  └──────────────┘               │
├──────────────────────────────────────────────────────────────────────┤
│  Pipeline (增强流水线)                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐   │
│  │  TurnChunker │  │ 查询重写器    │  │ 渐进式扫描器 ProgressiveScanner│  │
│  │ (轮次切分)   │  │QueryRewriter │  │ (一周一步由近及远)         │   │
│  └──────────────┘  └──────────────┘  └──────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  TimeResolver (零依赖中文时间解析规则引擎)                      │   │
│  └──────────────────────────────────────────────────────────────┘   │
├──────────────────────────────────────────────────────────────────────┤
│                    抽象接口层 (Pluggable)                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐               │
│  │  Embedding   │  │ VectorStore  │  │ LLM Client   │               │
│  │  Provider    │  │  Provider    │  │  Provider    │               │
│  └──────────────┘  └──────────────┘  └──────────────┘               │
├──────────────────────────────────────────────────────────────────────┤
│                    存储层 (Storage)                                    │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │   File System (sessions/ + archives/) + 可选向量数据库         │   │
│  └──────────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────┘
```

---

## 检索流水线

核心设计原则：**检索系统不负责语义理解和答案生成，只按关键词+时间范围找原文。**

```
用户: "上周我们聊的那个股票怎么样了？"
  │
  ├─ 1. TimeResolver 解析时间
  │     "上周" → (2026-04-05, 2026-04-11)
  │
  ├─ 2. LLM 提炼关键词
  │     → keywords: ["股票", "讨论"], time_range: (04-05, 04-11)
  │
  ├─ 3. 向量检索 (BGE-M3 TurnChunker 切分后的轮次向量)
  │     └─ metadata 过滤: timestamp >= "2026-04-05" AND timestamp <= "2026-04-11"
  │
  ├─ 4. 上下文窗口扩展 (可选)
  │     命中 turn #5 → 自动带上 turn #3, #4, #6, #7
  │
  ├─ 5. Reranker 精排 (可选，仅语义模糊场景启用)
  │     BGE-M3 compute_score → ColBERT+Sparse+Dense 综合分数
  │
  └─ 6. 返回完整对话轮次 → LLM 理解语境并回答用户
```

**模糊时间查询**（无精确时间范围时）触发渐进式扫描：

```
用户: "前段时间我们讨论过什么来着？"
  │
  ├─ TimeResolver: "前段时间" → None (模糊)
  │
  ├─ ProgressiveScanner: 一周一步由近及远
  │   Round 1: 本周 → score_gap=0.02, 未命中
  │   Round 2: 上周 → score_gap=0.38, ✅ 命中!
  │   (支持 on_round 回调 + reached_limit 征询)
  │
  └─ 返回结果 + 扫描元信息
```

---

## 三层记忆模型

```
Level 2: 高层原则 (Principles)
    ↑  从多个摘要中自动提炼通用知识/决策规则
    │
Level 1: 上下文摘要 (Summaries)  
    ↑  LLM 生成结构化摘要 → 向量化 → 语义检索
    │
Level 0: 原始对话 (Raw Dialogues)
         短期存储，按周文件夹管理，过期自动归档
```

> **归档缓存机制**：超过保留期的对话按月压缩为 `.tar.zst`（Zstandard）。检索时按需解压到 `.cache/` 目录并缓存，默认 72 小时后自动过期清理，避免重复解压的 IO 开销。应用启动时自动扫描并清理超龄缓存。

---

## 可插拔组件

> 所有组件均通过抽象接口解耦，支持任意替换。以下列出内置实现，你也可以自行实现接口。

### 嵌入模型 (Embedding)

| Provider | 说明 | 额外依赖 |
|----------|------|----------|
| **BGE-M3** | 多语言混合检索（稠密+稀疏+ColBERT），推荐首选 | `FlagEmbedding`, `torch` |
| **OpenAI** | 调用 OpenAI 兼容 API（无需本地 GPU） | `openai` |
| **LlamaCpp** | 本地 llama.cpp 嵌入 | `llama-cpp-python` |
| **MockEmbedding** | 返回固定向量，用于单元测试 | 无 |

### 向量数据库 (VectorStore)

| Provider | 说明 | 额外依赖 |
|----------|------|----------|
| **Chroma** | 功能丰富，支持持久化和元数据过滤，推荐首选 | `chromadb` |
| **FAISS** | 仅稠密向量，极致性能 | `faiss-cpu` |
| **Zvec** ⚠️ | 轻量嵌入式（需本地编译 C++ 源码） | `zvec` |
| **MemoryStore** | 内存向量，用于测试 | 无 |

### LLM 客户端 (LLMClient)

| Provider | 说明 | 额外依赖 |
|----------|------|----------|
| **OpenAI** | OpenAI 兼容 API（含 Qwen、DeepSeek 等） | `openai` |
| **DeepSeek** | DeepSeek 专用（兼容 OpenAI 格式） | `openai` |
| **Ollama** | 本地模型推理 | `requests` |

---

## 记忆存储格式

所有核心记忆以 **Markdown** 存储，人类可直接阅读和编辑：

```text
memory/
├── archives/                          # 压缩归档（月包 .tar.zst）
│   ├── 2026-04.tar.zst
│   └── 2026-05.tar.zst
├── .cache/                            # 归档解压缓存（72h 自动过期）
├── compress/                          # 压缩临时目录
├── vector_db/                         # 向量数据库文件（可选）
│   └── huimemory.db
└── sessions/                          # 当前活跃会话
    └── 2026-W15/                      # 按周分文件夹（ISO周数）
        ├── chat_2026-04-06_091423.md  # 对话记录
        ├── system_2026-04-06.md       # 系统提示（按天）
        ├── task_2026-04-06.md         # 任务记录（按天）
        └── summary_2026-04-06_091423.md # LLM 摘要（向量化）
```

### 对话记录格式 (`chat_*.md`)

```markdown
<!-- topic: 获取今日龙虎榜数据 -->
<!-- created_at: 2026-04-06 09:14:23 -->

<user timestamp="2026-04-06 09:14:23">
获取今日龙虎榜和三连板前5只股票数据
</user>

<assistant timestamp="2026-04-06 09:14:25">
[调用工具: get_stock_data, 任务ID: task_001]
</assistant>

<assistant timestamp="2026-04-06 09:14:30">
已获取龙虎榜前5：000001, 000002, 000003, 000004, 000005
三连板股票：000003, 000007
</assistant>
```

**TurnChunker 以 `<user>...</user>\n<assistant>...</assistant>` 配对为原子单位切分**，检索命中任何一部分均返回完整轮次，metadata 包含 `turn_index`、`timestamp`、`session_file`。

---

## 快速开始

### 方式一：使用 ClawdHub Skill（推荐，最便捷）

如果你使用 [WorkBuddy](https://www.codebuddy.cn) 或兼容的 AI 编码平台，可以直接安装我们预配置的 Skill，无需手动编写集成代码：

```bash
# 安装 HuiMemory 集成 Skill
clawdhub install huimemory-integration
```

安装后，在对话中提到 **"记忆系统"、"对话检索"、"HuiMemory"** 等关键词即可自动触发。Skill 内置了：

- 完整的集成指南和架构说明
- LLM System Prompt 模板 + Tool Schema（`recall_memory` / `recall_by_id`）
- 快速入门示例脚本
- API 参考文档

> **适用场景**：想快速给 AI Agent 加上记忆能力，不想自己写集成代码。

---

### 方式二：直接使用项目搭建记忆系统

如果你想将 HuiMemory 作为 Python 库集成到自己的应用中，可以按以下步骤操作。

#### 安装

```bash
pip install huimemory
```

### 零依赖模式（仅文件系统）

```python
from huimemory import HuiMemory

# 最简初始化，无需外部依赖
memory = HuiMemory(sessions_dir="./my_memory")

# 创建话题并添加消息
topic_id = memory.create_topic("项目讨论")
memory.add_message(topic_id, "user", "我们讨论一下架构方案...")
memory.add_message(topic_id, "assistant", "好的，目前有以下几个选项...")

# 触发压缩（生成摘要）
memory.compress_topic(topic_id)

# 检索记忆
results = memory.search("之前的架构方案是什么？")
for r in results:
    print(r.text, r.metadata)
```

### 完整模式（推荐组合：Chroma + BGE-M3 + LLM）

**1. 安装依赖**

```bash
# 核心依赖 + 向量数据库 + LLM 客户端（不含嵌入模型和 PyTorch）
pip install huimemory[full]
# 或从源码安装：
pip install -r requirements.txt
```

**2. 嵌入模型（任选其一）**

BGE-M3（本地部署，推荐）：

```bash
# 安装嵌入模型运行时（含 PyTorch CPU 版，约 800MB）
pip install -r requirements-embedding.txt
# 首次运行时 BGE-M3 模型权重会自动下载到 ~/.cache/huggingface/
```

或使用 OpenAI 兼容 API（无需本地 GPU，零额外依赖）：

```python
# 无需额外安装，只需在配置中指定
providers:
  embedding: "openai"
embedding:
  openai:
    api_key: ${OPENAI_API_KEY}
    model: "text-embedding-3-small"
```

**3. GPU 加速（可选）**

本地嵌入模型（如 BGE-M3）支持 CUDA 加速。替换 PyTorch 为 CUDA 版本即可，HuiMemory 会自动检测并使用 GPU：

```bash
# 以 CUDA 12.8 为例，根据你的环境选择对应版本
pip install torch --index-url https://download.pytorch.org/whl/cu128
```

> **注意**：GPU 依赖仅在本地运行嵌入模型时需要。使用 OpenAI API 等云端嵌入服务时，**无需安装 PyTorch 和 CUDA**。

**4. 配置文件 (`huimemory.yaml`)**

根据你选择的嵌入模型，修改 `providers.embedding` 和对应的模型配置：

```yaml
providers:
  embedding: "bge3"             # bge3 | openai | mock（选你的模型）
  vector_store: "chroma"
  llm_client: "deepseek"

embedding:
  bge3:
    model_path: "./your-model-path"  # ← 改成你自己的模型路径
    device: "cuda"              # 可选: cpu / cuda
  # openai:
  #   model: "text-embedding-3-small"
  #   api_key: ${OPENAI_API_KEY}

vector_store:
  chroma:
    persist_directory: "./memory/chroma_db"
    collection: "memories"

llm_client:
  deepseek:
    api_key: ${DEEPSEEK_API_KEY}
    model: "deepseek-chat"

memory:
  chunking:
    strategy: "turn"            # 轮次切分（推荐）
    max_tokens: 512
  retrieval:
    top_k_retrieve: 20
    top_k_rerank: 5
    enable_reranker: false       # 按需开启（需要嵌入模型支持 rerank）
    context_window: 2           # 邻轮扩展数量
    enable_progressive_scan: true
    max_scan_weeks: 16           # ≈4个月
  archiver:
    enabled: true
    months_to_keep: 3
    cache_ttl_hours: 72              # 归档解压缓存有效期（小时）
    # cache_dir: "./custom_cache"    # 可选：自定义缓存目录
  incremental_memory:
    enabled: true
```

**5. 使用**

```python
from huimemory import HuiMemory

memory = HuiMemory(config_path="huimemory.yaml")

# 添加对话
topic_id = memory.create_topic("讨论向量检索方案")
memory.add_message(topic_id, "user", "对比一下 HNSW 和 IVF 的性能差异")
memory.add_message(topic_id, "assistant", "HNSW 在召回率和延迟方面综合表现更好...")

# 压缩
memory.compress_topic(topic_id)

# 语义检索（TurnChunker 轮次级 + metadata 过滤 + 上下文窗口）
results = memory.search(
    "上周讨论的索引方案",
    filter_expr='timestamp >= "2026-04-05" AND timestamp <= "2026-04-11"',
    context_window=2,
)

# 模糊查询（渐进式扫描，带过程反馈）
def on_progress(round_num, week_label):
    print(f"正在回忆 {week_label} 的对话...")

result = memory.search_with_progress(
    "前段时间我们聊了什么来着？",
    on_round=on_progress,
)
if result.reached_limit:
    print("最近4个月没找到，要继续往前搜吗？")
```

---

## 项目结构

```
huimemory/
├── huimemory/                          # 主包
│   ├── __init__.py                     # 门面类 HuiMemory 导出
│   ├── config.py                       # 统一配置加载器（YAML + 环境变量）
│   ├── facade.py                       # HuiMemory 门面类（组合所有组件）
│   ├── types.py                        # 公共数据类型（Turn, Chunk 等）
│   ├── exceptions.py                   # 异常基类
│   ├── core/                           # 核心模块
│   │   ├── topic_manager.py            #   会话管理器
│   │   ├── context_monitor.py          #   上下文监控器（Token 阈值 + 压缩触发）
│   │   ├── summarizer.py               #   摘要生成器（LLM 结构化摘要）
│   │   ├── incremental_summarizer.py   #   增量摘要器（语义相似度驱动）
│   │   ├── retriever.py                #   记忆检索器（混合检索 + metadata 过滤 + 上下文窗口）
│   │   ├── reranker.py                 #   重排序器（复用嵌入模型 compute_score）
│   │   ├── query_expander.py           #   查询扩展器
│   │   ├── archiver.py                 #   压缩归档器（Zstandard .tar.zst）
│   │   ├── memory_evolver.py           #   记忆演化器
│   │   └── progressive_scanner.py      #   渐进式扫描器（一周步长由近及远）
│   ├── pipeline/                       # 增强流水线
│   │   ├── chunker.py                  #   分块器（TurnChunker / SlidingWindow / Adaptive）
│   │   ├── query_rewriter.py           #   查询重写器（LLM 改写 + 多查询）
│   │   └── kv_cache_compressor.py      #   KV Cache 压缩器（RocketKV 接口）
│   ├── providers/                      # 可插拔实现
│   │   ├── embedding/                  #   嵌入模型（BGE-M3 / OpenAI / LlamaCpp / Mock）
│   │   ├── vector_store/               #   向量数据库（Chroma / FAISS / Zvec / Memory）
│   │   └── llm_client/                 #   LLM 客户端（OpenAI / DeepSeek / Ollama / Mock）
│   ├── storage/                        # 存储层
│   │   ├── file_ops.py                 #   文件操作（读写、周文件夹管理）
│   │   └── markdown_parser.py          #   Markdown 解析（parse_turns 轮次切分）
│   ├── utils/                          # 工具模块
│   │   └── time_resolver.py            #   零依赖中文时间解析规则引擎
│   └── prompts/                        # Prompt 模板与 Tool Schema
├── configs/
│   └── default.yaml                    # 默认配置
├── tests/                              # 测试
│   ├── fixtures/sessions/              #   样本对话数据（短→超长）
│   ├── test_retriever.py               #   检索器测试
│   ├── test_archiver.py                #   归档器测试
│   ├── test_turn_chunker.py            #   TurnChunker 测试
│   ├── test_time_resolver.py           #   时间解析测试
│   ├── test_progressive_scanner.py     #   渐进式扫描测试
│   └── bench_turn_recall.py            #   Benchmark（三场景）
├── docs/                               # 文档
│   ├── llm_integration_guide.md        #   LLM 集成指南
│   ├── BUILD_ROADMAP.md                #   构建路线图
│   └── bench_*.json                    #   Benchmark 结果数据
├── pyproject.toml                      # 项目元数据与依赖（pip install -e .）
├── requirements.txt                    # 核心依赖（零模型依赖）
├── requirements-embedding.txt          # 本地嵌入模型依赖（按需安装）
├── LICENSE                             # MIT
└── README.md
```

---

## 性能基准

### BGE-M3 编码性能

| 指标 | 数值 |
|------|------|
| **GPU** | NVIDIA GeForce RTX 4060 Ti (16GB) |
| **精度** | FP16 |
| **Batch Size** | 256 |
| **向量维度** | 1024 |
| **平均吞吐** | **874 条/秒** |
| **峰值显存** | 1,243 MB |

> 测试环境：Windows 11, Python 3.x, PyTorch 2.11.0+cu128, FlagEmbedding 1.3.5

### 检索质量 Benchmark（TurnChunker 轮次级，BGE-M3，124 条查询）

| 场景 | R@1 | R@5 | MRR | NDCG@5 |
|------|-----|-----|-----|--------|
| A. 关键词+时间 | **1.00** | **1.00** | **1.00** | **1.00** |
| B. 语义模糊 | 0.97 | **1.00** | 0.98 | 0.98 |
| C. 时间过滤 | 0.97 | **1.00** | 0.98 | 0.99 |

### Reranker 效果对比

| 场景 | R@1 (无 Reranker) | R@1 (有 Reranker) | 延迟变化 |
|------|-------------------|-------------------|----------|
| A. 关键词+时间 | 1.00 | 1.00 | — |
| B. 语义模糊 | 0.968 | **1.00** | +175ms |
| C. 时间过滤 | 0.968 | **1.00** | +175ms |

> 结论：Reranker 对语义模糊场景最受益（+3.2%），延迟代价 5x。建议默认关闭，仅纯语义模糊查询时启用（Reranker 短路逻辑自动判断）。

---

## 环境要求

- Python >= 3.9
- 零外部依赖模式：无额外要求
- 完整模式推荐：`Chroma` + `BGE-M3`（或 OpenAI API）+ `DeepSeek/OpenAI`
- GPU 加速（可选）：CUDA Toolkit + 对应版本的 PyTorch（仅本地嵌入模型需要）

---

## 许可证

[MIT](./LICENSE)

---

## 贡献

欢迎提交 Issue 和 Pull Request。

1. Fork 本仓库
2. 创建功能分支 (`git checkout -b feat/amazing-feature`)
3. 提交更改 (`git commit -m 'Add amazing feature'`)
4. 推送分支 (`git push origin feat/amazing-feature`)
5. 发起 Pull Request
