Cherry Studio 持久记忆工具指南:mcp__agent-memory__memory的跨会话记忆机制与实战用法
【免费下载链接】cherry-studioAI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs项目地址: https://gitcode.com/GitHub_Trending/ch/cherry-studio
本指南围绕 Cherry Studio 内置 Skill 包
cherry-tool-guide中关于持久记忆(Persistent memory)的参考文档展开,深入讲解 Agent 通过mcp__agent-memory__memory工具在同一 Agent 的跨会话、跨工作区环境中读写记忆的完整机制。读完本文,你将掌握记忆工具的三个核心动作(search/append/update)的参数语义、选择策略、意图门控规则,以及其底层基于FACT.md与JOURNAL.jsonl的落盘实现原理,可直接用于编写或审查 Agent 的记忆调用逻辑。
1. 工具定位:Cherry Tool Guide 路由表中的记忆入口
在 Cherry Studio 中,应用会通过四个 MCP 服务器向会话注入第一方工具(mcp__cherry-tools__*、mcp__agent-memory__*、mcp__skills__*、mcp__mcp-manager__*),其中持久记忆能力由mcp__agent-memory__memory提供。在 cherry-tool-guide 的路由表 中,记忆工具被显式路由到两个典型意图:
- 回忆用户过去告知的事实、纠正或偏好→
mcp__agent-memory__memory(search),且要求先搜索、后提问; - 保存持久知识 vs 一次性事件→
mcp__agent-memory__memory(updatevsappend)。
该工具的作用域是同一个 Agent:记忆存放在该 Agent 自己的数据目录下,因此能跨会话、跨工作区存活,但不会在 Agent 之间共享。参考文档 memory.md 明确指出,本文档只提供路由(routing)与语义(semantics)层面的说明,确切的参数形状一律以会话中实时暴露的工具 Schema 为准。
2. 可用性与意图门控
2.1 可用性(Availability)
mcp__agent-memory__memory在常规会话中通常存在。如果它没有出现在当前会话的实时工具列表中,说明本会话内持久记忆能力不可用——应当如实告知用户,而不是假装调用成功或编造结果。这与 cherry-tool-guide 的全局规则一致:工具不在列表中就代表能力不可用,不应通过 shell/文件工具绕过(参考 SKILL.md 全局规则)。
2.2 意图门控(Intent gate)
与需要审批卡的变更类工具不同,记忆写入可以在不弹出审批卡片的情况下直接执行。因此使用门槛完全取决于 Agent 自身的判断:
- 不要因为工具可用就随手写入;
- 仅在用户明确要求记住某事,或某个持久事实确实值得在未来会话中保留时才写入。
这条规则同样来自 cherry-tool-guide 的全局规则:「Memory writes, schedule changes, notifications, and agent/channel configuration may execute without an approval card. Do not call them merely because they are available」(见 SKILL.md)。也就是说,记忆工具属于「意图仍会门控的自动批准效果」——工具调用本身不触发审批,但触发它的必须是真实的用户意图或已完成任务的必要组成部分。
3. 三个动作:search / append / update
记忆工具对外暴露统一入口memory,通过action参数区分三种行为。以下参数形状与默认值来自 memoryTools.ts 中的MEMORY_INPUT_SCHEMA,可直接作为调用参考(实时 Schema 仍为权威来源):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | string | ✅ | 枚举:update/append/search |
content | string | update 时必填 | FACT.md的完整 Markdown 内容 |
text | string | append 时必填 | 写入日志的条目文本 |
tags | string[] | append 可选 | 日志条目标签 |
query | string | search 时可选 | 搜索关键词,大小写不敏感的子串匹配 |
tag | string | search 可选 | 按标签过滤 |
limit | integer | search 可选 | 返回结果上限,默认 20 |
三个动作的语义如下:
search— 查询过去事件/笔记的日志(journal)。在再次询问用户之前,先搜索他们可能已经告诉过你的内容(一次纠正、一个偏好、先前的上下文)。注意:search覆盖的是追加式的日志文件,不包含持久事实文件(FACT.md)。append— 将一次性事件、已完成任务或会话笔记写入日志。update— 用长期知识和决策整体覆盖持久事实文件。
从工具描述可以进一步确认(见 memoryTool 定义):
'update'overwritesmemory/FACT.md(durable knowledge and decisions that should survive across sessions).'append'logs tomemory/JOURNAL.jsonl(one-time events, completed tasks, session notes).'search'queries the journal.
4. 选择update还是append:以「六个月法则」为准
决策依据是信息的存续期——「这件事六个月后还重要吗?」("Will this still matter in six months?"),这一定义同样被编码进了工具自身的描述文本中:
- 持久偏好、长期有效的决定、对工作方式的纠正、可复用的工具使用经验→ 使用
update; - 刚刚发生的事情→ 使用
append。
update会整体覆盖FACT.md。因此重写时必须保留已有内容——是「增补」而不是「清空重来」;如果对当前事实文件的内容不确定,应当先读取/回忆当前内容再写入。这一点在实现层面有强约束:memoryUpdate直接把传入的content作为FACT.md的全文写入(见下文第 5 节),不存在合并逻辑,误覆盖的代价完全由调用方承担。
5. 底层实现:文件布局与安全写入
理解底层的落盘机制有助于正确使用工具。持久记忆位于 Agent 数据目录的memory/子目录中,由 memoryTools.ts 实现。结合 docs/references/memory/overview.md,Agent 数据目录下的记忆相关文件为:
| 文件 | 角色 | 更新方式 |
|---|---|---|
SOUL.md | Agent 呈现自己的方式(人设 / 语气) | Read/Edit 工具 |
USER.md | 用户是谁(偏好、上下文) | Read/Edit 工具 |
memory/FACT.md | 持久知识与决定(6 个月以上) | memory工具update |
memory/JOURNAL.jsonl | 追加式事件日志 | memory工具append |
这些文件会在会话启动时被加载进系统提示词。从源码测试 prompt.test.ts 可以看到,memory/FACT.md会被包含进提示词的 memories 段落,验证了「会话启动加载 + Agent 自主更新」的设计。
5.1update的原子写入
memoryUpdate(源码 L113-L139)的实现要点:
- 校验
content为非空字符串,否则抛出InvalidParams错误; - 定位
memory/目录并解析FACT.md(大小写不敏感解析,见resolveFileCI); - 在同目录下创建临时文件
.FACT.md.<uuid>.tmp(权限0o600,wx模式即「不存在才创建」); - 写入完整内容后,通过
rename原子替换FACT.md; - 任一步失败都会清理临时文件并抛出错误。
这种「临时文件 + rename」的写法保证了FACT.md不会出现半写状态。
5.2 符号链接防护
实现中多处调用withNoFollow与lstat校验,确保FACT.md、JOURNAL.jsonl和memory/目录必须是真实文件/目录而非符号链接(源码 L20-L22、L93-L111):
- 非 Windows 平台下文件打开会附加
O_NOFOLLOW标志; lstat(而非stat)检查isFile()/isSymbolicLink(),凡是软链接一律拒绝。
这是一种针对 Agent 数据目录的符号链接攻击防护,保证工具只能操作 Agent 自己目录内的真实文件。
5.3append的日志格式
memoryAppend(源码 L141-L168)以O_APPEND | O_CREAT | O_WRONLY打开JOURNAL.jsonl,每行追加一条 JSON:
{"ts":"2026-09-11T12:00:00.000Z","tags":["preference"],"text":"用户偏好使用简洁回复"}每条日志条目包含三个字段:ts(ISO 时间戳)、tags(标签数组,可空)、text(正文)。追加采用单行 JSONL 格式,天然支持流式增量与逐行解析。
5.4search的匹配语义
memorySearch(源码 L170-L213)的行为细节:
- 匹配方式:对
text做大小写不敏感的子串匹配(toLowerCase().includes),并非全文检索或模糊匹配; - 标签过滤:
tag参数按大小写不敏感精确匹配条目的 tags; - 结果排序:取最后
limit(默认 20)条匹配结果并倒序返回,即「最近发生的事件排在最前」; - 空结果:文件不存在时返回
No journal entries found.;无匹配时返回No matching journal entries found.; - 容错:解析损坏的日志行时跳过并告警,不中断整个搜索(源码 L204-L206)。
6. 恢复策略(Recovery)
参考文档给出了明确的错误处理原则,这也与 cherry-tool-guide 的全局错误处理规则一致(SKILL.md):
- 工具返回错误结果→ 阅读错误消息并修正调用(例如补充
update缺的content、修正不存在的 ID),不要无脑重试相同参数; - 若
action传入未知值(非update/append/search),工具会抛出Unknown action的InvalidParams错误(源码 L228-L233); - 若审批被拒绝,应停止并汇报,不要换一条路径重试同样的变更。
7. 与 MCP 知识图谱记忆的区分
需要注意:mcp__agent-memory__memory是基于文件的 Agent 记忆,而 Cherry Studio 还内置了另一个 MCP 记忆服务@cherry/memory(实现位于 src/main/ai/mcp/servers/memory.ts),它以memory.json知识图谱(entities / relations / observations)为载体,通过create_entities、create_relations、search_nodes等 9 个工具操作结构化图谱数据。两者的选择逻辑在 docs/references/memory/overview.md 中有明确指引:
- 单 Agent 的人设与长期项目知识 →Agent File Memory(即本文主角);
- 可检索的、由用户策划的参考资料 →Knowledge Base;
- 由 MCP 驱动的结构化实体/关系记忆 →MCP Memory。
三者作用域、持久化方式与存储位置均不同,启用其中一个不会影响另外两个。
8. 延伸阅读
- cherry-tool-guide 路由总表(SKILL.md):了解记忆工具在整体工具路由中的位置与全局规则;
- memory 参考文档:本文的直接依据,包含路由与语义的权威说明;
- memoryTools.ts 实现:
update/append/search的完整底层实现与参数 Schema; - Memory Feature Overview:Agent File Memory、Knowledge Base、MCP Memory 三种机制的对比与选型;
- prompt.test.ts:验证
FACT.md等内容被加载进系统提示词的测试用例。
一句话总结:mcp__agent-memory__memory是 Cherry Studio 赋予 Agent 的跨会话记忆入口——用search先回忆、append记一次性事件、update维护六个月后仍重要的持久事实,并以「六个月法则」作为选择判据;底层通过FACT.md的原子覆盖与JOURNAL.jsonl的追加日志实现可靠、安全的落盘。
【免费下载链接】cherry-studioAI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs项目地址: https://gitcode.com/GitHub_Trending/ch/cherry-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考