内容
# mema
**可验证的七层AI智能体记忆。**
mema 为智能体提供了一种记忆,这种记忆可以被监管者、审计员或客户检查。它是为瑞士和欧盟的背景下设计的,适用于 FINMA、GDPR 和修订后的 nFADP,并强调审计重放、硬擦除、租户隔离和司法管辖区感知治理,以及回忆质量。底层是一个普通的 markdown 保险库:没有图数据库,没有向量数据库扩展,也没有区块链。文件系统是事实来源,每个索引都是派生状态,可以从中重建。
---
## 为什么
记忆错误会累积。一个错误或未归因的事实今天写入,就成为智能体明天推理的前提,而这个错误的成本随着时间推移而未被发现而不断增长。mema 在写入路径上设置了控制,这样坏记录在进入检索表面之前就被阻止,而不是在造成损害后才被发现。每次回忆都返回一个收据:`score_components`、`why_retrieved`、`governance` 决策、内容哈希和 UAL 记录,这些记录已被包装为资产。
---
## 七层
```
┌─────────────────────────────────────────────────────────────────┐
│ L7 资产 (内容哈希 + 元数据哈希 + UAL + 锚点) │
├─────────────────────────────────────────────────────────────────┤
│ L6 审计 (SHA-256 哈希链日志 + 密封见证) │
├─────────────────────────────────────────────────────────────────┤
│ L5 检索 (关键词 + IDF + 向量 + 图 + 策略) │
├─────────────────────────────────────────────────────────────────┤
│ L4 治理 (目的、保留、来源、硬擦除) │
├─────────────────────────────────────────────────────────────────┤
│ L3 认知 (经验、观察、信念、反思) │
├─────────────────────────────────────────────────────────────────┤
│ L2 语义 (实体 + 事实 + 双时间有效性) │
├─────────────────────────────────────────────────────────────────┤
│ L1 事件 (原始对话、文档、工具调用) │
└─────────────────────────────────────────────────────────────────┘
```
每一层都是一个或多个位于 `src/v2/layer{N}-*.ts` 下的 TypeScript 文件。文件系统布局反映了架构:`data/episodes/`、`data/facts/`、`data/cognitive/`、`data/v2-entities/`、`data/_meta/audit.sqlite`、`data/_meta/vectors.sqlite`、`data/_meta/anchors.sqlite`。
mema 借鉴了 Zep(双时间事实)、Hindsight(认知分离)、Mem0(生产记忆管道)和 OriginTrail(可验证的知识资产),但在没有图数据库底层、在线 LLM 提取或区块链依赖的情况下交付。有关相关工作的完整定位,请参见 [`docs/WHITEPAPER.md`](docs/WHITEPAPER.md)。
---
## 亮点
- **v2.22.13.** 538 个测试在 63 个测试文件中通过(1,362 个 `expect()` 断言),在 4 秒内使用 `bun test` 运行。
- **96.0% Precision@1** 在 347 文档语料库上的 25 查询检索基准测试中,相对于 v1 关键词基线为 44.0%。这是 `bench/recall-benchmark-v2.py` 中记录的 v2.0.0 架构的测量值;可以重新运行它以重现针对您自己的语料库的测试。
- **外部评估工具** 用于 LongMemEval(`bench/longmemeval-harness.ts`)和 LoCoMo(`bench/locomo-harness.ts`),具有用于单标志消融的检索模式和融合模式标志。
- **信任基准测试** (`bench/swiss-trust-bench.ts`):12 个端到端场景,涵盖严格模式拒绝、目的和司法管辖区不匹配、跨租户隔离、硬擦除审计重放和审计链完整性。这些是采购复选框属性,回忆基准测试无法衡量。
- **不信任生产者的接受生命周期**:LLM 提取器提出草稿,证据检查门控提升,审计链中记录每个转换。
- **严格策略模式** (`MEMA_POLICY_MODE=strict`)拒绝缺少治理、司法管辖区不匹配和监管云路由而无需人工审查。
- **具有审计来源的硬擦除**:擦除记录预擦除 `record_id`、内容和元数据哈希、`legal_basis`,而无需保留擦除的内容。
- **MCP 服务器**,向 Claude Code、Cursor 或任何 MCP 客户端公开九种 v2 工具,以及三个独立的对抗性安全审查和已交付的缓解措施。
> **v1 保留不变**,位于 `/v1/*` 以实现向后兼容。新部署应使用 v2。
---
## 快速入门
```bash
git clone https://github.com/machtsinnch/mema && cd mema
bun install
# 启动服务器(开发的宽松速率限制)
MACHTSINN_RATE_LIMIT_BURST=10000 ./scripts/start.sh
# 验证
curl http://localhost:3001/health
# 运行完整的测试套件
bun test
# 导入语料库
bun scripts/import-tree.ts /path/to/your/markdown/folders
# 构建向量索引(幂等,每次语料库更改一次)
curl -X POST http://localhost:3001/v2/vector/reindex -H "x-api-key: dev-ardin"
# 运行 v2 回忆基准测试
python3 bench/recall-benchmark-v2.py
```
---
## HTTP API
### v2(推荐)
| 方法 | 端点 | 层 | 目的 |
|---|---|---|---|
| POST | `/v2/observe` | L1 | 摄入原始事件(默认运行提取) |
| POST | `/v2/fact` | L2 | 记录双时间事实。传递 `status: "draft"` + `evidence_excerpt` 以获取不受信任的生产者 |
| POST | `/v2/fact/:id/invalidate` | L2 | 标记事实无效或被取代 |
| POST | `/v2/fact/:id/approve` | L2 | 提升草稿事实(除非 `force: true`,否则运行服务器端证据检查) |
| POST | `/v2/fact/:id/reject` | L2 | 拒绝草稿事实(需要 `reason`) |
| GET | `/v2/facts/drafts` | L2 | 列出所有者草稿事实 |
| GET | `/v2/facts/valid-at?at=...` | L2 | 在给定时间戳处有效的事实 |
| POST | `/v2/entity` | L2 | 创建实体(支持 `status: "draft"`) |
| GET | `/v2/entity/find/:name` | L2 | 将名称或别名解析为实体 |
| POST | `/v2/entity/:keeperId/merge/:mergedId` | L2 | 合并两个实体 |
| POST | `/v2/cognitive` | L3 | 记录经验、观察或信念 |
| POST | `/v2/reflect` | L3 | 运行自动化反思 |
| POST | `/v2/governance/build` | L4 | 从源计算治理块 |
| POST | `/v2/erase` | L4 | 硬擦除记录(墓碑 + 审计) |
| POST | `/v2/recall` | L5 | 混合检索,返回可验证的数据包 |
| POST | `/v2/recall/packet` | L5 | 查询的编译记忆数据包 |
| POST | `/v2/vector/reindex` | L5 | 重建向量索引 |
| GET | `/v2/graph/derived-from/:id` | L5 | 步行支持记录 |
| GET | `/v2/audit/log` | L6 | 查询审计日志 |
| GET | `/v2/audit/verify` | L6 | 验证哈希链完整性 |
| POST | `/v2/asset/wrap` | L7 | 将记录包装为可验证的资产 |
| POST | `/v2/asset/anchor` | L7 | 将资产锚定到目标 |
| GET | `/v2/asset/anchors?ual=...` | L7 | 列出调用者的锚点 |
完整的路由集,包括认知审批、判断、矛盾和取代,位于 `src/index.ts`。v1 操作(`/v1/remember`、`/v1/recall`、`/v1/memory/:id`、`/v1/forget`、`/v1/promote`、`/v1/link`、`/v1/log`、`/v1/stats`)保留在 `/v1/*`。
身份验证:`x-api-key` 头。开发密钥:`dev-ardin`、`dev-marcel`、`dev-founder3`。
---
## MCP 服务器
添加到 `~/.claude.json` 或 `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"machtsinn": {
"command": "bun",
"args": ["/absolute/path/to/mema/src/mcp.ts"],
"env": {
"MACHTSINN_URL": "http://localhost:3001",
"MACHTSINN_KEY": "dev-ardin",
"MACHTSINN_ACTOR": "claude-code"
}
}
}
}
```
v2 工具:`memory_v2_observe`、`memory_v2_fact`、`memory_v2_recall`、`memory_v2_reflect`、`memory_v2_audit_log`、`memory_v2_audit_verify`、`memory_v2_erase`、`memory_v2_asset_wrap`、`memory_v2_asset_anchor`。八个 v1 工具(`memory_remember`、`memory_recall`、`memory_show`、`memory_forget`、`memory_promote`、`memory_stats`、`memory_health`、`memory_log`)仍然可用。
---
## 不信任生产者的接受生命周期
LLM 提取器和其他不受信任的生产者不直接写入检索表面。他们提出草稿,一个证据检查的审查步骤将它们提升为 `approved` 或标记为 `rejected`。
```
原始事件 ─▶ LLM 提取器 ─▶ 草稿事实/实体(状态:“草稿”)
│
▼
证据检查门控
│
┌───────────┴───────────┐
▼ ▼
APPROVED REJECTED
(在回忆中可见) (保留用于审计,
永远不可检索)
```
门控在 `/v2/fact/:id/approve` 上运行在服务器端,并在事实的 `subject` 或 `object` 不出现在源事件正文中时返回 `422 evidence_check_failed`(不区分大小写)。传递 `force: true` 以覆盖同义词或别名情况。每个转换都追加一个 `APPROVE` 或 `REJECT` 条目到哈希链审计日志中,并且 `verifyChain()` 包括它们。没有明确 `status` 的记录默认为 `approved`,因此生命周期是可选的,并且与现有保险库向后兼容。
---
## 架构不变
1. **文件系统是事实来源。** SQLite(审计、向量、锚点)是派生状态,可以从 markdown 保险库中重建。
2. **所有写入路径都是原子的**(临时 + fsync + 重命名 via `src/v2/atomic.ts`)。v2 接口中不再直接使用 `writeFileSync`。
3. **所有读取操作都按所有者过滤**(v1 中的 `canRead`,v2 中的拒绝所有者不匹配)。无例外。
4. **统一 404**,用于未找到与不可读的记录。
5. **每个用户提供的段都进行路径净化**,包括 URL 解码后的 UAL。
6. **审计日志是只追加的**,具有哈希链和外部密封见证。
7. **不受信任的生产者只写入草稿**,并且在进入检索表面之前由接受生命周期控制。
---
## 威胁模型
mema v2 经历了三次独立的对抗性审查。已交付缓解措施:
| 攻击 | 缓解措施 |
|---|---|
| 审计行删除或后缀删除 | 序列连续性检查 + `sqlite_sequence` 比较 + 外部密封见证 |
| 通过竞争的审计链分叉 | `appendAudit` 封装在 `BEGIN IMMEDIATE` 事务中 |
| 跨租户回忆或锚点泄漏 | 所有者过滤器默认为拒绝;`listAnchors` 为所有者范围 |
| UAL 路径遍历 | 在 URL 解码后应用 `SAFE_SEGMENT` 正则表达式 |
| NaN/Inf 置信度中毒 | 在每次写入和读取边界处使用 `clampConfidence()` |
| 磁盘填充 DoS | 请求体上限(`MACHTSINN_V2_MAX_BODY_BYTES`) |
| 无声检索失败 | ripgrep 退出代码检查,如果缺少二进制文件则抛出 |
| 向量跨嵌入者污染 | 向量搜索按嵌入者名称过滤 |
完整详细信息请参见 [`docs/WHITEPAPER.md`](docs/WHITEPAPER.md) 第 4.4 至 4.5 节。
---
## 图视图
三种方式查看记忆网络,共享一个层颜色调色板:
- **Obsidian:** 打开 `data/` 作为保险库并运行 `./scripts/install-obsidian-config.sh` 以安装层着色,然后运行 `Cmd+G`。
- **内置查看器:** 打开 `http://localhost:3001/graph`,输入 API 密钥,并加载零依赖力导向画布。
- **外部工具:** `curl 'http://localhost:3001/v2/graph?limit=2000'` 返回 `{nodes, edges, stats}`,可用于 Cytoscape、vis-network、Gephi 或 D3。
---
## 技术栈
- Bun 和 TypeScript
- Hono 用于 HTTP
- `bun:sqlite` 用于审计、向量和锚点存储
- `@modelcontextprotocol/sdk` 用于 MCP 服务器
- ripgrep 用于关键词搜索(系统依赖)
- gray-matter 用于 frontmatter,ulid 用于 ID
没有图数据库,没有向量数据库扩展,没有区块链。可选的语义嵌入在没有外部嵌入器的情况下会回落到本地哈希嵌入器。
---
## 许可证
**商业源代码许可证 1.1**,转换为 **Apache 2.0 于 2030-05-15**。非生产用途(评估、学术研究、安全审查、内部开发)是免费的。生产用途需要商业许可证:联系许可方。
BUSL 从 v2.9.0 开始生效。**v2.0.0 至 v2.8.0 版本仍受 MIT 许可**,在其发布的 git 标签中可见。参见 [`LICENSE`](LICENSE)、[`NOTICE-LICENSE-HISTORY.md`](NOTICE-LICENSE-HISTORY.md) 和 [`LICENSE-MIT-PRE-V2.9.md`](LICENSE-MIT-PRE-V2.9.md),了解完整的历史记录。