# 记忆模型

在选择集成方式前，先理解持久事实、决策、交接和来源归属。

- Canonical: https://docs.xmemo.dev/zh/docs/concepts/memory-model
- Locale: zh-CN
- Content-Locale: zh-CN
- Canonical-Content-Digest: 9ffe2da573b664ce4e37254715ed959c138dfd6b89262c6d0a1bda8dd473291a
- Edition-Digest: 0987d35d64db596fccb884866d9a18fd0de6398f23d7dcc6bda7eef28e50cfce
- Source-Revision: sha256:310bf66a9ffcf2384ebc6400fad1b1da9d01fa0cdadc9d129c9084e880334e73

## XMemo 存储什么

XMemo 保存当前聊天或任务结束后仍然有用的持久上下文：项目事实、决策、偏好、修正和交接备注。临时的对话噪声、一次性回答和原始工具输出不属于 memory。

- semantic — 跨会话仍然成立的持久事实和决策。
- episodic — 发生在任务或会话某个时刻的事件。
- procedural — 在本项目中执行任务的方法。
- working — 当前正在进行的任务的活动状态。
- identity — 关于 owner 或 agent 本身的稳定信息。

## 写入持久 memory

持久写入需要 content、连接到项目或 namespace 的逻辑 path，以及 memory type。后续 recall 会按 path 进行过滤。

```ts
remember({
  content: "Use OAuth for hosted ChatGPT connections.",
  path: "projects/memory-os/decisions"
})
```

## SDK 中的 memory type

MemoryCandidate.memory_type 通过 TypeScript SDK 接受同一组值，因此经过规范化的 agent event 会携带应存储的 type。

```ts
import { normalizeAgentEvent, toMemoryCandidate } from '@xmemo/client';

const event = normalizeAgentEvent(
  { type: 'command_completed', command: 'pytest', exit_code: 0, output: '12 passed' },
  { source: 'shell', defaultAgentId: 'codex' },
);

console.log(toMemoryCandidate(event).memory_type); // episodic
```

## 交互式来源出处与生命周期演示（合成演示）

分步可验证的生命周期演示，展示记忆创建、跨客户端检索、具有版本更替（v1 -> v2）的实时用户修正、Token 预算保护、软删除墓碑标记以及隔离的合成销毁。每一步均有一次性运行时凭证支持，零暴露真实用户记忆：

- 步骤 1 [STATE_1_CREATED_ACTIVE_V1]：Agent A (Claude Desktop) 通过 tools.py::remember 写入初始偏好，附带不可篡改的作者、实例哈希和设备元数据 — 回执：状态 200 OK，demo_mem_lifecycle_001@v1，active — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。
- 步骤 2 [STATE_2_ACCESSED_ATTRIBUTED]：同一授权作用域内的 Agent B (Codex CLI) 立即通过 tools.py::recall 检索记忆，附带引用回执且跨客户端零漂移 — 回执：状态 200 OK，引用 demo_mem_lifecycle_001@v1 — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。
- 步骤 3 [STATE_3_CORRECTED_SUPERSEDED_V2]：用户通过 tools.py::update_memory 修正会议室和时间。VersionController 为 v1 创建不可变快照（status='superseded'）并将活动记录升至 v2 — 回执：状态 200 OK，v2，父版本 v1，差异：Room Orion -> Room Polaris — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。
- 步骤 4 [STATE_4_RETRIEVAL_FILTERED]：后续 recall 查询仅选择活动 v2，而已废弃的 v1 被严格过滤出 LLM 上下文窗口以防止幻觉并节省 Token 预算 — 回执：状态 200 OK，选择 v2，已排除更替的 v1 — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。
- 步骤 5 [STATE_5_TOMBSTONE_DELETED]：所有者通过 tools.py::forget 将事实标记为已删除。它立即从召回候选查询中排除，并移入带恢复操作的回收站视图 — 回执：状态 200 OK，状态：deleted，候选数：0 — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。
- 步骤 6 [STATE_6_RESET_PURGED]：隔离的一次性销毁（reset_synthetic_state）将演示作用域记录清除至磁盘上正好 0 个残留行。个人账户硬重置（POST /api/v1/me/memories/reset）被严格排除 — 回执：teardown_status: SUCCESS_PURGED，residual_rows: 0，account_hard_reset_called: FALSE — 状态：[SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 边界：[DEMO_DATA: SYNTHETIC]。

```text
+------------------------------------------------------------------------------------------------------------------------+
| [PROVENANCE & LIFECYCLE 6-STATE STATE MACHINE: DISPOSABLE HARNESS WALKTHROUGH]                                        |
|                                                                                                                        |
|  Agent A (Claude Desktop)    XMemo FastMCP & Engine           Agent B (Codex CLI)          Demo Owner (Supervising)    |
|  [04f9b8c2 / MacBook]        [VersionController / Scope]      [e81d7a31 / Workstation]     [user:demo_owner]           |
|         |                               |                              |                              |                |
|  (1) remember(sync in Orion)            |                              |                              |                |
|  -------------------------------------> |                              |                              |                |
|         |                          [STATE 1: Created Active v1]        |                              |                |
|  <------------------------------------- |                              |                              |                |
|    Receipt: mem-001@v1                  |                              |                              |                |
|         |                               |      (2) recall(sync)        |                              |                |
|         |                               | <--------------------------- |                              |                |
|         |                               |  [STATE 2: Cited @v1]        |                              |                |
|         |                               | ---------------------------> |                              |                |
|         |                               |   Citation: mem-001@v1       |                              |                |
|         |                               |                              |   (3) update_memory(Polaris) |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               |                          [STATE 3: Bump v2, Supersede v1]   |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               |                          Receipt: mem-001@v2 (parent: v1)   |                |
|         |                               |                              |                              |                |
|         |                               |      (4) recall(Polaris)     |                              |                |
|         |                               | <--------------------------- |                              |                |
|         |                               |  [STATE 4: Select v2,        |                              |                |
|         |                               |   Filter superseded v1]      |                              |                |
|         |                               | ---------------------------> |                              |                |
|         |                               |   Citation: mem-001@v2 only  |                              |                |
|         |                               |                              |   (5) forget(mem-001)        |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               |                          [STATE 5: Tombstone / Trash View]  |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               |                          Receipt: status=deleted            |                |
|         |                               |                              |                              |                |
|         |                               |   (6) reset_synthetic_state()                               |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               | [STATE 6: Teardown Purge]                                   |                |
|         |                               | Scope purged: 0 residual rows (account reset excluded)      |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               | Teardown Status: SUCCESS_PURGED                             |                |
+------------------------------------------------------------------------------------------------------------------------+
```

## ChatGPT 用户

让 ChatGPT 持久访问你的 XMemo 偏好、项目事实、决策和 TODO，同时不把 bearer token 粘贴到聊天里。

通过 ChatGPT/OpenAI app 的 OAuth 流程连接托管 XMemo MCP server，然后为你的 XMemo 账户批准 memory:read 与 memory:write 授权。

保存一条合成偏好或项目笔记，开启新聊天，再让 ChatGPT 在继续工作前通过 XMemo 召回它。

如果 OAuth 失败或工具未出现，先在宿主应用里退出该 MCP server，重新连接 XMemo server URL 并重试，再考虑创建 direct token。

## Copilot / Codex 开发者

在 IDE 与 CLI agent 之间携带仓库决策、编码规范、bug 修复说明和任务历史。

在可用时对 VS Code / GitHub Copilot 和 Gemini CLI 使用 OAuth。对于 Copilot CLI、Codex、Cursor 或其他直连 MCP 客户端，请在本地环境或密钥存储中保留 XMEMO_KEY，并设置稳定的 XMEMO_AGENT_INSTANCE_ID。

记录一条代码库决策或 bug 修复，然后让下一个 IDE 或 CLI agent 在编辑前召回相关 XMemo 上下文。

如果召回为空，检查所选 MCP 配置路径、direct client 的 XMEMO_KEY 环境变量，以及宿主应用中是否存在过期 OAuth 凭据。

## 团队 / 企业 pilot owner

用账户控制、来源归因、导出/删除流程和 reviewer-safe 设置证据来评估共享记忆。

创建或进入受保护的 XMemo workspace，邀请已批准用户，然后根据 readiness badges 通过 OAuth 或 scoped direct credential 连接各客户端。

让一名 pilot 成员保存一条合成团队记忆，在 XMemo 中确认来源归因，然后审阅删除/导出和支持路径。

如果成员无法连接，先检查角色权限、OAuth 批准、客户端 readiness 状态和支持指引，再签发新 token。

## 自主 agent operator

让 headless 或定时 agent 记录进度、取回历史决策，并保持稳定的非秘密实例身份。

获取 /api/v1/mcp/config/autonomous-agent。当 runner 支持 OAuth + 自定义 headers 时优先使用 auth_modes.oauth；只有完全 headless 的 runner 才使用 auth_modes.xmemo_key，并从密钥库读取 XMEMO_KEY。

运行一个会向 XMemo 写入进度的合成任务，重启 runner，并确认它使用同一个 XMEMO_AGENT_INSTANCE_ID 召回该进度。

如果归因变化或召回分散到多个实例，请把 XMEMO_AGENT_INSTANCE_ID 持久化到 git 之外，并确认 runner 不会每次启动都重新生成它。
