Metadata-Version: 2.4
Name: palacelite
Version: 0.7.0
Summary: 轻量级本地 AI 记忆系统
Author: fajknli
License-Expression: AGPL-3.0-or-later
Project-URL: Changelog, https://github.com/fajknli/palacelite/blob/main/CHANGELOG.md
Classifier: Development Status :: 4 - Beta
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
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: <3.15,>=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sqlite-vec>=0.1.9
Requires-Dist: sentence-transformers>=5.0.0
Requires-Dist: click>=8.1.0
Requires-Dist: jieba-fast>=0.53
Requires-Dist: numpy>=1.26.0
Requires-Dist: rich>=13.0.0
Provides-Extra: chat
Requires-Dist: llama-cpp-python>=0.3.0; extra == "chat"
Provides-Extra: test
Requires-Dist: pytest>=8.0.0; extra == "test"
Dynamic: license-file

# PalaceLite

轻量级 · 纯本地 · 可解释的 AI 记忆系统

[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![PyPI version](https://badge.fury.io/py/palacelite.svg)](https://pypi.org/project/palacelite/)

---

当对话结束，记忆不应消失。PalaceLite 用结构代替摘要，用本地存储代替云端同步，用透明公式代替黑盒检索。

Rooted. Reflecting.

这不是在造工具，是在造一面随时间生长的镜子。


## 核心特性

| 特性 | 说明 |
|------|------|
| 纯本地运行 | 单 SQLite 文件存储元数据 + 向量，零外部依赖 |
| 三层空间隐喻 | Wing → Room → Drawer，贴合人类记忆组织方式 |
| 透明混合检索 | 5 因子加权公式，每因子可调可审计 |
| 矛盾检测 | 自动识别观点变化，写入关系表 |
| 主动提醒 | AI 在对话中温和指出用户前后不一致 |
| 异步提炼 + 规则兜底 | 后台压缩用户输入，关键词规则自动分类 |
| 数据反哺工作流 | audit 命令输出关键词建议，结构从使用中生长 |

## 核心概念

- **Wing**：work / life / tech / unsorted（系统预置）
- **Room**：每个 Wing 下默认 general，按需添加
- **Drawer**：单条记忆，存储内容 + 向量 + 元数据
- **Relation**：记忆之间的关系（矛盾、支持、演化）
- **Patrol Queue**：主动巡逻队列，定期扫描矛盾

## 快速开始

### 安装

```bash
# 核心功能
pip install palacelite

# 含对话支持
pip install "palacelite[chat]"
```

### 准备模型

PalaceLite 需要自备 GGUF 格式的模型文件：

| 模型 | 用途 | 是否必需 |
|------|------|----------|
| 对话模型 | 生成 AI 回复 | 必需 |
| 提炼模型 | 压缩用户输入为简洁记忆 | 可选 |

```bash
# 首次运行会自动下载嵌入模型（约 100MB），之后永久离线使用
palacelite chat -m ~/models/qwen-7b.gguf --online
```

### 日常使用

```bash
# 默认进入 unsorted/general
palacelite chat -m ~/models/qwen-7b.gguf

# 指定工作空间
palacelite chat -m ~/models/qwen-7b.gguf -w work -r auth-design
```

### 命令行管理

```bash
# 添加记忆
palacelite add -w tech -r db -c "PostgreSQL 并发写入优于 MySQL"

# 搜索
palacelite search -q "数据库选型" -w tech

# 检测矛盾
palacelite detect --wing tech

# 盘点未分类记忆
palacelite audit -k 15

# 恢复所有归档记忆
palacelite unarchive-all

# 查看统计
palacelite stats
```

## 命令速查

### CLI 命令

| 命令 | 说明 |
|------|------|
| `add -w <wing> -r <room> -c <内容>` | 添加记忆 |
| `search -q <关键词> [-w wing] [-r room]` | 搜索记忆 |
| `list [-w wing] [-r room] [-l 数量] [-a]` | 列出活跃记忆 |
| `list-ids [-w wing] [-r room] [-l 数量]` | 紧凑显示记忆 ID |
| `detect --wing <wing> [--threshold 0.6]` | 检测矛盾并写入关系表 |
| `move -i <id> [-w wing] [-r room]` | 移动单条记忆（支持前缀匹配） |
| `move -i <id1> -i <id2> [-w wing] [-r room]` | 移动范围内记忆 |
| `move-all -fw <wing> [-fr room] -tw <wing> -tr <room>` | 批量移动记忆 |
| `audit [-k N] [-w wing]` | 盘点高频词，输出分类建议 |
| `stats` | 显示数据库统计 |
| `archive-old [--days N] [--importance N]` | 批量归档旧记忆 |
| `list-archived` | 列出已归档记忆 |
| `export-archived [-o 路径]` | 导出归档记忆到 JSON |
| `delete-archived` | 永久删除归档记忆 |
| `unarchive-all` | 一键恢复所有归档记忆 |

### 对话内命令

| 命令 | 说明 |
|------|------|
| `/mem <关键词>` | 搜索记忆 |
| `/add <内容>` | 手动添加记忆 |
| `/list [N]` | 列出最近 N 条 |
| `/move <id> [id2] <wing>/<room>` | 移动记忆 |
| `/reflect` | 检测当前空间的矛盾 |
| `/wings` / `/rooms` | 列出空间结构 |
| `/cd [wing]/[room]` | 切换当前空间 |
| `/stats` / `/clear` / `/help` / `/quit` | 系统操作 |

## 主动矛盾提醒

PalaceLite 不仅能被动检测矛盾，还能在对话中主动提醒：

```
你: 我觉得 MySQL 比 PostgreSQL 好

AI: 你之前好像说过 PostgreSQL 比 MySQL 好，现在觉得 MySQL 更好，是想法变了吗？
```

系统会：
1. 自动检测用户当前说法与历史记忆的矛盾
2. 将矛盾信息注入上下文
3. 由 AI 用温和的语气主动提醒

同一矛盾不会重复提醒，避免唠叨。

## 记忆的根

一个 AI 可以记住你，但它知道自己是谁吗？

PalaceLite 不回答这个问题。它只做三件事：
- 给每条记忆一个可验证的身份（DID）
- 给 AI 一个属于自己的 Wing，记录它对用户的认知演化
- 把矛盾、支持、演化写成关系，永久存储

这不是让 AI 拥有意识。是让它拥有可追溯、可验证、可迁移的存在感。

根不在代码里。根在你愿意持续写进去的那些话里。

## 检索原理

```
score = similarity × time_decay × importance × freshness × keyword_bonus
```

| 因子 | 计算方式 | 可调参数 |
|------|----------|----------|
| 向量相似度 | 余弦相似度（sqlite-vec 批量计算） | 无 |
| 时间衰减 | 0.5 ^ (天数/30)，最低 0.1 | half_life_days=30 |
| 重要性 | 0.5 + min(importance,10)/10，范围 0.6~1.5 | 用户标记 1~10 |
| 新鲜度 | 7 天内线性加成，最高 1.5× | freshness_days=7 |
| 关键词匹配 | Jaccard 相似度（jieba 分词），最高 1.5× | keyword_weight=0.5 |

所有因子均在 `retrieval.py` 中明文实现。

## 架构概览

```
用户对话
   │
   ▼
Distiller（异步提炼）→ 队列 → Storage（SQLite + sqlite-vec）
   │                              │
   ▼                              ▼
Manager（规则分类）        Retriever（透明混合检索）
   │                              │
   └──────────┬───────────────────┘
              ▼
      PalaceLite Core（统一 API）
              │
              ▼
   主动提醒 + 矛盾检测 + 关系存储
```

## 设计原则

质量 · 本地 · 透明 · 克制 · 人工在环

## 定位说明

PalaceLite 不提供 API 接入，也不计划支持云端模型调用。

记忆数据是你最私密的数字资产。一旦通过 API 发送给云端模型，数据就已离开你的控制范围。

PalaceLite 选择纯本地：
- 对话模型在本地运行
- 记忆存储在本地 SQLite
- 检索计算在本地完成

至于你想用 CLI 模式把记忆复制到 ChatGPT/Claude —— 那是你的自由。工具不限制你，但也不替你送出去。

如果你需要更强模型，建议等待本地模型能力演进，或自行部署更大参数的 GGUF 模型。

## 配置

### 环境变量

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `PALACE_MODEL_PATH` | — | GGUF 模型路径 |
| `PALACE_MODEL_DIR` | `~/Public/ai/models` | 模型默认存放目录 |
| `GPU_LAYERS` | 20 | GPU 加速层数 |
| `PYTHONLOGLEVEL` | INFO | 设为 DEBUG 输出分类调试日志 |

### 工作目录

默认：`~/.palacelite`

自定义：
```python
from palacelite import PalaceLite
p = PalaceLite(workspace="/custom/path")
```

数据库文件：`~/.palacelite/palace.db`（单文件，含元数据 + 向量）

## 维护指南

### 分类关键词维护

```bash
palacelite audit -k 15
```

输出示例：
```
建议新增分类关键词（当前未覆盖，可直接复制）：
["PostgreSQL", "asyncio", "部署"]
```

复制列表 → 粘贴到 `palacelite/manager.py` 对应分类 → 保存生效

### 更换嵌入模型后重建向量

```bash
python scripts/rebuild_embeddings.py --workspace ~/.palacelite
```

### 导出记忆用于微调

```bash
python scripts/clean_memories.py ~/backup.json ~/cleaned.json
```

### 运行测试

```bash
pytest
pytest palacelite/tests/test_retrieval.py -v
pytest -v -x
```

## 依赖

```txt
# 核心
sqlite-vec>=0.1.0
sentence-transformers>=5.0.0
click>=8.0.0
rich>=13.0.0
jieba>=0.42.1
numpy>=1.20.0

# 可选
llama-cpp-python>=0.3.0

# 开发
pytest>=7.0.0
```

安装：
```bash
pip install palacelite              # 仅核心
pip install "palacelite[chat]"      # 含对话
```

## 项目结构

```
palacelite/
├── palacelite/
│   ├── __init__.py          # 版本与导出
│   ├── core.py              # PalaceLite 主类
│   ├── storage.py           # SQLite + sqlite-vec 存储层
│   ├── retrieval.py         # 透明混合检索
│   ├── distiller.py         # 异步记忆提炼
│   ├── manager.py           # 规则分类器
│   ├── models.py            # 数据模型
│   ├── utils.py             # 工具函数
│   ├── cli.py               # 命令行
│   ├── chat.py              # 对话入口
│   └── tests/               # 测试套件
├── pyproject.toml
├── requirements.txt
├── pytest.ini
├── README.md
└── LICENSE
```

## 许可证

AGPL-3.0 License

---

<p align="center"><strong>Rooted.</strong></p>
