# MimiClaw AI Agent - 开发指南 ## 项目概述 MimiClaw 是一个运行在 ESP32-S3 上的 AI 助手,使用纯 C 语言编写。用户通过 Telegram 或飞书与设备交互,设备连接 WiFi 后,将消息传递给 LLM(大语言模型)进行处理,并支持工具调用。 ## 项目结构 ``` mimiclaw/ ├── main/ # 主应用程序代码 │ ├── agent/ # 代理循环(核心逻辑) │ │ ├── agent_loop.c # 主代理循环,处理消息和工具调用 │ │ └── context_builder.c # 构建上下文(系统提示、记忆等) │ ├── llm/ # LLM 代理 │ │ ├── llm_proxy.c # 处理与 LLM API 的通信 │ │ └── llm_provider.c # 多提供商支持(Anthropic/OpenAI/硅基流动/火山引擎) │ ├── cli/ # 串口命令行界面 │ │ └── serial_cli.c # 处理运行时配置命令 │ ├── channels/ # 输入/输出通道 │ │ ├── telegram/ # Telegram 机器人集成(可选) │ │ └── feishu/ # 飞书机器人集成(可选) │ ├── tools/ # LLM 可调用的工具 │ ├── memory/ # 记忆和会话管理 │ ├── proxy/ # HTTP/SOCKS5 代理支持 │ ├── cron/ # 定时任务调度 │ ├── heartbeat/ # 心跳服务 │ ├── gateway/ # WebSocket 网关 │ ├── onboard/ # WiFi 配置门户(Captive Portal) │ ├── skills/ # 技能加载器 │ ├── bus/ # 消息总线(连接通道和代理循环) │ ├── mimi_config.h # 全局配置定义 │ ├── mimi_secrets.h # 构建时密钥(需用户创建) │ └── mimi_secrets.h.example # 密钥模板 ├── docs/ # 文档 ├── scripts/ # 构建和设置脚本 ├── CMakeLists.txt # 顶层 CMake 文件 └── sdkconfig.defaults # ESP-IDF 默认配置 ``` ## 核心系统 ### 1. 配置系统 - **构建时配置**:在 `main/mimi_secrets.h` 中定义(从 `.example` 复制) - **运行时配置**:通过串口 CLI 命令设置,存储在 NVS 中,优先级高于构建时配置 - **关键配置项**: - `MIMI_SECRET_WIFI_SSID/PASS`:WiFi 凭证 - `MIMI_SECRET_TG_TOKEN`:Telegram 机器人令牌 - `MIMI_SECRET_API_KEY`:LLM API 密钥 - `MIMI_SECRET_MODEL_PROVIDER`:模型提供商("anthropic" 或 "openai") - `MIMI_SECRET_MODEL`:模型名称 ### 2. LLM 集成 - **当前支持**:Anthropic (Claude) 和 OpenAI (GPT) - **提供商切换**:通过 `MIMI_SECRET_MODEL_PROVIDER` 或 CLI 命令 `set_model_provider ` - **代码路径**:`main/llm/llm_proxy.c` - **关键函数**: - `llm_proxy_init()`:初始化,从 NVS 加载配置 - `llm_chat_tools()`:发送聊天请求,支持工具调用 - `provider_is_openai()`:检查是否为 OpenAI 提供商 ### 3. 代理循环 - **代码路径**:`main/agent/agent_loop.c` - **工作流程**: 1. 接收消息 2. 构建上下文(系统提示、记忆、会话历史) 3. 调用 LLM(支持工具调用) 4. 处理工具调用结果 5. 返回响应 ### 4. 工具系统 - 工具在 `main/tools/` 中定义 - 工具注册在 `tool_registry.c` - 支持的工具:`web_search`、`get_current_time`、`cron_add/list/remove` ## 模块配置系统 MimiClaw 支持**编译时模块开关**,可以禁用不需要的模块以减少固件体积和内存占用。 ### 可配置模块 | 模块 | 配置项 | 默认 | 说明 | |------|--------|------|------| | Telegram | `CONFIG_MIMI_CHAN_TELEGRAM` | n | Telegram 机器人集成 | | 飞书 | `CONFIG_MIMI_CHAN_FEISHU` | y | 飞书机器人集成 | | WebSocket | `CONFIG_MIMI_WS_SERVER` | y | WebSocket 网关 | | Web Search | `CONFIG_MIMI_TOOL_WEB_SEARCH` | y | 网络搜索工具 | | GPIO | `CONFIG_MIMI_TOOL_GPIO` | n | GPIO 控制工具 | | WiFi 配置页 | `CONFIG_MIMI_WIFI_ONBOARD` | y | Captive Portal | | OTA | `CONFIG_MIMI_OTA` | n | OTA 升级(未实现) | ### 修改模块配置 编辑 `sdkconfig.defaults` 文件,添加或修改配置项: ``` CONFIG_MIMI_CHAN_TELEGRAM=n CONFIG_MIMI_CHAN_FEISHU=y CONFIG_MIMI_TOOL_WEB_SEARCH=y CONFIG_MIMI_TOOL_GPIO=n ``` 修改后必须重新编译: ```bash idf.py fullclean && idf.py build ``` ### 添加新模块的编译时开关 1. **创建 `main/Kconfig.projbuild`**(关键!没有它配置项不会被识别): ```kconfig config MIMI_MODULE_EXAMPLE bool "Example module" default n help Enable example module for MimiClaw. ``` 2. 在 `sdkconfig.defaults` 中添加配置项: ``` CONFIG_MIMI_MODULE_EXAMPLE=y ``` 3. 在 `main/CMakeLists.txt` 中条件编译: ```cmake if(CONFIG_MIMI_MODULE_EXAMPLE) list(APPEND srcs "modules/example/example.c") endif() ``` 4. 在模块头文件中添加 stub: ```c #ifdef CONFIG_MIMI_MODULE_EXAMPLE esp_err_t example_init(void); #else static inline esp_err_t example_init(void) { return ESP_OK; } #endif ``` ## 构建和烧录 ### 前提条件 - ESP-IDF v5.5+ 已安装 - ESP32-S3 开发板(16MB flash, 8MB PSRAM) ### 步骤 ```bash # 设置目标芯片 idf.py set-target esp32s3 # 配置(首次需要) cp main/mimi_secrets.h.example main/mimi_secrets.h # 编辑 mimi_secrets.h 填写 WiFi、LLM 密钥 # 编辑 sdkconfig.defaults 启用/禁用模块(可选) # 清理构建(修改配置后必须执行) idf.py fullclean && idf.py build # 烧录(替换 PORT 为实际串口) idf.py -p PORT flash monitor ``` ## 串口 CLI 命令 连接到 UART(COM)端口后,可用的配置命令: ``` wifi_set # 设置 WiFi 凭证 set_tg_token # 设置 Telegram 机器人令牌 set_api_key # 设置 LLM API 密钥 set_model_provider # 设置提供商(anthropic/openai) set_model # 设置模型名称 config_show # 显示当前配置(脱敏) config_reset # 重置为构建时配置 ``` ## 认知修正 | 日期 | 问题 | 根因 | 修复 | 详情 | |------|------|------|------|------| | 2026-04-04 | 模块开关失效(飞书命令消失、HTTP 配置页不可用) | 缺少 `Kconfig.projbuild`,ESP-IDF 不识别自定义配置项 | 创建 `main/Kconfig.projbuild` 声明所有模块开关 | [详细讨论](taolun.md#讨论kconfig-缺失导致模块开关失效) | --- ## 开发注意事项 ## 开发注意事项 1. **内存限制**:ESP32-S3 内存有限,使用 `MALLOC_CAP_SPIRAM` 分配大内存 2. **堆栈大小**:任务堆栈在 `mimi_config.h` 中定义 3. **日志**:使用 `ESP_LOG` 宏,标签在每个文件中定义 4. **错误处理**:使用 `esp_err_t` 返回码 5. **JSON 处理**:使用 cJSON 库 6. **模块开关**:新增模块或可选模块应在 `sdkconfig.defaults` 中添加配置项,并在头文件中添加 `#ifdef` stub ## 调试技巧 - 查看日志:`idf.py -p PORT monitor` - 内存状态:串口 CLI 命令 `heap_info` - 会话列表:`session_list` - 记忆内容:`memory_read` ## 扩展指南 ### 添加新的 LLM 提供商 1. 在 `llm_proxy.c` 中添加提供商检查函数 2. 添加新的 API URL 和主机名 3. 如需要,添加特定的请求头和消息格式转换 4. 更新 `mimi_config.h` 中的默认配置 ### 添加新工具 1. 在 `tools/` 目录创建新文件 2. 实现工具函数 3. 在 `tool_registry.c` 中注册工具 4. 定义工具的 JSON Schema ### 添加新通道 1. 在 `channels/` 目录创建新子目录 2. 实现通道初始化和消息收发 3. 在 `mimi.c` 中初始化新通道