OpenClaw 是如何使用上下文工程来自动进化的?

这个视频谈谈 OpenClaw 在 agent 方面的架构。OpenClaw 本身不只是 agent,而是一个网关服务,但这篇文章我们主要从 Agent 的角度解析它。核心回答两个问题:

  1. OpenClaw 是怎么做到基于复杂上下文的?
  2. OpenClaw 是如何做到主动的?

答案可以概括为:通过工程化的上下文管理实现自动进化。下面我们展开,从 System Prompt 和 Memory 两个核心机制来看 OpenClaw 如何处理复杂上下文,再介绍 Cron/Heartbeat/Message 三种主动性机制。


一、System Prompt:四层上下文架构

OpenClaw 的 system prompt 不是简单的信息罗列,而是一个从”系统能力”到”用户定制”的分层结构。这种分层直接支持复杂上下文的处理能力。

具体来看,这四层分别是:

层次 1:能力声明(Capabilities) —— 告诉 agent 它”能做什么”。包括当前可用的工具列表及简要说明、如何按需加载技能指令(通过 read 读取 SKILL.md),以及可用的模型别名。

层次 2:安全与约束(Safety & Constraints) —— 划定行为的边界。这里明确禁止权力寻求、自我复制、绕过监管等行为,同时说明沙盒运行环境的路径和权限级别。

层次 3:操作指南(Operational Guidance) —— 提供日常操作的快速参考,比如网关管理命令、memory_search 的使用时机、gateway tool 的使用场景,以及跨会话消息发送的方法。

层次 4:项目上下文(Project Context) —— 这是最灵活的一层,通过工作目录中的文件注入,是用户定制的核心。这些文件包括:

文件作用
AGENTS.md告诉智能体:每次会话该读什么文件、怎么管理记忆、什么时候该说话/沉默、安全边界、群聊礼仪、心跳检查策略等。相当于”员工手册”。
SOUL.md定义名字、性格、说话风格、价值观。比如:你叫小明,说话简洁幽默,偏好用中文回答,遇到不确定的事会坦诚说不知道。
IDENTITY.mdSOUL.md 的别名/补充

部分模板用 IDENTITY.md 代替或补充SOUL.md,作用相同——定义智能体的角色定位。两者可以只用一个。
MEMORY.md需要长期记忆的东西
TOOLS.md给智能体记录外部工具的使用注意事项和本地配置细节。比如:

> - SSH 到服务器用 ssh myserver,密钥已配好
> - 摄像头名字叫 “Front Door”
> - 用 ElevenLabs TTS 时默认用 “Adam” 声音

注意:它不定义工具本身(工具由插件/技能提供),只是”使用笔记”。
USER.md用户画像

告诉智能体关于”你”的信息:你的名字、职业、偏好、常用工具、时区等。让智能体不用每次重新了解你。比如:

> 我叫胡琦琦,全栈开发者,偏好 TypeScript,时区 UTC+8,喜欢简洁的回答。
HEARTBEAT.md心跳任务清单

智能体会定期收到心跳轮询(默认约每 30 分钟)。收到心跳时,它会读取HEARTBEAT.md,按里面的指示执行后台任务。没任务就回复 HEARTBEAT_OK。

典型内容:
> - 检查邮箱有没有紧急邮件
> - 看看日历未来 2 小时有没有会议
> - 每天下午 3 点提醒我喝水

保持简短,因为每次心跳都会消耗 token。

这里有一个关键机制需要理解:这些文件会直接注入 system prompt,但有字符限制,防止窗口爆掉。如果文件缺失,system prompt 会标记 [MISSING]。

针对不同的使用场景,OpenClaw 还提供三种 system prompt 模式:

  • “full” 模式(主 agent)包含完整的 4 层架构加 Runtime;
  • “minimal” 模式是精简版(Tooling + Workspace + Runtime),用于处理复杂/耗时任务,避免污染主会话上下文,用于 sub agent。
  • “none” 模式则只有基础身份,给简单任务的 sub agent 用。

二、Memory:双轨制记忆系统

如果说 system prompt 解决了”当下该知道什么”,那么记忆系统回答的就是复杂上下文问题的另一个关键:如何让 agent 在记住海量信息的同时,还能快速检索出这次需要的信息?

OpenClaw 的 Memory 系统采用 “文件为源、数据库为索引” 的双重存储架构:文件系统保存原始内容,SQLite 数据库建立可搜索的索引。这种设计兼顾了人类可读性和机器检索效率。

文件存储:源头内容

所有记忆内容首先以文件形式存在,分为两类:

1. 长期记忆文件(Markdown 格式)

  • MEMORY.md:位于工作目录根,存放精选的长期记忆
  • memory/*.md:按日记录的日志文件,如 memory/2025-02-06.md
  • 人类可读,便于直接编辑和管理

2. 会话记录文件(JSONL 格式)

  • 路径:~/.openclaw/agents/<agentId>/sessions/YYYY-MM-DD.jsonl
  • 机器格式,每行一条消息,记录完整对话历史
  • 用于自动回溯,但不易人工阅读

简单来说,.md 是”精选知识库”(人工维护),.jsonl 是”全量流水账”(自动生成)。

数据库存储:搜索索引

为了快速检索,系统会自动将文件内容索引到 SQLite 数据库(位于 ~/.openclaw/memory.db)。数据库不存储原始文件的完整内容,而是存储可搜索的文本块及其向量嵌入:

表用途
files跟踪已索引的文件路径、修改时间、内容哈希
chunks存储文本块(分块后的内容)及其向量嵌入(JSON 格式)
chunks_vecsqlite-vec 虚拟表,存储二进制向量用于相似度搜索
chunks_ftsFTS5 虚拟表,存储分词后的文本用于关键词搜索
embedding_cache按内容哈希缓存嵌入结果,避免重复计算

什么内容会做 embedding?

只有文本内容会被分块和向量化:

  • Markdown 文件:按 token 数分块(默认约 256-512 tokens),块之间有重叠(32-64 tokens),保留行号引用
  • Session JSONL:解析出用户和助手消息,格式化为 "User: {content}" 或 "Assistant: {content}",每个会话文件作为一个文档

数据库通过文件监听和定期同步机制保持与源文件的同步。当文件修改时,系统会检测内容哈希变化,仅重新索引变更的文件。

记忆检索:混合搜索

当用户询问之前的工作、做过的决策、日期/时间相关、相关人员、用户偏好或待办事项时,必须先运行 memory_search。这种设计确保 agent 在处理涉及历史上下文的问题时,能够主动检索相关信息。

搜索采用混合策略:向量搜索擅长语义匹配(比如 “Mac Studio gateway host” 能匹配 “the machine running the gateway”),而 BM25 擅长精确匹配(ID、代码符号、错误字符串)。最终得分由两者加权计算:finalScore = 0.7 * vectorScore + 0.3 * textScore。

双重访问:注入 vs RAG

这里需要澄清 MEMORY.md 的一个特殊设计:它同时存在两种访问方式。

第一种是注入访问——文件内容直接注入 system prompt。优点是零延迟、每次请求都携带,但受 20k 字符上限限制,适合高频访问的核心记忆。

第二种是RAG 访问——通过 memory_search / memory_get 按需检索。优点是无容量上限且支持语义搜索,适合大容量、需要模糊匹配的记忆。

这两种方式不是互斥的,而是互补的——核心内容靠注入快速访问,完整内容靠 RAG 深度检索。

上下文保护:预刷新机制

长期运行的会话会遇到上下文窗口限制的问题。OpenClaw 通过**压缩(Compaction)**来解决——将旧对话总结成摘要,丢弃原始消息。

但压缩会导致信息丢失。为此 OpenClaw 在压缩前触发一次静默的 agentic turn:上下文接近上限时,agent 先将关键信息写入 memory/YYYY-MM-DD.md,然后再执行压缩。这确保了关键信息在上下文被截断前被固化到磁盘。


三、主动性机制:从被动响应到主动触达

这部分回答第一个问题:OpenClaw 是如何做到主动的?

传统 Bot 是”用户问 → Bot 答”的被动模式。OpenClaw 通过三种机制实现主动性,每种都由特定的工具支持。

Cron:定时触发

通过 cron 工具创建定时任务。例如每周一早上 9 点触发提醒:

{
  action: "create",
  schedule: "0 9 * * 1",
  systemEvent: "Weekly standup reminder..."
}

触发时系统发送 systemEvent 作为用户消息,agent 收到后像处理普通消息一样处理。典型场景包括每日总结、定时检查、生日祝福等。

Heartbeat:定期自检

Heartbeat 是 OpenClaw 内置的定期自检机制。通过 heartbeat.every 配置(默认 30 分钟),系统会定期触发 agent 执行一次检查:

  • agent 读取 HEARTBEAT.md(如果存在)获取检查清单
  • 评估当前是否有需要关注的事项(待办、未完成任务等)
  • 如果一切正常,回复 HEARTBEAT_OK——系统静默,不向用户发送消息
  • 如果有事项需要关注,回复具体内容——系统主动推送给用户

这是一种静默的主动监控:大多数时间什么都不发生,但一旦发现需要关注的事情,agent 会主动提醒。

HEARTBEAT.md 示例:

# Heartbeat checklist
 
- 检查收件箱是否有紧急邮件
- 查看未来 2 小时内的日历事件
- 检查是否有后台任务完成,如有则总结结果
- 如果空闲超过 8 小时,发送一个简短的问候

agent 会在每次心跳时读取这个清单,批量处理所有检查项。如果一切正常,回复 HEARTBEAT_OK;如果有需要关注的事情,则主动推送给用户。

Message:主动推送

通过 message 工具的 action=send,agent 可以从”被动回复当前会话”转变为”主动推送任意频道/用户”。这是真正的主动触达能力,让 agent 能够在发现重要情况时主动通知用户。


四、结论:上下文工程与自动进化

现在回到文章开头的两个问题。

OpenClaw 是怎么做到基于复杂上下文的?

通过四种策略:

策略实现效果
分层缓存System Prompt 4 层结构高频信息常驻,低频按需加载
双轨记忆注入(20k) + RAG(无上限)快速访问 + 深度检索
混合搜索向量 70% + BM25 30%语义模糊匹配 + 精确符号匹配
预刷新Pre-compaction flush关键信息在截断前固化
OpenClaw 是如何做到主动的?

通过三种机制:Cron 实现定时触发、Heartbeat 实现定期自检、Message 实现主动推送。


OpenClaw 的”自动进化”不是科幻意义上的 AI 自我改进,而是工程化的上下文管理。其精髓在于:不是让模型变聪明,而是让上下文恰到好处地支持模型的推理——记住该记住的(Memory 双轨系统)、在正确的时间做正确的事(Cron/Heartbeat/Message)。这就是 OpenClaw 使用上下文工程实现自动进化的方式。

┌─────────────────────────────────────────────────────────────┐
│                    上下文工程架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┐     ┌─────────────────┐               │
│  │  System Prompt  │◄────│  Memory System  │               │
│  │   (4 Layers)    │     │ (File + SQLite) │               │
│  └────────┬────────┘     └─────────────────┘               │
│           │                                                 │
│           ▼                                                 │
│  ┌─────────────────┐                                       │
│  │   Agent 决策     │                                       │
│  └────────┬────────┘                                       │
│           │                                                 │
│    ┌──────┴──────┬──────────────┐                          │
│    ▼             ▼              ▼                          │
│ ┌──────┐    ┌─────────┐   ┌─────────┐                     │
│ │ Cron │    │Heartbeat│   │ Message │                     │
│ │定时触发│    │主动监控  │   │主动推送 │                     │
│ └──────┘    └─────────┘   └─────────┘                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
               ┌────────────────────────┐
               │   写入 Memory.md       │
               │      (知识固化)         │
               └────────────────────────┘