这两周 openclaw 非常的火热,大家都在探索它的使用方法和用应用场景。我也对它产生了浓厚的兴趣,深入研究了它 也有一些网易在研究它的架构设计和实现细节,贡献了 nanbot、miniclaw 等个别的项目。我也花了一些时间研究了 openclaw 的代码,并基于它的设计理念,使用 Go 语言重新实现了一个类似的项目,命名为 goclaw。
goclaw 使用和 openclaw 相同的配置文件、技能系统和类似的 cli 命令,并且兼容 openclaw 的技能生态。同时,goclaw 也借鉴了 openclaw 的核心设计理念,但在实现细节上做了一些不同的选择,以充分利用 Go 语言的优势,构建了一个更加健壮、高性能的 AI 助手。
项目地址: https://github.com/smallnest/goclaw
概述
GoClaw 是一个用 Go 语言编写的个人 AI 助手,灵感来自 OpenClaw(原 Clawdbot/Moltbot)。它运行在本地服务器上,通过 WebSocket/HTTP 暴露服务,支持多种消息 channel(Telegram、WhatsApp、飞书、QQ、Slack 等)接入。
核心定位
| 语言 | |
| 架构 | |
| 部署 | |
| 扩展性 | |
| 可靠性 |
核心架构
系统全景图
┌──────────────────────────────────────────────────────────────────────────────┐
│ GoClaw 系统架构 │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 输入Channel │── →│ 网关服务器 │───→│ Agent Loop │───→│ LLM/工具 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ v v v v │
│ Telegram/WhatsApp MessageBus SessionManager Providers │
│ 飞书/QQ/Slack 串行队列 JSONL存储 OpenAI/AI... │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
消息处理流程
用户消息 → Channel适配器 → 网关服务器 → Agent Loop → LLM 调用 → 工具执行 → 响应返回
Agent Loop 执行引擎
Agent Loop 是 GoClaw 的大脑,负责思考、规划和执行。它受到 OpenClaw 的 PI Agent 架构启发。
PI Agent 理念
PI = 极简编码代理(Mario Zechner 创建)
"LLMs 本身就擅长编写和运行代码,不需要过多的包装"
执行流程图
┌───────────────────────────────────────────────────────────────────┐
│ GoClaw Agent Loop │
├───────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 接收消息 │────→│ 构建上下文 │────→│ LLM 调用 │────→│ 执行工具 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │
│ v │
│ ┌─────────────────┐ │
│ │ 工具结果返回 │ │
│ └─────────────────┘ │
│ │ │
│ v │
│ ┌─────────────────┐ │
│ │ 反思机制判断 │ │
│ │ (可选) │ │
│ └─────────────────┘ │
│ │ │
│ ┌─────────────┴────────────┐ │
│ v v │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 继续迭代 │ │ 返回响应 │ │
│ └─────────────┘ └─────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────┘
核心组件
1. 上下文构建器 (ContextBuilder)
文件: agent/context.go
type ContextBuilder struct {
memory *MemoryStore
workspace string
agentID string
defaultModel string
provider string
}
职责:
动态组装系统提示词 注入可用工具定义 添加会话历史(从 JSONL) 整合相关记忆 上下文窗口保护与压缩
上下文压缩策略:
// agent/loop.go:571
func (l *Loop) compressSession(sess *session.Session) {
// 保留最近 10 轮对话
// 保留所有系统消息
// 丢弃早期历史,保留关键上下文
}
2. 工具注册表 (Tools Registry)
文件: agent/tools/registry.go
核心工具集(对应 PI 的四个工具):
read_file | read | |
write_file | write | |
edit_file | edit | |
run_shell | bash |
GoClaw 扩展工具:
browser_*- 浏览器操作 (Chrome DevTools Protocol)smart_search- 混合搜索 (向量 + FTS5)spawn- 子代理管理message- 消息发送
工具执行与重试:
// agent/loop.go:526
func (l *Loop) executeToolWithRetry(ctx context.Context, toolName string, params map[string]interface{}) (string, error) {
// 网络错误自动重试
// 错误分类与降级建议
// 结构化错误返回给 LLM 自我校正
}
3. 反思器 (Reflector)
文件: agent/reflection.go
解决传统 Agent "何时停止" 的难题:
type Reflector struct {
config *ReflectionConfig
provider providers.Provider
workspace string
}
type TaskReflection struct {
Status TaskStatus // "completed", "in_progress", "failed", "blocked"
Confidence float64 // 0.0 - 1.0
CompletedSteps []string // 已完成步骤
RemainingSteps []string // 剩余步骤
Reasoning string // 思考过程
NextAction string // 下一步行动
}
反思流程:
// agent/loop.go:487
reflection, reflectErr := l.reflector.Reflect(ctx, userRequest, reflectionHistory)
if l.reflector.ShouldContinueIteration(reflection, iteration, l.maxIteration) {
continuePrompt = l.reflector.GenerateContinuePrompt(reflection)
continue
}
与传统 max-iterations 的区别:
传统:固定步数后强制停止 反思:动态判断任务状态,智能决定是否继续
4. 错误分类器 (ErrorClassifier)
文件: agent/error_classifier.go
type ErrorClassifier struct {
authPatterns []string
rateLimitPatterns []string
timeoutPatterns []string
billingPatterns []string
}
错误分类:
auth- 认证错误(需要故障转移)rate_limit- 限流错误(需要冷却)timeout- 超时错误(可重试)billing- 计费错误(需要故障转移)tool- 工具错误(返回给 LLM)
智能降级策略:
// agent/loop.go:628
func (l *Loop) formatToolError(toolName string, params map[string]interface{}, err error) string {
// 根据工具类型和错误提供具体建议
// 例如:write_file 失败 → 建议输出到控制台
// 例如:browser 失败 → 建议使用 web_fetch
}
GoClaw vs OpenClaw PI Agent
架构对比
OpenClaw PI (TypeScript) - 极简循环:
while (true) {
const response = await streamCompletion(model, context);
if (!response.toolCalls?.length) break;
for (const call of response.toolCalls) {
const result = await executeToolCall(call, context);
context.messages.push(result);
}
}
GoClaw (Go) - 增强循环:
for iteration < l.maxIteration {
response, err := l.provider.Chat(ctx, messages, tools)
if len(response.ToolCalls) > 0 {
for _, tc := range response.ToolCalls {
result, err := l.executeToolWithRetry(ctx, tc.Name, tc.Params)
}
continue
}
if response.Content == "" && l.reflector != nil {
reflection := l.reflector.Reflect(ctx, userRequest, history)
if !l.reflector.ShouldContinueIteration(reflection, iteration, l.maxIteration) {
break
}
continue
}
break
}
会话存储对比
扩展系统对比
OpenClaw PI - TypeScript Hooks:
hooks: {
onSessionStart: async (session) => { ... },
onBeforeTurn: async (session) => { ... },
onToolCall: async (tool, params) => { ... },
// 20+ 生命周期钩子
}
GoClaw - Skills System:
type Skill struct {
Name string
Description string
Triggers []string // 触发关键词
Content string // Markdown 指令
Requires []string // 环境依赖 (Gating)
}
设计哲学对比
GoClaw 独特创新
反思机制 - 解决 Agent "何时停止" 难题 错误分类与重试 - 三层容错(工具级、迭代级、提供商级) 混合搜索 - 向量 + FTS5 双重检索 技能准入 (Gating) - 根据环境自动加载技能 上下文压缩 - 智能保留关键历史
网关服务器
文件: gateway/server.go
网关服务器是 GoClaw 的心脏,负责任务/会话协调:
type Server struct {
config *config.GatewayConfig
wsConfig *WebSocketConfig
bus *bus.MessageBus
channelMgr *channels.Manager
sessionMgr *session.Manager
connections map[string]*Connection
}
核心功能:
处理多个重叠请求 基于队列的消息总线(串行默认) WebSocket 连接支持 Webhook 回调处理 HTTP 健康检查端点
内存系统
双重记忆架构
会话记录 (JSONL)
每行一个 JSON 对象 包含用户消息、工具调用、结果、响应 会话基础的持久化记忆
记忆文件 (Markdown)
MEMORY.md或memory/文件夹由代理使用标准文件写入工具生成 没有特殊的记忆写入 API
混合搜索
| 向量搜索 | ||
| 关键词搜索 (FTS5) |
文件: memory/search.go
type MemoryManager struct {
store Store
provider EmbeddingProvider
cache map[string]*VectorEmbedding
}
计算机使用
Shell 执行
| 沙箱 | |
| 直接主机 | |
| 远程设备 |
文件系统工具
read_file- 读取文件write_file- 写入文件edit_file- 编辑文件list_files- 列出目录
浏览器工具 (Chrome DevTools Protocol)
browser_navigate- 导航到 URLbrowser_screenshot- 截取页面截图browser_execute_script- 执行 JavaScriptbrowser_click- 点击元素browser_fill_input- 填写输入框browser_get_text- 获取页面文本
文件: agent/tools/browser.go
type BrowserTool struct {
headless bool
timeout time.Duration
outputDir string
}
进程管理
后台长期命令 终止进程
安全机制
允许列表 (Allowlist)
{
"agents": {
"main": {
"allowlist": [
{ "pattern": "/usr/bin/npm", "lastUsedAt": 1706644800 },
{ "pattern": "/opt/homebrew/bin/git", "lastUsedAt": 1706644900 }
]
}
}
}
预批准的安全命令
jq、grep、cut、sort、uniq、head、tail、tr、wc 等
危险构造阻止
# 这些在执行前会被拒绝:
npm install $(cat /etc/passwd) # 命令替换
cat file > /etc/hosts # 重定向
rm -rf / || echo "failed" # 用 || 链接
(sudo rm -rf /) # 子shell
LLM 提供商与故障转移
支持的提供商
OpenAI(兼容接口) Anthropic OpenRouter
故障转移机制
文件: providers/failover.go
type FailoverProvider struct {
primary Provider
fallback Provider
circuitBreaker *CircuitBreaker
errorClassifier types.ErrorClassifier
}
特性:
断路器模式 - 防止连续失败时持续调用失败的提供商 错误分类 - 区分可重试和不可重试错误 自动切换 - 主提供商失败时自动切换到备用
技能系统 (Skills)
特性
Prompt-Driven - 技能本质上是注入到 System Prompt 中的指令集 OpenClaw 兼容 - 完全兼容 OpenClaw 的技能生态 自动准入 (Gating) - 智能检测系统环境
技能加载顺序
传入的自定义目录 workspace/skills/workspace/.goclaw/skills/可执行文件路径 /skills/./skills/(当前目录,优先级最高)
项目结构
goclaw/
├── agent/ # Agent 核心逻辑
│ ├── loop.go # Agent 循环(含重试逻辑)
│ ├── context.go # 上下文构建器
│ ├── memory.go # 记忆系统
│ ├── skills.go # 技能加载器
│ ├── reflection.go # 反思机制
│ ├── error_classifier.go # 错误分类器
│ └── tools/ # 工具系统
│ ├── registry.go
│ ├── browser.go
│ ├── filesystem.go
│ ├── shell.go
│ └── ...
├── channels/ # 消息通道
├── bus/ # 消息总线
├── config/ # 配置管理
├── providers/ # LLM 提供商
│ ├── failover.go
│ ├── circuit.go
│ └── ...
├── session/ # 会话管理
├── memory/ # 记忆存储
├── cli/ # 命令行界面
└── gateway/ # 网关服务器
与 OpenClaw 的主要区别
快速开始
# 构建
go build -o goclaw .
# 配置
cat > config.json << EOF
{
"agents": {
"defaults": {
"model": "openrouter:anthropic/claude-opus-4-5",
"max_iterations": 15
}
},
"providers": {
"openrouter": {
"api_key": "your-key"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "your-bot-token"
}
}
}
EOF
# 启动
./goclaw start
总结
GoClaw 继承了 OpenClaw 的核心设计理念,同时利用 Go 语言的特性构建了一个更加健壮、高性能的 AI 助手。
设计原则:
极简核心 + 可扩展技能 串行默认,显式并行 可靠性优于复杂性 完全可观测(日志 + 会话持久化)
"这种简单性可能是优势也可能是陷阱,取决于你的视角。但我总是倾向于可解释的简单性,而不是复杂的意大利面条代码。"
