← Back to Plugins
Tools

Pi Memory

bushuhui By bushuhui 👁 46 views ▲ 0 votes

Enhanced Long-Term Memory Plugin for OpenClaw, Hermes, Claude Code

GitHub

Install

npm install
```

Configuration Example

{
  "plugins": {
    "load": {
      "paths": ["plugins/pi-memory"]
    },
    "entries": {
      "pi-memory": {
        "enabled": true,
        "config": {
          "embedding": {
            "apiKey": "${JINA_API_KEY}",
            "model": "jina-embeddings-v5-text-small",
            "baseURL": "https://api.jina.ai/v1",
            "dimensions": 1024,
            "taskQuery": "retrieval.query",
            "taskPassage": "retrieval.passage",
            "normalized": true
          }
        }
      }
    },
    "slots": {
      "memory": "pi-memory"
    }
  }
}

README

<div align="center">

# 🧠 pi-memory · OpenClaw Plugin

**[OpenClaw](https://github.com/openclaw/openclaw) 增强型 LanceDB 长期记忆插件**

混合检索(Vector + BM25)· 跨编码器 Rerank · 多 Scope 隔离 · 管理 CLI · 独立 HTTP/MCP Server

[![OpenClaw Plugin](https://img.shields.io/badge/OpenClaw-Plugin-blue)](https://github.com/openclaw/openclaw)
[![LanceDB](https://img.shields.io/badge/LanceDB-Vectorstore-orange)](https://lancedb.com)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

</div>


---

## 为什么需要这个插件?

OpenClaw 内置的 `memory-lancedb` 插件仅提供基本的向量搜索。**pi-memory** 在此基础上进行了全面升级:

| 功能 | 内置 `memory-lancedb` | **pi-memory** |
|------|----------------------|----------------------|
| 向量搜索 | ✅ | ✅ |
| BM25 全文检索 | ❌ | ✅ |
| 混合融合(Vector + BM25) | ❌ | ✅ |
| 跨编码器 Rerank(Jina) | ❌ | ✅ |
| 时效性加成 | ❌ | ✅ |
| 时间衰减 | ❌ | ✅ |
| 长度归一化 | ❌ | ✅ |
| MMR 多样性去重 | ❌ | ✅ |
| 多 Scope 隔离 | ❌ | ✅ |
| 噪声过滤 | ❌ | ✅ |
| 自适应检索 | ❌ | ✅ |
| 管理 CLI | ❌ | ✅ |
| Session 记忆 | ❌ | ✅ |
| Task-aware Embedding | ❌ | ✅ |
| 任意 OpenAI 兼容 Embedding | 有限 | ✅(OpenAI、Gemini、Jina、Ollama 等) |
| **独立 HTTP Server** | ❌ | ✅(REST API + MCP Server,单端口) |
| **外部系统集成** | ❌ | ✅(Hermes Agent、Claude Code、任意脚本) |

pi-memory 基于项目 https://github.com/CortexReach/memory-lancedb-pro 改进而来。

---

## 架构概览

### OpenClaw 插件模式

```
┌─────────────────────────────────────────────────────────┐
│                   index.ts (入口)                        │
│  插件注册 · 配置解析 · 生命周期钩子 · 自动捕获/回忆       │
└────────┬──────────┬──────────┬──────────┬───────────────┘
         │          │          │          │
    ┌────▼───┐ ┌────▼───┐ ┌───▼────┐ ┌──▼──────────┐
    │ store  │ │embedder│ │retriever│ │   scopes    │
    │ .ts    │ │ .ts    │ │ .ts    │ │    .ts      │
    └────────┘ └────────┘ └────────┘ └─────────────┘
         │                     │
    ┌────▼───┐           ┌─────▼──────────┐
    │migrate │           │noise-filter.ts │
    │ .ts    │           │adaptive-       │
    └────────┘           │retrieval.ts    │
                         └────────────────┘
    ┌─────────────┐   ┌──────────┐
    │  tools.ts   │   │  cli.ts  │
    │ (Agent API) │   │ (CLI)    │
    └─────────────┘   └──────────┘
```

### 独立 HTTP/MCP Server 模式

```
┌──────────────────────────────────────────────────────┐
│                  pi-memory-server                     │
│              (单进程 · 单端口 · 9873)                  │
│                                                      │
│  ┌─────────────┐    ┌──────────────┐                 │
│  │  REST API   │    │  MCP Server  │                 │
│  │   (router)  │    │  /mcp (SSE)  │                 │
│  └──────┬──────┘    └──────┬───────┘                 │
│         │                  │                         │
│    ┌────▼────┐   ┌─────────▼────────┐                │
│    │middleware│   │StreamableHTTP    │                │
│    │(auth/CORS)│  │Transport(无状态)  │                │
│    └────┬─────┘   └────────┬─────────┘                │
│         │                  │                         │
│    ┌────▼────┐   ┌─────────▼────────┐                │
│    │ memory   │   │ knowledge        │                │
│    │ API      │   │ API              │                │
│    └────┬─────┘   └────────┬─────────┘                │
│         │                  │                         │
│    ┌────▼──────────────────▼─────────┐               │
│    │        server-bootstrap.ts       │               │
│    │  (embedder · store · retriever   │               │
│    │   · knowledgeStore · indexer)    │               │
│    └──────────────────────────────────┘               │
└──────────────────────────────────────────────────────┘
         │                          │
   ┌─────▼─────┐           ┌────────▼────────┐
   │ Hermes    │           │ Claude Code     │
   │ Agent     │           │ / 任意脚本      │
   └───────────┘           └─────────────────┘
```

### 文件说明

| 文件 | 用途 |
|------|------|
| `index.ts` | 插件入口。注册到 OpenClaw Plugin API,解析配置,挂载 `before_agent_start`(自动回忆)、`agent_end`(自动捕获)、`command:new`(Session 记忆)等钩子 |
| `openclaw.plugin.json` | 插件元数据 + 完整 JSON Schema 配置声明(含 `uiHints`) |
| `package.json` | NPM 包信息,依赖 `@lancedb/lancedb`、`openai`、`@sinclair/typebox`、`@modelcontextprotocol/sdk` |
| `cli.ts` | CLI 命令实现:`memory list/search/stats/delete/delete-bulk/export/import/reembed/migrate` |
| `src/store.ts` | LanceDB 存储层。表创建 / FTS 索引 / Vector Search / BM25 Search / CRUD / 批量删除 / 统计 |
| `src/embedder.ts` | Embedding 抽象层。兼容 OpenAI API 的任意 Provider(OpenAI、Gemini、Jina、Ollama 等),支持 task-aware embedding(`taskQuery`/`taskPassage`) |
| `src/retriever.ts` | 混合检索引擎。Vector + BM25 → RRF 融合 → Jina Cross-Encoder Rerank → Recency Boost → Importance Weight → Length Norm → Time Decay → Hard Min Score → Noise Filter → MMR Diversity |
| `src/scopes.ts` | 多 Scope 访问控制。支持 `global`、`agent:<id>`、`custom:<name>`、`project:<id>`、`user:<id>` 等 Scope 模式 |
| `src/tools.ts` | Agent 工具定义:`memory_recall`、`memory_store`、`memory_forget`(核心)+ `memory_stats`、`memory_list`(管理) |
| `src/knowledge-store.ts` | 知识库存储层。LanceDB 知识库表、FTS 索引、向量搜索 |
| `src/knowledge-indexer.ts` | 知识库索引器。扫描目录、分块、向量化、增量索引 |
| `src/knowledge-tools.ts` | 知识库工具定义:`knowledge_search`、`knowledge_index`、`knowledge_stats` |
| `src/noise-filter.ts` | 噪声过滤器。过滤 Agent 拒绝回复、Meta 问题、寒暄等低质量记忆 |
| `src/adaptive-retrieval.ts` | 自适应检索。判断 query 是否需要触发记忆检索(跳过问候、命令、简单确认等) |
| `src/migrate.ts` | 迁移工具。从旧版 `memory-lancedb` 插件迁移数据到 Pro 版 |
| `src/server-config.ts` | 服务器配置加载器。4 层优先级:CLI > 环境变量 > openclaw.json > 默认值 |
| `src/server-response.ts` | HTTP 响应辅助函数。统一 JSON 响应格式 |
| `src/server-middleware.ts` | HTTP 中间件。API Key 认证、CORS、请求日志 |
| `src/server-router.ts` | 轻量级 HTTP 路由器。方法+路径匹配、URL 参数提取 |
| `src/server.ts` | 统一 HTTP 服务器。REST API + MCP StreamableHTTP,单端口共享 |
| `src/server-bootstrap.ts` | 服务器启动引导。组件初始化(embedder → store → retriever → knowledge → server) |
| `scripts/pi-memory-server.ts` | CLI 入口脚本。独立服务器启动入口,支持 `--port`/`--host`/`--api-key`/`--no-http`/`--no-mcp` 等参数 |

---

## 核心特性

### 1. 混合检索 (Hybrid Retrieval)

```
Query → embedQuery() ─┐
                       ├─→ RRF 融合 → Rerank → 时效加成 → 重要性加权 → 过滤
Query → BM25 FTS ─────┘
```

- **向量搜索**: 语义相似度搜索(cosine distance via LanceDB ANN)
- **BM25 全文搜索**: 关键词精确匹配(LanceDB FTS 索引)
- **融合策略**: Vector score 为基础,BM25 命中给予 15% 加成(非传统 RRF,经过调优)
- **可配置权重**: `vectorWeight`、`bm25Weight`、`minScore`

### 2. 跨编码器 Rerank

- **Jina Reranker API**: `jina-reranker-v2-base-multilingual`(5s 超时保护)
- **混合评分**: 60% cross-encoder score + 40% 原始融合分
- **降级策略**: API 失败时回退到 cosine similarity rerank

### 3. 多层评分管线

| 阶段 | 公式 | 效果 |
|------|------|------|
| **时效加成** | `exp(-ageDays / halfLife) * weight` | 新记忆分数更高(默认半衰期 14 天,权重 0.10) |
| **重要性加权** | `score *= (0.7 + 0.3 * importance)` | importance=1.0 → ×1.0,importance=0.5 → ×0.85 |
| **长度归一化** | `score *= 1 / (1 + 0.5 * log2(len/anchor))` | 防止长条目凭关键词密度霸占所有查询(锚点:500 字符) |
| **时间衰减** | `score *= 0.5 + 0.5 * exp(-ageDays / halfLife)` | 旧条目逐渐降权,下限 0.5×(60 天半衰期) |
| **硬最低分** | 低于阈值直接丢弃 | 移除不相关结果(默认 0.35) |
| **MMR 多样性** | cosine 相似度 > 0.85 → 降级 | 防止近似重复结果 |

### 4. 多 Scope 隔离

- **内置 Scope 模式**: `global`、`agent:<id>`、`custom:<name>`、`project:<id>`、`user:<id>`
- **Agent 级访问控制**: 通过 `scopes.agentAccess` 配置每个 Agent 可访问的 Scope
- **默认行为**: Agent 可访问 `global` + 自己的 `agent:<id>` Scope

### 5. 自适应检索

- 跳过不需要记忆的 query(问候、slash 命令、简单确认、emoji)
- 强制检索含记忆相关关键词的 query("remember"、"之前"、"上次"等)
- 支持 CJK 字符的更低阈值(中文 6 字符 vs 英文 15 字符)

### 6. 噪声过滤

在自动捕获和工具存储阶段同时生效:
- 过滤 Agent 拒绝回复("I don't have any information")
- 过滤 Meta 问题("do you remember")
- 过滤寒暄("hi"、"hello"、"HEARTBEAT")

### 7. Session 记忆

- `/new` 命令触发时可保存上一个 Session 的对话摘要到 LanceDB
- 默认关闭(`enabled: false`),因为 OpenClaw 已有原生 .jsonl 会话保存
- 开启会导致大段摘要污染检索质量,建议仅在需要语义搜索历史会话时开启
- 可配置消息数量(默认 15 条)

### 8. 自动捕获 & 自动回忆

- **Auto-Capture**(`agent_end` hook): 从对话中提取 preference/fact/decision/entity,去重后存储(每次最多 3 条)
- **Auto-Recall**(`before_agent_start` hook): 注入 `<relevant-memories>` 上下文(最多 3 条)

### 9. 独立 HTTP Server + MCP Server

v1.2.0 新增:pi-memory 可作为独立 HTTP/MCP 服务运行,无需通过 OpenClaw Gateway。外部系统(Hermes Agent、Claude Code、任意脚本)可通过 REST API 或 MCP 协议调用知识库检索和记忆管理功能。

#### 9.1 启动

```bash
# 使用默认配置启动(端口 9873)
pi-memory-server

# 或通过 npm script
npm run server

# 指定端口和主机
pi-memory-server --port 9873 --host 0.0.0.0

# 仅启用 REST API(禁用 MCP)
pi-memory-server --no-mcp

# 仅启用 MCP(禁用 REST API)
pi-memory-server --no-http

# 启用 API Key 认证
pi-memory-server --api-key your-secret-key
```

#### 9.2 配置加载

配置直接从 `~/.openclaw/openclaw.json` 中读取(`plugins.entries["pi-memory"].config`),与 OpenClaw 插件使用同一份配置。

优先级:**CLI 参数 > 环境变量 > openclaw.json > 内置默认**

| 环境变量 | 说明 |
|----------|------|
| `PI_MEMORY_EMBED_API_KEY` | Embedding API Key |
| `PI_MEMORY_EMBED_BASE_URL` | Embedding Base URL |
| `PI_MEMORY_EMBED_MODEL` | Embedding 模型名 |
| `PI_MEMORY_EMBED_DIMENSIONS` | Embedding 维度 |
| `PI_MEMORY_DB_PATH` | 数据库路径 |
| `PI_MEMORY_API_KEY` | HTTP 服务 API Key |
| `PI_MEMORY_HTTP_HOST` | HTTP 监听地址 |
| `PI_MEMORY_HTTP_PORT` | HTTP 监听端口 |
| `PI_MEMORY_KNOWLEDGE_PATHS` | 知识库路径(JSON 数组) |
| `PI_MEMORY_RERANK_API_KEY` | Reranker API Key |
| `PI_MEMORY_RERANK_MODEL` | Reranker 模型 |
| `PI_MEMORY_RERANK_ENDPOINT` | Reranker 端点 |
| `PI_MEMORY_RERANK_PROVIDER` | Reranker 提供商 |

#### 9.3 REST API 端点

**健康检查:**

| 方法 | 端点 | 说明 |
|------|------|------|
| `GET` | `/health` | 服务状态、版本、内存使用 |

**记忆管理(`/api/memory`):**

| 方法 | 端点 | 说明 |
|------|------|------|
| `POST` | `/api/memory/search` | 搜索记忆(混合检索) |
| `POST` | `/api/memory/store` | 存储新记忆 |
| `GET` | `/api/memory/list` | 列出记忆(分页) |
| `GET` | `/api/memory/stats` | 记忆统计信息 |
| `DELETE` | `/api/memory/:id` | 删除记忆 |
| `PATCH` | `/api/memory/:id` | 更新记忆 |

**知识库(`/api/knowledge`):**

| 方法 | 端点 | 说明 |
|------|------|------|
| `POST` | `/api/knowledge/search` | 搜索知识库(混合检索) |
| `POST` | `/api/knowledge/index` | 重建知识库索引 |
| `GET` | `/api/knowledge/stats` | 知识库统计信息 |

所有 POST 请求体为 JSON 格式,响应统一为 `{ "success": true/false, "data": {...}, "error": "..." }`。

#### 9.4 MCP Server(Streamable HTTP Transport)

MCP Server 与 REST API 共享同一进程和端口,通过 `/mcp` 端点提供服务。使用 MCP 2024-11-05 协议,Streamable HTTP 传输(SSE 的继任者),无状态

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...