Skip to content

OpenClaw:memory.md vs Skill 的本质差异

整理日期:2026-03-27 来源:OpenClaw 官方文档、phppan.com 技术分析、实际使用经验


先说结论

把流程放在 MEMORY.md 和放在 SKILL.md 里,表面上都是"写一个 Markdown 文件让 AI 读",但它们在系统里走的是完全不同的两条路,解决的也是两个不同的问题:

  • MEMORY.md 解决的是"AI 记住了什么"——跨会话的事实持久化,靠语义检索按需召回
  • SKILL.md 解决的是"AI 知道怎么做"——结构化的操作流程,靠目录注入按需展开

这两条路的加载时机、注入方式、触发机制、适用内容都不一样。混用会导致流程失效或记忆污染。


一、两者的加载机制

MEMORY.md 的加载路径

OpenClaw 的记忆系统是"文件即真相"的设计哲学:模型只"记住"写入磁盘的内容,内存里的东西不算记忆。

记忆文件有两层:

  • memory/YYYY-MM-DD.md:每日日志,仅追加,会话开始时自动读取今天和昨天的内容
  • MEMORY.md:长期记忆,精心整理的持久化事实,仅在主要私人会话中加载(群组上下文中不加载)

关键点:MEMORY.md 不是直接注入 system prompt 的。它的内容通过向量索引 + BM25 混合检索来召回。当模型需要某段记忆时,它调用 memory_search 工具,系统返回相关片段(约 700 字符上限),模型再通过 memory_get 精读具体行段。

这是一套"先定位,再精读"的渐进式披露机制,目的是控制 token 预算——不是把整个 MEMORY.md 塞进上下文,而是按需取用。

SKILL.md 的加载路径

Skill 的加载走的是完全不同的路:

  1. 发现阶段:启动时扫描多个目录,找到所有 SKILL.md 文件,合并成候选集
  2. 过滤阶段:根据配置开关、环境依赖、allowlist 等条件筛选出可用 skill
  3. 注入阶段:把所有可用 skill 的名称和 description 生成 <available_skills> 目录清单,直接注入 system prompt
  4. 读取阶段:模型看到目录清单后,如果判断某个 skill 匹配当前请求,才通过 Read 工具读取对应 SKILL.md 的完整内容

关键点:skill 的目录清单是 system prompt 的一部分,始终存在;但 skill 的正文内容是按需读取的,作为 toolResult 追加进消息流。


二、触发方式的根本差异

这是两者最核心的区别。

MEMORY.md 是被动召回的。模型不会主动去翻 MEMORY.md,它需要在对话中遇到相关话题,然后主动调用 memory_search 去检索。如果模型没有意识到需要查记忆,或者检索词不准,记忆就不会被用到。记忆的触发依赖模型的判断,不是确定性的。

SKILL.md 是主动匹配的。每次对话,模型都能在 system prompt 里看到完整的 skill 目录清单。只要用户的请求和某个 skill 的 description 明确匹配,模型就会去读那个 skill 的正文。触发是基于 description 的显式匹配,相对确定。

这个差异决定了什么内容适合放哪里:

  • 需要"在特定场景下必须被执行"的流程 → Skill(触发更可靠)
  • 需要"在相关话题出现时作为背景知识参考"的内容 → Memory(按需召回)

三、内容性质的差异

适合放 MEMORY.md 的内容

MEMORY.md 的官方定位是"决策、偏好和持久性事实"。具体来说:

  • 用户的个人偏好("我喜欢简洁的代码风格")
  • 项目的关键决策("我们选择了 PostgreSQL 而不是 MySQL,原因是...")
  • 调试经验("这个项目的 X 问题是因为 Y,解决方法是 Z")
  • 历史上下文("上周我们讨论了 A 方案,最终因为 B 原因放弃了")
  • 用户身份信息("我是后端工程师,主要用 Go")

这些内容的特点是:它们是事实,不是指令。它们描述"是什么",而不是"怎么做"。

适合放 SKILL.md 的内容

Skill 的定位是"结构化的操作流程"。具体来说:

  • 特定任务的执行步骤("发送大象消息的完整流程")
  • 工具的使用规范("如何用 catdesk CLI 操作浏览器")
  • 领域专项知识("MRN 项目的代码规范和禁止事项")
  • 复杂工作流("从需求到代码提交的完整 AI 辅助流程")

这些内容的特点是:它们是流程,不是事实。它们描述"怎么做",而不是"是什么"。


四、一个容易犯的错误

很多人会把"流程"写进 MEMORY.md,比如:

markdown
# 发送大象消息的流程
1. 先用 catdesk 查找群 ID
2. 然后构造消息体
3. 最后调用发送接口

这样写有几个问题:

问题一:召回不确定。MEMORY.md 靠语义检索,如果用户说"帮我发个大象消息",模型不一定会先去搜记忆,它可能直接开始行动,用自己训练数据里的知识来操作,而不是你写的流程。

问题二:内容混杂。MEMORY.md 里既有事实("我的大象 ID 是 xxx")又有流程("发消息的步骤是..."),检索时两类内容会互相干扰,召回质量下降。

问题三:无法强制执行。Skill 的 description 会出现在 system prompt 里,模型每次都能看到。但 MEMORY.md 里的流程只有被检索到才能被看到,而且即使看到了,它的权威性也只是一条 toolResult,不如 system prompt 里的指令有约束力。

正确做法:把流程写成 Skill,把流程执行过程中产生的上下文(比如"这个群的 ID 是 xxx")写进 Memory。


五、上下文预算的影响

两者对 token 预算的影响方式不同。

MEMORY.md 的预算影响是动态的。每次检索只返回约 700 字符的片段,不是全文。整个 MEMORY.md 可以很长,但每次对话消耗的 token 取决于实际检索到的内容量。这是一种"按需付费"的模式。

SKILL.md 的预算影响分两部分

  • <available_skills> 目录清单是固定成本,每次对话都要消耗(skill 越多,这个成本越高)
  • skill 正文是变动成本,只有被触发时才消耗

当 skill 数量过多时,OpenClaw 会把目录清单降级为 compact 格式甚至截断,这会影响 skill 的触发准确性。所以 skill 不是越多越好,要控制数量和 description 的质量。


六、生命周期的差异

MEMORY.md 是持续演化的。它随着每次对话不断积累,通过压缩机制(Compaction)在上下文快满时自动触发记忆刷新,把重要内容写入磁盘。它的内容会随时间增长,需要定期整理。

SKILL.md 是相对稳定的。一个 skill 写好之后,除非流程本身发生变化,否则不需要频繁修改。它更像一份操作手册,而不是一个动态增长的日记本。


七、实践建议

判断内容应该放哪里,问自己两个问题:

  1. 这是"事实/背景"还是"流程/操作步骤"?

    • 事实/背景 → MEMORY.md
    • 流程/操作步骤 → SKILL.md
  2. 这个内容需要"在特定任务触发时必须被执行",还是"在相关话题出现时作为参考"?

    • 必须被执行 → SKILL.md(触发更可靠)
    • 作为参考 → MEMORY.md(按需召回)

一个典型的配合使用场景:

假设你要让 AI 帮你管理一个项目的代码审查流程:

  • SKILL.md 里写:代码审查的完整步骤(检查哪些维度、用什么工具、输出什么格式)
  • MEMORY.md 里写:这个项目的特殊约定("这个项目不用 ESLint,用 Biome")、历史决策("我们决定不强制要求单元测试覆盖率")

Skill 保证流程被正确执行,Memory 保证执行时能用上项目特有的上下文。


八、底层原理总结

维度MEMORY.mdSKILL.md
加载时机会话开始时建立向量索引,按需检索启动时扫描,目录清单注入 system prompt
触发方式模型主动调用 memory_search模型匹配 available_skills 目录后读取
内容性质事实、偏好、历史决策操作流程、执行步骤、工具规范
权威性toolResult(较弱)system prompt 目录 + toolResult 正文
预算模式按需付费(片段召回)固定成本(目录)+ 变动成本(正文)
生命周期持续积累,动态演化相对稳定,按需更新
适合内容"是什么""怎么做"

两者不是竞争关系,而是互补关系。Memory 是 AI 的"长期记忆",Skill 是 AI 的"操作手册"。一个好的 OpenClaw 配置,应该让两者各司其职:Memory 积累上下文,Skill 规范行为。


参考来源