Metadata-Version: 2.4
Name: dual-mem
Version: 0.1.3
Summary: Dual-system layered memory SDK
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.6
Requires-Dist: pydantic-settings>=2.2
Requires-Dist: pyyaml>=6.0
Requires-Dist: openai>=1.30
Requires-Dist: httpx>=0.27
Requires-Dist: chromadb>=1.0
Requires-Dist: kuzu>=0.4
Requires-Dist: numpy>=1.26
Provides-Extra: api
Requires-Dist: fastapi>=0.110; extra == "api"
Requires-Dist: uvicorn>=0.29; extra == "api"
Provides-Extra: cli
Requires-Dist: typer>=0.12; extra == "cli"
Provides-Extra: mcp
Requires-Dist: mcp<2,>=1.2; extra == "mcp"
Provides-Extra: agentica
Requires-Dist: agentica; extra == "agentica"
Provides-Extra: test
Requires-Dist: agentica; extra == "test"
Provides-Extra: all
Requires-Dist: dual-mem[api,cli,mcp]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: dual-mem[all,test]; extra == "dev"
Dynamic: license-file

[**🇨🇳中文**](https://github.com/shibing624/dual-mem/blob/main/README.md) | [**🌐English**](https://github.com/shibing624/dual-mem/blob/main/README_EN.md)

# dual-mem: Dual-System Layered Memory SDK
[![PyPI version](https://badge.fury.io/py/dual-mem.svg)](https://badge.fury.io/py/dual-mem)
[![License Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![python_version](https://img.shields.io/badge/Python-3.11%2B-green.svg)](pyproject.toml)
[![GitHub issues](https://img.shields.io/github/issues/shibing624/dual-mem.svg)](https://github.com/shibing624/dual-mem/issues)
[![Wechat Group](https://img.shields.io/badge/wechat-group-green.svg?logo=wechat)](#社区与支持)

**dual-mem** 让 Agent **真正记住用户**——不是堆聊天记录，而是像人一样：**先快速记下今天说了什么，再慢慢整理成用户画像、习惯和未来打算**。分层存储、偏好会变就更新、检索时自动带出相关记忆。通过 **SDK / REST / MCP / CLI / Skill** 即插即用。

## JEV 四层记忆架构

`system1` 与 `dual` 的每次写入共享一个流程：**保留 L0 原文 → 生成候选 → JEV 批量裁决 → 追加版本并链接历史**。`dual` 额外在显式 `digest()` 中生成跨证据记忆。

| 层 | 保存内容 |
| --- | --- |
| L0_RAW | 原始来源证据 |
| L1_FACT | 显式事实、独立事件、明确意图 |
| L2_PROFILE | 用户身份、状态、画像维度 |
| L3_DERIVED | 跨证据模式、推导、摘要 |

JEV 判断 `ADD / DELETE / SKIP` 及 `OVERRIDE / MERGE / SUPPLEMENT / TEMPORAL / NEGATE / CONFLICT`；生成模型只提供候选、合并文本和推导文本。正常写入一次生成、一次 JEV，多个问题共享 state，HTTP 请求默认并行 4。

北京→上海→北京是对当前状态的更新；不会因为历史曾出现北京而跳过。相似度仅用于读侧检索，novelty 与 weak_candidate_score 不参与写入。所有 reconcile 保留原文与版本，通过 `is_latest` 区分当前表示。

本分支为 SDK 破坏性设计迁移：`update()` 返回新版本 ID，`delete()` 归档；默认读取 latest。旧层名、旧存储自动迁移及旧控制键兼容已删除；配置只接受规范平铺键。已有 `.dual_mem_data` 不能打开，换一个新的 `storage_dir`。使用前配置 `jev_api_key`、`llm_api_key`、`embed_api_key`，或注入三个 provider。

[完整设计与迁移](docs/jev-memory-design.md) · `docs/design/jev-memory-flow.html`（本地流程页，不提交） · [层定义](docs/memory_layers.md)

## 为什么选 dual-mem

| | |
|---|---|
| **开箱即用** | `SyncMemoryClient` 三行写入 + 搜索；配置首次启动自动生成 |
| **Agent 友好** | 多轮 `messages` 一次写入；与 Agentica 等框架对接见 [Quickstart](docs/getting-started/quickstart.md) |
| **会进化** | 偏好更新走演化链，不是粗暴覆盖 |
| **五种接入** | 同一套 `MemoryClient`，按需装 REST / MCP / CLI |

## 🔥 News

- [2026/10/15] **v0.1.3**：JEV 四层记忆与 target-first 裁决；`update` 返回新 id，`delete` 归档。旧数据目录不能打开，需换新的 `storage_dir`。一并纳入生态集成与实验性 coding。
- [2026/06/20] **v0.1.2**：MemoryOperations 统一 REST/MCP；SyncMemoryClient；CLI `messages`；post-extract embed 合并；MCP 启动修复与文档。
- [2026/06/19] **v0.1.1**：依赖拆分为 `[api]` / `[cli]` / `[mcp]` extras；默认 `hybrid` 读路径。
- [2026/06/18] **v0.1.0**：首版开源 — system1 / dual 两档、演化链、REST `/v1/memories/` 契约、MCP 工具集。

## 架构一览

```
  你的 Agent / 应用
        │  SDK · REST · MCP · CLI · Skill
        ▼
   MemoryClient（写入 System1 / 检索 / 演化链）
        │
   向量 + 图 + 本地存储
```

实现细节（JEV 写入裁决、Reconcile、混合检索管线等）见 [架构文档](docs/architecture.md) · [在线文档](https://shibing624.github.io/dual-mem/architecture/)。

## 安装

需要 Python ≥ 3.11。

```bash
pip install dual-mem              # 核心 SDK
pip install dual-mem[all]         # + REST / CLI / MCP
```

开发安装：

```bash
git clone https://github.com/shibing624/dual-mem.git
cd dual-mem
pip install -e ".[dev]"
```

| Extra | 依赖 | 用途 |
|---|---|---|
| `api` | fastapi, uvicorn | `dual-mem serve`、REST API |
| `cli` | typer | `dual-mem add/search/...` |
| `mcp` | mcp | `dual-mem-mcp`、Cursor MCP |
| `agentica` | agentica | agentica 框架记忆集成 |
| `all` | api + cli + mcp | REST / CLI / MCP 一次装齐 |

## 快速开始

脚本 / 同步应用（推荐入门）：

```python
from dual_mem import SyncMemoryClient

with SyncMemoryClient(mode="system1", storage_dir="./.dual_mem_data") as client:
    client.add(
        content="我最爱的编程语言是 Java，已经用了5年。",
        user_id="alice",
    )
    res = client.search(
        query="用户的编程语言偏好",
        user_id="alice",
    )
    for m in res.memories.profile:
        print(m.content)
```

FastAPI / asyncio Agent 用异步客户端（同一内核，可 `await`）：

```python
import asyncio
from dual_mem import MemoryClient


async def main():
    client = MemoryClient(mode="system1", storage_dir="./.dual_mem_data")
    await client.add(content="...", user_id="alice")
    await client.aclose()


asyncio.run(main())
```

配置位于 `~/.dual_mem/config.yaml`（**首次启动自动创建**）。**JEV、生成 LLM、Embedding 三套服务均需配置或注入**。

→ 参数详解、多轮对话、`aclose()`、Agent 集成最佳实践见 **[Quickstart 文档](docs/getting-started/quickstart.md)**（在线：[Quickstart](https://shibing624.github.io/dual-mem/getting-started/quickstart/)）。

## 功能特性

- **四个阶段层 + 演化链** — `L0_RAW` 到事实、画像和 `L3_DERIVED`，偏好变更可追溯
- **System1 短期记忆** — 写入即结构化；由 JEV 决定写入动作与关系
- **System2 深度记忆**（dual）— 在明确业务边界调用 `digest()` 归纳 L3_DERIVED
- **混合检索** — 语义 + 关键词；画像 / 主动 / 常规三路召回
- **同步 & 异步 SDK** — `SyncMemoryClient` 给脚本；`MemoryClient` 给 FastAPI / Agent
- **OpenAI 兼容** — 任意 LLM / Embedding 端点
- **单产品默认** — 省略 `app_id` 时用 `default_app_id`（默认 `"default"`）；`user_id` 为主隔离键

## 两档模式

| | **system1**（默认） | **dual** |
|---|---|---|
| 短期记忆 | ✓ | ✓ |
| 深度记忆 | — | ✓（显式 `digest()` 巩固） |
| 适合 | 个人助手、客服、快速接入 | 需要行为画像、意图推断的深度场景 |
| 图关联 | 关 | 开（记忆之间可关联） |

## REST / MCP / CLI

```bash
pip install dual-mem[all]

dual-mem serve --host 0.0.0.0 --port 8000          # REST
dual-mem-mcp                                          # MCP stdio
dual-mem-mcp --transport streamable-http --port 8765 # MCP HTTP /mcp
dual-mem add --content "用户喜欢咖啡" --app-id default --user-id u1
dual-mem search "饮品偏好" --app-id default --user-id u1
dual-mem digest   # dual：生成 L3_DERIVED
```

REST 契约：`POST /v1/memories/`、`POST /v1/memories/search`、`GET|DELETE /v1/memories/{id}` 等。MCP 分 **本地 uvx**（已实现）与 **云端 HTTP**（REST 底座已就绪，HTTP MCP 待封装）两条路径，详见 [MCP 接入](docs/mcp_integration.md)。

## 生态集成

`dual_mem.integrations` 把同一个 `MemoryClient` 适配到主流 Agent 框架与协议，共享统一的记忆注入块格式化（`<relevant-memories>`）：

| 后端 | 接入 | 说明 |
|------|------|------|
| **agentica** | `dual-mem[agentica]` | `DualMemMemory` / `DualMemWorkspace`，直接 `Agent(workspace=...)` |
| **Claude Code** | `dual-mem-hook search` / `ingest` | UserPromptSubmit / Stop hook，自动注入与归档 |
| **Hermes** | `DualMemHermesProvider` | MemoryProvider 插件（prefetch + `sync_turn`） |
| **OpenClaw** | `DualMemOpenClawProvider` | 与 Hermes 同源契约 |
| **MCP** | `dual_mem.integrations.mcp` | FastMCP server（`dual-mem-mcp`） |

```bash
pip install dual-mem[agentica]   # agentica 框架
dual-mem-hook search              # Claude Code: 搜记忆注入 additionalContext
dual-mem-hook ingest              # Claude Code: 提取对话写入记忆
```

> 另有 **coding 记忆子系统**（`dual_mem.coding`，`coding_enabled=true`）针对含工具调用的工程对话。它走同一套 JEV 动作，默认关闭。

## 示例

查看 [examples/](https://github.com/shibing624/dual-mem/tree/main/examples) 获取完整示例，涵盖：

| 类别 | 内容 |
|------|------|
| **SDK 基础** | 短期记忆写入、演化链、多轮 `messages` |
| **深度记忆** | dual 模式、显式 `digest()` 巩固 |
| **REST** | FastAPI TestClient 走 `/v1/memories/` 全契约 |
| **生命周期** | `add_raw` / `distill`、原文检索、`update` 新 id、归档删除 |
| **CLI** | `dual-mem` 子命令 add / search / list / delete |

[→ 查看完整示例目录](https://github.com/shibing624/dual-mem/blob/main/examples/README.md)

```bash
python examples/01_system1.py
python examples/02_dual.py
python examples/03_rest_api.py
python examples/04_cli.py
python examples/05_lifecycle.py
```

> 示例需真实 JEV、LLM 与 Embedding，会产生少量费用。

## 文档

完整使用文档：**https://shibing624.github.io/dual-mem**

本地预览：

```bash
pip install -r requirements-docs.txt
mkdocs serve
```

## 社区与支持

- **GitHub Issues** — [提交 issue](https://github.com/shibing624/dual-mem/issues)
- **微信群** — 添加微信号 `xuming624`，备注 "llm"，加入技术交流群

<img src="https://github.com/shibing624/agentica/blob/main/docs/assets/wechat.jpeg" width="200" />

## 引用

如果您在研究中使用了 dual-mem，请引用：

> Xu, M. (2026). dual-mem: Dual-System Layered Memory SDK for LLM Applications. GitHub. https://github.com/shibing624/dual-mem

## 许可证

[Apache License 2.0](LICENSE)

## 贡献

欢迎贡献！请查看 [CONTRIBUTING.md](CONTRIBUTING.md)。

## 致谢

- [chromadb/chroma](https://github.com/chroma-core/chroma) — 向量存储
- [kuzudb/kuzu](https://github.com/kuzudb/kuzu) — 图存储
- [tiangolo/fastapi](https://github.com/tiangolo/fastapi) — REST 层
- [modelcontextprotocol/python-sdk](https://github.com/modelcontextprotocol/python-sdk) — MCP 集成
- [mem0ai/mem0](https://github.com/mem0ai/mem0) — 记忆 SDK 生态
