OpenClaw 架构简要分析
OpenClaw架构介绍
OpenClaw智能体分层架构简要介绍

0.OpenClaw Flow
用户消息(任意渠道)
│
▼
┌─────────────────────────────────────────┐
│ Channel Plugin │ extensions/slack, telegram...
│ (onMessage → api.runtime.send) │
└──────────────────┬──────────────────────┘
│ Gateway WebSocket RPC
▼
┌─────────────────────────────────────────┐
│ Gateway Server (server.impl.ts) │
│ ┌─────────────────────────────────────┐ │
│ │ Protocol 验证 (AJV schema check) │ │
│ │ Auth + Scope 检查 │ │
│ │ CommandLane 队列路由 │ │
│ └──────────────┬──────────────────────┘ │
└─────────────────┼───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ agentCommand (命令执行层) │
│ 1.
加载 SessionStore(会话历史)
│
│ 2.
构建 System Prompt │
│ +
MEMORY.md
/ memory/*.md 注入 │
│ + Skills 工具描述注入
│
│ 3.
调用 Memory.search() 语义检索 │
│ → 向量搜索 / FTS / Hybrid 融合 │
│ 4. 调用 @mariozechner/pi-ai │
│ → LLM Provider 执行(流式/非流式)
│
└──────────────────┬──────────────────────┘
│ AgentEvent 流
▼
┌─────────────────────────────────────────┐
│
Event 处理 & 工具调用循环 │
│ tool_call → 执行 Skill/Bash/ACP spawn │
│ → 回填结果 → 继续推理 │
│ assistant_message → 流式输出
│
└──────────────────┬──────────────────────┘
│ deliver via channel
▼
渠道回复(Slack/TG/iMessage...)
一.Channel层
通过Telegram、Whats APP、飞书等IM渠道的接入适配,把 Telegram / WhatsApp / 飞书 的事件转换成统一消息格式
二.GateWay层
OpenClaw GateWay是整个Agent的核心组件,其通过WebSocket协议和多个IM进行交互。 做认证、授权、路由、会话定位、发送回执等功能
三.Agent编排层
- session 解析 / 加载,session会话记忆,类比称为短记忆或者临时记忆
- system prompt / user prompt / history 对话的组装
- 上下文裁剪 - 控制是否启用工具
- 控制是否启用记忆
- 多轮 reasoning loop 管理
- Function Call 的中转和结果回灌
四.模型执行层
模型执行层进行模型选择,同时其有fallback机制,如果primary模型推理失败,可以fallback到备选的模型进行执行。其包括 - primary / fallback 执行 - runner 调用(embedded / CLI / API等方式都支持) -最终结果的返回
五.工具层
主要针对模型的Function Call机制,OpenClaw目前内置有记忆工具、Message 工具、设备&UI设计等工具。工具层可以对接到Skill的实现,用户可以将相关能力封装为Skill导入到工具层,让模型能够很好的使用。
六.长期记忆层
MemoryIndexManager(核心调度器)
├── EmbeddingProvider(向量化层)
│ ├── OpenAI text-embedding-3-*
│ ├── Gemini embedding-004
│ ├── Voyage voyage-3-*
│ ├── Mistral mistral-embed
│ └── Local node-llama-cpp(本地模型)
├── SQLite 存储层(node:sqlite 内置)
│ ├── files 表 — 文件元数据 + hash + mtime
│ ├── chunks 表 — 文本分块 + 向量(JSON)
│ ├── chunks_vec — sqlite-vec 扩展加速向量搜索
│ ├── chunks_fts — FTS5 全文搜索索引
│ └── embedding_cache — 向量缓存,避免重复计算
└── MemorySource: "memory" | "sessions"
记忆层的实现目前openclaw是以本地文件存储的形式实现。
主要memory目录下的http://Memory.md和*日期.md文件,类比长期记忆 openclaw会利用本地的embedding 小模型等定期将长期记忆文件进行分块向量化,然后存储在本地的sqlite数据库中 .
当用户的prompt语言带有上次/你记得/xxx等提示时,工具层通过调用memory_search/memory_get 接口从本地长期记忆中寻找历史记忆进行上下文组装,其中memory_search首先会将要搜索的“记忆事件“通过embedding 模型编码语义向量,然后再在数据库中进行查找匹配。SQLlite数据库中存储了记忆向量在source .md文件中的位置片段信息,memory_get会既然从source文件中获取到精确的”记忆事件“信息,然后回传给模型进行上下文组装。
从源码可以看到三层搜索路径:
// 三种搜索模式,按条件降级:
// 模式①: FTS-only(无 Embedding Provider 时)
if (!this.provider) {
const keywords = extractKeywords(cleaned); // 停用词过滤 + 关键词提取
const resultSets = await Promise.all(
searchTerms.map((term) => this.searchKeyword(term, candidates))
);
// 合并去重,取最高分
}
// 模式②: 纯向量搜索
const queryVec = await this.embedQueryWithTimeout(cleaned);
const vectorResults = await this.searchVector(queryVec, candidates);
// 模式③: Hybrid(向量 + BM25 融合)
const merged = await this.mergeHybridResults({
vector: vectorResults,
keyword: keywordResults,
vectorWeight: hybrid.vectorWeight,
textWeight: hybrid.textWeight,
mmr: hybrid.mmr, // MMR 多样性重排
temporalDecay: hybrid.temporalDecay, // 时间衰减
});
Maximal Marginal Relevance (MMR) 重排算法
公式:MMR = λ * relevance - (1-λ) * max_similarity_to_selected.默认 λ=0.7(偏向相关性,适度引入多样性)相似度计算:基于 Jaccard token overlap
export const DEFAULT_MMR_CONFIG: MMRConfig = {
enabled: false, // 默认关闭,显式 opt-in
lambda: 0.7,
};
目前语义检索效果并不太好, 长期记忆检索召回率与精确率不足,这也是openclaw为什么经常失忆的原因,目前开源的记忆系统很多,zep/memos/openviki等等,我自己给他补充了ZEP记忆系统,失忆现象有所降低。记住:记忆系统是Agent是否聪明的核心因素
七.持久配置层
针对SOUL.md[User.md](https://t.co/UYt19PUeWA)\[Tool.md](https://t.co/s9zpyCfD1A)等的持久配置。Agent 人设与行为风格、 用户偏好、行为规则等等
评论
加载评论中...