OpenClaw 架构总览
这是顶层地图。所有其他架构文档都从这里分支出去。
基于 OpenClaw 版本 2026.2.23(commit aceb17a)。
高层架构
消息流(入站 → 出站)
一条从 Telegram 发出的消息到回复的完整链路:
模块索引
每个模块有独立的详细文档。Status 列标识写作进度。
跨模块设计模式
横跨多个模块的复用设计模式。完整列表见 patterns 索引。
深入分析
高影响子系统的代码级 walkthrough。完整列表见 deep-dives 索引。
关键架构决策(源码验证)
-
单进程:Gateway(
src/gateway/server.impl.ts)在一个 Node.js 进程中运行所有内容 — WebSocket 服务器、HTTP API、Channel 插件、Agent 运行时、Cron。默认端口18789,Canvas Host 在端口+1,Browser Control 在端口+2。 -
本地优先持久化:会话以只追加 JSONL 文件存储(
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl)。记忆使用带向量扩展的 SQLite(memory.db)。配置使用支持环境变量替换的 JSON5(openclaw.json)。不依赖云服务。 -
BYOM(自带模型):Pi Agent SDK(
@mariozechner/pi-agent-core)抽象了 LLM 提供商。支持 Anthropic、OpenAI、Google Gemini、xAI Grok、DeepSeek、Mistral、Ollama 等。可按 agent、按会话或按轮次选择模型。 -
Markdown 即配置:Skills 是带 YAML frontmatter 的
SKILL.md文件。记忆笔记是 Markdown。Agent 工作空间文件是 Markdown。全部人类可读、Git 友好、LLM 原生可解析。 -
通道无关的插件架构:每个消息平台是一个扩展包(
extensions/*/),实现src/channels/plugins/types.plugin.ts中的ChannelPlugin接口。目前 38 个扩展,每个包含约 15 种 adapter 类型(config、security、outbound、status、gateway、threading 等)。 -
pnpm workspaces monorepo:根包 +
ui/+extensions/*作为工作空间成员。通过tsdown构建。TypeScript 5.9,Node.js 22+,严格模式。
源码目录结构
配置结构(openclaw.json)
从 src/config/types.openclaw.ts 和 Zod schema 验证:
我的认知盲区
诚实记录我尚未理解的部分。随着认知增长持续更新。
- 工具策略流水线如何组合过滤层?——已解答:7 步级联白名单管道,每步渐进式过滤工具。无显式 deny,不在白名单中的工具即被排除。详见 Tool Policy。
- 压缩流程如何决定总结/保留?——已解答:
BASE_CHUNK_RATIO=0.4自适应分块,splitMessagesByTokenShare()按 token 均分消息到 N 个块,最旧的块优先丢弃,repairToolUseResultPairing()修复裁剪后孤立的 tool_results。详见 Pi Agent Runtime 和 Compaction Internals。 - 记忆混合搜索权重——已解答:
score = vectorWeight * vectorScore + textWeight * textScore,可选 MMR 重排(lambda=0.7:70% 相关性,30% 多样性惩罚,基于 Jaccard 相似度)。详见 Memory (RAG)。 - 设备配对协议——已解答:Ed25519 挑战-响应,8 位字母数字配对码(排除易混淆的 0O1I),60 分钟 TTL,最多 3 个待处理,设备 ID 由公钥 SHA-256 哈希派生。详见 Native Apps 和 Ed25519 Device Auth。
- 扩展热重载——已解答:扩展不支持热重载(需要重启 Gateway)。仅配置级的 hooks 和 cron 支持热重载,通过
chokidar文件监听器实现,300ms 防抖。详见src/gateway/config-reload.ts。 - 子 Agent 注册表——已解答:无显式深度限制。通过
rootSessionKey在listDescendantRunsForRequester()中递归查询追踪所有层级。孤儿检测 viaresolveSubagentRunOrphanReason(),announce 最多重试 3 次,5 分钟超时。详见src/agents/subagent-registry.ts(1,081 行)。 - WebSocket 重连策略——已解答:服务端不主动重连(无状态接受连接)。Web UI(
ui/src/ui/gateway.ts)使用指数退避:初始 800ms,倍率 1.7x,上限 15s。iOS 应用仅在切到前台时重试(attemptAutoReconnectIfNeeded())。详见 WebSocket Disconnects。 - Config 热重载失败处理——已解答:重载失败时,系统记录错误并跳过更新,旧配置继续驻留内存。无回滚机制。文件缺失时重试 2 次(150ms 间隔)后跳过。无效配置记录校验错误后跳过。详见
src/gateway/config-reload.ts:370-388。 - JSONL 转录损坏恢复——已解答:双层恢复。文件级:
repairSessionFileIfNeeded()(src/agents/session-file-repair.ts)丢弃无法解析的 JSON 行并创建.bak-{pid}-{timestamp}备份。转录级:repairToolUseResultPairing()+repairToolCallInputs()+sanitizeToolCallInputs()修复孤立/重复的 tool results。详见 Session Transcript Corruption。 - Memory 索引缓存淘汰——
maxEntries配置存在于src/memory/manager.ts,但未实现任何淘汰/驱逐逻辑。INDEX_CACHE是无界的Map,无 LRU、大小检查或 TTL。疑似未实现的功能。 - 多 Agent 会话键碰撞——会话键是确定性的(
agent:{agentId}:{mainKey},见src/routing/session-key.ts)。无 UUID 生成、碰撞检测或锁机制。系统依赖外部唯一性(不同的 agent ID + 每 channel 不同的 peer ID)而非内建安全保障。