OpenClaw 记忆系统 -- 记忆预加载
【摘要】 本篇继续 OpenClaw 记忆系统分析系列,介绍了 OpenClaw 记忆系统的预加载过程。
1. 记忆系统启动流程
记忆初始化过程分为两个主要阶段:系统启动时的记忆后端初始化和会话启动时的记忆上下文构建。
- 系统启动阶段主要初始化QMD类型的记忆后端,为后续的记忆操作做准备;
- 会话启动阶段则根据配置加载最近几天的记忆文件,构建启动上下文,为大模型提供必要的上下文信息。
2. 系统启动阶段 (server-startup-memory.ts)
2.1. 系统启动阶段流程图

2.2. 主要过程
- 遍历Agent:系统启动时遍历所有配置的agent
- 配置检查:检查每个agent的记忆搜索配置是否启用
- 后端类型:只初始化QMD(Quantized Memory Database)类型的记忆后端
- 管理器初始化:为每个符合条件的agent初始化记忆搜索管理器
- 错误处理:记录初始化失败的情况
2.3. 系统启动触发
- 触发时机:Gateway 服务启动时
- 配置检查:检查每个 agent 的记忆搜索配置是否启用
- 后端类型:只初始化 QMD 类型的记忆后端
2.4. 系统启动阶段参数
agents.defaults.memorySearch.enabled- 是否启用记忆搜索agents.defaults.memorySearch.backend- 记忆后端类型(必须为"qmd")agents.defaults.memorySearch.qmd- QMD后端配置
2.5. 读取的信息
- 配置文件中的记忆搜索配置 (
resolveMemorySearchConfig) - 记忆后端配置 (
resolveActiveMemoryBackendConfig) - 初始化 QMD 类型的记忆后端
- 不直接读取具体记忆文件,而是初始化记忆搜索管理器
2.6. 输入/输出
-
系统启动时的记忆后端初始化:
src/gateway/server-startup-memory.ts#L8-L35-startGatewayMemoryBackend
-
系统启动输入:
- 配置对象
OpenClawConfig - 代理ID
agentId
- 配置对象
-
系统启动输出:
- 记忆搜索管理器
MemorySearchManager - 错误信息(如果有)
- 记忆搜索管理器
2.7. 主要代码和函数
| 函数名 | 文件路径 | 作用 |
|---|---|---|
startGatewayMemoryBackend |
src/gateway/server-startup-memory.ts#L9-L35 |
系统启动时初始化记忆后端 |
listAgentIds |
src/agents/agent-scope.js |
列出所有agent ID |
resolveMemorySearchConfig |
src/agents/memory-search.js |
解析记忆搜索配置 |
resolveActiveMemoryBackendConfig |
src/plugins/memory-runtime.js |
解析活跃记忆后端配置 |
getActiveMemorySearchManager |
src/plugins/memory-runtime.js |
获取记忆搜索管理器 |
3. 会话启动阶段 (startup-context.ts)
3.1. 会话启动阶段流程图

3.2. 主要过程
- 配置检查:检查是否启用启动上下文,以及是否应用到当前操作
- 参数解析:解析用户时区和启动上下文限制参数
- 日期窗口:生成需要加载的记忆日期范围,考虑本地时区和UTC的差异
- 文件扫描:扫描memory目录,按日期分组文件,包括主要文件和slugged文件
- 文件读取:读取每个文件的内容,应用单个文件大小限制
- 内容处理:修剪和格式化记忆内容,确保符合字符限制
- 上下文构建:构建启动上下文字符串,应用总字符数限制
- 结果返回:返回构建好的启动上下文,或null(如果没有加载到记忆)
3.3. 会话启动触发
- 触发时机:新会话创建或会话重置时
- 配置检查:
agents.defaults.startupContext.enabled不为 false - 应用条件:
agents.defaults.startupContext.applyOn包含当前操作类型(“new” 或 “reset”)
3.4. 会话启动阶段参数
// src/auto-reply/reply/startup-context.ts
startupContext: {
enabled: boolean; // 是否启用启动上下文
applyOn: string[]; // 应用到哪些操作("new", "reset")
dailyMemoryDays: number; // 加载最近几天的记忆,默认2天
maxFileBytes: number; // 单个文件最大字节数,默认16384
maxFileChars: number; // 单个文件最大字符数,默认1200
maxTotalChars: number; // 总字符数限制,默认2800
}
agents.defaults.startupContext.enabled- 是否启用启动上下文agents.defaults.startupContext.applyOn- 应用场景(“new"或"reset”)agents.defaults.startupContext.dailyMemoryDays- 加载最近几天的记忆(1-14天,默认2天)agents.defaults.startupContext.maxFileBytes- 单个文件最大字节数(默认16384,最大64KB)agents.defaults.startupContext.maxFileChars- 单个文件最大字符数(默认1200,最大10000)agents.defaults.startupContext.maxTotalChars- 总字符数限制(默认2800,最大50000)agents.defaults.userTimezone- 用户时区设置
3.5. 读取的信息
-
每日记忆文件:
memory/YYYY-MM-DD.md -
每日slugged文件:
memory/YYYY-MM-DD-*.md(最多4个/天) -
注意:
MEMORY.md、SOUL.md、USER.md由其他模块单独处理 -
读取的数据库信息:
- 此阶段不直接读取SQLite数据库
- 数据库读取在后续的记忆搜索和同步过程中进行
3.6. 输入/输出
-
会话启动时的记忆上下文构建:
src/auto-reply/reply/startup-context.ts#L309-L386-buildSessionStartupContextPrelude
-
会话启动输入:
- 工作区目录
workspaceDir - 配置对象
OpenClawConfig - 当前时间
nowMs(可选)
- 工作区目录
-
会话启动输出:
- 启动上下文字符串
string或null
- 启动上下文字符串
3.7. 主要代码和函数
| 函数名 | 文件路径 | 作用 |
|---|---|---|
shouldApplyStartupContext |
src/auto-reply/reply/startup-context.ts#L17-L30 |
判断是否应用启动上下文 |
buildSessionStartupContextPrelude |
src/auto-reply/reply/startup-context.ts#L309-L386 |
构建会话启动上下文 |
resolveUserTimezone |
src/agents/date-time.js |
解析用户时区 |
resolveStartupContextLimits |
src/auto-reply/reply/startup-context.ts#L32-L64 |
解析启动上下文限制 |
buildStartupMemoryDateStamps |
src/auto-reply/reply/startup-context.ts#L91-L111 |
构建记忆日期窗口 |
listStartupMemoryPathsByDate |
src/auto-reply/reply/startup-context.ts#L224-L307 |
列出按日期分组的记忆路径 |
readStartupMemoryFile |
src/auto-reply/reply/startup-context.ts#L202-L222 |
读取记忆文件内容 |
trimStartupMemoryContent |
src/auto-reply/reply/startup-context.ts#L113-L119 |
修剪记忆内容到字符限制 |
formatStartupMemoryBlock |
src/auto-reply/reply/startup-context.ts#L133-L142 |
格式化记忆块 |
fitStartupMemoryBlock |
src/auto-reply/reply/startup-context.ts#L144-L174 |
适配记忆块到字符限制 |
4. 读取记忆的限制条件
4.1. 文件数量限制
- 时间范围:最近
dailyMemoryDays天(默认2天) - 文件数量:每天最多5个文件(1个主要文件 + 4个slugged文件)
- 总量限制:
- 单个文件:最多64KB或10000字符
- 总内容:最多50000字符
4.2. 文件大小限制
- 单个文件最大字节数:
maxFileBytes(默认16384,最大64KB) - 单个文件最大字符数:
maxFileChars(默认1200,最大10000) - 总字符数限制:
maxTotalChars(默认2800,最大50000)
4.3. 安全限制
- 文件路径必须在工作区内(
openBoundaryFile检查) - 记忆内容标记为"不受信任",防止执行其中的指令
4.4. 重要的常量和默认值
| 常量 | 值 | 描述 |
|---|---|---|
STARTUP_MEMORY_FILE_MAX_BYTES |
16384 | 单个文件最大字节数默认值 |
STARTUP_MEMORY_FILE_MAX_CHARS |
1200 | 单个文件最大字符数默认值 |
STARTUP_MEMORY_TOTAL_MAX_CHARS |
2800 | 总字符数限制默认值 |
STARTUP_MEMORY_DAILY_DAYS |
2 | 加载最近几天的记忆默认值 |
STARTUP_MEMORY_FILE_MAX_BYTES_CAP |
64*1024 | 单个文件最大字节数上限 |
STARTUP_MEMORY_FILE_MAX_CHARS_CAP |
10000 | 单个文件最大字符数上限 |
STARTUP_MEMORY_TOTAL_MAX_CHARS_CAP |
50000 | 总字符数限制上限 |
STARTUP_MEMORY_DAILY_DAYS_CAP |
14 | 加载最近几天的记忆上限 |
STARTUP_MEMORY_MAX_SLUGGED_FILES_PER_DAY |
4 | 每天最多加载的slugged文件数 |
5. 记忆内存存储格式
5.0.1. 中间存储格式
- 数组形式:
Array<{ relativePath: string; content: string }> - 每个元素包含文件路径和内容
5.0.2. 最终存储格式
- 最终格式:格式化的文本区块,合并为单个字符串
- 字符串形式,包含:
- 头部说明(启动上下文信息)
- 格式化的记忆区块(每个文件一个区块)
- 每个区块格式:
[Untrusted daily memory: {relativePath}]
BEGIN_QUOTED_NOTES
\`\`\`text
{content}
\`\`\`
END_QUOTED_NOTES
6. 系统配置
6.1. 记忆搜索配置
// src/agents/memory-search.ts
sync: {
onSessionStart: boolean; // 会话开始时是否同步
onSearch: boolean; // 搜索时是否同步
watch: boolean; // 是否监视文件变化
watchDebounceMs: number; // 监视防抖时间
intervalMinutes: number; // 同步间隔
sessions: {
deltaBytes: number; // 会话增量字节数阈值
deltaMessages: number; // 会话增量消息数阈值
postCompactionForce: boolean; // 压缩后是否强制同步
};
}
7. 总结
记忆预热是 OpenClaw 记忆系统的重要组成部分,通过以下步骤确保系统启动和会话开始时记忆的有效加载:
- 系统启动:初始化 QMD 类型的记忆后端,确保记忆搜索管理器就绪
- 会话启动:根据配置加载最近几天的记忆文件,构建启动上下文
- 数量控制:通过多种配置参数控制读取的文件数量和大小
- 内存管理:优化内存使用,确保启动上下文在合理大小范围内
这种设计既保证了记忆的有效加载,又控制了系统资源的使用,为大模型提供了必要的上下文信息,同时避免了过度加载导致的性能问题。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)