15 KiB
DeskPaw 连续智能体与记忆架构
DeskPaw 对用户提供一个持续存在的智能体身份。上层负责理解、承诺、决策和调度;Pi 等执行者负责受限任务;记忆系统维护可追溯的经历、事实和约束,并在相关时提供给上层。会话身份持久存在,不要求任何一个模型的上下文无限增长。
改造前的实现
上层目前通过一次 completeSimple 调用产生包含 action、reply、objective 等字段的 JSON。运行时从文本的第一对外层花括号之间截取内容,解析并路由到九种固定动作。对话回复与控制指令耦合,回复又被截断到 2000 字符。它没有独立工具循环,也不直接共享 Pi 的全部消息列表。
Pi 使用持久化 JSONL 会话文件;Runtime SQLite 保存交互、执行队列、日程和事件。Memory SQLite 保存任务卡、话题、事实和资料夹,Markdown 是投影。模型输出 JSON、JSONL 审计文件、JSON Lines 本地通信是三个不同问题,不能通过替换文件格式来解决语义和调度耦合。
当前上层先等待问答同步和记忆召回,然后调用模型。较完整的整理由执行队列中的 memory_maintenance 完成,依赖下层空闲。任务完成、阻塞等事件主要进入执行日志和展示渠道,尚未形成有版本校验的上层事件收件箱。自然语言暂停还会等待 Pi 停止;直接 /v1/stop 则已经能够先确认请求。
架构原则
- 上层是记忆的主要消费者和任务意图的管理者。后台整理者不能改变用户目标、授予操作权限或自行恢复暂停任务。
- Runtime 是任务状态的权威,Executor 是动作回执的来源,Memory 是记忆记录的权威。检索索引和 Markdown 都可重建,不形成第二份可独立修改的事实库。
- 上层不等待电脑任务或后台整理完成。不能安全继续的任务可以等待证据,整个上层仍可接收新消息和控制请求。
- 原始观察、执行者报告、用户陈述、验证结果和模型推断分开记录。动作成功不等于业务完成。
- 所有跨异步边界的结果带来源、对象、请求标识和版本。迟到结果可以归档,不能覆盖更新的约束或作用于另一任务。
- 至少一次投递与幂等提交构成可靠性基础,不假定跨数据库事务或端到端恰好一次。
组件与责任
用户和消息入口 → 上层收件箱 → Supervisor → 经校验的控制命令
↑ ↓
事件筛选与回调策略 Runtime 与日程调度
↑ ↓
记忆召回结果 Pi 等执行者 → Executor
↑ ↓
上层上下文投影 ← Memory ← 有界事件与证据引用
↑
后台观察和整理 Worker
Supervisor 只持有控制和只读查询能力。发送任务后立即获得持久化任务回执。对用户的文字与工具参数分离;JSON 继续作为通信和模式校验格式,但不再要求每次聊天都是一个控制 JSON 对象。
Runtime 管理队列、取消、任务版本和执行资源。一个物理桌面同一时刻只能有一个有副作用的执行所有者。未来研究、文件解析和记忆 Worker 可以并行,但不能绕过桌面资源所有权。已发出的原子操作无法保证撤回;不确定结果应暂停后续动作并核验。
Memory 分为接入、状态投影、观察提取、合并复核、检索和上下文组装。模型只生成受校验的记忆提案,程序负责事务、来源校验、生命周期、索引和预算。
这些是逻辑边界。首阶段后台 Worker 复用 Agent 的模型适配层,但拥有独立队列,不占 Pi 执行队列;Memory 仍通过本地协议独立运行。后续可将模型 Worker 和 Pi Runner 迁到独立进程。首阶段不宣称提供进程级实时隔离。
对象与记忆模型
对象标识与会话标识分离。对象包括长期责任领域、有限项目、持续维护资产、可复用流程、周期计划和一次执行。项目休眠只表示当前不活跃,不表示其记忆失效。
报销领域包含报销规则和资料入口;每月报销是独立项目;每日整理和每月提交是不同计划;每次操作是执行实例。软件资产保留仓库、部署和故障经历,某次修复则是关联该资产的独立任务。没有下一次计划时间的资产也可以在事件或问题命中时恢复上下文。
事件可以关联多个对象,保留一个主要归属以支持低成本路由。多设备、多用户扩展必须增加明确的所有者和授权范围;当前统一会话不能被解释为可以跨用户共享全部记忆。
记忆分为以下类型:
- 当前状态:当前讨论、活跃任务、未兑现承诺、阻塞和等待确认。任务状态由程序投影。
- 经历:目标、关键操作、结果、失败方法、剩余事项及证据。经历按对象和事件段组织,工作日只是浏览维度。
- 事实和偏好:带范围、来源、有效时间与状态的原子陈述。
- 规则和纠正:注明约束对象、何时生效、是否取代旧规则。一次例外不自动成为全局规则。
- 操作经验:适用条件、步骤、失败条件和验证方法。候选经验不自动成为已批准技能。
- 召回线索:说明未来何种问题可能需要这段记忆。线索不是事实、命令或日程。
记录至少包含 id、owner_scope、subject_id、kind、content、source_refs、observed_at、recorded_at、status、revision。稳定条目再提供有效时间、复核时间和 supersedes。对象版本按对象递增,避免一个无关项目更新导致全库写入冲突。
记忆形成
接入用户消息、上层控制决定和承诺、Pi 阶段报告、Executor 有意义的观察与产物、Runtime 和日程事件。外部网页和屏幕内容只作为数据,不提升为用户指令。
普通鼠标动作和重复成功回执留在审计层。程序合并重复观察和同一错误,保留次数和时间范围;关键变化、错误、用户纠正、产物和终态进入记忆事件。图片、大段 UIA 和模型供应商原始响应不复制进记忆。来源引用不等于授权读取任意文件,读取证据仍需范围校验与脱敏。
事件先持久化,再异步发送。接收位置、已整理位置和已发布版本分开维护。高优先级批次可以先处理,但不能越过尚未处理的事件而使其永久丢失。以事件序号和 ID 去重,不以毫秒时间作为唯一游标。
状态通道立即更新确定性的任务变化。用户最新原话进入上层上下文,不等待语义整理。自然语言理解本身仍需模型;明确停止按钮和控制接口走快速通道。
语义通道按任务或对象构造有界工作包。首版普通事件按约 30 秒、20 条有效事件或输入预算触发;阻塞、结束和明确纠正优先。Worker 无新数据不调用模型。初始并发为 1,使用已配置文本模型,模型名称和超时独立可配。
观察者提取经历与稀疏候选条目;合并者在任务边界或对象记录过多时合并。每个候选都要能回到原始来源。缺少来源、扩大范围、试图覆盖较新纠正或包含敏感信息的提案不能生效。失败保留待处理事件并退避,成功提交后才消费来源。
用户明确陈述与模型推断保留不同标签。数次复述同一来源不增加独立证据数量。环境状态需要时重新检查,旧故障不能成为永远成立的操作前提。压缩后的文本不替代原始证据;重要条目仍能按引用展开。
记忆管理
候选、有效、被取代、过期和归档是记忆生命周期;活跃、休眠、完成是对象生命周期,两者独立。
纠正以新增版本和关联旧版本实现。最新规则优先的前提是同一对象、同一适用范围和相应有效时间;不能用简单的全库最后写入胜出。冲突无法消除时保留冲突标记,不暗中选择一个结果。
暂态观察按类型设置复核和保留策略。未完成承诺不能仅因长时间未访问被遗忘。用户要求删除时,应同时失效相关索引、上下文缓存和派生记录,按保留策略清理内容;审计机制不能成为拒绝删除的理由。
数据库与证据保留量可以增长,上层上下文必须有界。核心画像只保留少量稳定条目,休眠对象通过索引找回,不把全对象目录长期放入提示词。SQLite 负责权威记录;Markdown 用于查看与导出,外部编辑通过显式导入和版本校验。
召回与结果回调
召回是检索历史知识,回调是异步结果返回到接收者,两者用不同协议表示。
一次召回请求包含请求 ID、所有者范围、问题、对象或任务引用、用途、预算、发起意图版本和有效期。结果包含命中条目、证据引用、记忆版本、检索原因、缺口和完成状态。查不到、暂时不可用和记录已过期必须区分。
检索顺序为:权限和有效性过滤;确定对象及强制适用约束;关键词或结构化 ID 召回;必要时加入语义及关联线索召回;合并排序;展开少量证据;在预算内组装。强制约束不依赖相似度排名。未来混合通道可以使用 RRF 融合,向量索引可替换,不影响权威数据。
上层使用已发布快照加最新 Runtime 变化。缓存未命中时发起异步检索,不能因此把未知解释为不存在。涉及不可逆动作而依据不足时,仅让该任务等待上下文,不阻塞其他对话。
| 时机 | 召回内容 | 上层处理 |
|---|---|---|
| 新用户消息或话题切换 | 当前对象、相关规则和经历 | 读取缓存,必要时异步补查 |
| 派发任务前 | 约束、验收条件、相关错误经验 | 形成带版本的任务工作包 |
| 下层遇到阻塞或重复失败 | 同对象历史原因和修复经验 | 合并事件,重新判断或请求用户输入 |
| 日程到期 | 对应计划、周期项目和未完成事项 | Runtime 触发,必要时让上层判断变化 |
| 重要观察与休眠资产相关 | 相关资产摘要和证据 | 后台匹配后按必要性唤醒 |
| 用户纠正或相关记忆更新 | 新约束及被取代版本 | 失效旧缓存,必要时改向正在执行的任务 |
| 普通点击或无变化观察 | 通常无 | 不唤醒上层模型 |
回调进入持久化上层收件箱,包含因果事件 ID、任务 ID、任务版本、请求 ID和优先级。用户消息优先,重复进度合并。回调过期或目标已变化时归档,不对新任务应用旧结果。模型生成控制命令后,执行前还要检查目标与版本,避免给任务 A 的修改落到刚接替的任务 B。
控制回执区分已接收、已开始、正在停止和已停止。上层不能在命令未持久化前声称已安排,也不能在原子操作结束前声称已经停止。后台记忆更新通常只替换快照,不每次触发聊天或继续执行。
三个项目的复用边界
源码基线为 T-Mem dd9e152、Letta Code 253a3bc8 和 Mastra e832eb4870。
- T-Mem:复用原子条目到经历的证据关联、写入时形成召回线索以及
stage6_retrieval.py的 RRF 算法。Python 数据集脚本和默认英文分词不作为生产接入层;其倾向完整提取的提示词需要改成有预算的稀疏筛选。触发线索不进入事实证据路径。 - Letta Code:复用常驻与按需加载的分层、按引用交接以及后台修改成功落地后才消费历史的规则。
memory-format.ts的路径判断可用于 Markdown 投影,memory-handoff.ts的交接协议需换成我们的来源接口。当前本地初始化使用 MemFS v2,不直接沿用旧system/布局;按英文字符估 token 的方法不适合作为中文硬预算。 - Mastra:复用
anchor-ids.ts、观察分组与来源维护等可拆出的纯函数,以及安全批次边界、后台准备后激活和异步问答协议。ObservationalMemory也提供独立 API,但直接采用仍需适配其消息与存储模型。首阶段摘取需要的模块和回归案例,不迁移整个 Agent 框架。部分激活路径可能等待后台作业,不能置于上层响应路径;提醒检索的英文正则必须补中文处理。
移植代码记录上游版本和对应许可证,保留要求的声明。T-Mem 为 MIT;所选 Letta Code 和 Mastra 非企业模块为 Apache 2.0。Mastra 的 ee 内容不纳入本次复用。
第一阶段实现边界
第一阶段实现事件接入、后台整理、来源可追溯的经历、基本索引召回、有界上层上下文与异步控制和结果收件箱。先沿用现有模型适配层与 SQLite,本地 JSON Lines 协议继续使用。
实施顺序:
- 增加版本化事件协议、幂等接入和可恢复批次;保留现有原始记录。
- 增加独立于 Pi 队列的观察 Worker,模型只处理有界事件并提交受校验提案。
- 组装上层缓存和异步召回结果,当前任务状态始终覆盖旧快照。
- 分离模型正文与原生控制工具,暂停先返回控制回执,补充任务目标校验。
- 接通关键执行事件的上层收件箱,限制自动回调的权限和重试,避免自动执行循环。
- 通过离线模型、隔离数据库和假 Executor 验证,不操作真实桌面。
首阶段不建设完整财务台账、发票解析、向量基础设施、多设备调度或自主技能发布。全量项目管理、语义索引和进程级隔离通过现有协议继续扩展。正式环境启用须在测试后单独部署;源码修改与部署是不同操作。
该阶段已在 feat/supervisor-memory-v1 分支实施一版。具体参数、协议、实测范围及尚未实现的边界见
第一阶段说明。尤其要区分只读结果收件箱与自动续做:本阶段实现前者,不让回调擅自创建操作。
验收
- 上层聊天和暂停控制不等待记忆模型或 Pi 原子动作结束。
- 任务完成、阻塞和记忆召回结果有可恢复、幂等的回调记录。
- 迟到结果不覆盖更新约束,不对不同任务实施旧命令。
- 重启或模型错误不会使未完成整理的事件永久丢失。
- 普通操作洪流经过筛选,模型批次和上层上下文有明确大小上限。
- 中文报销、跨月份经历和休眠软件资产可以按相关对象或关键词找回。
- 工具成功与业务验证结果分开,网页指令、密码、隐藏推理不提升为长期规则。
- 已有任务、日程、技能和会话身份保持可用。测试记录明确哪些属于单元、协议、集成和实际硬件验证。