Claw 生态01: nanobot - 4000 行代码重建 OpenClaw 的架构设计

如果你想理解 OpenClaw 的核心架构,但又不想啃 43 万行 TypeScript 代码,nanobot 是最好的选择。

香港大学数据科学实验室做的这个项目,用 4000 行 Python 代码重建了 OpenClaw 的核心功能。不是简化版,是精简版 —— 保留了所有关键特性,砍掉了冗余和历史包袱。

GitHub 上 23k 星标,社区里经常有人说”4k 行 vs 43 万行”,说的就是它。

为什么要重写

OpenClaw 的问题不是功能不够,而是太重了

43 万行代码,启动要好几秒,运行时内存占用超 1GB。对于想在树莓派或者老手机上跑的人来说,这就是灾难。更重要的是,代码太多,新手根本看不懂架构。

nanobot 的目标很明确:用最少的代码,实现 OpenClaw 的核心功能

结果是 4000 行 Python,支持:
– 多 LLM(OpenRouter/Anthropic/OpenAI/vLLM 本地)
– 多聊天平台(Telegram/Discord/WhatsApp/Feishu)
– MCP 工具集成
– cron 定时任务
– 双层 memory(filesystem + grep)
– 子代理(subagents)

架构设计

nanobot 的架构清晰到可以用一张图说明:

nanobot/
├── agent/          # 核心 agent 逻辑
│   ├── loop.py     # ReAct 循环
│   ├── context.py  # 上下文管理
│   ├── memory.py   # 双层记忆
│   ├── skills.py   # 技能注册
│   └── subagents.py # 子代理
├── channels/       # 聊天平台适配
│   ├── telegram.py
│   ├── discord.py
│   └── whatsapp.py
├── providers/      # LLM 提供商
│   ├── registry.py # 统一注册
│   ├── openai.py
│   └── anthropic.py
├── tools/          # 工具集
│   ├── web.py
│   ├── file.py
│   └── code.py
├── bus/            # 消息总线
└── cron/           # 定时任务

1. Agent Loop – 核心循环

nanobot 的核心是一个 ReAct 循环:

# agent/loop.py (简化版)
def agent_loop(user_input, context):
    while not done:
        # 1. 构建 prompt(包含 context + memory + tools)
        prompt = build_prompt(user_input, context)

        # 2. 调用 LLM
        response = llm.generate(prompt)

        # 3. 解析响应(是工具调用还是最终回复?)
        if is_tool_call(response):
            tool_name, tool_args = parse_tool_call(response)
            result = execute_tool(tool_name, tool_args)
            context.append(result)  # 添加到上下文
        else:
            return response  # 最终回复

这就是 ReAct(Reasoning + Acting)的核心:LLM 推理 → 决定是否调用工具 → 执行工具 → 继续推理。

2. Memory – 双层记忆

nanobot 用两层记忆:

短期记忆(Context)
– 当前对话的上下文
– 存在内存里,对话结束就清空

长期记忆(Filesystem)
– 用 markdown 文件存储
– 用 grep 搜索(简单但有效)

# agent/memory.py (简化版)
class Memory:
    def __init__(self, workspace):
        self.workspace = workspace
        self.memory_file = f"{workspace}/MEMORY.md"

    def save(self, content):
        with open(self.memory_file, 'a') as f:
            f.write(f"n## {datetime.now()}n{content}n")

    def search(self, query):
        # 用 grep 搜索
        result = subprocess.run(
            ['grep', '-i', query, self.memory_file],
            capture_output=True, text=True
        )
        return result.stdout

为什么不用向量数据库?因为简单够用。grep 对于几千条记录来说,速度完全够,而且不需要额外依赖。

3. Providers – LLM 注册

nanobot 的 LLM 集成非常简洁:

# providers/registry.py (简化版)
class ProviderRegistry:
    def __init__(self):
        self.providers = {}

    def register(self, name, provider_class):
        self.providers[name] = provider_class

    def get(self, name):
        return self.providers[name]

# 注册 provider 只需要两步
registry = ProviderRegistry()
registry.register('openai', OpenAIProvider)
registry.register('anthropic', AnthropicProvider)

加新模型?写一个 provider 类,注册一下,完事。

4. Channels – 平台适配

每个聊天平台都是一个 channel:

# channels/telegram.py (简化版)
class TelegramChannel:
    def __init__(self, token):
        self.bot = telegram.Bot(token)

    def listen(self, callback):
        # 监听消息
        for update in self.bot.get_updates():
            message = update.message.text
            response = callback(message)  # 调用 agent
            self.bot.send_message(update.message.chat_id, response)

所有 channel 都实现同一个接口:listen(callback)。这样 agent 不需要关心是哪个平台。

5. Tools – 工具集成

工具注册也很简单:

# tools/web.py (简化版)
@tool(name="web_search", description="Search the web")
def web_search(query: str) -> str:
    # 调用搜索 API
    results = search_api.search(query)
    return format_results(results)

用装饰器注册工具,agent 自动发现。

与 OpenClaw 的对比

维度 OpenClaw nanobot
代码量 43 万行 4000 行
语言 TypeScript Python
启动时间 3-5 秒 <1 秒
内存占用 >1GB ~200MB
依赖 重(Node.js 生态) 轻(标准库 + 几个包)
可读性 低(代码太多) 高(清晰分层)
扩展性 中(历史包袱) 高(模块化)

nanobot 砍掉了什么?

  • 技能市场:OpenClaw 有个在线技能市场,nanobot 没有(但可以手动添加)
  • 复杂的插件系统:OpenClaw 支持动态加载插件,nanobot 是静态注册
  • Web UI:OpenClaw 有个 Web 界面,nanobot 只有命令行

但核心功能都在:agent loop、memory、tools、channels、subagents。

实战:添加一个自定义工具

假设你想加一个”查询天气”的工具,步骤如下:

1. 写工具函数

# tools/weather.py
import requests

@tool(name="get_weather", description="Get weather for a city")
def get_weather(city: str) -> str:
    api_key = os.getenv('WEATHER_API_KEY')
    url = f"https://api.weather.com/v1/current?city={city}&key={api_key}"
    response = requests.get(url)
    data = response.json()
    return f"Weather in {city}: {data['temp']}°C, {data['condition']}"

2. 注册工具

# main.py
from tools.weather import get_weather

# 工具会自动注册(通过装饰器)

3. 测试

$ python main.py
User: What's the weather in Beijing?
Agent: [Calling tool: get_weather(city="Beijing")]
Agent: Weather in Beijing: 5°C, Cloudy

就这么简单。

部署建议

nanobot 适合:

本地开发

git clone https://github.com/HKUDS/nanobot
cd nanobot
pip install -r requirements.txt
python main.py

Docker 部署

docker build -t nanobot .
docker run -e OPENAI_API_KEY=xxx nanobot

树莓派
– Python 3.8+
– 内存 512MB+
– 启动时间 <1 秒

适合谁

nanobot 适合:

  • 想理解 OpenClaw 架构的人:代码少,容易看懂
  • 想快速上手的人:Python 生态,依赖少
  • 想二次开发的人:模块化设计,容易扩展
  • 资源受限的场景:树莓派、老手机、低配 VPS

不适合:

  • 需要技能市场的人:nanobot 没有在线市场
  • 需要 Web UI 的人:只有命令行
  • 需要复杂插件系统的人:静态注册,不支持动态加载

源码阅读建议

如果你想深入理解 nanobot,建议按这个顺序读代码:

  1. main.py – 入口,看整体流程
  2. agent/loop.py – 核心循环,理解 ReAct
  3. agent/memory.py – 记忆系统,理解双层设计
  4. providers/registry.py – LLM 集成,理解抽象
  5. channels/telegram.py – 平台适配,理解接口设计
  6. tools/ – 工具集,理解装饰器注册

总共 4000 行,一天就能看完。

总结

nanobot 证明了一件事:OpenClaw 的核心架构,4000 行代码就够了

它不是 OpenClaw 的简化版,而是精简版 —— 保留了所有关键特性,砍掉了冗余和历史包袱。对于想理解 AI Agent 架构、快速上手、二次开发的人来说,这是最好的选择。

如果你想在资源受限的环境(树莓派、老手机)上跑 AI Agent,或者想快速搭建一个原型,nanobot 是首选。


相关链接
nanobot GitHub
← 返回系列总览
下一篇:PicoClaw – 在 $10 开发板上跑 AI Agent →

抢沙发

评论前必须登录!

立即登录   注册