乐于分享
好东西不私藏

拆解 OpenClaw Agent 设计

拆解 OpenClaw Agent 设计

摘要:

OpenClaw Agent 设计如何通过 Pi 集成、系统提示词三层架构、智能体引导、会话裁剪、上下文压缩和记忆概览,构建完整的智能体上下文管理体系。

做智能体开发的人,大概都经历过这种崩溃:

上下文爆了、提示词混乱、对话历史越积越厚,模型开始「胡言乱语」,或者 Token 费用烧得让人心惊肉跳。

问题出在哪?

不是模型不够强,是架构没搭对。

最近完整拆解了 OpenClaw 的源码,它的 Agent 设计很有意思,没有花哨的概念,全是工程化实践。

下面是完整拆解。

01

Pi 集成:不启动子进程,直接嵌入会话

核心思路:OpenClaw 使用 Pi-Agent 作为它的底层 Agent 框架,Pi-Agent 底层也是一个 while(true) 循环,它会在循环中发布事件,例如:循环开始、工具调用开始、循环结束等等。OpenClaw 基于 PiAgent,在其基础上监听事件,做工程化。其不使用子进程或 RPC 模式调用 Pi,而是通过 createAgentSession() 直接导入并实例化 Pi 的 AgentSession。这种嵌入式架构带来了对会话的完全控制权。

嵌入式架构的 6 大优势

  • 对会话生命周期和事件处理的完全控制
  • 自定义工具注入(消息、沙箱、渠道特定操作)
  • 按渠道 / 上下文自定义系统提示词
  • 支持分支 / 压缩的会话持久化
  • 支持故障转移的多账号认证配置轮换
  • 与提供商无关的模型切换

事件订阅机制

OpenClaw 通过 subscribeEmbeddedPiSession() 订阅 Pi 的 AgentSession 事件,完整覆盖智能体运行的全生命周期:

const subscription subscribeEmbeddedPiSession({  session: activeSession,  runId: params.runId,  verboseLevel: params.verboseLevel,  reasoningMode: params.reasoningLevel,  toolResultFormat: params.toolResultFormat,  onToolResult: params.onToolResult,  onReasoningStream: params.onReasoningStream,  onBlockReply: params.onBlockReply,  onPartialReply: params.onPartialReply,  onAgentEvent: params.onAgentEvent,});

处理的事件全景:

事件类型
说明
message_start/message_end/message_update
流式文本与思考过程输出
tool_execution_start/tool_execution_update/tool_execution_end
工具执行全生命周期
turn_start/turn_end
对话轮次边界标记
agent_start/agent_end
智能体整体生命周期
compaction_start/compaction_end
上下文压缩生命周期

工具设计

OpenClaw 的工具不是简单的「传给模型」,而是做了完整的分层和过滤:

工具分层:

  • 基础工具:
  • Pi 原生 codingTools(readbasheditwrite
  • 自定义替换:
  • OpenClaw 用 exec/process 替换原生 bash,并为沙箱环境自定义 read/edit/write
  • OpenClaw 扩展工具:
  • 消息、浏览器、画布、会话、cron、Gateway 网关等
  • 渠道专属工具:
  • Discord / Telegram / Slack / WhatsApp 特定操作工具

管线处理:

  • 策略过滤:
  • 按配置、提供商、智能体、群组、沙箱策略多维度过滤可用工具
  • Schema 标准化:
  • 针对 Gemini / OpenAI 等不同提供商的 API 细节清理和统一工具 schema
  • AbortSignal 包装:
  • 所有工具包装以遵守中止信号,确保超时和取消能正确传播

系统提示词构造

系统提示词在 buildAgentSystemPrompt()system-prompt.ts)中构建。它不是简单拼接字符串,而是组装一个完整的运行时上下文,包含以下模块:

模块
作用
Tooling
工具列表与使用指导
Tool Call Style
工具调用风格规范
Safety guardrails
安全护栏与权限边界
OpenClaw Control
框架级控制指令
Skills
可用技能按需加载说明
Docs
文档引用路径
Workspace
工作区配置
Sandbox
沙箱环境信息
Messaging
消息通道配置
Assistant Output Directives
输出格式指令
Voice / Silent Replies / Heartbeats
语音 / 静默回复 / 心跳机制
Runtime metadata
运行时元数据

其中有意思的点是它把文档也加进了其系统提示词里,这使得它能自主解决各种安装配置问题,例如和它说下帮我对接 Claude Code,它会自己找文档自己去对接。

启用时还包含 Memory 和 Reactions 模块,以及可选的上下文文件和额外系统提示词内容。用于子智能体的最小提示词模式会智能裁剪这些部分。

提示词在会话创建后通过 applySystemPromptOverrideToSession() 动态应用。

会话文件与缓存

会话存储:

会话是带有树形结构(id / parentId 链接)的 JSONL 文件,由 Pi 的 SessionManager 负责持久化。~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl

会话缓存:

session-manager-cache.ts 缓存 SessionManager 实例,避免重复解析文件,提升响应速度。

错误分类与故障转移

pi-embedded-helpers.ts 提供了一套完整的错误分类体系:

分类函数
识别场景
isContextOverflowError(errorText)
上下文溢出
isCompactionFailureError(errorText)
压缩失败
isAuthAssistantError(lastAssistant)
认证失败
isRateLimitAssistantError(...)
速率限制
isFailoverAssistantError(...)
需要故障转移
classifyFailoverReason(errorText)
分类故障原因:
"auth" | "rate_limit" | "quota" | "timeout" | …

思考级别回退:如果当前模型不支持某个思考级别,系统会自动降级回退,不会中断流程。

02

系统提示词:三层架构,动态渲染

OpenClaw Agent 设计中,提示词不是静态模板,而是运行时动态组装的完整指令集

提示词组装三层架构

层级
职责
设计原则
buildAgentSystemPrompt
根据显式输入渲染提示词
保持为纯渲染器,不直接读取全局配置
resolveAgentSystemPromptConfig
为特定智能体解析配置支持的提示词开关
所有者显示、TTS 提示、模型别名、记忆引用模式、子智能体委派模式
运行时适配器
收集实时事实,调用已配置的提示词门面
嵌入式、CLI、命令 / 导出预览、压缩等场景各有专属适配器

运行时适配器负责收集实时事实:工具列表、沙箱状态、渠道能力、上下文文件、提供商提示词贡献,然后调用已配置的提示词门面。

提示词结构全景

部分
说明
工具
结构化工具事实来源提醒,以及运行时工具使用指导
执行倾向
紧凑的跟进指导:对可执行请求在当前轮次中行动,持续推进直到完成或受阻,从较弱的工具结果中恢复,实时检查可变状态,并在最终回复前验证
安全
简短的护栏提醒,避免寻求权力的行为或绕过监督
Skills
告诉模型如何按需加载技能说明(可用时)
OpenClaw 控制
告诉模型在配置 / 重启工作中优先使用 gateway 工具,避免编造 CLI 命令
OpenClaw 自更新
如何用 config.schema.lookup 安全检查配置,用 config.patch 修补配置,使用 config.apply 替换完整配置,并且仅在用户明确请求时运行 update.run。仅所有者可用的 gateway 工具也会拒绝重写 tools.exec.ask / tools.exec.security,包括会规范化到这些受保护执行路径的旧版 tools.bash.* 别名
工作区
工作目录(agents.defaults.workspace
文档
OpenClaw 文档 / source 的本地路径,以及何时读取它们
工作区文件(已注入)
表示启动文件已包含在下方
沙箱
表示沙箱隔离运行时、沙箱路径,以及是否可用提权执行(启用时)
当前日期和时间
仅时区(缓存稳定;实时钟来自 session_status
助手输出指令
紧凑的附件、语音备注和回复标签语法
Heartbeat
当默认智能体启用 Heartbeat 时的提示词和确认行为
运行时
主机、操作系统、Node、模型、仓库根目录(检测到时)、思考等级(一行)
推理
当前可见性等级 + /reasoning 切换提示

设计亮点:

提示词是「活」的。每次智能体运行,提示词都会根据当前运行时状态重新组装,而不是复用固定模板。这确保了模型始终拿到最新、最准确的上下文。

03

智能体启动引导(Bootstrapping):一次运行,终身记忆

Bootstrapping 是 OpenClaw Agent 设计中最容易被忽略但最关键的环节。它发生在新手引导之后,智能体第一次启动时。

Bootstrapping 会做什么

在首次运行智能体时,OpenClaw 会 bootstrap 工作区(默认 ~/.openclaw/workspace):

  1. 1生成身份文件:
  2. AGENTS.mdBOOTSTRAP.mdIDENTITY.mdUSER.md
  3. 2交互式问答:
  4. 运行一段简短的问答流程(一次一个问题)
  5. 3持久化偏好:
  6. 将身份 + 偏好写入 IDENTITY.mdUSER.mdSOUL.md
  7. 4一次性触发:
  8. 完成后移除 BOOTSTRAP.md,因此它只会运行一次

特殊场景处理

  • 嵌入式 / 本地模型运行:
  • OpenClaw 会将 BOOTSTRAP.md 排除在特权系统上下文之外
  • 主要交互式首次运行:
  • BOOTSTRAP.md 仍会在用户提示中传入文件内容,确保那些不能可靠调用 read 工具的模型也能完成该流程
  • 工作区访问受限:
  • 如果当前运行无法安全访问工作区,智能体会收到一条受限的 bootstrap 说明,而不是通用问候语

04

会话裁剪(Context Trimming):不写磁盘,只裁内存

上下文膨胀是智能体开发的隐形杀手。OpenClaw 的会话裁剪方案,在不丢失历史的前提下,精准控制每次调用送给模型的 token 量

⚠️ 裁剪仅发生在内存中——不会修改磁盘上的会话记录。你的完整历史始终会被保留。

工作原理

  1. 1等待缓存 TTL 过期
    (默认 5 分钟)
  2. 2识别目标:
    找出适合常规裁剪的旧工具结果(对话文本保持不变)
  3. 3软裁剪:
    对超大的结果保留开头和结尾,中间插入 ...
  4. 4硬清除:
    对其余内容替换为占位符
  5. 5重置 TTL:
    以便后续请求复用新的缓存

旧图片清理机制

对于在历史中保留了原始图片块或提示词注入媒体标记的会话,OpenClaw 构建了一个独立的、幂等的重放视图:

  • 逐字节保留最近 3 个已完成轮次,确保最近后续请求的提示缓存前缀保持稳定
  • 重放视图中,来自 user 或 toolResult 历史记录里、较早且已处理的图片块,替换为 [image data removed - already processed by model]
  • 较早的文本媒体引用(如 [media attached: ...][Image: source: ...] 和 media://inbound/...)替换为 [media reference removed - already processed by model]
  • 当前轮次的附件标记保持不变,视觉模型仍可为新图片注入内容
  • 原始会话记录不重写,历史查看器仍可渲染原始消息条目及图片
  • 与常规缓存 TTL 裁剪分离,防止重复图片负载或过期媒体引用破坏提示缓存

裁剪 vs 压缩:互补而非替代

维度
裁剪(Trimming)
压缩(Compaction)
是什么
裁剪工具结果
总结对话
会保存吗?
否(按请求)
是(写入记录)
范围
仅工具结果
整个对话
它们彼此互补——裁剪可以在压缩周期之间保持工具输出精简。

05

压缩(Compaction):上下文满了怎么办?

每个模型都有上下文窗口上限。当对话接近该限制时,OpenClaw 会将较早的消息压缩成摘要,让聊天可以继续。

工作原理

  • 较早的对话轮次被摘要成一条精简条目
  • 摘要保存在会话转录中
  • 最近的消息保持完整
  • 智能边界处理:
    当 OpenClaw 将历史拆分为压缩块时,会让智能体工具调用与其匹配的 toolResult 条目保持配对。如果拆分点落在工具块内部,OpenClaw 会移动边界,让这对条目保持在一起,并保留当前未摘要的尾部
  • 完整对话历史仍保留在磁盘上。压缩只改变模型在下一轮看到的内容

自动压缩

自动压缩默认开启。触发条件:

  1. 1
    会话接近上下文限制时自动运行
  2. 2
    模型返回上下文溢出错误时,OpenClaw 压缩并重试

防丢失机制:压缩前,OpenClaw 会自动提醒智能体将重要笔记保存到 memory 文件。这可以防止上下文丢失。

可识别的上下文溢出错误模式:

  • request_too_large
  • context length exceeded
  • input exceeds the maximum number of tokens
  • input token count exceeds the maximum number of input tokens
  • input is too long for the model
  • ollama error: context length exceeded

手动压缩

在任何聊天中输入 /compact 可强制压缩,给用户完全的控制权。

06

记忆概览(Memory):模型「记住」的唯一方式

OpenClaw Agent 设计中,记忆不是黑盒。模型只会「记住」保存到磁盘的内容,没有隐藏状态。

三个记忆文件

文件
用途
加载时机
MEMORY.md 长期记忆

。持久事实、偏好和决策
每个私密会话开始时加载
memory/YYYY-MM-DD.md 每日笔记

。持续上下文和观察记录
今天和昨天的笔记自动加载
DREAMS.md

(可选)
Dream Diary

。Dreaming 扫描摘要,供人工审阅,包括有依据的历史回填条目
后台流程管理

这些文件位于智能体工作区(默认 ~/.openclaw/workspace)。

内容分层策略

MEMORY.md —— 紧凑、经过整理的长期层

  • 存放
    :持久事实、偏好、长期决策、应在主私密会话开始时可用的简短摘要
  • 不是
    :原始记录、每日日志、详尽归档

memory/YYYY-MM-DD.md —— 详细的工作层

  • 存放
    :详细的每日笔记、观察记录、会话摘要、以后可能仍有用的原始上下文
  • 索引
    :用于 memory_search 和 memory_get,但不会在每一轮都注入常规启动提示

最佳实践:

随着时间推移,智能体应从每日笔记中提炼有用材料写入 MEMORY.md,并移除过时的长期条目。生成的工作区说明和 Heartbeat 流程可以定期完成这件事,不需要为每个记住的细节手动编辑 MEMORY.md

启动预算保护

如果 MEMORY.md 超过启动文件预算,OpenClaw 会保持磁盘上的文件完整,但会截断注入到模型上下文中的副本。

处理信号:

  • 将详细材料移回 memory/*.md
  • 只在 MEMORY.md 中保留持久摘要
  • 或在明确想花费更多提示预算时提高启动限制

使用 /context list/context detail 或 openclaw doctor 查看原始大小与注入大小,以及截断状态。

记忆指令

如果你想让智能体记住某件事,直接告诉它即可:「记住我偏好 TypeScript。」它会把内容写入适当的文件。

推断式跟进承诺

有些未来跟进不是持久事实。如果你提到明天有面试,有用的记忆可能是「面试后跟进一下」,而不是「永久存进 MEMORY.md」。

跟进承诺机制

  • 选择启用、短期跟进记忆
  • OpenClaw 在隐藏后台流程中推断它们
  • 限定到同一个智能体和渠道
  • 通过 Heartbeat 发送到期的跟进
  • 显式提醒仍使用定时任务

记忆工具

工具
说明
memory_search
使用语义搜索查找相关笔记,即使用词与原文不同也可以
memory_get
读取特定记忆文件或行范围

这两个工具都由主动记忆插件提供(默认:memory-core)。

记忆搜索

配置嵌入提供商后,memory_search 使用混合搜索

  • 向量相似度:
  • 语义含义匹配
  • 关键词匹配:
    ID 和代码符号等精确术语匹配

OpenClaw 根据可用 API key 自动检测嵌入提供商。配置了 OpenAI、Gemini、Voyage 或 Mistral key,记忆搜索自动启用。

记忆后端

后端
说明
SQLite(内置,默认)
开箱即用,支持关键词搜索、向量相似度和混合搜索。不需要额外依赖
QMD
本地优先的 sidecar,支持重排序、查询扩展,以及索引工作区外目录的能力
Honcho
AI 原生的跨会话记忆,支持用户建模、语义搜索和多智能体感知。通过插件安装
LanceDB
内置 LanceDB 支持记忆,包含 OpenAI 兼容嵌入、自动召回、自动捕获和本地 Ollama 嵌入支持

Dreaming:记忆的后台整合

Dreaming 是记忆的可选后台整合流程。它会收集短期信号、为候选项评分,并且只将符合条件的项目提升到长期记忆(MEMORY.md)。

设计目标:让长期记忆保持高信号

  • 选择启用:
    默认禁用
  • 定时:
    启用后,memory-core 自动管理用于完整 Dreaming 扫描的定期 cron 任务
  • 阈值控制:
    提升必须通过分数、召回频率和查询多样性门槛
  • 可审阅:
    阶段摘要和日记条目写入 DREAMS.md,供人工审阅

写在最后

OpenClaw 的 Agent 设计把智能体开发中遇到的问题逐一解决:

模块
解决的问题
Pi 集成
OpenClaw 与底层 Agent Loop 解耦
系统提示词
如何让模型始终拿到准确的运行时上下文
启动引导
如何让智能体「认识」用户
会话裁剪
如何控制上下文膨胀而不丢历史
压缩
上下文满了如何优雅续聊
记忆概览
如何让智能体真正「记住」事情

这套 Agent 设计值得每一个做智能体开发的人细读。不是因为它用了什么新技术,而是因为它把工程实践中那些「脏活累活」都做了标准化处理。