# ME MEMORY

> 具备 **主动记忆提取**、**Embedding 语义检索**、**置信度动态累积**、**长内容切分**与 **Token 预算智能选择** 的 AI 对话助手。

<p align="center">
  <img src="https://img.shields.io/badge/React-19-61DAFB?logo=react" alt="React">
  <img src="https://img.shields.io/badge/TypeScript-6-3178C6?logo=typescript" alt="TypeScript">
  <img src="https://img.shields.io/badge/Vite-8-646CFF?logo=vite" alt="Vite">
  <img src="https://img.shields.io/badge/Zustand-5-433e38" alt="Zustand">
  <img src="https://img.shields.io/badge/Tailwind-4-06B6D4?logo=tailwindcss" alt="Tailwind">
</p>

官网：[https://yammigo.github.io/mememory.github.io/](https://yammigo.github.io/mememory.github.io/)

npm 包：[https://www.npmjs.com/package/@mememory/memory-agent](https://www.npmjs.com/package/@mememory/memory-agent)

模型下载：[https://github.com/yammigo/mememory/releases](https://github.com/yammigo/mememory/releases)

### 需要 Node.js ≥ 18

### 快速开始
```bash
# 1. 安装本地模型
npx @mememory/memory-agent model:import
# 2. 启动助手
npx @mememory/memory-agent
```

### 全局安装与使用
```bash
#1.全局安装 
npm install -g @mememory/memory-agent

#2.安装本地模型 (前往Releases下载模型并解压到当前目录)
memory-agent model:import
#3.选择模型目录 (模型解压出来的目录)

#4.启动助手
memory-agent
# → 自动启动本地服务并打开浏览器 http://127.0.0.1:8080
# 常用选项
npx memory-agent --port 3000          # 自定义端口
npx memory-agent --host 0.0.0.0       # 允许局域网访问
npx memory-agent --no-open            # 不自动打开浏览器
npx memory-agent --help               # 查看全部选项
```

### 🔄 软件更新

应用内置了更新功能（需要本地服务运行）：

- **自动检查**：启动时自动检查 npm 上是否有新版本，之后每 6 小时检查一次；发现新版本时弹出更新日志窗口并提示（每个版本只自动弹一次，用户关闭后不再自动弹，顶部徽标仍保留入口）
- **手动检查**：右上角「检查更新」按钮或设置 → 软件更新 → 检查更新；有新版本时右上角按钮变为「发现新版本」（带角标提示），点击即可查看更新日志
- **一键更新**：点击「立即更新」后，应用会从 npm 下载最新包覆盖本地文件，并自动重启本地服务、刷新页面
  - 全局安装（`npm install -g`）、项目依赖（`npx` 启动）均支持
  - pm2 / Docker 容器等托管环境不支持一键更新，可手动执行 `npm install -g @mememory/memory-agent@latest`
- 更新日志来自随包发布的 [CHANGELOG.md](CHANGELOG.md)




## 📸 界面预览

![ME MEMORY 界面预览](https://yammigo.github.io/mememory.github.io/light.png)
![ME MEMORY 界面预览](https://yammigo.github.io/mememory.github.io/dark.png)

<!-- 截图占位：建议截取以下画面放入 docs/screenshots/ 目录 -->

<p align="center">
  <em>对话界面 — 流式输出 + 工具调用卡片实时展示</em>
</p>

```
┌──────────────────────────────────────────────────────────────────────────┐
│  ME MEMORY ●          [对话] [记忆库] [衰退] [图谱]   记忆 42  对话 12  ☀ ⚙ │
├──────────┬──────────────────────────────────┬─────────────────────────────┤
│ Embedding│  ┌──────────────────────────┐    │  记忆上下文                   │
│ 模型状态  │  │ ME MEMORY v2             │    │  ┌───────────────────────┐  │
│ ● 就绪    │  │ 具备主动记忆提取...       │    │  │ core  用户偏好          │  │
│          │  │                          │    │  │ 喜欢简洁的代码风格       │  │
│ 记忆金字塔 │  │  API: [_______________]  │    │  │ 访问12 重要80% 置信90%  │  │
│    12    │  │  Key: [_______________]  │    │  └───────────────────────┘  │
│  48      │  │  模型: [_______________]  │    │  ┌───────────────────────┐  │
│  156     │  │  [OpenAI][DeepSeek]...    │    │  │ long_term 技术栈        │  │
│  42      │  │  [    开始对话    ]       │    │  │ React+TypeScript       │  │
│ 工作 短期 │  └──────────────────────────┘    │  │ 访问5 重要70% 置信85%   │  │
│ 长期 核心 │  ┌──────────────────────────┐    │  └───────────────────────┘  │
│          │  │ U 你好，帮我记住...        │    │                             │
│ 类型      │  │ AI 好的，已创建记忆 ✓     │    │                             │
│ ● 全部 42 │  │ 💾 创建记忆    ✓          │    │                             │
│ ○ 情景 15 │  │ ──────────────────────── │    │                             │
│ ○ 语义 12 │  │ 🧠 提取记忆中…            │    │                             │
│ ○ 程序 8  │  │ ✓ 提取1条新记忆           │    │                             │
│ ○ 情感 7  │  └──────────────────────────┘    │                             │
│          │  [_________________] [➤] [🗑]     │                             │
│ 标签      │  ████████░░░░ 系统 记忆 历史 45%  │                             │
│ React TS │                                    │                             │
│ 偏好 配置 │  巩固 ↓2  即将遗忘 3  存储 12KB    │                             │
└──────────┴──────────────────────────────────┴─────────────────────────────┘
```

<details>
<summary>📸 记忆库视图</summary>

```
┌──────────────────────────────────────────────────────────────────┐
│  [搜索…]                                              [+ 新建]   │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ ■ 情景 短期记忆                          3小时前              │ │
│ │ 用户喜欢使用 React + TypeScript 技术栈                        │ │
│ │ 80% 有效72% 访问12 置信 ████████ 90%                         │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ ■ 语义 长期记忆                            1天前              │ │
│ │ 用户的职业是全栈工程师                                        │ │
│ │ 70% 有效65% 访问5 置信 ██████ 85%                            │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ ■ 情感 核心记忆                            7天前              │ │
│ │ 用户对代码质量有极高的要求                                    │ │
│ │ 95% 有效88% 访问23 置信 ██████████ 98%                       │ │
│ └──────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
```

</details>

<details>
<summary>📸 衰退分析视图</summary>

```
┌──────────────────────────────────────────────────────────────────┐
│  容量使用                                                         │
│  工作记忆 ████░░░░░░░░ 12/20                                      │
│  短期记忆 ██████████░░ 100/100 ⚠️                                  │
│  长期记忆 ██████░░░░░░ 156/500                                    │
│  核心记忆 ██░░░░░░░░░░ 5/∞                                       │
│                                                                   │
│  衰减曲线                                                         │
│  100% │╲                                                          │
│       │ ╲___  短期记忆 (t½≈4天)                                    │
│       │     ╲______ 长期记忆 (t½≈35天)                              │
│   20% │ -------- 危险区 --------                                   │
│       │    ·  ·   ·  实际记忆点                                    │
│     0%└──────────────────────────────                             │
│       0d   5d   10d   15d   20d   25d   30d                       │
│                                                                   │
│  遗忘预测          层级健康                                         │
│  1天  ↓2条        短期 ██████████ 89/100 ⚠11                      │
│  3天  ↓5条        长期 ██████░░░░ 142/156                         │
│  7天  ↓8条                                                         │
│  14天 ↓12条                                                        │
│  30天 ↓21条       即将遗忘 (11)                                     │
│                   ┌──────────────────────────────┐                │
│                   │ ⚠ 用户喜欢Vue  2天前  8%     │                │
│                   │ ⚠ 临时会议记录  5天前  15%    │                │
│                   └──────────────────────────────┘                │
└──────────────────────────────────────────────────────────────────┘
```

</details>

<details>
<summary>📸 记忆图谱视图</summary>

```
┌──────────────────────────────────────────────────────────────────┐
│  [全部层级 ▼] [全部类型 ▼]                      156 条记忆         │
│                                                                   │
│              ·  ·                                                 │
│          ·   ╱ ╲  ·                                              │
│        ·  ◉──·──◉  ·    ◉ = 核心记忆                             │
│         ·  │╲ ╱│  ·     ● = 长期记忆                             │
│        ·   │ ◉ │ ·      ○ = 短期记忆                             │
│         ·  │╱ ╲│  ·     · = 工作记忆                             │
│          · ◉──·──◉                                               │
│              ·  ·                                                 │
│                                                                   │
│  ┌─ Tooltip ─────────────────────────┐                            │
│  │ core  情景记忆                     │                            │
│  │ 用户的职业是全栈工程师               │                            │
│  │ 重要度:80% 有效:88% 置信:98% 访问:23│                            │
│  └────────────────────────────────────┘                            │
└──────────────────────────────────────────────────────────────────┘
```

</details>

---

## 🧠 核心功能详解

### ① 主动记忆提取

每轮对话结束后，系统自动分析对话内容，通过 LLM 提取值得记住的信息：

| 应该提取                     | 不应该提取               |
| ---------------------------- | ------------------------ |
| 用户偏好（喜欢/讨厌/习惯）   | 通用知识（天气、新闻）   |
| 身份信息（职业/所在地/年龄） | 闲聊寒暄（你好、谢谢）   |
| 重要事件或经历               | 临时信息（今天几点开会） |
| 用户明确要求记住的内容       | 助手的回答内容           |
| 有情感色彩的表达             | -                        |

提取流程：

```
用户消息 → Agent.chat() → LLM 回复 → extractMemories()
                                        │
                                        ▼
                              发送上下文给提取 LLM
                                        │
                                        ▼
                              解析 JSON 事实列表
                                        │
                               ┌───────┴───────┐
                               ▼               ▼
                         置信度匹配        新建记忆
                      (冲突检测+强化)    (自动分层)
                               │               │
                               └───────┬───────┘
                                       ▼
                                 保存对话快照
```

### ② Embedding 语义检索

**两阶段混合检索**，平衡召回率和精度：

```
用户查询: "我喜欢什么编程语言"
          │
          ▼
┌─────────────────────────────────────┐
│ 阶段一：BM25 + 规则评分（同步）       │
│ · 分词 TF-IDF 余弦相似度 ×30         │
│ · 标签精确匹配 +12                   │
│ · 层级加成 (core 12 / long 6 / ...) │
│ · 时间新鲜度 (7天内 +4 / 3天内 +5)    │
│ → 召回 Top 30 候选                  │
└─────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────┐
│ 阶段二：Embedding 精排（异步）       │
│ · 查询向量 × 候选向量 → 余弦相似度    │
│ · 加权合并：BM25分数 + cos×45         │
│ → 返回 Top K 结果                   │
└─────────────────────────────────────┘
```

支持本地模型（`model/` 目录）和 CDN 远程加载两种模式，默认使用 `Xenova/all-MiniLM-L6-v2`（384 维）。

### ③ 置信度动态累积

```
新记忆创建: confidence = 0.3 (主动提取) 或 0.6 (手动/AI对话)
     │
     ▼
后续对话中再次提及相同信息
     │
     ├─ 无冲突 → confidence += 0.08 (上限 0.99)
     │
     └─ 有冲突 (否定词方向反转) → 旧记忆 confidence -= 0.2
                                 新记忆创建 (source: "冲突更新")
                                 旧记忆 tag += "可能过时"
```

冲突检测通过分析否定词（不、没、不再、讨厌、反感...）判断新旧信息方向是否一致。

### ④ 长内容切分 + 递归摘要

```
原文 (2000 字)
     │
     ▼ split()
┌─────────┬─────────┬─────────┐
│ Chunk 1 │ Chunk 2 │ Chunk 3 │   (500字/块, 80字重叠)
│ 500字   │ 500字   │ 500字   │
└────┬────┘────┬────┘────┬────┘
     │         │         │
     ▼         ▼         ▼
  LLM 摘要  LLM 摘要  LLM 摘要   (1-2句话)
     │         │         │
     └────┬────┴────┬────┘
          ▼         ▼
        合并 → 再次分割 → 再次摘要   (最多2层递归)
```

### ⑤ Token 预算智能选择

上下文窗口分配策略：

```
┌────────────────────────────────────────────┐
│            上下文窗口 (128K)                 │
├──────────┬────────────┬────────────────────┤
│ System   │  Memory    │  History           │
│ Prompt   │  Injection │  Messages          │
│ ~500 tok │  ~剩余预算  │  ~55% 总预算        │
└──────────┴────────────┴────────────────────┘

记忆注入优先级:
1. 核心记忆 → 全部注入 (不占预算，保底)
2. 搜索结果 → 按评分排序，动态内容长度
   · 排名 1-3:  300 字/条
   · 排名 4-8:  200 字/条
   · 排名 9+:   100 字/条
3. 相似记忆 → 标记 [旧版]，较新版本优先展示
```

### ⑥ 有效重要度算法

记忆的真实价值通过 **双时间线模型** 动态计算，综合以下因素：

```
EffectiveImportance = BaseImportance
                    × StorageDecay      // 存储衰减: exp(-decay × days × 0.3)
                    × RecencyBoost      // 检索活跃: exp(-decay × idleDays × 0.7)
                    × FreqFactor        // 频率因子: min(1, 0.3 + log₂(1+N) × 0.15)
                    × TemporalWeight    // 分布权重: 0.7 + (recentRatio × 0.3)
                    × ConfidenceFactor  // 置信度: 0.5 + confidence × 0.5
```

- **存储衰减**：记忆越老衰减越快（长期记忆衰减率 0.02/天，短期 0.15/天）
- **检索活跃**：最近被访问的记忆有显著加成
- **频率因子**：高频访问比低频更有价值（对数增长，边际递减）
- **时间分布**：近期集中访问 > 均匀分布
- **置信度因子**：高置信度放大概率，低置信度缩小

---

## 🏛️ 分层记忆架构

```
                    ┌─────────┐
                    │  CORE   │  核心记忆，永不遗忘
                    │  No decay│  · 用户身份信息
                    │  ∞ cap  │  · 核心偏好/约定
                    └────┬────┘
                         │ 访问≥20次 + 重要≥0.7
                    ┌────┴────┐
                    │LONG_TERM│  长期记忆，缓慢衰减
                    │ decay   │  · 已验证的事实
                    │ 0.02/day│  · 多次提及的偏好
                    │ cap:500 │  t½ ≈ 35 天
                    └────┬────┘
                         │ 访问≥5次 + (重要≥0.5 或 强化≥3)
                    ┌────┴────┐
                    │  SHORT  │  短期记忆，默认层级
                    │ _TERM   │  · 新信息
                    │ decay   │  · 待确认内容
                    │ 0.15/day│  t½ ≈ 4.6 天
                    │ cap:100 │
                    └────┬────┘
                         │ 访问≥2次
                    ┌────┴────┐
                    │ WORKING │  工作记忆，临时上下文
                    │  No decay│  · 对话历史快照
                    │  cap:20  │  · 截断溢出保存
                    └─────────┘
```

**自动巩固机制**（每 60 秒执行一次）：

- 符合条件 → 晋升到更高层级（带 7 天冷却期）
- 有效重要度 < 0.1 → 降一级
- 容量超限 → 淘汰最弱的记忆为新晋升腾位

---

## 🔧 工具调用

AI 助手拥有 7 个 Function Calling 工具：

| 工具               | 触发场景                     | 示例                         |
| ------------------ | ---------------------------- | ---------------------------- |
| `search_memory`    | 回答涉及用户信息的问题前     | "你之前说喜欢什么颜色？"     |
| `create_memory`    | 用户说"记住"或提供重要新信息 | "帮我记住我的生日是5月20日"  |
| `update_memory`    | 发现记忆过时或需修正         | 用户改了偏好                 |
| `delete_memory`    | 用户要求删除或信息完全过时   | "忘掉我之前说的那个"         |
| `list_memories`    | 浏览记忆库                   | "列出所有关于编程的记忆"     |
| `get_current_time` | 需要时间上下文               | 时间戳相关操作               |
| `get_conversation` | 查看记忆的原始对话           | "这条记忆是哪个对话产生的？" |

## 🎨 明暗主题

<p align="center">
  <em>深色模式（默认）</em> &nbsp;&nbsp;&nbsp;&nbsp; <em>浅色模式</em>
</p>

所有组件、Canvas 图表均支持主题切换，切换后自动持久化到 `localStorage`。CSS 变量驱动，涵盖背景、文字、边框、图表元素等全部颜色。

## 🚀 快速开始
### 方式一：npx 直接运行（无需克隆仓库）

```bash
# 需要 Node.js ≥ 18
npx memory-agent
# → 自动启动本地服务并打开浏览器 http://127.0.0.1:8080

# 常用选项
npx memory-agent --port 3000          # 自定义端口
npx memory-agent --host 0.0.0.0       # 允许局域网访问
npx memory-agent --no-open            # 不自动打开浏览器
npx memory-agent --help               # 查看全部选项
```

> 💡 包内不含 Embedding 模型文件（约 350MB），首次使用语义检索时自动从 HuggingFace CDN 下载模型（浏览器缓存，仅需一次）；也可以设置 `--host` 后在局域网内多人使用。

#### 导入本地模型

npm 包默认不携带模型，如需使用本地模型，可执行：

```bash
# 通过 npx 使用
npx memory-agent model:import

# 或克隆源码后使用 npm script
npm run model:import
```

命令会弹出文件夹选择器，选择包含模型文件的文件夹后，自动复制到**用户数据目录**（npm 包之外，更新软件版本不会丢失模型）：

| 平台 | 模型目录 |
| --- | --- |
| macOS | `~/Library/Application Support/memory-agent/model` |
| Linux | `~/.local/share/memory-agent/model`（或 `$XDG_DATA_HOME`） |
| Windows | `%APPDATA%\memory-agent\model` |

也可以在 **设置 → Embedding 向量模型 → 模型目录** 中点击「选择文件夹」配置自定义目录（`model:import` 导入与本地模型加载共用该目录；「恢复默认」回到默认目录）。

也支持无界面指定路径：

```bash
npx memory-agent model:import --path /path/to/model-folder
# 或
node scripts/model-install.mjs --path /path/to/model-folder
```





### 首次使用配置

1. 在欢迎页填写 LLM API 信息：
   - OpenAI: `https://api.openai.com/v1` + `gpt-4o-mini`
   - DeepSeek: `https://api.deepseek.com/v1` + `deepseek-chat`
   - 或点击快速配置按钮自动填充

2. 等待 Embedding 模型加载完成（侧栏状态指示器变绿）

3. 开始对话！系统会自动提取记忆

## 🗄️ 数据存储

```
PGlite (WASM PostgreSQL, IndexedDB 持久化): neural-memory-chat
├── conversations 表 — 每次会话一条记录（标题、预览、时间、消息数、活跃标记）
└── messages 表     — 每条可见对话消息一行（is_hidden 记忆注入消息不入库），完整消息对象存于 meta (JSON)
    ├── search_text 列 + pg_trgm GIN 索引 → 全文检索（中英文子串匹配）
    └── 完整保存每一条可见历史对话（不受条数上限约束），可随时回看与全文检索

IndexedDB: NeuralMemoryDB (v6)
├── memories store
│   ├── id (autoIncrement)
│   ├── indexes: type, layer, createdAt, importance, lastAccessed, conversationId
│   └── 每条记录含: summary, content, tags, embedding, 访问统计...
│
└── conversations store
    ├── id (autoIncrement)
    ├── index: memoryId, createdAt
    └── 每条记录含: memoryId, messages[], createdAt

localStorage:
├── nm_b, nm_k, nm_m       # API 地址、密钥、模型
├── nm_t, nm_mt, nm_ctx    # temperature、max_tokens、上下文窗口
├── nm_embed_mode, nm_embed_model  # Embedding 配置
├── nm_layer_limits        # 容量限制
├── nm_theme               # 主题偏好
└── nm_h                   # 当前会话历史缓存（最近 100 条，快速恢复用）
```

> **加载优先级**：刷新页面时**优先使用 localStorage**（同步读取、瞬时渲染，不等 PGlite 就绪）；
> localStorage 无数据时回退到 PGlite 完整历史。PGlite 就绪后自动把 localStorage 数据迁移/补齐到完整历史库，
> 后续增量同步按「偏移映射」定位，保证尾部恢复后新消息仍正确追加到库末尾。

### 数据管理

- **导出备份**：JSON 格式，含所有记忆和对话快照
- **导入恢复**：支持合并模式（保留现有 + 跳过重复 ID）和替换模式（清空后导入）
- **Markdown 导出**：按层级分组，适合阅读和分享

## 📊 衰退分析

### 衰减曲线

Canvas 绘制的实时衰减曲线，显示：

- **青色曲线**：短期记忆衰减（半衰期 ~4.6 天）
- **黄色曲线**：长期记忆衰减（半衰期 ~35 天）
- **红色区域**：危险区（有效重要度 < 20%）
- **散点**：每条有衰减的记忆的实际位置

### 遗忘预测

基于当前衰减率预测未来时间点的记忆丢失数量：

- 1天后、3天后、7天后、14天后、30天后

### 层级健康

四个层级的健康度百分比：

- 🟢 绿色：健康率 ≥ 70%
- 🟡 黄色：40-69%
- 🔴 红色：< 40%

---

## 🕸️ 记忆图谱

工具栏提供 **显示样式** 切换（`select`）：

- **球体布局**（默认）：节点均匀分布在球面上，立体展示，支持拖拽旋转与自转
- **力导向布局**：平面力导向算法

### 力导向布局

- **斥力**：节点间互斥 (F = 800 / d²)
- **引力**：相似记忆通过连线吸引（余弦 ≥ 0.4）
- **中心力**：所有节点被拉向画布中心
- **阻尼**：0.85，逐步收敛

### 球体布局

- Fibonacci 球面均匀撒点，节点按深度从远到近绘制（画家算法）
- 近处节点更大更亮，远处更小更淡（透视投影）
- 拖拽空白区域旋转球体（俯仰角限制 ±1.2 rad）
- 初始缓慢自转；悬停节点或按住拖拽旋转时暂停自转，拖拽结束后 3 秒恢复自转

交互：

- 🖱️ 拖拽节点重新布局（力导向）
- 🖱️ 拖拽空白区域：平移（力导向）/ 旋转球体（球体）
- 🖱️ 滚轮缩放（0.2x ~ 5x）
- 🖱️ 悬停显示详情 tooltip
- 🖱️ 点击进入记忆详情
- 🖱️ 点击节点聚焦：高亮该节点及其直接关联的节点与连线，其余节点与连线变暗（两种布局均支持）；再次点击同一节点或点击空白恢复

筛选器：

- 按层级：全部 / 工作 / 短期 / 长期 / 核心
- 按类型：全部 / 情景 / 语义 / 程序 / 情感

---

## 🧪 技术细节

### Token 估算

```
中文字符 × 0.7 + 英文字符 × 0.25 + 2 (padding)
```

适用范围：GPT 系列 tokenizer 的粗略估算，用于上下文预算分配。

### 双时间线模型

```
存储龄 = (now - createdAt) / 86400000         # 天数
检索龄 = (now - lastAccessed) / 86400000      # 天数
```

记忆的价值取决于两个时间维度：

1. **存储时间**：记忆有多老（影响基础衰减）
2. **检索间隔**：最近一次被访问是什么时候（影响活跃度加成）

### 容量淘汰策略

当层级达到容量上限时，按 `有效重要度` 升序排列，淘汰最弱的记忆：

- 如果可以降级 → 降到下一层
- 如果已是最低层 → 删除

---

## 🛠️ 开发

```bash
# 类型检查
npm run lint

# 格式化
npm run format

# 完整检查
npm run check
```

### 环境要求

- Node.js ≥ 18
- 现代浏览器（支持 IndexedDB、WebAssembly、Canvas）
- 如果使用本地 Embedding 模型，需要 `model/` 目录下的模型文件

---

## 📄 License

MIT
