记忆
在 Coding 中,可选的 Memory 插件保存会话结束后仍然有用的信息。用户笔记本适合偏好和可复用的反馈,工作区记忆适合长期项目知识。会话历史和核心 agent 的工作笔记是另外两类记录。
在扩展中启用 Memory,再从设置 → 扩展打开它的设置页。页面会列出笔记本源文件,供你查看已经保存的内容。如果要添加、修正或删除记忆,在任意 Coding 会话里告诉 agent 即可。
笔记本位于 Wuu 主目录下的 memory/,默认是 ~/.wuu/memory/。MEMORY.md 是索引,各个 Markdown 文件保存具体记忆。保存或忘记一个主题,需要同时修改主题文件和索引条目。插件提供 memory_list、memory_read、memory_write 和 memory_delete 工具完成这些操作。
每个主题文件以 frontmatter 开头:name、description、type(user、feedback、reference 或 lesson),以及可选的 verified(最近一次对照证据确认的日期,格式为 YYYY-MM-DD)和 sources(逗号分隔的依据,例如 session:<id>)。Memory 会统计 agent 在各工作区用 memory_read 读取每个主题的次数;Dream 据此决定优先核实哪些未验证的笔记。
插件会把有限长度的索引放入 agent 上下文,帮助它找到相关主题,而不是每次请求都加载所有主题文件。源文件就是实际保存的内容。打开页面不需要模型请求。
插件的 session_memory 工具通过 project_memory 保存单个工作区的稳定知识,与用户笔记本分开。它在该工作区状态目录下分两层:memory/MEMORY.md 是简短索引,memory/ 中的其他 .md 文件是主题页,用 file 参数指定。每个会话都会看到索引的前 100 行或 8,000 字节,过滤方式与笔记本索引相同;主题页按需读取。agent 可以追加或替换索引和主题页,delete 用于删除主题页(索引不能删除),status 会列出现有主题页。
适合保存的内容包括已经确认的架构决策、反复适用的工作经验,以及难以重新发现的工具限制。团队共享规则优先放在仓库指令中;源码里很容易查到的事实,直接查源码即可。
Memory 还通过 session_memory 提供 summary、checkpoint 和 notes 目标。这些是插件管理的会话文件,其中 checkpoint 用于兼容。
核心 notes 工具与此不同。它为当前会话维护持久的虚拟工作笔记,可记录目标、约束、进展和检查结果。这些笔记在上下文重置、重启和切换模型后仍保留,不写入项目文件,也不依赖 Memory 插件。两种会话笔记都不等同于跨项目的用户记忆。
内置 agent 在通过 new_context 请求新窗口前保存恢复笔记,可用最新 notes
结果的路径和版本组成 checkpoint: {path, revision} 传入。Wuu 校验当前会话的笔记,
并向新窗口传递可直接使用的 notes 读取参数。版本覆盖整个笔记集合,不只
对应单个文件;随后发生写入时,需要按当前版本重读同一路径。不带检查点的
原有调用仍通过笔记发现和归档历史恢复。宿主传递的是引用,而非重新生成的
摘要,模型读取已保存的证据后再继续工作。
保持记忆有用
Section titled “保持记忆有用”只保存已经确认、长期有效的信息。不要把记忆当作会话归档、密钥存储或临时任务日志。记忆与当前证据冲突时,应修正记忆,而不是盲目遵循。
记忆可能发送给已配置的模型,并影响后续操作。请检查敏感条目和导入的不可信文本。禁用插件会移除它的提示、工具、服务和设置页,但不会删除已有笔记本文件。
Dream 可以在后台整理工作区知识,需要单独开启,也会产生额外模型请求。AGENTS.md 等项目指令独立于这两个插件;相关说明见配置和安全模型。
面向扩展的只读服务
Section titled “面向扩展的只读服务”Memory 通过已有的服务注册表提供 memory.notebook 版本 1.1.0。
在 required_services 中声明
{ name: "memory.notebook", major_version: 1, required: false },
再通过 host.service.call 调用 service: "memory.notebook" 的以下方法:
| 方法 | 参数 | 结果上限 |
|---|---|---|
index | 可选 max_bytes | 经过过滤的 MEMORY.md,最多 200 行、25,000 个 UTF-8 字节 |
read | file、可选 max_bytes | 一个主题,默认 16,384 个 UTF-8 字节,最大 65,536 |
list(1.1) | 无 | 全部主题的元数据,不含正文 |
省略 max_bytes 或设为零时采用默认值;负数或超过上限的值会报错。
read 只接受非隐藏的普通 .md 文件名,不接受 MEMORY.md、目录路径或符号链接。
源文件必须是有效的 UTF-8 普通文件,大小不超过 256 KiB。截断不会切开 UTF-8 字符。
这些方法不会返回全部主题正文、写入记忆或调用模型。
list 返回 memory.notebook.list.v1:{ version: 1, index, files, dangling }。
index 包含 found、bytes、lines、注入上限 max_bytes 和 max_lines,以及注入时是否
truncated。files 的每一项包含 file、可选的 frontmatter 字段 title、type、
description、verified 和 sources,以及 bytes、indexed(MEMORY.md 是否提到它)、
reads 和可选的 last_read_at。dangling 列出索引提到但不存在的普通主题文件名。
读取次数只用于排序参考。统计存储不可用时,list 会报错。调用前应确认提供方版本至少为 1.1。
两个方法都返回 { version: 1, source: { scope: "user_notebook", file }, found, revision?, content, truncated }。revision 标识完整源内容,即使返回的片段
被截断或经过过滤也保持相同;调用方应把它作为不透明标识使用。空文件仍返回
found: true 和版本;删除或不存在的文件返回 found: false、空内容且不带版本。
请求 schema 标识分别为 memory.notebook.index.request.v1 和
memory.notebook.read.request.v1,响应均为 memory.notebook.snapshot.v1。
TypeScript SDK 导出对应的 MemoryNotebook* 类型。
服务与现有记忆工具共用笔记本读取逻辑,index 与 agent 提示共用索引过滤逻辑。
每次调用都重新读取文件,不设服务缓存。调用方在复用记忆前必须重读;文件不存在
或服务不可用时,应清除保留的内容。服务提供方解析发生变化时,还应处理
service.changed;该通知不追踪文件编辑。每次结果只代表一个文件,索引和主题
之间不保证原子快照。
Memory 禁用或不可用时,注册表返回 service_unavailable;可选消费者仍可在没有记忆
的情况下工作。不要回退到直接读文件,也不要自动启用 Memory。笔记本内容是不可信的
上下文,当前指令和证据优先。个性化写作、补全或任务交接扩展可以按需读取相关主题;
这些是可行用途,并非已有内置集成。Dream 是 list 的内置消费者。工作区和会话记忆仍使用独立的 memory.session 服务,
版本 1.1.0 新增了 file 参数和 delete 方法。
Personal 记忆
Section titled “Personal 记忆”Personal 启动时直接装配自带的记忆模块,不需要另行启用 Memory 插件。
Personal 本身仍是默认开启的内置插件;禁用 Personal 也会停止它的记忆工具、
服务和召回。Coding 的 Memory 仍保持可选,原有行为不变。兼容的 memory.records
服务只由 Personal 提供,主身份绑定、来源校验和候选发布使用下文说明的公开
host.personal@1 记忆操作。
Dream 仍是可选能力,本次不会启用它,记忆也不依赖它。
升级通过两个包相互匹配的存储所有权声明迁移已有 Personal 记录,即使 Memory 处于禁用状态也能迁移。记录 ID、版本、来源、候选、冲突和遗忘来源标记均保留。 迁移可恢复、可重复执行;旧存储保留用于恢复,不再作为第二份活动记录库。 迁移失败会明确报告,不会静默使用缺失记录的空库。Coding 笔记本不会被导入。
Personal 使用独立的带来源记录库,不使用 Coding 笔记本。每个模型步骤只投影
少量内容:显式选定的核心画像、来源在最近 14 天内的近期上下文,以及相关详情。
三个区域的事实预算分别为 2,000、1,500、2,500 个 UTF-8 字节,各最多八条;过大的
事实仍可按需查询。完整来源和贡献历史通过 personal_memory_query/read 获取,
不在每步重复注入。旧记录默认属于详情,不会自动升级为核心。过期、纠正和遗忘
标记对所有投影及新执行会话生效,投影不额外复制记忆。
绑定的主对话可以发布、纠正和遗忘。拥有精确执行授权和宿主绑定原始用户来源的
后台事项只能创建和修订候选,不能修改已接受记录、选择核心层、纠正或遗忘。候选不参与普通召回,使用
include_inactive: true 可检查。主对话在下一次正常模型步骤收到最多八个候选 ID,
而不是把候选事实混入已接受记忆。主对话通过 personal_memory_evidence 阅读原始
用户文本、检查支持程度和冲突,再用检查到的版本调用 personal_memory_accept。
有来源支持且不冲突的候选不需要用户重复陈述或逐条批准。接纳保留正文、推断或明确
证据等级以及原始来源、生效和过期时间,不自动升级核心层,不额外启动模型或后台
定时任务。模糊候选保留待处理;只在有意义的冲突影响当前事项时询问。新的明确用户
纠正仍使用 correct。不需要逐会话弹窗授权。
自动接纳目前只支持绑定的 Personal 主对话中的规范引用
personal-message:<encodeURIComponent(session_id)>:<正整数 seq>。后台只能使用真实
create_task 宿主轮次捕获的来源,不能任意选择历史消息或使用无来源绑定的客户端
创建事项。提供方核对仍有效的原始可见用户身份,拒绝隐藏、生成或截断内容,并使用持久化时间。后台只能获得
来源时间元数据,原文审阅只向主对话开放。程序验证的是来源,不是语义蕴含;主模型
仍须判断原文是否支持未改动的候选。来源缺失、时间在未来或类型不支持时拒绝接纳。
旧的任意引用、文件和用户编辑引用仍走人工纠正路径。不得编造原始序号或使用 Dream
分叉后的序号代替原始序号。保留既有来源去重和遗忘保护,因此目前一个规范消息来源
只对应一条记忆;尚未实现消息拆分或更广泛的自动接纳。
权限来自宿主传入的工具会话和 Personal 提供方保存的当前主会话绑定,不依赖 会话名称、提示词或是否缺少父会话。提供方不可用时禁止写入。服务调用仍遵循 受信任扩展边界,不承诺防止已安装的受信任扩展冒用会话。读取仍在 Personal 用户空间共享,并非逐事项隔离。Coding 和 Project 不会因此获得 Personal 访问权。
查询有更多记录时返回 next_cursor,应保持筛选条件继续查询。记录变化或游标
被拒绝时重新查询。仍受选定提供方的文档限制。遗忘会清除记录正文并阻止已知来源
引用被重新提取,不会删除原始对话、文件、导出或备份。
发布与恢复契约
Section titled “发布与恢复契约”替换 Personal 的扩展可以声明 host.personal@1,使用 SDK 的
personalMemory(host)。records、source、operation 和 commit 依赖宿主解析的
会话所有权与选定的 Personal 提供方,不按内置插件 ID 提供特权。服务仅在 Personal
产品域可用,始终通过选定的 state.documents、事项状态、会话及
execution.authorization 提供方,不回退到本地存储,也不扩大主对话历史读取权限。
commit 输入是 {id, key, expected, value}:key 是 mem_ 加事实键的 SHA-256,
expected 是精确的前一版 JSON 或 null,value 是下一版 memory.records JSON。
宿主检查 id、revision、product_domain: "personal"、user_space_id、status、
tier、content、contributor_agent_id、updated_by_agent_id、sources 与
contributions。版本逐次加一,最新贡献注明 agent_id 与 executor_session_id;
来源注明 kind、ref 与 occurred_at。后台仅允许有精确规范消息来源的非核心候选。
遗忘记录仅保留 ID、版本、作用域、状态与 blocked_sources,不保留正文。事实规范化
和召回策略仍由选定的 Personal 实现负责。
所有新记忆写入独立的权威记录与回执日志。旧 Personal 存储仅作为只读兼容输入; 同 ID 的日志记录始终优先,包括遗忘标记。旧记录首次修改后由日志负责,不保留两份 活动记录库。创建、接纳、纠正和遗忘走同一权威路径。在事项与会话检查保护及选定 执行授权提供方的提交保护期间,记录和终态回执原子提交。并发停止事项、变更需求或 撤销授权不能悄悄越过此边界。不支持提交保护的旧授权会拒绝发布,需要用户重新授权。
操作 ID 表示稳定的语义意图,不是临时回调。重试 commit 前用 operation 找回首次
准备的精确内容;不同输入不能复用 ID。只有回执仍对应当前记录时才返回原提交结果。
遗忘同时清除先前操作中的正文,仅保留清理所需摘要,不留下可再次召回的副本。
提交结果未知不等于失败:持久化保护一直保留,直到原子终态回执或中止决定阻断延迟
提交。不要用新 ID 盲目重试未知结果。
operations 和 reconcile({id, writers_stopped: true, reason}) 是用户客户端维护操作,
不是模型工具。恢复会排空本宿主的写入,要求原选定绑定及单宿主提供方权威;在共享
部署中,一个布尔值不足以证明独占。恢复记录用户给出的原因,保留已提交回执或先
原子中止精确意图,再清理保护。提供方故障会明确报告;关闭时可以把未解决的持久化
保护交给恢复路径,不无限保留已停止的内存代际。替换提供方必须保留原权威数据集,
否则需恢复原绑定后再处理。