00 - TurboClaw 整体架构 github 源码(欢迎star)

目标

从零开始实现一个极简版的类openclaw的AI agent框架,帮助您快速理解openclaw的实现原理。

首先第一节课理解 TurboClaw 的整体设计,明白数据是如何在各个组件之间流动的。


1. 什么是 TurboClaw?

TurboClaw 是一个极简的 AI Agent 框架,它让大语言模型(LLM)能够:

  • 使用工具(文件操作、网络请求等)
  • 记住信息(长期记忆)
  • 持续对话(多轮交互)

核心能力

普通 LLM 对话:
用户:创建一个文件
AI:抱歉,我无法操作文件系统

TurboClaw Agent:
用户:创建一个文件
AI:[调用 write_file 工具]
AI:文件已创建!

2. 架构设计

2.1 整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                        TurboClaw                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                      Gateway                               │  │
│  │                  (控制中心)                                 │  │
│  │                                                            │  │
│  │   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐  │  │
│  │   │   Session   │    │    Agent    │    │    Tools    │  │  │
│  │   │   会话管理   │◄──►│   ReAct核心 │◄──►│   工具注册表 │  │  │
│  │   └─────────────┘    └──────┬──────┘    └──────┬──────┘  │  │
│  │                              │                  │        │  │
│  │                         ┌────▼────┐       ┌─────▼─────┐  │  │
│  │                         │   LLM   │       │ 内置/SKILL│  │  │
│  │                         │  接口   │       │   工具    │  │  │
│  │                         └─────────┘       └───────────┘  │  │
│  │                                                            │  │
│  └──────────────────────────────┬─────────────────────────────┘  │
│                                 │                                │
│  ┌──────────────────────────────▼─────────────────────────────┐  │
│  │                      Channels                              │  │
│  │                   (交互界面)                                │  │
│  │                                                            │  │
│  │   ┌─────────────┐              ┌─────────────┐            │  │
│  │   │  Terminal   │              │  WebSocket  │            │  │
│  │   │  命令行界面  │              │  网络接口   │            │  │
│  │   └─────────────┘              └─────────────┘            │  │
│  │                                                            │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

2.2 组件职责

组件 职责 类比
Gateway 协调所有组件,管理生命周期 项目经理
Agent ReAct 循环,决策核心 大脑
LLM 提供推理能力 智囊团
Tools 执行具体操作 手脚/工具
Memory 长期存储信息 笔记本
Channels 用户交互界面 前台/接待
Session 维护对话上下文 谈话记录

3. 数据流详解

3.1 完整请求生命周期

以"创建一个文件"为例:

┌──────────┐
│   用户   │  "创建一个 hello.txt 文件"
└────┬─────┘
     │
     ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 1: Channel 接收输入                                        │
│ ─────────────────────                                           │
│ TerminalChannel 读取用户输入                                    │
│ 创建 Message 对象                                               │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 2: Gateway 路由                                            │
│ ─────────────────────                                           │
│ 根据 channel + clientId 找到或创建 Session                      │
│ 调用 Agent.process(message, session)                            │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 3: Agent ReAct 循环 (第1轮 - THINK)                        │
│ ───────────────────────────────────────                         │
│ 构建消息历史: [user: "创建文件..."]                              │
│ 调用 LLM.complete()                                             │
│                                                                 │
│ LLM 返回: {                                                     │
│   content: "我来创建文件",                                       │
│   toolCalls: [{                                                 │
│     name: "write_file",                                         │
│     parameters: {path: "hello.txt", content: ""}               │
│   }]                                                            │
│ }                                                               │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 4: Agent ReAct 循环 (第1轮 - ACT)                          │
│ ─────────────────────────────────────                           │
│ 从 ToolRegistry 获取 write_file 工具                           │
│ 执行 tool.execute({path: "hello.txt", content: ""})             │
│ 返回结果: "已写入: hello.txt"                                   │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 5: Agent ReAct 循环 (第1轮 - OBSERVE)                      │
│ ──────────────────────────────────────────                      │
│ 添加 assistant 消息(包含 toolCalls)到历史                     │
│ 添加 tool 消息(包含执行结果)到历史                            │
│                                                                 │
│ 历史现在: [                                                     │
│   {role: "user", content: "创建文件..."},                        │
│   {role: "assistant", toolCalls: [...]},                        │
│   {role: "tool", content: "已写入..."}                          │
│ ]                                                               │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 6: Agent ReAct 循环 (第2轮 - THINK)                        │
│ ───────────────────────────────────────                         │
│ 构建消息历史(包含上一轮结果)                                  │
│ 调用 LLM.complete()                                             │
│                                                                 │
│ LLM 看到历史里已经有 write_file 的结果                          │
│ 知道任务已完成                                                  │
│                                                                 │
│ LLM 返回: {                                                     │
│   content: "文件已创建完成!",                                   │
│   toolCalls: []  // 无工具调用                                  │
│ }                                                               │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 7: Agent 返回结果                                          │
│ ─────────────────────                                           │
│ 没有 toolCalls,循环结束                                        │
│ 返回 Message 给 Gateway                                         │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         ▼
┌────────────────────────────────────────────────────────────────┐
│ Step 8: Gateway → Channel → 用户                                │
│ ────────────────────────────────                                │
│ Gateway 调用 channel.send()                                     │
│ Terminal 打印: "文件已创建完成!"                               │
└────────────────────────────────────────────────────────────────┘

3.2 关键数据结构流转

// 1. 用户输入
const userInput = "创建文件";

// 2. 转换为 Message
const message: Message = {
  id: "uuid-1",
  role: "user",
  content: "创建文件",
  timestamp: Date.now()
};

// 3. 加入 Session
session.messages = [message];

// 4. 构建 LLM 请求
const llmRequest = {
  model: "deepseek-chat",
  messages: [
    {role: "system", content: "You are helpful"},
    {role: "user", content: "创建文件"}
  ],
  tools: [/* 工具定义 */]
};

// 5. LLM 响应
const llmResponse = {
  content: "",
  toolCalls: [{
    id: "call-1",
    name: "write_file",
    parameters: {path: "test.txt"}
  }]
};

// 6. 执行工具
const result = await tool.execute({path: "test.txt"});
// result: "已写入"

// 7. 更新 Session
session.messages.push(
  {role: "assistant", toolCalls: [...]},
  {role: "tool", content: "已写入"}
);

// 8. 再次调用 LLM...
// 9. 最终响应给用户

4. 模块关系图

4.1 依赖关系

                    ┌─────────────┐
                    │    types    │
                    └──────┬──────┘
           ┌───────────────┼───────────────┐
           │               │               │
           ▼               ▼               ▼
    ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
    │    tools    │ │    llm      │ │   memory    │
    └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
           │               │               │
           └───────────────┼───────────────┘
                           │
                           ▼
                    ┌─────────────┐
                    │    agent    │
                    └──────┬──────┘
                           │
           ┌───────────────┼───────────────┐
           │               │               │
           ▼               ▼               ▼
    ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
    │  channels   │ │   skills    │ │   config    │
    └──────┬──────┘ └─────────────┘ └─────────────┘
           │
           ▼
    ┌─────────────┐
    │   gateway   │
    └─────────────┘

说明:

  • types 被所有人依赖(最底层)
  • agent 依赖 toolsllmmemory
  • gateway 协调所有组件(最顶层)

5. 核心设计原则

5.1 单一职责

每个模块只做一件事:

  • Agent: 只负责 ReAct 循环
  • Tools: 只负责执行操作
  • Memory: 只负责存储
  • Channel: 只负责交互

5.2 依赖注入

不硬编码依赖,通过构造函数传入:

// 好的设计
class Agent {
  constructor(tools: ToolRegistry) {
    this.tools = tools;
  }
}

// 坏的设计
class Agent {
  constructor() {
    this.tools = new ToolRegistry(); // 硬编码
  }
}

5.3 接口隔离

通过接口定义契约:

interface Channel {
  start(): Promise<void>;
  stop(): Promise<void>;
  send(message: Message): Promise<void>;
}

// 可以有多种实现
class TerminalChannel implements Channel {}
class WebSocketChannel implements Channel {}

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐