ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

oh-my-pi 记忆编辑指南:深入解析 `memory_edit` 的 update / forget / invalidate 操作与 memory:// 协议

oh-my-pi 记忆编辑指南:深入解析 `memory_edit` 的 update / forget / invalidate 操作与 memory:// 协议 oh-my-pi 记忆编辑指南深入解析memory_edit的 update / forget / invalidate 操作与 memory:// 协议【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi导读memory_edit是 oh-my-picoding agent with the IDE wired in在启用 Mnemopi 本地长期记忆后端时提供的记忆维护工具它允许 Agent 按 ID 对长期记忆执行update更新工作记忆、forget硬删除工作记忆、invalidate软作废旧记忆可指定替代记忆三种操作。本文以 memory-edit.md 为骨架结合 memory-edit.ts、mnemopi/state.ts、Mnemopi Beam 存储层实现与契约测试讲清每条编辑规则背后的源码依据、参数语义与安全操作流程。读完你将掌握何时该用哪种编辑操作、为什么 fact 记忆只读、为什么 update 前必须先read memory://id以及每一步在仓库源码中的具体落点。前置条件Mnemopi 后端与工具注册memory_edit并非默认可用。它的工厂函数在 memory-edit.ts 中做了严格的门控static createIf(session: ToolSession): MemoryEditTool | null { const backend session.settings.get(memory.backend); if (backend ! mnemopi) return null; return new MemoryEditTool(session); }即只有当memory.backend配置为mnemopi时工具才会被注册进内置工具表见 tools/index.ts 的memory_edit: MemoryEditTool.createIf。契约测试 memory-tools.test.ts 验证了这一点off、hindsight后端下createIf返回null而mnemopi后端下retain/recall/reflect/edit四个工厂均返回工具实例。启用 Mnemopi 的最小配置详见 mnemosyne-memory-backend.mdmemory: backend: mnemopi可选的常用参数mnemopi: scoping: per-project-tagged # global / per-project / per-project-tagged autoRecall: true # 会话首轮自动召回 autoRetain: true # 自动留存已完成的对话轮次 retainEveryNTurns: 4 # 自动留存的最小用户轮次间隔 recallLimit: 8 # 提示词块中最大召回条数记忆属于“背景上下文”而非指令当它与当前用户消息或工具输出冲突时以当前用户消息和工具输出为准见 mnemosyne-memory-backend.md。这也是为什么编辑记忆需要谨慎——你修改的是影响未来会话召回的背景信息。memory_edit的输入参数与操作语义工具的参数模式定义在 memory-edit.tsconst memoryEditSchema type({ op: type(update | forget | invalidate).describe(memory edit operation), id: type(string).describe(memory id from recall output), content?: type(string).describe(replacement content for update), importance?: type(number).describe(replacement importance for update (0–1)), replacement_id?: type(string).describe(replacement memory id for invalidate), });参数类型必填含义op枚举update \| forget \| invalidate是要执行的编辑操作idstring是来自recall输出的记忆 IDcontentstring否update 时需二选一update的替换内容importancenumber (0–1)否update 时需二选一update的替换重要性replacement_idstring否invalidate时记录的替代记忆 ID三种操作的语义与文档 memory-edit.md 一一对应update面向工作记忆working memory替换其内容和/或重要性。适用于更正过时、不准确或表述不佳的既有记忆。update是整体替换wholesale replace——传入content会整段覆盖旧内容因此必须先读取完整内容再合并防止丢失未预览的尾部。forget永久删除工作记忆hard delete面向需要硬删除的内容。删除是物理性的Beam 层的forgetWorking会执行DELETE FROM working_memory并顺带清理该记忆的派生工件见下文源码剖析。invalidate软作废softly supersede面向仍可能有用历史的过时记忆。它不删除任何行只打上失效标记并记录替代记忆 ID历史仍可被追溯。工具在调用前对参数做了一层前置校验memory-edit.ts若op update且content与importance都未提供直接抛错memory_edit update requires content or importance.。同时importance会被夹紧到[0, 1]区间Math.max(0, Math.min(1, params.importance))见 memory-edit.ts与模式描述中的(0–1)约定一致。工具执行时会调用会话状态的editScopedMemorymemory-edit.ts并把结果含所在 bank / store格式化为人类可读的返回文本对not_found与not_editable两种失败场景返回不同提示其中 fact 记忆会提示Read it with memory://id.memory-edit.ts。编辑的分层路由从工具到 Beam 存储一次memory_edit调用跨越三个层次理解这条链路有助于定位任何异常行为工具层ToolMemoryEditTool.execute负责参数校验、importance 夹紧、调用state.editScopedMemory(op, id, {...})、格式化结果文本memory-edit.ts。会话状态层Session StateMnemopiSessionState.editScopedMemory负责在多个 bank 之间按顺序解析目标记忆、判定可编辑性、分派具体操作mnemopi/state.ts。存储层BeamMnemopi门面把update/forget分别转发给beam.updateWorking/beam.forgetWorkingmemory.tsinvalidate直接调用beam.invalidatebeam/index.ts。会话状态层作用域解析与可编辑性判定editScopedMemory是编辑语义的核心裁决者。它先把会话可触及的 bank 去重排序为「retain 目标、recall 目标、global bank」mnemopi/state.ts然后按顺序查找目标记忆命中即中止first hit wins。对每条命中的记忆它根据memory_store字段判定归属memory_store fact返回not_editable——fact 表是只读的任何编辑操作都不修改 facts 表因此即使 ID 能解析也必须精确报告为不可编辑mnemopi/state.ts注释引用了 issue #4725。op为update或forget但store ! working返回not_found——这两类操作只面向工作记忆mnemopi/state.ts。update命中工作记忆调用target.memory.update(id, content, importance)mnemopi/state.ts。forget命中工作记忆调用target.memory.forget(id)mnemopi/state.ts。其余走invalidate调用target.memory.beam.invalidate(id, replacementId)可同时作用于工作记忆与情景记忆episodic memorymnemopi/state.ts。若所有 bank 都未命中返回not_found若中途遇到不可编辑目标但最终没有成功操作则返回首个ineligible即not_editable或not_found保证错误信息尽量精确mnemopi/state.ts。存储层三种操作的真实 SQLBeam 存储层的实现把文档语义落到具体 SQLstore.tsupdateWorkingstore.ts动态拼接 SET 子句——提供content时更新content并置空embed_text触发重新嵌入调度scheduleEmbedding提供importance时更新importance。两者都未提供则返回false。更新成功后使查询缓存失效invalidateCaches保证后续召回能看到新内容。forgetWorkingstore.ts在事务中执行DELETE FROM working_memory WHERE id ? AND session_id ?命中后调用purgeWorkingMemoryArtifacts清理关联工件并同样使缓存失效。注意 WHERE 条件带session_id——删除被限定在调用者所属会话作用域内。invalidatestore.ts执行两条UPDATE——先尝试working_memory未命中再尝试episodic_memory将valid_until置为当前时间、superseded_by置为replacement_id。这是一种软删除行仍然存在但召回查询统一以valid_until IS NULL OR valid_until now且superseded_by IS NULL为过滤条件见 recall.ts因此被作废的记忆不会再进入召回结果历史却完整保留。superseded_by字段让替代记忆与被替代记忆之间形成可追溯的链接。从 schema 看working_memory与episodic_memory两张表都定义了valid_until TIMESTAMP DEFAULT NULL与superseded_by TEXT DEFAULT NULLschema.ts这正是invalidate软作废机制的物理基础。只读的 fact 记忆与 not_editable文档明确recall结果中标记为[facts]的是只读事实任何编辑操作都会返回not_editablememory-edit.md。仓库证据有两处存储层注释直接声明memory_store: fact标记为只读——不允许 update/forget/invalidatestore.ts。状态层的editScopedMemory对 fact 专门返回not_editable且即使后续 bank 也找不到该 ID仍保留这个精确错误而非退化为not_foundmnemopi/state.ts。对 fact 记忆正确做法是用read memory://id检视内容只读查看而不是编辑。这保证了事实性知识例如实体关系、已知约束不会被 Agent 随意改写。为什么 update 前必须read memory://id这是本工具最重要的安全约束文档用加粗的 MUST 强调memory-edit.mdMUST read full memory beforeupdate. Recall previews clipped: trailing…marks truncation;full_lengthoriginal size.updatereplaces content wholesale → updating a preview deletes its unseen tail. Firstread memory://id; pass merged content incontent.原因链如下召回结果是预览previewrecall返回的是截断的内容预览超出预览上限的部分以尾随…标记并附带truncated: true与full_length原始长度字段见 recall.md。update 是整体替换updateWorking直接用新content覆盖旧内容store.ts没有增量合并机制。因此若拿一段被…截断的预览去 update被省略的尾部会被永久抹掉。memory://id返回完整行getScopedMemory从 retain/recall/global 各 bank 按序查找并组装完整行含 content、source、timestamp、importance、veracity、metadata 等其设计目的正是支撑memory://id读取让 Agent 在整体替换前看到未裁剪的全文mnemopi/state.ts 的注释明确引用 issue #4443。memory://属于内部 URL 协议族agent://、artifact://、memory://、skill://等见 internal-urls/types.ts。其中memory://id这一命名空间只有在memory.backendmnemopi时可用——在 Hindsight 后端下read memory://id会得到明确纠错提示memory-protocol.ts。而memory://root则指向项目级记忆摘要文件system-prompt.md与本工具的按 ID 编辑无关。安全的 update 流程用recall定位目标记忆记录其id。用read memory://id获取完整内容而非被截断的预览。在完整内容基础上合并你的修改构造新的content。调用memory_editop: update, id: id, content: 合并后的完整内容。如何选择invalidate 与 forget 的取舍文档给出的决策准则memory-edit.mdPreferinvalidatefor stale memory whose history may still be useful. Useforgetonly for content requiring hard deletion.场景推荐操作理由记忆过时但仍可能有追溯价值如决策沿革、曾被采纳后被推翻的方案invalidate软作废保留历史可选replacement_id关联替代记忆召回自动过滤需要物理删除的内容隐私、错误数据、敏感信息forget硬删除DELETE行并清理派生工件不可恢复记忆内容不准确或表达欠佳主体仍有价值update保留同一 ID整体替换内容/重要性invalidate的replacement_id参数把新旧记忆串成superseded_by链invalidateSQL 会把superseded_by写成替代记忆的 IDstore.ts使“谁取代了谁”在数据层面可查询。这一软删除设计也避免了硬删除导致的引用悬空作废行仍可被合并、压缩或人工审计读到只是不再出现在面向 Agent 的召回结果中。错误信息速查memory_edit的可能返回状态来自editScopedMemory的结果与工具格式化逻辑memory-edit.ts状态含义提示文本示例updated/deleted/invalidated操作成功并附带所在 bank及 storeMemory id updated in bank bank (store).not_found在任何作用域 bank 中都找不到该 IDMemory id was not found[ in bank …].not_editable命中 fact 只读记忆Memory id is a read-only fact…; cannot be edited. Read it with memory://id.此外工具层会先抛参数错误memory_edit update requires content or importance.memory-edit.ts若会话尚未初始化 Mnemopi 状态则抛Mnemopi backend is not initialised for this session.memory-edit.ts。总结memory_edit是 oh-my-pi Mnemopi 记忆体系中的“写操作”入口与recall读、retain写新、reflect综合共同构成完整的记忆生命周期管理。它的设计处处体现数据安全优先fact 只读、update 强制先读全文、invalidate 软作废优于 forget 硬删除、SQL 更新带session_id/scope作用域约束。在使用时牢记三条铁律即可只编辑recall返回的 IDupdate前先read memory://id能invalidate就别轻易forget。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表