云同步 (cmem.ai Pro)¶
云同步通过一个每用户同步中枢在设备之间复制你的本地记忆数据库——它是你所有设备写入内容的有序日志。该功能内置于 worker 中:没有守护进程——worker 在写入时同步。记录每条观察结果的同一进程也会上传它,并将其他设备的写入拉取回来。
Note
双通道,一个真相源。 所有持久数据都通过普通 HTTP 传输:推送追加到中枢的有序日志,拉取则用游标分页读取。可选的 Realtime 通道作为纯粹的加速层并行存在——它只是让下一次拉取更早发生。该通道可以被丢弃、禁用或出错,且零数据丢失;HTTP 游标始终是真相。
同步内容¶
有四种类型的行会在你的设备之间复制:
- 观察 — claude-mem 从你的会话中生成的压缩记忆。
- 会话摘要 — 每个会话的概览记录。
- 用户 Prompt — 你输入的 prompt。超过 200 KB 的 prompt 会上传其前 200 KB 外加一条截断说明;完整 prompt 仍保留在捕获它的设备上。
当同步中枢支持时,智能体工作状态也会同步:智能体保存的待办列表和工作状态,包括每个条目的字段。
除了这些行,三种变更也通过同一个日志传播,以便后续编辑在所有设备上收敛:会话标题更改、prompt→会话修复(在会话注册之前捕获的 prompt 会在每台设备上重新关联),以及项目重映射(工作树采用和基于 cwd 的移动会在每台设备上重新定向受影响的行)。
Warning
隐私: 云同步会将你的观察叙述和完整 prompt 文本上传到你的 cmem.ai 账户下的同步中枢。如果这些内容必须留在你的机器上,请不要启用它。
推送通道的工作原理¶
数据库就是队列。 每个已同步表都带有 synced_at 列(NULL = 尚未进入日志)。每次写入后,worker 会触发一个防抖的 flusher,它取出 WHERE synced_at IS NULL 的行,并在成功时打上标记。这一个机制同时处理实时同步、离线补传和重试。在 SyncHub 启动边界之后写入的行初始为 NULL;任何未能上传的行保持 NULL,直到后续 flush 将其拾取。启动前已有的本地行不会被当作云迁移语料库。
- 防抖: 写入突发会合并;flusher 在最后一次写入后约 1.5 s 运行(在加速层连接时为 250 ms),且同时只有一个 flush 在运行。
- 批量: 操作按每次请求最多 500 个操作 / 4,000,000 编码字节进行排空。每个单独的规范主体上限为 256,000 编码字节。
- 限时: 每个请求有 30 s 超时——网络死亡永远不会挂起 worker。
- 重试: 上传失败的行保持
NULL,会在下一次写入时重试,并附加有上限的指数退避(30 s → 10 min)。写入路径从不被阻塞——同步失败只造成延迟,没有任何其他代价。 - 幂等: 中枢按来源身份去重,因此重试的推送永远不会产生重复。
拉取通道的工作原理¶
每台设备都持有指向中枢日志的游标,并拉取游标之后的所有内容——按页拉取,所以离线一周(或全新设备从零开始)也能以与活跃设备保持最新相同的方式追上进度:
- 会话启动: worker 在注入上下文之前立即拉取(限制在 1.5 s 内,因此网络死亡不会卡住你的会话),这意味着另一台机器上写入的记忆在你开始工作的那一刻就已经就位。
- 稳定状态: 会话活跃时每 30 s 进行一次短轮询,空闲时每 5 min 一次,无活动一小时后完全暂停。每次推送响应还会报告日志头,因此活跃设备无需等待定时器结束就能获知远程写入。
- 像本地写入一样应用: 拉取的行保留其原始时间戳,携带其来源设备,通过与本地写入相同的路径索引到全文搜索和向量搜索,并被打上标记,因此绝不会被回传上传。
实时更新(可选)¶
启用后(默认启用),worker 还会为你的账户订阅一个私有 Realtime 通道。当另一台设备推送时,服务器广播一个微小的“日志已前进”信号,本设备立即拉取——多设备收敛大约在一秒内完成,而不是一个轮询间隔。该通道严格是通知性(advisory)的:它绝不携带你的数据,任何异常(连接断开、错过心跳、信号格式错误)都只会关闭它并回退到 HTTP 拉取,而 HTTP 拉取始终是正确的。将 CLAUDE_MEM_CLOUD_SYNC_WS 设为 false 即可关闭实时更新——同步在轮询延迟下依然完全正确。如果同步服务器不提供实时更新,worker 会保持轮询,并每小时再检查一次。
要求与设置¶
当 token、用户 ID 和中枢 URL 三者全部非空时,云同步处于活动状态——没有单独的启用开关;将其中任一项留空即可关闭同步。
- cmem.ai Pro 同步 token 和用户 ID(来自 cmem.ai → Connect)。
- 同步中枢 URL,位于
CLAUDE_MEM_CLOUD_SYNC_HUB_URL:https://sync.cmem.ai,安装器会为你写入(源码在services/sync-api/)。指向旧版 Cloudflare Workers hub 的中枢 URL 会自动迁移到该地址。
要连接,请在终端中运行 npx claude-mem install 并选择 CMEM Pro。安装器会让你通过浏览器登录,将这三个值写入 ~/.claude-mem/settings.json(模式 0600),并重启 worker。Claude Code 中的 /cloud-sync 技能会检查状态、引导你使用安装器进行设置,并验证已安装的客户端能否访问 SyncHub。它绝不会要求你把 token 粘贴到聊天中,因为粘贴到那里的任何内容都会进入会话记录。对于 CI 或远程机器,请参阅无头设置。
设置¶
| 键 | 默认值 | 含义 |
|---|---|---|
CLAUDE_MEM_CLOUD_SYNC_TOKEN |
'' |
你的 cmem.ai 同步令牌(来自 cmem.ai → Connect)。以 Authorization: Bearer 发送。 |
CLAUDE_MEM_CLOUD_SYNC_USER_ID |
'' |
你的 cmem.ai 用户 ID(来自 cmem.ai → Connect)。你的所有设备共享它——它决定了你的 hub 日志名称。 |
CLAUDE_MEM_CLOUD_SYNC_HUB_URL |
'' |
同步 hub 基础 URL。空 = 同步关闭。 |
CLAUDE_MEM_CLOUD_SYNC_WS |
'true' |
通过 Realtime 进行实时更新。'false' 禁用实时更新(仅 HTTP 轮询);在轮询延迟下,同步仍能保持完全正确。 |
CLAUDE_MEM_CLOUD_SYNC_DEVICE_ID |
'' |
此机器的稳定身份。首次启动时会生成并持久化一个新的 UUID。不要编辑它:每一行都归属于其来源设备。 |
CLAUDE_MEM_CLOUD_SYNC_DEVICE_NAME |
machine hostname | 此设备的人类可读标签。 |
CLAUDE_MEM_CLOUD_SYNC_CONTENT_BATCH_SIZE |
'40' |
每个内容刷新页的操作数。在 hub projection_busy 下,200 操作页会在 30 秒超时。最大 500。 |
CLAUDE_MEM_CLOUD_SYNC_REQUEST_TIMEOUT_MS |
'90000' |
内容推送 AbortSignal 超时。必须超过 hub 的 45 秒 projection 获取;默认值与 90 秒 projection 租约一致。 |
一个 Hub 每个账户最多接受 64 个不同的设备 ID。达到上限时,现有设备继续正常同步;新设备会收到 409 device_limit_exceeded。状态/元数据读取以及重命名未知设备不会创建幽灵设备。
状态端点¶
Worker 在与其他 worker HTTP API 相同的端口上暴露 GET /api/sync/status。它是无条件注册的,因此未配置的安装会返回 200 而不是 404——调用者可以区分“未设置”和“worker 宕机”。
已配置:
{
"configured": true,
"deviceId": "2f6b1c9e-7d41-4c1a-9b0e-3d5f8a2c6e10",
"pending": { "observations": 0, "summaries": 0, "prompts": 2, "mutations": 0, "tombstones": 0 },
"quarantine": { "count": 0, "latestReason": null },
"lastFlushAt": 1783981042731,
"lastError": null,
"hub": {
"checkedAt": 1783981042800,
"reachable": true,
"epoch": "1783981042000",
"headSeq": "42",
"projectedSeq": "42",
"error": null
}
}
每次已配置的状态请求都会直接向 SyncHub 发出一次经过身份验证的只读 GET /v1/sync/status,即使在所有待处理计数为零时也是如此。该探测不会追加操作,也不会推进拉取游标。因此,hub.reachable: false 和 hub.error 会暴露错误的令牌、错误的 Hub URL、格式错误的响应、超时或网络故障——而这些在队列为空时本会被隐藏。
pending— 仍在等待上传的行(以及排队的变更操作)。计数接近 0 表示 hub 的日志已包含此设备写入的所有内容。lastFlushAt— 上次成功刷新的纪元毫秒数,首次之前为null。lastError— 最近一次失败刷新的消息,健康时为null。它绝不会包含令牌。hub— 最近一次经过身份验证的 SyncHub 探测。将hub.reachable: true视为连通性检查;仅lastError: null不够。序列和纪元字段仍保持十进制字符串。
未配置:
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/claude-mem