ARTICLE · 1328570
OpenClaw 源码架构与核心功能原理
OpenClaw 源码架构与核心功能原理
目录
架构总览 Gateway 原理 Agent 执行引擎与任务编排 上下文管理 插件系统 Skills 原理 Tools 原理 MCP 原理 懒加载原理 沙箱原理 ACP 原理 记忆系统 模型选择与 Provider 运行时 定时任务与自动回复 渠道消息流转 审批与权限 密钥与凭据 审计与可观测 状态与数据库 会话工作区与 Worktrees 更新与生命周期 开发实践步骤
一句话理解 OpenClaw
Gateway 是常驻控制平面:所有客户端通过 WebSocket/HTTP 调 RPC,统一做认证、准入、插件路由。 Agent 执行引擎 把一个“逻辑回合”拆成多个“尝试(attempt)”,在模型候选之间回退,失败可恢复。 Context Engine 负责把会话历史、记忆、技能、工具描述等资源组装成有界的模型上下文。 插件/Skills/Tools/MCP 是四层可扩展面:插件承载渠道与模型提供者,Skills 是给模型看的指令包,Tools 是模型可调用的函数,MCP 把这三者暴露给外部客户端。 懒加载 贯穿启动路径,冷路径模块按需 import()。沙箱 把工具执行从 Gateway 主机隔离到容器/远程后端。 ACP 是给 IDE 的标准 Agent Client Protocol 桥。

1. 架构总览
1. 定位与形态
OpenClaw 是一个多通道 AI 网关(项目清单的 description 即 “Multi-channel AI gateway with extensible messaging integrations”)。
常驻一个 Gateway 进程:负责 WebSocket/HTTP 服务、认证、会话、插件路由。 消息渠道、模型提供者、工具、技能都是可插拔扩展,核心保持小而稳定。 状态默认落在 SQLite,也可切到 Postgres(项目清单声明的 databaseEngines)。
2. 进程与包拓扑

协议包:Gateway 与客户端共享的协议 schema、帧校验、能力常量。 agent-core 包:Agent/Tool 的核心类型契约(如 AgentTool、AgentToolResult)。主体实现层:gateway、agents、plugins、skills、context-engine、acp、mcp 等。 内置插件层:内置渠道与模型提供者插件。 应用与控制界面层:桌面/控制界面宿主。
3. 运行时拓扑

关键原则:Gateway 永远留在主机;只有工具执行、以及需要隔离的 worker/插件才离开主机或进入沙箱。
4. 核心数据流(一条消息如何变成回复)

5. 分层职责
6. 设计原则
One owner per responsibility:每个状态只有一个所有者,其他组件只消费其操作与记录。 Small core, capable plugins:可选能力放边缘,核心只提供通用契约。 Stable conversation context:生成 prompt/tool/context 必须有界且确定,保护 prompt 前缀复用。 Updates always work:更新、迁移、插件加载等生命周期路径必须 best-effort,不因单点失败整体宕机。 Behavior over test count:优先端到端集成证据,单测支持但不替代。 Do less work:信任边界处校验一次,内部不再重复防御;性能优化先删后缓存。
7. 关键模块索引
Gateway:连接生命周期模块、RPC 方法处理层 Agent:回合入口、尝试循环、运行编排器 上下文:上下文引擎 插件:插件运行时、插件 SDK 技能:技能发现、技能加载 工具:工具模块 MCP:MCP 能力层 ACP:ACP 能力层 沙箱:沙箱模块 懒加载:懒加载运行时原语、懒加载 promise 缓存原语
2. Gateway 原理
Gateway 是 OpenClaw 的常驻控制平面。所有客户端(CLI、渠道插件、Control UI、ACP 桥、MCP serve)最终都通过它路由。
1. 角色定位
入口:WebSocket + HTTP,承载 JSON-RPC 风格的 method 请求。 编排:鉴权 → 准入 → 路由到 server-method → 派发 Agent/插件工作 → 事件回推。 状态所有者:会话、代理、审批、连接等权威状态由 Gateway 维护,客户端只做投影。
2. 连接生命周期
实现对应:连接生命周期与 WebSocket 收发模块(准入、注册、分发、追踪清理、握手与接收)。

要点:
连接对象同时负责admission(准入)、registration(注册)、dispatch(分发)、tracked cleanup(追踪清理)。 握手阶段有 preauthHandshakeTimeoutMs与连接预算,防止未授权连接占资源。每个连接按需加载消息处理器( attachGatewayWsMessageHandlerOnDemand),避免冷路径常驻。
3. server-methods:RPC 处理层
实现对应:RPC 方法处理层。方法按域拆分,例如:
发起 Agent 运行的方法处理器。 中止与取消相关的方法处理器。 会话属性修改的方法处理器。 授权与审批相关的方法处理器。

请求参数在入口处用 gateway-protocol 协议包的 schema/validator 校验一次,内部信任已校验数据。 关键能力(如 sessions.list)通过服务端能力清单声明,客户端据此协商。
4. 懒加载的 method handler
实现对应:懒加载的 RPC 方法处理器注册机制。

设计:注册一个转发占位符,首次调用时才 loadHandlers() 拉取真实方法族;requestEntryLifetime 保证请求在准备期间仍受生命周期/关闭检查约束。
5. 认证与授权
实现对应:认证入口、认证策略、认证解析与 token 解析模块。
支持本机/远程访问、token 与 token 文件、节点配对、agent 身份 token 等形态。 gatewayExposure/ isLoopbackAddress等决定暴露面;browserRateLimiter区分浏览器与普通客户端。安全边界遵循“当前所有者持有权威”:token、签名、过期时间、ID 匹配都不单独构成活权限,副作用前要重新验证。
6. 健康、就绪与排空
实现对应:健康状态、就绪态与活跃会话关闭排空模块。
健康快照(health snapshot)与就绪态(readiness)分离:进程活着 ≠ 可接客。 关闭时对活跃会话做 drain,受 gateway-shutdown-budget控制,避免硬切丢工作。
7. 一句话总结
Gateway 是“协议边界 + 授权/准入 + 路由分发 + 事件回推”的薄而稳定的控制平面;业务执行下沉到 Agent Runner、插件运行时与 worker,状态写入由各自所有者完成。
3. Agent 执行引擎与任务编排
一个“逻辑回合”如何被拆成“尝试”,如何在模型间回退,又如何派生子代理。
1. 入口分层
实现对应:嵌入式 Agent 执行引擎。

回合级入口:负责模型候选推进、会话放置约束、请求者结算。 运行编排器:把单次运行编排起来(模型解析、插件运行时准备、lane 控制)。 尝试循环:重试预算、回退策略、压缩触发、终止判定。 单次尝试阶段:prompt 阶段 / 执行阶段 / 结算阶段。
2. 一个 attempt 的形态

3. 模型回退与重试
实现对应:尝试循环、模型回退运行器与 failover 信号模块。
尝试结果被分类(结果回退分类器),决定是重试同模型、换候选模型还是终止。 createRunRetryBudget/ resolveMaxRunRetryIterations限制重试,防止无界循环。failover 信号与重试控制器分离:物理尝试关闭后,恢复逻辑仍要观察队列过期与中止信号。
4. 子代理(Subagent)派生
实现对应:子代理模块(注册表、派生、完成通知、完成准入)。

上下文继承与隔离:子代理继承父代理的部分身份/工作区上下文,但拥有独立 session key 与结算。 生命周期:registry 追踪活跃子代理与后代( active-descendants),控制 kill 范围与结算。结果回传: announce负责完成通知与直投,completion负责完成准入与最终投递。
5. Lane 队列与并发保护
实现对应:lane 队列与 lane 控制器模块。
同一会话/代理的并发尝试通过 lane 排队,避免互相覆盖状态。 lane controller 提供 abortSignal、执行 deadline、throwIfAborted,把“中止”贯穿到每个阶段。
6. Harness 抽象
实现对应:执行后端 harness 抽象层。
selectAgentHarness选择执行后端(内置模型插件或外部 harness,如 Codex/Claude 的 ACP harness)。 通过 harness 统一会话创建、prompt 构造、结果归一,保持核心循环与具体模型解耦。
7. 终止、结算与恢复
每个 attempt 都有明确终止态(终止判定与终止解析)。 请求者结算在回合结束时释放子代与资源。 崩溃/重启后,会话重置与续跑恢复逻辑会恢复未完成的会话工作。
8. 一句话总结
执行引擎 =回合入口 → lane 串行化 → attempt 循环(模型候选/回退)→ 工具执行 → 子代理派生 → 终止结算;每个阶段都可中止、可恢复、可追责。
4. 上下文管理
模型一次能看的东西有限。上下文管理负责把“历史 + 记忆 + 技能 + 工具 + 系统指令”组装成有界、确定、可复用的 prompt。
1. 两个层次

2. Context Engine Registry
实现对应:上下文注册表、注册契约、资源与选择逻辑。
注册表管理各资源所有者(owner)的读写面,并负责选择哪些资源进入当前逻辑回合。 选择逻辑决定取舍,注册表迁移逻辑处理旧路径向注册表的迁移。 隔离与健康检查逻辑:不健康的资源会被隔离,避免拖垮上下文。
3. 有界上下文与字节预算
实现对应:有界上下文与 transcript 字节上限模块。

transcript 字节上限:对历史 transcript 做字节上限控制,防止无限增长。 有界上下文:把选中资源收敛到预算内,保持输出确定。
4. 压缩(Compaction)
实现对应:压缩执行、压缩钩子与压缩看门狗模块。

压缩不是简单截断:保留最近原文 + 生成早期摘要,并遵守 hook、资源委托与 sandbox 信息约束。 压缩后新基线的生命周期管理。 记录压缩原因(可观测性)。
5. 稳定性与 prompt 前缀复用
上下文生成必须有界、确定:同一 session 与配置下,重复构建应尽量复用 prompt 前缀。 工具定义、系统指令只依赖 session/配置事实,不依赖回合内波动值;回合级事实放到该回合消息里。 相关契约见“prompt 缓存”参考文档,并有 prompt 前缀稳定性测试保障。
6. 会话与 transcript 投影
实现对应:会话管理器、transcript 事件与会话配置模块。
transcript 是消息历史的权威投影;SessionManager 消费它,不另造第二份真相。 写入方与读取方解耦,通过事件(如 onSessionTranscriptUpdate)同步缓存。
7. 一句话总结
上下文管理 =资源注册表 + 选择策略 + 字节预算 + 压缩看门狗,目标是有界、确定、可复用、可观测的 prompt。
5. 插件系统
OpenClaw 的可扩展面。核心小而稳定,渠道、模型提供者、hooks、工具等能力都挂在插件上。
1. 三层结构

核心只提供通用契约(session、gateway 请求、模型 facade、媒体等)。 SDK(插件公共 SDK 层)是公共边界:插件只能 import SDK 的 public/local 契约入口,不能碰核心内部。 运行时(插件运行时层)是核心侧实现,给插件提供受限的、按请求作用域隔离的宿主 API。
2. 插件运行时(Runtime)
实现对应:插件运行时入口、运行时基础、渠道/代理/模型 facade 各域模块。
createRuntimeBase 组装一个插件可见的 runtime 面,按域拆成:
gateway:受信插件方法转发(网关插件方法懒加载)。 agent:会话/代理操作。 channel:渠道消息投递。 llm:模型 facade 与错误处理。 media/ tts/logging:媒体、语音、日志能力。
3. 请求作用域与安全
实现对应:请求作用域、Gateway 上下文绑定与加载上下文模块。
runtime 面按 request scope 创建:不同请求/会话看到不同上下文,避免跨会话串数据。 Gateway 上下文绑定把当前请求上下文绑定到插件调用链(AsyncLocalStorage)。 插件不能绕过授权:受信方法由核心侧 dispatchTrustedPluginGatewayMethod二次校验。
4. 加载与元数据
实现对应:插件元数据注册表加载器与运行时加载器模块。
元数据(manifest)先行,运行时代码按需加载。 loader 解析插件入口、模型认证、原生依赖,并把失败隔离成可诊断错误。
5. 插件类型
6. Hook 系统
实现对应:hook 编排、hook 配置与 before-agent-reply 钩子模块。
hook 在关键节点被调用(如 before-agent-reply、审批、会话事件)。 getGlobalHookRunner统一执行;hook 的准入与上下文由 hook-claim-admission控制。
7. 懒加载在插件里的体现
实现对应:插件运行时入口的懒加载声明区。
loadTtsRuntime、 loadMediaUnderstandingRuntime、loadGatewayPluginRuntime都用createLazyRuntimeModule包裹。插件 runtime 的冷能力只在真正被调用时 import(),避免拖慢启动。
8. 一句话总结
插件 =SDK 公共契约 + 请求作用域运行时 + 元数据/代码分离加载;核心通过运行时给能力,插件通过契约回馈扩展。
6. Skills 原理
Skill 是给模型看的、可安装的指令资源包(Markdown + 可选脚本/资源),不是可执行插件。核心区别:Skill 提供“怎么做”的上下文,Tools 提供“能调什么”。
1. Skill 的生命周期

发现:技能发现层从工作区、插件、技能库找 skill。 加载:技能加载层解析 frontmatter、路径、优先级,读取正文。 材料化:材料化逻辑把入口与引用资源拼成模型可读内容。 安全过滤:安全过滤层在进入 prompt 前做可见性/调用控制。
2. 发现与索引
实现对应:技能索引、agent 过滤、通用过滤与聊天命令发现逻辑。
normalizeSkillIndexName统一命名,便于去重与匹配。 isSkillPromptVisible/ isSkillUserInvocable决定一个 skill 是否进模型可见清单、是否允许用户/command调用。agent 过滤逻辑按 agent 过滤可用技能;聊天命令发现逻辑把可调用 skill 暴露为斜杠命令。
3. 加载与优先级
实现对应:技能加载层。

多个来源(工作区、插件 bundle、技能库)可能同名;优先级逻辑决定谁赢。 根目录发现与工作区根枚举逻辑定位根目录,软链处理逻辑解析软链。 工作区技能 prompt 生成逻辑生成最终片段,并受大小限制约束。
4. 技能库与安装
实现对应:技能库存储与技能安装生命周期模块。
技能库服务与存储是权威存储;选择读取逻辑负责读取。 安装走安装生命周期(下载、解压、落盘、回滚),ClawHub 是内置来源之一。 创作校验逻辑提供创作/校验辅助,保证 skill 结构合法。
5. 与 Tools / Plugin 的边界
6. 一句话总结
Skills 是可发现的指令资源:发现 → 按优先级加载 → 材料化 → 安全过滤 → 进入有界 prompt;它扩展“模型知道怎么做”,不直接新增“能调用的函数”。
7. Tools 原理
Tool 是模型可调用的函数,带有 JSON schema 参数、执行器、结果类型与策略控制。
1. Tool 的类型契约
实现对应:Agent/Tool 核心类型契约与工具公共运行态视图。
AgentTool:name/description/schema/execute/结果类型。 AnyAgentTool:擦除具体参数泛型后的运行态视图,便于统一存储与分发。 AgentToolWithMeta增加 displaySummary、canDeliverSourceReply、getExecutionTimeoutMs等元信息。

2. 工具注册与发现
核心内置工具集中在工具模块(如 cron、system-agent)。 插件工具通过插件运行时贡献,最终统一进注册表。 工具名支持命名空间与组展开( expandToolGroups/normalizeToolPolicyName)。
3. 策略匹配
实现对应:工具策略匹配、工具策略与 agent 工具策略合成模块。
deny 永远优先;allow 为空表示“除 deny 外全部允许”。 支持通配符(如 tool_*、bundle-mcp、group:plugins)与命名空间前缀。多来源策略(global、agent、subagent、sender、inherited)按规则合成最终 allow/deny。

4. 审批与执行权威
实现对应:审批模块与 agent 运行时审批权威模块。
危险/写操作在执行前需审批;审批是当前所有者持有的活权限,不是一次性 token。 工具执行结果本身不能随意触发副作用;只有工具作者声明的 canDeliverSourceReply等契约才允许。执行超时( getExecutionTimeoutMs)与中止信号贯穿调用。
5. 与沙箱的关系
工具政策先于沙箱生效:全局/按 agent deny 的工具,沙箱不会“救活”。 tools.elevated是显式逃生口,把 exec 放到沙箱外执行(默认 gateway/node)。沙箱内默认工具 allowlist 由沙箱工具策略定义。
6. 一句话总结
Tools =schema 注册 + 多层策略合并 + 活权限审批 + 可中止执行;策略匹配的规则是“deny 优先,allow 为空则全放行”。
8. MCP 原理
OpenClaw 既是 MCP 的消费者(接外部 MCP 服务器/工具),也是 MCP 的提供者(对外
serve三种服务器)。
1. 三种 MCP 服务形态
实现对应:MCP 能力层。
openclaw mcp serve | ||

2. 底层 stdio 服务器
实现对应:底层 stdio 服务器模块。
基于 @modelcontextprotocol/server的Server+StdioServerTransport。关键约束:MCP stdio 的 stdout 必须保持协议纯净,日志重定向到 stderr( routeLogsToStderr)。ToolsMcpServer封装 AsyncWorkScope:close 时先把 transport 关闭、再 drain 已接受的工具工作,支持再次连接。
3. 渠道会话服务
实现对应:渠道服务与渠道桥模块。
serveOpenClawChannelMcp注册 conversations_list、conversation_get等工具。OpenClawChannelBridge是 MCP 与 Gateway 的适配层:MCP 工具调用 → Gateway 会话/消息操作。 支持 Claude 渠道模式与权限请求通知( claude/channel/permission)。
4. 内置工具服务
实现对应:内置工具服务与工具面配置模块。
通过环境变量选择工具面( OPENCLAW_TOOLS_MCP_TOOLS_ENV等)与代理会话 key。resolveOpenClawToolsForMcp先构造工具,再按请求者工具策略过滤:用 resolveRequesterToolPolicies+isToolAllowedByPolicies只暴露被允许的工具。会话上下文通过会话环境解析逻辑解析,保证工具落在正确会话。
5. 插件工具服务
实现对应:插件工具服务、处理器与注册模块。
把插件注册的工具转成 MCP tools/list/tools/callhandler。保留取消语义: runWithTrackedCancellation把 MCP 请求信号传给工具执行。
6. 与其他桥的区别
openclaw acp:IDE 用 ACP 协议驱动 Gateway 会话。 openclaw mcp serve:外部 MCP 客户端读写渠道会话。 ACPX 相关 MCP bridge:让 Codex/Claude harness 看到 OpenClaw 的插件工具。
7. 一句话总结
MCP 层 =三种 stdio 服务 + Gateway 适配桥 + 工具策略过滤;它把 OpenClaw 的能力以标准 MCP tools 形式暴露,同时遵守既有的工具 allow/deny 策略。
9. 懒加载原理
OpenClaw 用“动态 import + promise 缓存”把冷路径能力推迟到真正调用时加载,保护启动性能与内存。
1. 两个核心原语
实现对应:懒加载 promise 缓存与懒加载运行时两个公共原语。
createLazyPromiseLoader

并发去重:多次 load()共享同一个 promise,不重复触发动态 import。默认 reject 即清除缓存,下一次可重试(适合 transient import/runtime 失败)。 cacheRejections: true时保留被拒 promise,避免风暴式重试。 peek()只读缓存不触发加载; clear()手动失效。
createLazyRuntimeSurface / createLazyRuntimeModule

createLazyRuntimeModule:缓存整个动态导入的模块。 createLazyRuntimeNamedExport:只缓存指定命名导出。 两者都基于 createLazyRuntimeSurface,且使用cacheRejections: true(失败保留缓存,与默认 loader 的 evict 策略不同)。createLazyRuntimeMethod/ Binder:把一个懒加载 surface 的方法包装成可调用函数,调用时才加载。
2. 典型用法:插件运行时
实现对应:插件运行时入口。
const loadTtsRuntime = createLazyRuntimeModule(() => import(”../../tts/tts.js”));const loadMediaUnderstandingRuntime =createLazyRuntimeModule(() => import(”../../media-understanding/runtime.js”));
插件 runtime 的 tts、mediaUnderstanding、gateway等冷能力不随插件 runtime 加载,而是首次调用才 import。createLazyRuntimeMethodBinder把“加载 surface + 选方法”绑定成稳定函数。
3. 典型用法:Gateway method handler
实现对应:懒加载的 RPC 方法处理器注册机制。

注册阶段只放转发占位符;真实方法族首次调用时加载。 requestEntryLifetime.enter/release+ assertOpen保证懒准备期间请求仍受关闭/生命周期约束。
4. 懒加载设计取舍
clear() | |
5. 一句话总结
懒加载 =import()+ promise 缓存去重 + 可配置失败重试 + 转发占位;核心原则是“热路径急切、冷路径按需、失败可恢复”。
10. 沙箱原理
沙箱把“工具执行”从 Gateway 主机隔离出去。Gateway 永远在主机;只有工具执行进入沙箱后端。
1. 核心模型
实现对应:沙箱核心类型与配置模型。

2. 什么进沙箱、什么不进
进沙箱:工具执行(exec、读写、浏览器等),按 mode/scope 决定。 不进沙箱:Gateway 进程本身、模型推理、会话状态。 官方说明强调这是实质限制而非完美安全边界(沙箱官方文档)。
3. 沙箱后端类型
4. 工作区访问与挂载
实现对应:工作区挂载、挂载规划、工作区权威与文件桥模块。

workspaceAccess控制 none/ro/rw;工作区权威逻辑验证会话是否被真正限制在可写工作区内。 文件桥提供跨边界的文件操作与路径安全(文件桥路径安全逻辑)。 危险 Docker 隔离覆盖(如 dangerouslyAllowExternalBindSources)会关闭“工作区受限”的判定。
5. 工具策略与逃生口
工具 allow/deny 策略先于沙箱生效;deny 的工具沙箱不会恢复。 tools.elevated是显式逃生口,让 exec在沙箱外(gateway/node)运行,需授权。沙箱默认工具 allowlist 与多代理覆盖: agents.entries.*.sandbox、agents.entries.*.tools.sandbox.tools。
6. 生命周期与诊断
openclaw sandbox list / explain / recreate管理容器与环境。 沙箱注册表与运行时状态逻辑追踪沙箱运行时归属与当前状态。 回收逻辑回收空闲容器;进程清理逻辑清理残留进程。
7. 一句话总结
沙箱 =配置解析(mode/backend/scope/workspaceAccess)→ 运行时上下文 → 挂载与文件桥 → 受限工具执行;工具策略与 elevated 逃生口共同决定最终边界。
11. ACP 原理
ACP(Agent Client Protocol)桥让 IDE / 外部 agent 客户端通过标准 stdio JSON-RPC 驱动 OpenClaw Gateway 会话。
1. 定位:Gateway-backed bridge
openclaw acp 是服务端桥:IDE 或 ACP 客户端连到它,它再把工作转发到 Gateway。

不是完整 ACP-native 编辑器运行时,聚焦会话路由、prompt 投递、流式更新。 每个 ACP 会话映射到一个 Gateway session key;agent 用 agent::定位。
2. 客户端与服务端两侧
实现对应:ACP 客户端进程管理与 ACP 控制平面单例模块。
客户端侧:负责 spawn/terminate ACP server 子进程、打印 session update、处理工具审批分类。 控制平面:进程级会话管理器单例,核心实现独立。 运行时:运行时注册表与可用性判断。
3. 会话生命周期方法
initializenewSession / prompt / cancel | |
listSessions | |
resumeSessioncloseSession | |
loadSession |
4. 事件与流式更新
实现对应:事件账本、事件映射与回合流模块。

event-ledger记录可回放的事件账本,支撑 loadSession的历史回放。event-mapper把 Gateway 会话快照映射为 ACP 通知( session_info_update、available_commands_update、usage_update)。
5. 权限模型
自动审批是 allowlist,只对受信核心工具 ID 生效。 read自动审批限定当前工作目录;只读搜索类( search、web_search、memory_search)可自动放行。exec 能力、控制平面工具、写工具、交互流必须显式审批。 服务端传来的 toolCall.kind只作元数据,不作授权来源(审批分类逻辑)。
6. ACP vs ACPX vs MCP serve
openclaw acp | |
/acp spawn | |
openclaw mcp serve |
7. 一句话总结
ACP 桥 =stdio JSON-RPC 服务端 + Gateway WebSocket 转发 + 会话 key 映射 + 事件账本回放;它是标准协议面,状态权威仍在 Gateway。
12. 记忆系统
12.1 两条记忆通道
OpenClaw 的记忆不是单一向量库,而是“快速规则召回 + 按需深召回”两级:

规则 lane:直接、快速、可信触发词匹配,默认路径。 Active Memory:默认 escalate模式,只在“问过去”且规则 lane 无强匹配时,才跑一次阻塞式召回子代理,用一次模型调用换取多会话/时间/多跳问题的更强召回。
12.2 混合检索:向量 + 关键词并行

向量检索捕捉语义相似(如 “gateway host” 匹配 “跑 OpenClaw 的机器”)。 关键词检索捕捉精确词(ID、错误串、配置键);SQLite 用 BM25,Postgres 用原生全文排名或 trigram。 两路都命中时,先缩放每路关键词分:最强关键词命中最多等于最佳语义分,其余按 BM25 比例; minScore作用于“余弦相似度 + 缩放后关键词分”的加权和。
12.3 排序与去重:relevance × recency × importance → MMR

recency:30 天半衰期指数衰减; MEMORY.md/USER.md等 curated 文件常青不衰减。importance:写入时由模型赋 1–10,缺失时中性;避免查询期再调模型(Generative Agents 思路)。 MMR:对已排序候选做多样性重排,去掉冗余片段,不改分数、门槛,也不额外调用模型。 minScore用“衰减前相关性”判定资格;recency 只影响排序,不影响是否合格。
12.4 规则触发召回(Lane 1)与深召回(Lane 2)

Bootstrap 注入: MEMORY.md/USER.md在 provenance 合格时于会话启动载入,长会话内按预算刷新。Ranked search: memory_search走上面的混合检索 + 排序。Trigger 注入:写者可给条目加触发短语;每条入站消息做快速词法+向量预过滤,分数 ≥ 0.65 才作为紧凑隐藏上下文注入,每轮最多 3 条,且只允许 curated 层(安全属性)。 Lane 2 深召回:仅当“有召回意图”且 Lane 1 无强命中时,跑阻塞式子代理;默认 escalate,也可always/off。失败不阻塞:每条召回路径都有超时或回退,记忆故障只降质,不吞掉回合。
12.5 源码与配置
核心:记忆模块与记忆宿主 SDK(存储引擎、事件存储、查询、事件)。 产品文档:Active Memory 概念文档(九页子文档:enabling、how-it-works、tuning、memory-tools…)。
12.6 关键取舍
默认不跑深召回,保证普通回复低延迟。 召回工具可接内置记忆、LanceDB、Lossless Claw(见 memory-tools)。召回结果注入会话上下文,但不改变状态所有者:记忆的权威仍由 memory store 持有。
13. 模型选择与 Provider 运行时
13.1 模型如何被选中
实现对应:会话模型选择应用、模型注册表抽象与模型选择逻辑。

ModelRegistry抽象 getAll / getAvailable / find / hasConfiguredAuth,供选择器与可用性检查使用。模型选择受可见性策略、operator 策略、sticky 选择、auth profile 多层约束。
13.2 Provider 运行时与回退
LLM 层:模型运行时绑定、provider 限流、OAuth 与重试工具。 Agent harness(执行后端选择逻辑)选择执行后端;模型回退运行器在候选模型间回退。 失败分类决定重试、换候选还是终止(见第 3 章)。
13.3 一句话
模型选择 =目录 → 可见性/operator 策略 → auth → sticky/session 覆盖 → 运行时绑定;回退在 harness 层统一处理。
14. 定时任务与自动回复
14.1 定时任务(Cron)
实现对应:定时任务模块(命令运行器、活跃任务、投递规划、命令 shell)。

支持 shell 命令任务与 agent 会话任务。 命令执行带超时、无输出超时、输出摘要、退出码/信号诊断( DEFAULT_COMMAND_TIMEOUT_MS默认 10 分钟)。
14.2 自动回复(Auto-reply)
实现对应:自动回复派发、命令注册、派发器与群组线程派发模块。
自动回复派发编排入站回复:hook 组合、前台投递围栏、FIFO 租约。 commands-registry处理 /command检测、注册、文本路由。createKeyedFifoLeaseRegistry保证同一键的有序投递。
14.3 一句话
定时任务负责“到点自动干活”,自动回复负责“来消息自动回”;两者最终都复用 Agent 执行引擎与渠道投递。
15. 渠道消息流转
15.1 入站到出站的路径
实现对应:渠道模块(入站事件、账号解析、白名单、transport、消息访问)与自动回复模块。

15.2 关键职责
account-resolution / allowlists:把渠道事件解析到账号,做白名单与直接 DM 门禁。 command detection:区分普通消息、 /command、群组线程(group-thread-dispatch)。auto-reply dispatch:组合 before-deliver hooks,并做前台投递围栏与 FIFO 租约。 transport 适配:每个渠道有不同的收发适配器,但都汇入统一的 inbound-event 契约。
15.3 一句话
渠道层把异构平台归一化成统一的入站事件,再交给 auto-reply 派发;出站时再通过 transport 适配器还原成平台消息。
16. 审批与权限
16.1 审批不是一次性 token
实现对应:审批渠道归属、审批会话受众、审批 Web 推送与 agent 运行时审批权威模块。

审批是当前所有者持有的活权限:token、签名、过期时间、ID 匹配都不单独构成权限。 副作用执行前要重新验证,不能把“曾批准”当“永远有效”。
16.2 渠道与受众
审批渠道归属:审批的渠道归属。 审批会话受众:审批的会话受众(谁能看到/响应)。 审批 Web 推送:审批的 Web 推送。
16.3 与工具策略、elevated 的关系
工具策略(第 7 章)先于审批;deny 的工具不会走到审批。 tools.elevated是显式逃生口,让 exec 在沙箱外执行,需授权。
16.4 一句话
审批 =策略预筛 → 活权限检查 → 渠道/受众路由 → 副作用前重验。
17. 密钥与凭据
17.1 密钥存储
实现对应:密钥存储、密钥变更与密钥校验模块。
密钥存进 OpenClaw state 数据库(SQLite/Postgres),不散落配置文件。 每条密钥有 kind、scope(team/identity)、scopeId、allowedHosts、过期、创建/更新时间。值以 sentinel 标记注册进日志脱敏注册表( registerSecretValueForRedaction),日志出口统一脱敏。
17.2 出站代理(egress proxy)
实现对应:出站代理(代理服务器、代理 worker、连接隧道、环境注入)。

密钥不直接进入子进程环境明文扩散;必要时通过 egress proxy 按 allowedHosts转发。配置密钥目标与配置逻辑负责把密钥写入目标配置位置。
17.3 一句话
密钥 =state DB 存储 + sentinel 脱敏 + allowedHosts + egress proxy 转发;原则是“能不出主机就不出主机”。
18. 审计与可观测
18.1 审计事件
实现对应:审计模块(审计记录器、审计事件存储、审计配置、执行决策事实)。

createAuditEventRecorder汇总受信 run、tool、message 生命周期流。 消息审计按模式(off/direct/all)过滤,direct 只记私聊。 持久化失败只告警一次,不影响主流程(best-effort)。
18.2 日志与观测
日志原始写入,只在出口(tail、诊断包、远程导出)脱敏;不记录消息/工具内容本身。 日志层提供子系统 logger 与密钥脱敏注册表。 OpenTelemetry 导出见“可观测性”官方文档。
18.3 一句话
审计是“best-effort 的受信事件账本”,日志是“raw 存储 + egress 脱敏”,两者共同支撑可观测与责任追溯。
19. 状态与数据库
19.1 数据库引擎与家族
项目清单声明:数据库引擎 sqlite / postgres;Postgres 家族含 state、agent、workboard、logbook、team-reports。

19.2 准入与所有权
实现对应:agent 数据库准入、数据库启动与 state 数据库缓存模块。
数据库访问先做 admission:所有权、检查、FTS 修复、corruption repair hint。 拒绝是公开协议对象( UNAVAILABLE+ retryable),检查原因保持私有。SQLite 写走 worker,锁错误/未知结果有专门诊断。
19.3 规则
数据库/状态代码改动前必读 worker 访问规则文档。 Schema 变更要带迁移,Doctor/迁移所有者负责规范化旧形状。
19.4 一句话
状态层 =引擎抽象 + admission 准入 + worker 串行写 + 版本化 schema;SQLite 是默认真相源。
20. 会话工作区与 Worktrees
20.1 为什么需要 Worktree
代码类 agent 需要在隔离的 git worktree 里改代码,避免与用户/其他会话争用同一个 checkout。
20.2 分配与容量
实现对应:worktree 分配、容量、checkout、基线分支与派发 worker 模块。

withWorktreeAllocationLease串行化 slot 准入与容量变更; WORKTREE_CREATE_LEASE_MS、WORKTREE_CREATE_LEASE_WAIT_MS控制租约。容量逻辑做磁盘准入;checkout 物化逻辑物化代码;基线分支逻辑确定基线分支。 退役只拥有自己的 checkout,磁盘准入考虑并发写。
20.3 一句话
Worktree =租约 + 容量准入 + 基线 checkout + worker 派发 + 退役,是代码类 agent 的隔离工作区。
20.4 与沙箱的关系
worktree 是“代码工作区隔离”,沙箱是“执行环境隔离”,两者可叠加(managed worktree 作为沙箱工作区来源)。
21. 更新与生命周期
21.1 更新契约
实现对应:更新契约文档、更新 CLI、Doctor 命令与配置模块。
核心要求:Updates always work(best-effort everywhere)。更新、Doctor、生命周期、迁移、插件加载改变状态更新行为时,必须遵守更新实现契约。

21.2 关键机制
候选预检:候选版本先在私有命名空间验证 config/状态,不污染 live。 Doctor:插件 setup、配置迁移、状态修复在 Gateway 启动前完成;容器入口先跑 Doctor,无法安全修复则退出。 回滚:迁移前创建验证过的备份;严格恢复保留自己的 artifact-preservation 要求。 app-owned 包:安装所有者清单声明更新所有者,macOS app / 桌面 app 更新连 Gateway+运行时一起更新。 插件更新:保留已写环境引用,旧记录仍可读。
21.3 一句话
更新生命周期 =预检 → 备份 → 候选排练 → Doctor/迁移 → 重启验证 → 失败回滚;每一环都 best-effort、可观测、可恢复。
22. 开发实践步骤
从零开始,到改代码、验证、提交 PR 的可执行清单。以下命令来自项目脚本清单。
1. 环境与工具链
Node.js: >=24.16.0 <25 || >=26.1.0(项目清单声明的 engines)。包管理:pnpm( packageManager声明pnpm@12.15.0)。语言:TypeScript,严格 ESM。 测试:Vitest;质量:oxlint / oxfmt;构建:tsdown / Bun。
corepack enablepnpm install
2. 开发前先读
根目录的 AGENTS 指南(工作约定、设计优先级、执行纪律)。 修改涉及的子目录 AGENTS 指南(如插件层、插件 SDK、控制界面)。 行为变更前 pnpm docs:list找相关正式文档。数据库/状态代码先读 worker 访问规则文档。
3. 运行与调试
pnpm devpnpm openclaw | |
pnpm openclaw gateway | |
pnpm ui:dev | |
pnpm tui |
规则:CLI 一律
pnpm openclaw ...或pnpm dev,不要直接以 node+tsx 启动源码入口。
4. 改动与验证顺序(由窄到宽)

先复现:真实失败入口跑一遍,定位 bug 在哪一行。 最小修复:改根因,不修无关 bug。 跑相关测试:从最贴近改动处开始。 全量质量门:见下节。 端到端证据:真实 Gateway + 真实 agent/模型,或对应渠道 e2e。
5. 常用质量命令
pnpm test | |
pnpm test:unit | |
pnpm tsgopnpm tsgo:core / pnpm tsgo:extensions | |
pnpm lintpnpm lint:fix | |
pnpm formatpnpm format:check | |
pnpm check:docs | |
pnpm docs:check-links | |
pnpm verify |
6. 测试与证明策略
证明边界行为:优先在生产路径边界写测试,而不是 mock 一切(见测试写作参考文档)。 修复要证不变量:1~2 个“base 红、fix 绿”的回归测试。 测试失败即缺陷:复现、修所有者、加回归;不能靠宣称“重放通过”掩盖。 成本预算:测试改动遵守测试成本预算约定。
7. 提交与 PR
先 git status -sb,保留无关工作,只暂存意图内的文件。Conventional Commits,作者/写入者身份真实。 PR 前跑自己改动的测试 + 定向 typecheck/lint/format,以及 git diff --check。开 PR 前对自己改动跑简化流程(pr-simplify 技能)。 提交前遵循新鲜 review 流程(PR 维护技能)。
8. 给本学习文档贡献的约定
新增学习笔记放到学习文档目录,用编号前缀维持顺序。 每个主题写清楚:定位、关键源码路径、一张以上 Mermaid 图、一句话总结。 优先引用源码事实,不写臆测;引用官方文档用相对路径链接。
9. 高频踩坑
MCP stdio:stdout 必须协议纯净,日志走 stderr。 沙箱:Gateway 永在主机,只有工具执行进沙箱;工具 deny 优先于沙箱。 懒加载:动态 import 失败默认清除缓存以便重试;热路径不要懒加载。 插件:只能走插件 SDK 公共契约入口,不能碰核心内部或别的插件私有文件。
10. 一句话总结
开发实践 =环境对齐 → 读 AGENTS/文档 → 复现 → 最小修复 → 由窄到宽验证 → 端到端证据 → 简化和 review 后提交。














































































