作者:mpoll.top 发布时间:2026-04-03 6 次浏览
OpenClaw 是一个开源的 AI Agent 自动化框架,它让你能够用自然语言定义任务,自动执行系统命令、浏览器操作和消息发送。但 OpenClaw 是如何工作的?它的核心组件有哪些?数据如何在各组件间流动?本文将深入解析 OpenClaw 的架构设计,帮助你理解这个强大的自动化工具的内部原理,从而更好地编写 Skill 和排查问题。
图片来源:Pexels(可商用)
---
OpenClaw 采用分层架构设计,从用户交互到系统执行,共分为四个层次:
┌─────────────────────────────────────────────────────────┐
│ 用户接口层 (User Interface) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web Chat │ │ Discord │ │ CLI │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 网关服务层 (Gateway) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ openclaw gateway │ │
│ │ - 消息路由 │ │
│ │ - 会话管理 │ │
│ │ - 认证授权 │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 核心引擎层 (Core Engine) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Session │ │ Tool │ │ Memory │ │
│ │ Manager │ │ Executor │ │ Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 工具执行层 (Tool Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ exec │ │ browser │ │ message │ │
│ │ (系统命令) │ │ (浏览器) │ │ (消息发送) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ nodes │ │ canvas │ │ memory │ │
│ │ (设备控制) │ │ (画布呈现) │ │ (记忆管理) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
各层职责:
| 层级 | 组件 | 职责 |
|------|------|------|
| 用户接口层 | Web Chat/Discord/CLI | 接收用户输入,展示执行结果 |
| 网关服务层 | Gateway | 消息路由、会话管理、认证授权 |
| 核心引擎层 | Session/Tool/Memory Manager | 会话调度、工具执行、记忆管理 |
| 工具执行层 | exec/browser/message/nodes | 实际执行系统操作 |
Gateway 是 OpenClaw 的入口,负责处理所有外部请求。
核心功能:
// Gateway 核心逻辑简化
class Gateway {
constructor(config) {
this.channels = new Map(); // 已连接的渠道
this.sessions = new Map(); // 活跃会话
this.skills = new Map(); // 已加载的 Skill
}
// 处理 incoming 消息
async handleMessage(message) {
// 1. 验证消息来源
const channel = this.validateChannel(message);
// 2. 获取或创建会话
const session = this.getOrCreateSession(message.sessionId);
// 3. 解析用户意图
const intent = await this.parseIntent(message.text);
// 4. 路由到对应 Skill
const skill = this.findMatchingSkill(intent);
// 5. 执行 Skill
const result = await this.executeSkill(skill, intent.params);
// 6. 返回结果
return this.sendResponse(channel, result);
}
}
消息处理流程:
用户消息 → Gateway 接收 → 验证认证 → 创建/获取会话 →
解析意图 → 匹配 Skill → 执行工具 → 返回结果
支持的渠道:
Session Manager 负责维护用户会话状态,确保对话的连续性。
会话数据结构:
{
"sessionKey": "abc123xyz",
"userId": "user_001",
"channel": "discord",
"createdAt": "2024-01-15T10:30:00Z",
"lastActivity": "2024-01-15T11:45:00Z",
"context": {
"currentSkill": "weather",
"parameters": {"city": "北京"},
"history": [...]
},
"memory": {
"shortTerm": [...],
"longTerm": "MEMORY.md"
}
}
会话生命周期:
# 会话管理伪代码
def manage_session(session_id, message):
# 1. 查找现有会话
session = session_store.get(session_id)
if not session:
# 创建新会话
session = create_session(
user_id=message.user_id,
channel=message.channel
)
session_store.save(session)
# 2. 更新最后活动时间
session.last_activity = now()
# 3. 添加消息到历史
session.history.append(message)
# 4. 检查会话超时
if is_expired(session):
archive_session(session)
session = create_new_session(...)
return session
会话持久化:
Tool Executor 是 OpenClaw 的核心,负责执行各种工具调用。
工具执行流程:
Skill 定义 → 解析执行步骤 → 准备工具输入 →
执行工具 → 捕获输出 → 处理结果 → 返回响应
工具注册机制:
// 工具注册表
const toolRegistry = {
exec: {
handler: execHandler,
schema: execSchema,
permissions: ['filesystem', 'process']
},
browser: {
handler: browserHandler,
schema: browserSchema,
permissions: ['browser']
},
message: {
handler: messageHandler,
schema: messageSchema,
permissions: ['messaging']
},
nodes: {
handler: nodesHandler,
schema: nodesSchema,
permissions: ['devices']
}
};
// 工具执行
async function executeTool(toolName, params, context) {
const tool = toolRegistry[toolName];
// 1. 验证参数
validateParams(tool.schema, params);
// 2. 检查权限
checkPermissions(tool.permissions, context);
// 3. 执行工具
const result = await tool.handler(params, context);
// 4. 记录日志
logToolExecution(toolName, params, result);
return result;
}
Memory Manager 负责管理短期和长期记忆,支持对话连续性。
记忆层次结构:
┌─────────────────────────────────────────┐
│ 工作记忆 (Working Memory) │
│ - 当前会话上下文 │
│ - 临时变量 │
│ - 执行状态 │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 短期记忆 (Short-term Memory) │
│ - 最近对话历史 │
│ - 会话间共享上下文 │
│ - 临时学到的信息 │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 长期记忆 (Long-term Memory) │
│ - MEMORY.md 文件 │
│ - 用户偏好 │
│ - 重要决策和事实 │
└─────────────────────────────────────────┘
记忆操作流程:
class MemoryManager:
def __init__(self, workspace_path):
self.workspace = workspace_path
self.memory_file = os.path.join(workspace, 'MEMORY.md')
self.short_term = []
def add_short_term(self, content):
"""添加短期记忆"""
self.short_term.append({
'content': content,
'timestamp': datetime.now(),
'importance': self.calculate_importance(content)
})
# 保持最近 100 条
self.short_term = self.short_term[-100:]
def consolidate_to_long_term(self):
"""将重要的短期记忆合并到长期记忆"""
important = [m for m in self.short_term if m['importance'] > 0.8]
if important:
self.append_to_memory_file(important)
self.short_term = [m for m in self.short_term if m['importance'] <= 0.8]
def search(self, query):
"""语义搜索记忆"""
results = semantic_search(query, self.memory_file)
return results
功能:执行 shell 命令,支持前台/后台运行、PTY、超时控制。
执行流程:
用户请求 → 解析命令 → 安全检查 →
创建进程 → 捕获输出 → 返回结果
安全机制:
// 命令安全检查
function validateCommand(command, securityMode) {
const dangerousPatterns = [
'rm -rf /',
'dd if=/dev/zero',
'mkfs',
'chmod -R 777'
];
if (securityMode === 'deny') {
// 阻止所有写操作
if (isWriteOperation(command)) {
throw new Error('Write operations not allowed');
}
} else if (securityMode === 'allowlist') {
// 只允许白名单命令
if (!isInAllowlist(command)) {
throw new Error('Command not in allowlist');
}
}
// securityMode === 'full' 时不限制
return true;
}
使用示例:
execution:
steps:
- tool: exec
name: list-files
input:
command: ls -la /workspace
- tool: exec
name: process-data
input:
command: node process.js
timeout: 60
pty: true
功能:控制浏览器进行网页交互、截图、数据抓取。
架构设计:
┌─────────────────┐ ┌─────────────────┐
│ OpenClaw Core │ → │ Browser Server │
│ │ │ (Playwright) │
└─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ Browser │
│ (Chrome/Firefox)│
└─────────────────┘
核心操作:
| 操作 | 描述 | 示例 |
|------|------|------|
| navigate | 导航到 URL | `browser.navigate(url)` |
| snapshot | 获取页面快照 | `browser.snapshot()` |
| act | 执行 UI 操作 | `browser.act({kind: 'click', ref: 'e12'})` |
| screenshot | 截图 | `browser.screenshot()` |
| evaluate | 执行 JS | `browser.evaluate('document.title')` |
使用示例:
execution:
steps:
- tool: browser
name: open-page
input:
action: navigate
url: https://example.com
- tool: browser
name: take-snapshot
input:
action: snapshot
refs: aria
- tool: browser
name: click-button
input:
action: act
kind: click
ref: e12
功能:通过各渠道发送消息、管理频道、创建线程。
支持的操作:
const messageActions = {
send: '发送消息',
reply: '回复消息',
react: '添加反应',
edit: '编辑消息',
delete: '删除消息',
thread_create: '创建线程',
broadcast: '广播消息'
};
渠道适配:
class MessageChannel:
def __init__(self, provider):
self.provider = provider
def send(self, channel_id, content, options):
if self.provider == 'discord':
return self.send_discord(channel_id, content, options)
elif self.provider == 'telegram':
return self.send_telegram(channel_id, content, options)
elif self.provider == 'whatsapp':
return self.send_whatsapp(channel_id, content, options)
# ... 其他渠道
功能:控制配对的移动设备,支持摄像头、屏幕、通知等操作。
支持的设备操作:
| 操作 | 描述 | 设备要求 |
|------|------|---------|
| camera_snap | 拍照 | 配对的手机 |
| screen_record | 录屏 | 配对的手机 |
| location_get | 获取位置 | 配对的手机 |
| notifications_list | 查看通知 | 配对的手机 |
| notify | 发送通知 | 配对的手机 |
设备配对流程:
1. 手机端安装 OpenClaw Companion App
- 扫描 Gateway 提供的配对码
- 建立 WebSocket 连接
- 设备出现在 nodes 列表中
- 可通过 nodes 工具控制
Skill 文件结构:
metadata:
name: weather
version: "1.0.0"
description: 获取天气预报
author: Your Name
parameters:
city:
description: 城市名称
required: true
type: string
execution:
steps:
- tool: exec
name: fetch-weather
input:
command: curl wttr.in/{{city}}
解析流程:
def parse_skill(skill_path):
# 1. 读取文件
content = read_file(skill_path)
# 2. 解析 YAML
skill_def = yaml.safe_load(content)
# 3. 验证结构
validate_structure(skill_def)
# 4. 验证参数定义
validate_parameters(skill_def['parameters'])
# 5. 验证执行步骤
validate_execution_steps(skill_def['execution'])
# 6. 返回解析后的 Skill
return Skill(skill_def)
模板引擎:
// 参数替换
function renderTemplate(template, params) {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return params[key] || match;
});
}
// 示例
const command = "curl wttr.in/{{city}}";
const rendered = renderTemplate(command, {city: '北京'});
// 结果:curl wttr.in/北京
执行引擎:
class SkillExecutor:
def __init__(self, tool_registry):
self.tools = tool_registry
async def execute(self, skill, params, context):
results = []
for step in skill.execution.steps:
try:
# 渲染模板
rendered_input = self.render(step.input, params)
# 执行工具
result = await self.tools.execute(
step.tool,
rendered_input,
context
)
results.append(result)
# 存储结果供后续步骤使用
context.variables[step.name] = result
except ToolError as e:
if step.on_error == 'continue':
results.append({'error': str(e)})
else:
raise SkillExecutionError(f"Step {step.name} failed: {e}")
return results
1. 用户发送消息 "查询北京天气"
↓
- Gateway 接收消息,创建/获取会话
↓
- 解析意图,匹配到 weather Skill
↓
- 提取参数 city="北京"
↓
- Session Manager 更新会话状态
↓
- Tool Executor 执行 Skill 步骤
↓
- exec 工具运行 curl wttr.in/北京
↓
- 捕获命令输出
↓
- 格式化响应
↓
- Gateway 通过原渠道返回结果
↓
- 更新会话历史和记忆
会话状态:
记忆状态:
执行日志:
// 并行执行独立步骤
async function executeParallelSteps(steps, context) {
const independentSteps = findIndependentSteps(steps);
const results = await Promise.all(
independentSteps.map(step => executeStep(step, context))
);
return results;
}
class ResultCache:
def __init__(self, ttl=3600):
self.cache = {}
self.ttl = ttl
def get(self, key):
if key in self.cache:
entry = self.cache[key]
if time.time() - entry['timestamp'] < self.ttl:
return entry['result']
return None
def set(self, key, result):
self.cache[key] = {
'result': result,
'timestamp': time.time()
}
OpenClaw 支持通过插件扩展功能:
// 插件注册
function registerPlugin(plugin) {
// 注册新工具
if (plugin.tools) {
for (const [name, tool] of Object.entries(plugin.tools)) {
toolRegistry[name] = tool;
}
}
// 注册新渠道
if (plugin.channels) {
for (const channel of plugin.channels) {
channelManager.register(channel);
}
}
}
OpenClaw 的架构设计遵循以下原则:
理解这些核心组件后,你可以:
本文属于「OpenClaw 小龙虾专区」系列专题
快速链接:
没有了,已经是最新文章