看到了 zclaw 重写了一个 可以在esp32跑的agent mini版本 openclaw

w0x7ce
Posts: 1
Joined: Thu Mar 12, 2026 9:33 am

看到了 zclaw 重写了一个 可以在esp32跑的agent mini版本 openclaw

Postby w0x7ce » Thu Mar 12, 2026 9:39 am

为什么有了 zclaw 和 MimiClaw,我还折腾了个 ESPClaw

https://github.com/tianrking/espclaw

先说结论:**不是重复造轮子,是解决不同的问题**。

三个项目的定位

| 项目 | 目标 | 约束 |
|------|------|------|
| zclaw | 888 KiB 极限体积 | 功能必须为体积让路 |
| MimiClaw | 开箱即用的个人助手 | 需要 S3 + PSRAM |
| ESPClaw | 可扩展的 IoT Agent 平台 | 无 PSRAM 也要能跑 |

zclaw 是在做减法艺术,MimiClaw 是在做产品体验。

ESPClaw 在做加法——加工具、加 HAL、加渠道——但有个硬约束:**C3 上也能跑**。

技术上为什么要做

1. 无 PSRAM 运行 LLM Agent

这是 ESPClaw 的核心工程挑战。

C3 只有 400KB SRAM,去掉 ESP-IDF 栈、FreeRTOS、TLS 缓冲,留给你用的也就 100KB 左右。而 LLM 的 JSON 响应动辄几 KB。

怎么解?

**流式 JSON 解析**。不缓存完整响应,边收边解析,用完即弃。

```c
// 8KB 环形缓冲区
#define LLM_RESPONSE_BUF_SIZE 8192

// 逐字符解析状态机
typedef struct {
json_parse_state_t state;
char key[64];
char value[512];
// ...
} json_stream_parser_t;
```

代价是代码复杂度上升,但换来的是:**$2 的 C3 也能跑完整 Agent**。

### 2. HAL 硬件抽象层

如果你接过嵌入式项目,应该体会过硬件耦合的痛苦。

ESPClaw 把所有硬件操作抽象成了 HAL:

```c
// hal_pwm.h
esp_err_t hal_pwm_setup(uint8_t ch, int gpio, uint32_t freq, float duty);
esp_err_t hal_pwm_set_duty(uint8_t ch, float duty);

// hal_servo.h
esp_err_t hal_servo_attach(uint8_t id, int gpio);
esp_err_t hal_servo_write(uint8_t id, float angle);

// hal_adc.h
esp_err_t hal_adc_read_voltage(int ch, int *out_mv);

// hal_onewire.h
esp_err_t hal_onewire_read_temp(uint8_t bus, const uint8_t rom[8], float *temp);
```

工具层只调 HAL,不知道底层是 LEDC 还是别的。换芯片?改 HAL 实现。换驱动?改 HAL 实现。

这是正经项目该有的分层。

### 3. 40 个工具不是堆砌

工具多不代表有用,关键是有没有形成**组合能力**。

```
temp_read() → memory_set() → cron_schedule() → telegram_push()
```

这四个工具组合起来,就是一个完整的温度监控系统。用户不需要写代码,用自然语言描述需求,LLM 自己编排调用。

工具的定义是标准的:

```c
typedef struct {
const char *name; // 工具名
const char *description; // LLM 理解用的描述
const char *input_schema; // JSON Schema
bool (*execute)(const char *input_json, char *result, size_t sz);
} tool_def_t;
```

写一个 C 函数,实现 execute,注册到 tool_registry,LLM 就能调用。

### 4. 平台自适应

`platform.h` 一个头文件,解决 C3/C5/S3 的差异:

```c
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5
#define ESPCLAW_HAS_PSRAM 0
#define LLM_RESPONSE_BUF_SIZE 8192
#define MAX_HISTORY_TURNS 8
#else
#define ESPCLAW_HAS_PSRAM 1
#define LLM_RESPONSE_BUF_SIZE 32768
#define MAX_HISTORY_TURNS 24
#endif
```

同一份代码,编译到不同芯片,行为自动适配。

5. 9 个通知渠道的工程意义

不是炫技,是**实际需求**。

国内企业用钉钉、飞书、企业微信。海外用 Discord、Slack。IoT 场景用 MQTT。

ESPClaw 把 Channel 抽象成 vtable:

```c
typedef struct {
const char *name;
esp_err_t (*start)(message_bus_t *bus);
bool (*is_available)(void);
} channel_ops_t;
```

所有渠道通过 Kconfig 按需编译,不用的渠道零开销。

实际能干什么

说几个实际场景:

**1. 边缘数据采集**

ADC 采样 → LLM 生成报告 → 定时推送到钉钉群。

不需要云服务器,不需要写后端,一块 C3 搞定。

**2. 自然语言硬件控制**

> 「把 2 号舵机转到 45 度」

LLM 解析意图 → 调用 `servo_write` → 返回确认。

**3. 完全离线的私有 Agent**

接 Ollama 本地部署,MQTT 收指令,GPIO 执行动作。数据全程不出局域网。

**4. 你想做的任何东西**

I2C、SPI、继电器、传感器——写个 HAL,注册个工具,LLM 就能控制。

## 和 zclaw/MimiClaw 的关系

**不是竞品,是不同赛道。**

- 想 888 KiB 极限?用 zclaw
- 想开箱即用?用 MimiClaw
- 想折腾硬件、做 IoT 项目?用 ESPClaw

它们甚至可以互相借鉴代码——都是 Pure C + ESP-IDF,架构相似。

当前状态

| 步骤 | 状态 | 内容 |
|------|------|------|
| Step 1-4 | ✅ | 最小固件 → WiFi → 串口 → LLM 对话 |
| Step 5-6 | ✅ | ReAct Agent + 工具系统 + 持久记忆 |
| Step 7 | ✅ | 9 通知渠道 |
| Step 8 | ✅ | Cron 定时 + 速率限制 |
| Step 8.5 | ✅ | PWM/ADC/Servo/DS18B20 HAL |
| Step 9 | 🔄 | OTA + 启动保护 + NVS 加密 |

代码在 GitHub,MIT 协议,欢迎挑刺。

如果你想试试
买一块esp32s3 下载项目 然后命令行执行
```bash
idf.py build flash monitor
```

串口敲 `/help` 看命令,`/tools` 看已注册工具。

有问题直接提 issue,代码有问题就骂,我改。

Who is online

Users browsing this forum: No registered users and 1 guest