deskpaw-memory/OBJECT_MEMORY.md

13 KiB
Raw Permalink Blame History

对象记忆与两阶段整理(2026-10-13)

本文件描述两阶段对象记忆实现。已于 2026-10-14 00:34 与 Agent 配套部署;实际记录见第 8 节。部署不等于已有记忆全部重新整理完成。

1. 定义

  • 事件:带发生时间的不可变原文,保存在 timeline。时间不明确用接入时间。
  • 热时间轴:Super 的基础上下文。近期是事件原文片段,整理后是概括索引头,children 可逐级展开到原文。
  • 经历附件:退出热时间轴的事件原文;仍在原表,不删除、不另复制一份。不要求每个事件都提炼出对象。
  • 长期对象:稳定 ID 对应一份高度概括、当前有效的档案。人物、任务、待办、日程、知识、项目采用相同结构。credential 仅额外保存用途/引用,不保存密钥值。
  • 项目:也是对象,同时是可交叉的关联集合,不是独占文件夹。日常是内置 project:daily。
  • 附件关系:对象→事件的证据索引,及事件→对象的归档索引。原话、工具流水留在附件,不不断追加进正文。

建议正文:人物的身份/职责/特点/协作提示;任务的目标/进度/约束/下一步;待办的事项/条件/状态;日程的时间规则/事项/状态;知识的结论/适用条件/经验;项目的范围/目标/现状。缺失信息标记未知,不猜测补全。object.status 是记忆生命周期,业务“待办/完成”等写在正文。

2. 两种职责,三个执行模式

timeline 原文 → 热时间轴
                  │ compact
                  ├─ 概括头替换原文节点
                  └─ 保留原文 + 持久归档队列
                                  │ organize / deep
                                  ├─ 对象档案及联系 → linked
                                  ├─ 仅留经历附件 → archive_only
                                  └─ 尚未完成 → continue 检查点

compact:时间轴整理

模型只拿本批节点与一个压缩提交工具,不再加载对象正文、核心文件、目录和对象写入协议。校验覆盖范围和实际缩短后,在同一 SQLite 事务中创建概括头、停用原热节点、登记待归档事件、记录回执。尝试顺便写对象会被拒绝。

事件最多 32,000 字符,原文热节点每片 2,000 字符。一个大事件可能跨多个批次;只有全部原文片段退出热时间轴,整个事件才进入归档队列。再次压缩概括头不会让已归档事件重新入队。

阈值任务在低于阈值 60% 或固定范围已处理后结束;主动 compact 处理请求范围内全部节点。整理期间新进入的后缀不被覆盖。

organize:对象归档

每批领取一个事件的一页原文,以及预算内的相关对象。Memory 可以浏览全库、检索、读取对象/来源,再分批写人物、任务、项目、联系等。一次提交可更新多个有关对象。

每个领取的事件必须明确处置:

outcome 含义及程序约束
continue 还有下一页,或还有对象工作;保存 progress。末页继续必须确实更新对象/关系/core,不允许无进展空转
linked 全事件读完,至少有一个持久对象/core 目标;允许只挂附件而不重复改写已有事实
archive_only 全事件读完,没有对象目标,明确说明无需更新对象的原因;仍可按时间查询原文

正文、关系、附件目标、页游标、进度和完成处置同事务提交。后续失败不撤销前一批成功写入。下一批读取当前档案和 progress,继续未完成部分。已有对象目标的事件不能再说完全无长期价值;linked/archive_only 不再参与小时扫描。

deep:深度对象审阅

沿用对象归档协议,另外持久建立首次领取时的全库对象清单,包括归档和长期未提及的对象。每批最多审阅四个,显式确认已审阅的 ID;没变化的对象无需重写,失败不推进清单。

处理跨项目关系、过时结论、重复与可复用知识;不再改热时间轴,不每天强行修改人格。必要时展开原文,不强制每晚重读全量附件。

边界:未被 compact 摘取的近期事件不会仅因 hourly/deep 而进入归档。若要立刻把最新对话形成对象,先 compact,再 organize/deep;请求本身也是事件。全库可寻址不代表模型已理解全库每句话。

3. 触发与调度

触发 行为
达到时间轴阈值 compact,沿用估算 token 口径
Super 主动 memory_organize(mode, scope, retry_blocked?),只等待入队回执
每 1 小时 持久记录检查时间;存在 pending 事件且无在途 hourly 作业才创建 organize,空队列不调用模型
每日 02:50,五分钟无对话 deep;按本地日期去重,不安静则延后,启动时已过该时间可补本日一次

Worker 每两秒检查,已经开始的归档作业逐批推进,不是每批再等一小时。Worker 在 Agent 进程内;Agent 停止则不调用模型。

只有一个有效租约。按上次领取时间轮转,未领取过的任务中主动请求优先;持续压缩不再永久压住夜间任务。Super 忙时不领下一批,已经在后台运行的请求不阻塞前台。scope 是给模型的目标和检索线索,不是硬性权限/范围过滤。

4. 对象和召回

新关系仅用短标签:member_of(对象→项目,可多项目)、related_to、assigned_to、depends_on、about、supersedes、knows。详情写档案,不用长句当标签。旧长句关系保留可读,可在 deep 中归档后建立标准关系,不由程序猜测映射。

新项目强制 candidate,Super 询问用户后才可激活。无明确项目可联系日常,但不强制为每条事件建立对象或项目,也不强制每对象只属一个项目。

档案维护名称、别名、摘要、正文、cues(未来什么问题会用到它)与来源。Super 同步用 memory_find 查询姓名/词项/cues/项目直接关系,再用 memory_read 读档案,memory_evidence 展开附件。没有 embedding,没有自动每轮塞入全部对象。

常驻仍是三份核心 MD、有限目录、热时间轴及本轮输入。档案增长不直接扩大每轮上下文。原文、历史版本和审计会增加磁盘占用,尚无自动删除策略。

5. 参数与恢复

参数 当前值
compact 每批最多 8 个节点,容量失败可缩批
organize 原文页 每批 1 事件,最多 8,000 字符,按字节余量/失败缩小,最小 256
deep 对象 每批最多 4 个,按容量缩小
领取传输预算 Worker 默认 96,000 字节,协议允许 24,000–200,000;不是 token
progress / reason 最多 2,000 / 1,000 字符
对象正文 / 摘要 最多 16,000 / 400 字符;不建议写满
单次图写入 最多 32 对象、64 关系、3 core;提案小于 900,000 传输字节
模型输出 默认 32,768,截断重试增长至 131,072 token,仍受模型及剩余上下文限制
批次 默认 300 秒、16 轮、3 次字段级修正;沿用 MEMORY 环境配置
租约 Worker 超时 + 60 秒,默认 360 秒
重试 同批最多连续 5 次失败领取,退避后终止;成功批次重置计数
Markdown 投影 每次最多 10 个对象,内容不变不重写,后续 heartbeat 继续

同 token 重投返回原回执;旧图版本、过期租约、未读对象覆盖、越界证据、漏事件或跳过未读页均拒绝。保证数据库幂等提交,不保证模型只调用一次。

终止失败只将该批事件标为 blocked,原文和先前检查点保留;其它事件仍可由后续小时任务处理。memory_status 给出各状态数量和最早 20 条未完成记录。存在 blocked 的范围只能算 partial,不能伪报全完成。修复原因后显式 retry_blocked=true 解封,重复旧请求不会再次解封。

阈值失败后抑制自动新建一小时,避免“失败通知入时间轴→再建五次失败作业”的循环。主动请求不受自动冷却影响。

6. 如何亲自阅读

部署后的默认入口:/home/kickpi/.deskpaw/memory/objects/README.md。按名称点击人物/任务/待办/日程/知识/项目档案;底层文件名为稳定 ID 哈希,避免重名与路径问题。各类型位于 person/task/todo/schedule/knowledge/project/credential 子目录。

一对象一份当前正文、检索线索、关系及附件时间/ID;每文件最多展示 50 条关系/来源,更多可分页。SQLite 权威,对象文件不导入人工修改;投影分批生成可能暂时落后,失败在 status 中显示。三份核心 MD 的人工编辑导入机制不变。

在 deskpaw-memory 目录只读查看,不调用模型:

node src/inspect.js status
node src/inspect.js list person
node src/inspect.js object person:qhy
node src/inspect.js events '2026-10-13T12:30:00+08:00' '2026-10-13T13:30:00+08:00'
node src/inspect.js event '实际事件ID'

对象/事件返回 next_offset,时间列表返回 cursor,可作为最后一个参数续读。person:qhy 是示例,不表示生产库已有此人。

7. 迁移、验证和未完成项

首次初始化为旧的已摘取事件补 pending 记录及已有对象来源关系;不删除原文/档案/版本。旧协议 running 快照被释放以重新领取;部署必须停止旧 Agent 后切换两端,不混跑。历史 failed 不改成 done。升级代码不会瞬间生成所有人物档案,需要后续模型渐进整理。

验证覆盖两阶段事务、原文保留、无价值终态、全事件页覆盖、检查点、回执重投、过期租约、隔离恢复、每小时空转、夜间轮转、项目审批、来源防回灌、Markdown 文件,以及真实临时 socket/独立 Worker/Super 同步召回。

本轮结果:Memory npm test 63/63;Agent memory-recovery、chain-memory、timeline-bridge、super-context、super-session 五组 25/25,无跳过;Agent npm run check 与两个仓库 git diff --check 通过。均使用隔离数据和模拟模型,没有收费调用或真实键鼠动作。

另使用 SQLite backup 从生产库生成一致性副本,在副本执行迁移及 Markdown 投影:迁移前后均为 876 事件、17 对象、1,145 节点,补出 250 条待归档事件;integrity_check=ok,投影错误为空。该验证未写入生产库,不代表线上已经迁移或语义整理完成。

未验收:真实模型长期保持档案简洁与正确、跨项目关系质量、连续整夜稳定性、断电和大规模磁盘增长。未实现:embedding、自动物理删除、合并对象的重定向、记忆图形编辑 UI、完整模型用量总账。自动测试不等于语义质量或生产长稳验收。

8. 2026-10-14 实际部署与存量状态

00:33:43 Memory 启动新代码,00:34:15 Agent 启动新 Worker。停服备份和验证见 FullGet 配套部署记录。部署前追加回归 Memory 63/63,Agent Super/Memory/PawCode 五组 44/44;Agent 构建成功。

部署前已经有 120 个成功批次回执、29 个对象(人物 2、待办 11、知识 15、项目 1),最后旧对象更新时间 00:18。这证明旧模型确实做过整理,但不是新版整理完成;存量还有 11 个失败 compact、2 个失败 deep,历史状态没有篡改为成功。部分对象标题/正文偏流水账,旧长句关系也仍存在,需后续 organize/deep 逐步维护。

迁移保留 886 条原始事件和 29 个对象,将已摘取经历补入待归档队列,初始 632 条。Markdown 投影由服务分批生成,objects/README.md 与人物/待办/知识/项目文件已实际存在;不是手工编造样例。投影错误为空,Runtime/Memory quick_check 均为 ok。

部署后观察到真实模型 compact 成功提交 revision 121、122,时间轴由 322 节点/264,447 估算 token 减至 308 节点/252,642;待归档增长至 641 条,因为新摘取经历转入下一阶段。小时 organize 已入队,不能把队列建立等同完成。失败历史保留,当前 Worker 错误已在成功提交后清除。

上下文检查:本机 Super 模型登记 contextWindow=1,000,000、maxTokens=384,000;输入预算 800,000、输出预留 150,000、安全余量 50,000。最近一次部署前请求估算 307,716,提供商报告输入 134,700、输出 136;不要把估算当真实计费。Computer 输入预算 128,000、64,000 压缩、近期 16,000、摘要 4,096、输出 8,192。未修改这些配置。

另有独立时间轴传输限制 max_bytes=350,000,最近快照只装入 241/308 节点、67 节点未进入本次视图;虽然 Super 尚有模型容量,字节传输限额仍会先触发显式截断。当前核心文件实际只有 AGENTS.md(1,907 字符),SOUL.md/USER.md 尚未生成;不能把代码支持三份文件描述成三份已经有完整内容。