OpenClaw源码深度剖析:AI记忆机制与安全防线

2026-05-31阅读 0热度 0
OpenClaw

OpenClaw 源码剖析(五):Memory 与安全——AI 的记忆机制与防线


存储与安全体系,是AI Agent迈向实用化的关卡。一个连用户基础信息都记不住的助手,和一个能精准回溯项目细节的助手,体验差距巨大。OpenClaw作为坐拥21万Star的个人AI框架,在此问题上提供了极为务实的设计方案。本文直击其底层源码,拆解记忆机制的运作逻辑与安全防线的构建方式。

核心结论先放在这里:OpenClaw在记忆与安全上走的是"实用主义"路线——无需昂贵的向量数据库,也无须复杂的模型微调,仅凭标准的文件系统与精妙的策略组合,便搭建了一套可投入使用的记忆与防护系统。


一、Memory 系统:AI 的"记忆大脑"是怎么工作的

为什么 AI 助手需要记忆?

缺乏记忆能力的AI助手好比一条金鱼——每次对话都是全新开始。你告知的偏好它转身即忘,讨论过的项目背景下次还得重新铺垫。这种体验在简单的一问一答场景下或许忍忍就过去了,但对于OpenClaw这样的个人AI助手是完全不可接受的。一个真正有价值的助手必须记住:你的称呼、常用编程语言、在进行的项目、过往的对话要点。

然而,记忆系统绝不能是"将所有对话原文存档"的粗暴方案。LLM的上下文窗口终究存在上限——GPT-4o是128K tokens,Claude 3.5是200K tokens,且全量检索既拖慢响应速度又消耗大量计算资源。OpenClaw的解法是分层记忆加混合检索:将记忆按层级拆解,用不同策略进行存取,在"记牢关键信息"与"遗忘冗余内容"之间找到最优平衡点。

Memory 系统的设计原则

原则说明
文件优先(File-First)所有记忆均以纯 Markdown 文件存储,可读、可编辑、可纳入 Git 版本追踪
本地优先(Local-First)索引存放于本地 SQLite,无需依赖外部向量数据库
混合检索(Hybrid Search)BM25 关键词匹配 + sqlite-vec 向量语义搜索
自动保存(Auto-Flush)上下文压缩前自动触发 Memory Flush,避免信息丢失
可观测(Observable)记忆文件为纯文本,用户可随时查阅与修改

二、三层记忆架构:Session → Daily → Persistent

OpenClaw的记忆系统划分为三层,从短期到长期,从热数据到冷数据,逐层递进。

Session 记忆(会话级)

这是最短暂的一层,存于JSONL会话文件中。它完整记录了当前对话的全过程——用户的提问、Agent的回复、调用的工具、返回的结果。Session记忆与对话生命周期完全绑定:对话结束即持久化至磁盘,下次对话可通过session.list回溯历史会话。

Session记忆面临的核心挑战在于上下文窗口限制。随着对话轮次增多、工具调用结果变长,Session内容很快会触及LLM的承载上限。此时必须执行Compaction(压缩)——将旧消息提炼为摘要,为新内容腾出空间。这部分流程系列第三篇已做过详细阐述,此处不再赘述。

Daily Notes(日级)

Daily Notes属于中期记忆,存储于memory/YYYY-MM-DD.md文件中。每天一个独立文件,记录当日发生的关键事项。它由Memory Flush自动生成——当上下文即将占满预设阈值时,Agent会触发一次静默推理轮次,将重要信息整理写入当天的Daily Note。

这个设计非常有巧思:Daily Notes并非原封不动复制对话内容,而是让LLM主动判断"今天发生了哪些重要事件"。被保留下来的信息经过了筛选与提炼,只有LLM判定为有价值的内容才会被写入。这种"AI自主决定记录什么"的机制,远比简单的全量存储高效。

Persistent Memory(持久级)

这是最长周期的记忆,存放于MEMORY.md文件中。它记录的是结构化、稳定、跨时间的信息——用户偏好、项目配置、常用模式、重要决策等。与Daily Notes不同,MEMORY.md通常由用户手动维护,或在Agent收到明确指令时更新。

MEMORY.md采用结构化Markdown格式,通常包含以下几个Section:

# User Preferences
- 编程语言:Python、TypeScript
- 编辑器:VS Code + Vim
- 沟通语言:中文

# Current Projects
- OpenClaw 源码剖析系列(5篇,进行中)
- RAG 系统优化(调研阶段)

# Important Decisions
- 2026-04-15:决定使用 SQLite + sqlite-vec 替代 Pinecone

纯文本格式带来的最大优势就是可读性与可编辑性——用户随时可以用任何文本编辑器打开MEMORY.md,查看Agent记住了哪些信息,修正错误的记忆,或添加新内容。这正是"文件优先"哲学的极致体现。


三、混合检索:BM25 + 向量搜索的双引擎

为什么需要混合检索?

单一的检索方式总有局限:

  • BM25(关键词匹配):擅长精确匹配,例如"OpenClaw"、"SQLite"这类关键词一抓一个准,但它无法理解语义——搜索"数据库"匹配不到"DB"。
  • 向量搜索(语义匹配):擅长语义相似度判断,"记忆系统"能匹配到"知识存储",但反过来它可能漏掉精确定位的关键词。

OpenClaw的解决思路是混合检索——同时执行BM25和向量搜索,再将结果合并、去重、排序。这样既能精确匹配关键词,又不会丢失语义层面的相关性。

MemoryIndexManager 的实现

MemoryIndexManagersrc/memory/manager.ts)是记忆检索的核心引擎。底层使用SQLite进行存储,配合两个SQLite扩展:

组件功能说明
SQLite FTS5全文搜索(BM25)内置扩展,零配置,对 Markdown 文本建立倒排索引
sqlite-vec向量搜索SQLite 扩展,支持向量相似度搜索(余弦距离)

索引构建的流程大致如下:

  1. 文件扫描:扫描memory/*.mdMEMORY.md,提取所有文本内容
  2. 分块:按段落或标题进行分割,每个块控制在200-500 tokens左右
  3. BM25索引:将文本块插入FTS5虚拟表
  4. 向量索引:将文本块通过Embedding模型转换为向量,存入sqlite-vec
  5. 增量更新:文件变更时仅更新受影响的块,避免全量重建

Embedding 提供者:本地优先,云端回退

OpenClaw的Embedding策略是"本地优先,云端回退":

尝试本地 Embedding(ONNX Runtime + 小模型)
↓ 失败?尝试云端 Embedding(OpenAI text-embedding-3-small)
↓ 失败?降级为纯 BM25 检索(无向量搜索)

这套降级策略确保了即使在离线环境下,记忆检索仍然可用——缺失的只是语义层面的搜索能力,但精确匹配依旧正常运行。

检索 API

Agent通过两个工具来访问记忆:

工具功能说明
memory_search搜索记忆输入查询,返回最相关的记忆片段
memory_get获取具体行输入文件路径和行号,返回精确内容

这两个工具会在System Prompt的Memory Section中被注入,Agent知道何时该调用。举个例子,如果用户问"我之前讨论过哪些RAG方案?",Agent就会执行memory_search("RAG 方案"),从Daily Notes和MEMORY.md中检索相关信息。


四、双源存储:Daily Notes 与 MEMORY.md

OpenClaw的长期记忆有两个"水源":

动态源:Daily Notes(memory/YYYY-MM-DD.md

Daily Notes是动态、自动生成的记忆,特点如下:

  • 自动创建:Memory Flush触发时,Agent自动写入
  • 按时间组织:每天一个文件,形成自然的时间轴
  • 内容灵活:可以是总结、决策、待办事项、关键信息
  • 检索权重较低:在混合检索中,Daily Notes的权重低于MEMORY.md

Daily Notes的典型内容:

# 2026-05-07

## 讨论要点
- 完成了 OpenClaw 源码剖析系列第四篇(Channel 与 Skills)
- 确认第五篇将覆盖 Memory 和安全系统
- 用户偏好:文章风格保持技术深度 + 图文并茂

## 待办事项
- [ ] 第五篇需要包含 PRISM 安全层详解
- [ ] 系列完结后整理为 PDF 合集

静态源:MEMORY.md

MEMORY.md是静态、手动维护的记忆,特点不同:

  • 用户控制:用户可以随时查看、编辑、删除
  • 结构化:按Section组织,信息相对稳定
  • 检索权重较高:混合检索时,MEMORY.md的匹配结果会排在Daily Notes前面
  • 跨时间:不按日期分割,所有持久信息集中在一个文件里

双源合并检索

当Agent调用memory_search时,检索流程如下:

  1. 并行查询:同时查FTS5(BM25)和sqlite-vec(向量)
  2. 结果合并:BM25结果和向量结果取并集,按相关度排序
  3. 权重调整:MEMORY.md的匹配结果权重 × 1.5,Daily Notes权重 × 1.0
  4. 去重:同一个文件的不同块只保留最相关的
  5. 返回Top-K:返回最相关的K个记忆片段(默认K=5)

五、Memory Flush:压缩前的"存档点"

Memory Flush可以说是OpenClaw记忆系统里最精妙的设计之一。核心思想非常直接:在上下文压缩(Compaction)之前,先让Agent把重要信息保存到记忆文件里,确保信息不丢失。

触发条件

Memory Flush由shouldRunMemoryFlush()函数判断:

function shouldRunMemoryFlush(params) {
    const totalTokens = params.entry?.totalTokens;
    if (!totalTokens || totalTokens <= 0) return false;

    // 计算阈值:上下文窗口 - 预留 - 软阈值
    const threshold = Math.max(0, params.contextWindowTokens - params.reserveTokensFloor - params.softThresholdTokens);
    if (totalTokens < threshold) return false;

    // 每个 Compaction 周期只 Flush 一次
    const compactionCount = params.entry?.compactionCount ?? 0;
    const lastFlushAt = params.entry?.memoryFlushCompactionCount;
    if (typeof lastFlushAt === "number" && lastFlushAt === compactionCount) {
        return false; // 本周期已 Flush 过
    }

    return true;
}

几个关键参数:

参数默认值说明
DEFAULT_MEMORY_FLUSH_SOFT_TOKENS4000软阈值,给 Agent 留出"存档"的空间
reserveTokensFloor模型相关硬预留,确保 Compaction 有足够空间
memoryFlushCompactionCount自动追踪防止同一周期重复 Flush

Flush 流程

  1. 检测shouldRunMemoryFlush()返回true
  2. 静默推理:Agent执行一次不向用户展示的推理轮次,Prompt为"将重要信息保存到 memory/YYYY-MM-DD.md"
  3. 写入:Agent调用write_file工具,把总结写入Daily Note
  4. 标记:记录memoryFlushCompactionCount,防止重复
  5. 继续:Compaction正常执行,旧消息被压缩

这个设计的精妙之处在于:它把一个破坏性操作(压缩 = 丢失信息)变成了一个有准备的操作(先存档,再压缩)。就像是游戏里的"存档点"——在Boss战之前自动保存,就算失败了也不至于从头再来。


六、安全架构:五层纵深防御

OpenClaw的安全架构采用的是纵深防御策略,从外到内分五层:

L1:Gateway 认证

最外层的防御线是Gateway的认证机制。所有连接到Gateway的客户端——不管是Channel、CLI还是Web UI——都必须通过挑战-响应认证。Gateway支持两种认证模式:

  • Token认证:在openclaw.yaml中配置auth.token,客户端连接时必须提供
  • Password认证:配置auth.password,客户端通过密码认证

远程访问时推荐使用Tailscale——Gateway绑定127.0.0.1:18789,Tailscale提供加密隧道,无需公网暴露端口。

L2:Tool Policy 策略

第二层是工具执行策略。每个工具调用都要经过Tool Policy检查:

  • allow:自动放行(比如read_filebrowser_tool
  • confirm:需要用户确认(比如write_filebash
  • deny:硬性拒绝(比如rm -rf /

这部分在第三篇已经详细拆解过六步链路,不再重复了。

L3:Sandbox 沙箱隔离

第三层是工具执行的沙箱隔离,提供以下隔离维度:

隔离维度实现方式
文件系统限制可访问的目录范围
网络可选的网络隔离
进程Docker 容器隔离
资源CPU、内存、执行时间限制

沙箱信息通过sandbox-info.ts注入到System Prompt中,Agent知道自己的执行边界在哪里。

L4:PRISM 运行时防护

第四层是PRISM——OpenClaw的运行时安全层。这是最复杂也最关键的安全组件,下一节会详细拆解。

L5:审计与可观测

最内一层是审计和可观测性。所有工具调用、安全事件、策略变更都记录到链式审计日志中,支持完整性校验和事后追溯。


七、PRISM:零 Fork 运行时安全层

PRISM(Plugin-based Runtime Intrusion Security Monitor)是OpenClaw的运行时安全层,2026年3月发表在arXiv上(arXiv:2603.11853)。其核心设计理念是零Fork——不修改OpenClaw任何上游代码,通过插件机制嵌入Gateway进程。

三组件架构

PRISM由三个组件构成:

组件运行方式职责
In-Process Plugin嵌入 Gateway 进程10 个运行时 Hook 拦截,热重载策略
Sidecar Service独立进程(可选)LLM 辅助扫描,网络治理,密钥过滤
Security DashboardWeb UI审计记录,健康探针,Allow 工作流

十个运行时 Hook

PRISM在Agent运行时的10个关键节点插入了Hook:

Hook拦截点安全检查
onToolCall工具调用前策略检查、风险评分
onToolResult工具返回后输出过滤、密钥检测
onMessage消息发送前Prompt Injection 检测
onResponseLLM 响应后敏感信息过滤
onFileWrite文件写入前路径白名单、权限检查
onFileRead文件读取前路径白名单
onNetworkRequest网络请求前域名/路径白名单
onShellExecShell 执行前命令白名单、危险命令检测
onSessionStart会话开始时初始化安全上下文
onSessionEnd会话结束时审计记录、安全清理

风险累积评分

PRISM最重要的创新是风险累积评分。它不对每个操作做独立的"允许/拒绝"判断,而是累积风险分数。随着可疑操作增多,响应级别会逐步升级:

风险等级分数范围响应动作
✅ 低风险0-30正常执行,记录审计日志
⚠️ 中风险31-60额外日志,限制工具范围
???? 高风险61-80禁止危险工具,需要用户确认
???? 严重81-100会话级锁定,停止所有工具调用

这种渐进式响应比简单的"一刀切"实用得多。单个可疑操作不会直接触发锁定,但连续多个可疑操作会让风险分数逐渐累积到锁定级别。这就好比信用卡的风控系统——一笔异常交易可能只是你在旅行,但连续多笔异常交易就会触发冻结。

启发式优先,LLM 辅助

PRISM的扫描路径是启发式优先,LLM辅助:

  1. 启发式扫描(快速、低成本):正则匹配危险命令、路径遍历、密钥模式
  2. LLM 辅助扫描(慢速、高成本):当启发式无法判断时,调用 LLM 分析意图

这种设计保证了大部分安全检查都在毫秒级完成,只有边缘情况才需要LLM介入。


八、Sandbox 沙箱:工具执行的隔离边界

沙箱的必要性

当AI助手具备执行Shell命令的能力时,沙箱就不是"可选的"了,而是"必须的"。一个没有沙箱的Agent就像一把没有保险的枪——你不知道它什么时候会走火。

OpenClaw的沙箱系统在三个维度提供隔离:

文件系统沙箱

文件系统沙箱限制Agent可访问的目录范围。默认情况下,Agent只能访问工作空间目录(~/.openclaw/workspace/)和临时目录。访问其他目录需要经过Tool Policy的confirm级别审批。

# openclaw.yaml 沙箱配置
sandbox:
  allowedPaths:
    - ~/.openclaw/workspace/
    - /tmp/openclaw/
  deniedPaths:
    - /etc/
    - ~/.ssh/
    - ~/.aws/

网络沙箱

网络沙箱限制Agent的出站网络访问。PRISM的Sidecar Service提供网络治理:

  • 域名白名单:只允许访问特定域名
  • 路径保护:禁止访问内网敏感路径
  • 出站密钥过滤:检测并阻止API Key、密码等敏感信息外泄

Docker 容器沙箱

对于高风险操作(比如执行用户提交的代码),OpenClaw支持Docker容器级别的隔离:

sandbox:
  docker:
    enabled: true
    image: openclaw/sandbox:latest
    readOnlyRoot: true          # 只读根文件系统
    memoryLimit: 512m           # 内存限制
    cpuLimit: 0.5               # CPU 限制
    timeout: 30s                # 执行超时
    networkMode: none           # 无网络访问

九、生产部署安全清单

将OpenClaw部署到生产环境时,安全不是什么"锦上添花"的事,而是必须到位。下面是根据官方文档和社区最佳实践整理的安全清单:

网络层

检查项说明配置
Gateway 绑定 127.0.0.1禁止公网直接访问openclaw.yaml: gateway.host: 127.0.0.1
启用认证Token 或 Password 至少选一个openclaw.yaml: auth.token:
远程访问走 Tailscale加密隧道,零公网暴露tailscale up + Gateway 绑定 Tailscale IP
禁止暴露 18789 端口防火墙规则ufw deny 18789

容器层

检查项说明
非特权用户运行Docker 容器不以 root 运行
只读文件系统根文件系统挂载为 read-only
资源限制CPU、内存、PID 限制
禁止特权模式--privileged 标志永远不要用

凭证层

检查项说明
API Key 存 .env不入 Git,不硬编码
PRISM 密钥过滤防止 API Key 通过工具调用外泄
Auth Profile 轮换LLM API Key 轮换/冷却机制
定期轮换 Gateway Token至少每月更换一次

运行时层

检查项说明
启用 PRISM生产环境必须开启
Tool Policy 最小权限只开放必要的工具
ClawHub 技能审查安装前检查技能来源和代码
定期审计日志每周检查 PRISM 审计记录

十、系列终章回顾

五篇文章,从全局到局部,从架构到源码,完整拆解了OpenClaw这个21万Star的AI Agent框架。用一张表来回顾整个系列:

篇目核心主题一句话总结
第一篇项目全景框架做得越少,Agent 能做的越多——减法才是最难的加法
第二篇Gateway不思考,但确保思考发生在正确的时间、正确的上下文、正确的隔离边界内
第三篇Agent Loop双层循环分离健壮性和正确性,让 AI 既能干好事,又不出坏事
第四篇Channel & Skills适配器模式抹平平台差异,提示词插件实现能力无限扩展
第五篇Memory & 安全文件优先的记忆 + 纵深防御的安全,守护 AI 的记忆完整性和行为安全性

OpenClaw 的核心设计哲学

回顾整个系列,OpenClaw的设计哲学可以归纳为三条:

1. 减法优于加法

OpenClaw的底层框架pi-mono只有4个工具,系统提示词不到1000个token。它不依赖LangChain/LangGraph这些重量级框架,而是用最少的代码解决最核心的问题。这种"减法"不是偷懒,而是对问题本质的深刻理解——AI Agent的复杂性应该来自任务本身,而不是框架。

2. 文件优先

配置是YAML文件,记忆是Markdown文件,会话是JSONL文件,技能是Markdown加脚本文件。所有状态都是纯文件,可读、可编辑、可Git追踪。这种"文件优先"设计让OpenClaw的每个组件都是可观测的、可审计的、可恢复的。

3. 纵深防御

从Gateway认证到Tool Policy,从Sandbox隔离到PRISM运行时防护,从审计日志到密钥过滤——OpenClaw的安全不是一层墙,而是一条完整的防线。每一层都不完美,但每一层都在不同维度提供保护,组合起来就是一道坚不可摧的纵深防御体系。

给开发者的建议

如果正在基于OpenClaw构建自己的AI助手,可以给出五条建议:

  1. 先跑起来,再优化:用openclaw onboard五分钟启动,先体验再深入
  2. 从Skill开始扩展:不要改框架代码,先写一个SKILL.md试试
  3. 安全不能省:生产环境必须开启PRISM + Tool Policy + Sandbox
  4. 记忆是你的资产:定期维护MEMORY.md,它是你AI助手的"长期记忆"
  5. 读源码:OpenClaw的源码写得非常清晰,是最好的学习材料

总结速查卡

Memory 核心概念

概念一句话解释
三层记忆Session(会话级)→ Daily Notes(日级)→ MEMORY.md(持久级)
混合检索BM25 关键词匹配 + sqlite-vec 向量语义搜索
双源存储Daily Notes(动态自动)+ MEMORY.md(静态手动)
Memory Flush压缩前自动存档,防止信息丢失
MemoryIndexManagerSQLite + FTS5 + sqlite-vec,本地优先零依赖
Embedding 降级本地 ONNX → 云端 OpenAI → 纯 BM25

安全核心概念

概念一句话解释
五层纵深防御认证 → Tool Policy → Sandbox → PRISM → 审计
PRISM零 Fork 运行时安全层,插件嵌入 Gateway 进程
风险累积评分渐进式响应,0-100 分,四级响应
10 Hook从工具调用到会话生命周期的全链路拦截
启发式优先正则快速扫描,LLM 辅助边缘情况
零 Fork不修改上游代码,通过插件机制嵌入

参考链接:

  • OpenClaw GitHub 仓库
  • OpenClaw Memory 文档
  • OpenClaw PRISM 论文 (arXiv:2603.11853)
  • PingCAP: Local-First RAG with SQLite
  • MMNTM: OpenClaw Memory Architecture Walkthrough
  • Nebius: OpenClaw Security Hardening Guide
  • DataCamp: OpenClaw Security Best Practices
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策