FlipperClaw项目:基于ESP32-S3与Flipper Zero的离线AI智能体硬件实践
1. 项目概述:当Flipper Zero遇上AI大脑
如果你和我一样,是个喜欢折腾硬件的极客,手边大概率躺着一台Flipper Zero。这玩意儿是个万能钥匙,能玩转NFC、Sub-GHz、红外,但它的交互界面——那块小小的128x64 OLED屏幕和几个物理按键——总让人觉得潜力还没完全释放。我们用它来“复制”门禁卡、遥控器,但有没有想过,如果它能“理解”自己在做什么,甚至能主动帮你处理一些任务,会是什么样子?
这就是FlipperClaw项目吸引我的地方。它本质上是一个运行在ESP32-S3微控制器上的开源AI智能体,而Flipper Zero则扮演了它的物理交互界面和“手”的角色。想象一下:你对着Flipper Zero的屏幕输入一个问题,比如“刚才读到的NFC标签是什么类型的?”,问题通过串口发给ESP32,ESP32调用云端的大语言模型(LLM)进行推理,模型可能会说:“我需要查看原始数据才能判断,请使用flipper_nfc_read工具。” 然后,这个指令被发回Flipper Zero,Flipper Zero执行读取操作,再把数据传回去给AI分析,最后把人类可读的结果——“这是一个MIFARE Classic 1K标签,UID是…”——显示在屏幕上。整个过程是流式的,你能看到AI“思考”的每一个字在屏幕上蹦出来。
这个项目的核心价值在于,它将一个强大的、具备工具调用能力的AI智能体,塞进了一个成本不到200美元、完全离线的硬件组合里。它不再是手机或电脑上的一个聊天窗口,而是一个拥有实体、能直接与物理世界交互(通过Flipper Zero的射频和红外模块)的AI伙伴。无论是自动化处理日常的NFC打卡记录,还是定时检查并执行你写在待办清单里的Sub-GHz信号重放任务,FlipperClaw都提供了一个极具创意的实现范式。
2. 核心架构与设计哲学
2.1 为什么是ESP32-S3 + Flipper Zero的组合?
这个选型背后有非常务实的工程考量。Flipper Zero本身基于STM32,性能有限且系统封闭,直接在其上运行复杂的AI代理循环和网络通信几乎不可能。而ESP32-S3则是一个完美的协处理器:它拥有更强大的双核处理能力、充足的PSRAM(用于处理网络数据流和JSON解析)、成熟的Wi-Fi和TLS协议栈,以及丰富的存储空间(SPIFFS文件系统)。
分工明确是这套架构的精髓:
- Flipper Zero (C11, Furi SDK):专职于人机交互(显示、按键输入)和硬件驱动(NFC/Sub-GHz/IR的底层操作)。它运行一个轻量的
.fap应用,只负责协议编解码和硬件指令执行,逻辑简单稳定。 - ESP32-S3 (C++17, ESP-IDF v5.5):担任“大脑”。负责管理Wi-Fi连接、与LLM API进行HTTPS/SSE通信、运行ReAct代理循环、解析流式响应、调度定时任务,并通过串口与Flipper Zero通信。
这种解耦带来了巨大的灵活性。理论上,只要遵循定义好的串口协议,你可以把Flipper Zero替换成任何其他显示和输入设备,甚至是一个简单的串口终端。而ESP32端的AI逻辑则可以独立升级和优化。
2.2 ReAct代理循环:让AI学会“使用工具”
FlipperClaw的核心智能来源于ReAct(Reasoning + Acting)框架。这不是一个简单的“问答机”,而是一个能进行多步推理和执行的智能体。
让我用一个实际场景来解释其工作流程:
- 用户输入:“帮我查一下北京时间,然后如果时间是晚上8点后,就打开客厅的空调。”(假设你已录制了空调的IR信号)。
- 推理(Reason):AI首先分析请求,它意识到需要两个动作:获取当前时间,以及一个条件判断后的IR发送。
- 行动(Act):AI调用
get_current_time工具,从网络时间API获取UTC时间并转换为北京时间。 - 观察(Observe):ESP32收到工具调用的结果,比如“2023-10-27 20:30 UTC+8”。
- 再推理与行动:AI判断时间晚于20:00,于是决定调用
flipper_ir_send工具,并附上对应的红外协议编码。 - 最终响应:Flipper Zero执行红外发射,AI将整个过程总结并流式输出到屏幕:“已获取当前时间为晚上8点30分。条件满足,已通过红外信号尝试打开客厅空调。”
这个循环最多会进行5次迭代,以防止AI陷入死循环。最关键的是,整个推理过程是流式传输的。你不仅能看到最终答案,还能在过程中看到AI的思考链,比如“我需要先获取时间…现在时间是…接下来需要判断…”,这种透明性对于调试和建立信任感至关重要。
注意:每次工具调用都意味着一次网络请求(时间查询、搜索)或一次硬件操作,这会增加整体响应时间。在设计提示词或给AI下指令时,尽量保持指令清晰、步骤精简,可以有效提升体验。
3. 硬件搭建与固件烧录实战
3.1 物料清单与接线图
你需要准备以下硬件,总成本可以控制在200美元以内:
- Flipper Zero:一台,任何固件版本均可。
- ESP32-S3开发板:推荐选择带有外部PSRAM的型号,如Freenove ESP32-S3 Lite或乐鑫官方的ESP32-S3-DevKitC-1。4MB以上的Flash是必须的,用于存放固件和文件系统。
- 连接线:4根母对母杜邦线。
接线非常简单,只需要连接4根线,实现UART串口通信和供电:
Flipper Zero GPIO Pin <--> ESP32-S3 Pin ------------------------------------------------- GND <--> GND 5V (或 3V3) <--> 5V (或 3V3) // 注意电平匹配,建议都接3.3V RX (Pin 13) <--> TX (GPIO17) TX (Pin 14) <--> RX (GPIO18)重要提示:务必确认电压匹配。Flipper Zero的5V引脚输出是5V,而大多数ESP32-S3开发板的IO口和供电电压是3.3V。虽然很多ESP32板子有宽电压容忍,但最稳妥的方案是:将Flipper Zero的3.3V引脚与ESP32-S3的3.3V引脚相连,同时GND相连。这样确保逻辑电平一致,避免损坏芯片。
3.2 编译与烧录ESP32固件
固件编译环境主要依赖ESP-IDF。以下是基于Linux/macOS的详细步骤,Windows用户建议使用ESP-IDF的PowerShell环境。
# 1. 克隆项目仓库 git clone https://github.com/yasher3413/flipperclaw.git cd flipperclaw # 2. 准备密钥配置文件 cp esp32/main/fc_secrets.h.example esp32/main/fc_secrets.h接下来,用文本编辑器打开esp32/main/fc_secrets.h,这是整个项目的核心配置文件。
// fc_secrets.h 关键配置项详解 #define FC_SECRET_WIFI_SSID "Your_WiFi_SSID" // 你的2.4GHz WiFi名称,不支持5GHz #define FC_SECRET_WIFI_PASS "Your_WiFi_Password" #define FC_SECRET_API_KEY "sk-ant-api03-..." // 你的Claude或OpenAI API密钥 #define FC_SECRET_MODEL_PROVIDER "anthropic" // 初始提供商,可选 "anthropic" 或 "openai" // 以下搜索API密钥为非必须,但强烈建议配置至少一个,以启用网络搜索功能 #define FC_SECRET_TAVILY_KEY "" // Tavily搜索API密钥(有免费额度) #define FC_SECRET_BRAVE_KEY "" // Brave搜索API密钥(替代方案)配置完成后,进入ESP32目录进行编译和烧录。项目提供了便捷的脚本。
# 3. 进入ESP32目录并编译 cd esp32 ./scripts/build.sh # 该脚本会初始化IDF环境(如果首次运行)并执行idf.py build # 4. 烧录固件到ESP32 # 首先,通过USB连接ESP32开发板,并使用 ls /dev/tty* 或 dmesg | grep tty 查看端口 # 通常是 /dev/ttyUSB0 或 /dev/ttyACM0 ./scripts/flash.sh /dev/ttyUSB0烧录脚本会自动处理擦除、烧录固件和文件系统分区等操作。看到终端提示“Hard resetting via RTS pin...”且无报错,即表示烧录成功。
3.3 编译与部署Flipper Zero应用
Flipper端应用使用uFBT工具链编译,这是一个专为Flipper Zero应用开发定制的构建系统。
# 1. 返回项目根目录,进入flipper应用目录 cd ../flipper # 2. 使用uFBT编译 ufbt # 如果首次使用,ufbt会自动下载所需的SDK和工具链,这可能需要一些时间。 # 3. 部署应用到Flipper Zero # 编译成功后,在 `dist` 文件夹下会生成 `flipperclaw.fap` 文件。 # 将Flipper Zero通过USB连接到电脑,并将其挂载为U盘(进入“USB Mass Storage”模式)。 # 将 `flipperclaw.fap` 文件复制到SD卡的以下路径: # [SD卡根目录]/apps/GPIO/flipperclaw.fap复制完成后,安全弹出U盘,在Flipper Zero的主菜单中进入GPIO应用分类,你应该就能看到FlipperClaw的应用图标了。
4. 首次配置与核心功能深度解析
4.1 上电、联网与串口CLI配置
给硬件上电后,首先打开Flipper Zero上的FlipperClaw应用。此时,ESP32可能正在尝试连接你在fc_secrets.h中预设的Wi-Fi。你可以通过串口监视器更详细地了解启动过程和进行运行时配置。
使用screen或picocom等工具连接ESP32的串口:
screen /dev/ttyUSB0 115200连接成功后,你会看到ESP32的启动日志,以及一个简洁的fc>命令行提示符。这是项目的串口CLI,所有关键配置都可以在这里动态修改,并会保存到ESP32的NVS(非易失性存储)中,掉电不丢失。
下面是一些最常用的命令,我强烈建议你逐一尝试:
| 命令 | 示例 | 说明与技巧 |
|---|---|---|
wifi_set <ssid> <pass> | fc> wifi_set MyHomeWiFi MyPassword | 设置新Wi-Fi。注意:ESP32通常只支持2.4GHz网络。 |
set_api_key <key> | fc> set_api_key sk-ant-api03-xxx | 切换LLM API密钥。如果你有OpenAI和Anthropic的密钥,可以随时切换。 |
set_model_provider <anthropic|openai> | fc> set_model_provider openai | 切换AI服务提供商。这会影响可用的模型。 |
set_model <name> | fc> set_model gpt-4o-mini | 设置具体模型。例如Claude的claude-3-haiku-20240307或OpenAI的gpt-4o-mini。 |
set_tavily_key <key> | fc> set_tavily_key tvy-xxx | 配置Tavily搜索密钥,启用web_search工具。 |
config_show | fc> config_show | 显示当前所有配置,包括Wi-Fi状态、API提供商、模型名等,用于排查问题。 |
status | fc> status | 查看系统状态:Wi-Fi连接信息、剩余内存、UART通信统计。内存不足可能导致异常。 |
restart | fc> restart | 软重启ESP32。在更改某些配置(如Wi-Fi)后可能需要重启才能完全生效。 |
实操心得:
config_show和status是你最好的调试伙伴。如果AI没有响应,首先检查config_show确认API密钥和提供商是否正确,再用status查看Wi-Fi是否已连接(Connected)以及剩余堆内存(Heap free)是否充足(建议大于100KB)。
4.2 灵魂文件与记忆系统:打造专属AI助手
FlipperClaw的个性化能力源于其文件系统的设计。在ESP32的SPIFFS分区中,有几个关键的Markdown文件,它们共同构成了AI的“记忆”和“人格”。
1. SOUL.md:定义AI的性格这个文件是AI的“系统提示词”。你可以像修改普通文本文件一样修改它,定义AI的角色、说话风格和核心规则。例如,你可以把它变成一个“极客助手”或“生活管家”。下次启动时,AI就会以这个新人格与你对话。
2. USER.md:让AI认识你在这里描述你自己:你的职业、常用设备、家庭环境、偏好等。例如:“我是一个嵌入式开发工程师,家里有小米空调和索尼电视,Flipper Zero里存有它们的红外码库。” AI在后续对话中会引用这些信息,提供更贴切的帮助。
3. MEMORY.md:AI的长期记忆当AI调用remember工具时,内容就会被追加到这里。比如,你告诉它“我的车钥匙NFC标签的UID是XX:XX:XX:XX”,它调用remember工具后,这个事实就永久存储了。未来你问“我的车钥匙是什么?”,它可以从记忆中检索。
4. HEARTBEAT.md:自动化任务队列这是我最喜欢的功能之一。你可以在/spiffs/HEARTBEAT.md里写一个Markdown任务列表:
- [ ] 每天上午9点,检查天气并告诉我是否需要带伞。 - [ ] 每周一晚上8点,通过红外打开客厅的空气净化器。 - [ ] 读取今天新遇到的NFC标签并分析其类型。AI会每30分钟自动检查这个文件,执行未完成([ ])的任务,并在完成后标记为[x]。这实现了真正的离线、低功耗自动化。
5. YYYY-MM-DD.md:每日笔记每次会话的对话记录都会被自动追加到当天的Markdown文件中。这形成了一个完整的、可搜索的日志,方便你回顾AI做了什么,或者提取重要信息。
如何管理这些文件?这些文件位于ESP32的SPIFFS文件系统中。最直接的管理方式是通过串口CLI配合简单的文件操作工具(如echo、cat),或者使用PlatformIO的ESP-IDF插件上传/下载文件。项目文档中通常也会提供管理脚本。
4.3 工具生态:连接数字与物理世界
FlipperClaw的工具集是其从“聊天机器人”跃升为“行动助手”的关键。我们来深入看看几个与硬件交互的核心工具:
flipper_nfc_read:让AI“看见”NFC当你发出“扫描一下我面前的NFC标签”的指令后:
- AI调用该工具,并通过串口发送请求。
- Flipper Zero收到指令,激活NFC阅读器。
- 将读取到的原始字节数据(如UID、ATQA、SAK等)传回AI。
- AI可以分析这些字节:“这是一个MIFARE Ultralight标签,UID是...,可能用于门禁系统。” 这为资产盘点、安全审计提供了智能化的前端。
flipper_subghz_replay:重放无线信号此工具能读取Flipper Zero SD卡上已有的.sub文件并重放。AI的智能体现在:
- 自动解析:工具内部会从
.sub文件头中提取频率和预设参数,无需用户手动指定。 - 条件触发:你可以结合
HEARTBEAT.md和cron功能,实现“如果今天是工作日且时间在下午6点,则自动重放车库门开启信号”。
flipper_ir_send:控制红外设备支持两种模式:
- 解析模式:发送
{“protocol”: “SAMSUNG”, “address”: 0x707, “command”: 0x2”}这样的结构化数据。这需要你事先知道设备的红外编码协议。 - 原始模式:发送一串代表高低电平持续时间的原始微秒数组。这可以直接使用Flipper Zero从遥控器上“学习”到的原始信号数据,通用性更强。
避坑指南:红外和Sub-GHz重放的成功率高度依赖现场环境。红外需要对准设备且距离不能太远;Sub-GHz则可能受建筑物遮挡和无线电干扰。如果AI报告工具执行成功但设备没反应,首先排查物理环境因素,其次检查Flipper Zero是否确实存在对应的信号文件。
5. 高级应用与自动化场景
5.1 利用Cron调度器实现离线自动化
Cron调度器是FlipperClaw的“后台任务管理器”。它独立于主对话循环,即使你没有主动与它聊天,定时任务也会在后台默默执行。
通过cron_add工具添加任务,其语法非常直观:
fc> 请添加一个定时任务:每周一到周五上午8点,对我说“早安,该起床了”。AI会理解并调用cron_add工具,创建一个Cron记录。所有任务都持久化在/spiffs/cron.json中。你可以用cron_list查看所有计划任务,用cron_remove删除不再需要的任务。
一个复杂的自动化场景设想:
- 任务:确保我每天下班回家时客厅灯是亮的(假设灯可通过红外遥控)。
- 实现:
- 在
HEARTBEAT.md中写:- [ ] 如果当前时间在下午6点到7点之间,且今天是工作日,则打开客厅灯。 - AI的心跳检查触发此任务。
- AI调用
get_current_time工具确认时间。 - 时间符合条件,AI调用
flipper_ir_send工具发送开灯的红外信号。 - 任务标记为完成
- [x]。
- 在
- 升级:你甚至可以结合
web_search,让AI在决定是否开灯前先查询当地的日落时间,实现更智能的照明控制。
5.2 构建个性化工作流
将上述功能组合,你能创造出高度个性化的智能工作流。
场景:智能门禁日志
- 准备:在
USER.md中说明:“我家大门使用MIFARE Classic卡,其UID是AA:BB:CC:DD。” - 触发:将FlipperClaw放在门口,并让它保持运行。每次有人刷卡时,你手动(或未来通过传感器自动)触发一次NFC读取。
- 执行:AI读取到UID后,与记忆中的合法UID对比。如果是家人卡,则在当日笔记中记录“
[时间] 家人回家”;如果是未知UID,则记录“[时间] 未知标签告警”,并可以通过网络搜索(如果配置了)向你发送通知(这需要额外的通知服务集成)。 - 回顾:每天结束,你可以问AI:“今天大门有哪些刷卡记录?” AI会汇总
YYYY-MM-DD.md中的相关信息告诉你。
场景:实验室设备控制助手
- 准备:用Flipper Zero学习所有实验仪器(示波器、电源、信号发生器)的红外遥控信号,并命名保存。
- 编程:在
SOUL.md中将AI角色定义为“实验室助理”,熟悉各种仪器操作规范。 - 交互:你可以用自然语言指挥:“准备进行频率响应测试,请将信号发生器设置为1kHz正弦波,输出幅度为1Vpp。” AI会解析指令,依次调用多个
flipper_ir_send工具来设置仪器。
6. 故障排除与性能优化
6.1 常见问题速查表
在部署和使用过程中,你可能会遇到以下典型问题。这里提供我的排查思路:
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Flipper屏幕显示“ESP32 Disconnected” | 1. 物理连接松动 2. 波特率不匹配 3. ESP32未启动或死机 | 1. 检查4根连接线是否插稳。 2. 确认双方波特率均为115200。 3. 通过串口监视器查看ESP32是否有日志输出。 |
| AI无响应,或提示API错误 | 1. Wi-Fi未连接 2. API密钥错误或过期 3. 模型提供商设置错误 4. 网络问题(如API服务被墙) | 1. 串口输入status查看Wi-Fi状态。2. 输入 config_show核对API密钥和提供商。3. 尝试在串口CLI中 ping一个网站测试网络连通性。重要:确保你的网络环境能稳定访问所选的AI服务API。 |
| 工具调用失败(如NFC读不到) | 1. 硬件操作条件不满足(如标签不在感应区) 2. Flipper端应用bug 3. 协议解析错误 | 1. 先单独测试Flipper Zero本身的NFC功能是否正常。 2. 查看串口日志,看错误信息是来自ESP32还是Flipper。 3. 确保使用的 .sub或IR文件存在于Flipper的SD卡正确路径。 |
| 系统运行一段时间后卡死或重启 | 1. 内存泄漏 2. 网络连接不稳定导致看门狗超时 3. 电源供电不足 | 1. 定期用status命令监控Heap free值,看是否持续下降。2. 检查Wi-Fi信号强度。 3. 尝试使用外部电源为ESP32供电,而非从Flipper取电。 |
| 流式响应中断或显示乱码 | 1. UART通信受到干扰 2. 缓冲区溢出 3. 固件版本不匹配 | 1. 检查接线,远离强干扰源。 2. 尝试降低LLM的响应速度(如果模型支持)或简化查询。 3. 确保ESP32固件和Flipper .fap应用来自同一版本的项目代码。 |
6.2 性能调优与稳定性建议
电源管理:这是稳定性的基石。ESP32-S3在Wi-Fi活跃和CPU全速运行时功耗不低。强烈建议为ESP32开发板提供独立的、可靠的5V/1A以上电源适配器供电,避免与Flipper Zero共用其内部电池,以防电压跌落导致意外重启。
内存优化:ESP32的堆内存是宝贵资源。在
SOUL.md和USER.md中,避免写入过于冗长的文本。过于复杂的系统提示词会消耗大量token和内存。定期通过串口CLI清理不必要的会话历史(如果项目提供相关命令)或重启设备,可以释放内存。网络可靠性:
- 将ESP32放置在Wi-Fi信号良好的位置。
- 在
fc_secrets.h中考虑配置备用Wi-Fi(如果项目后续支持)。 - 对于关键定时任务(如
HEARTBEAT.md),AI的重试逻辑很重要。可以修改SOUL.md,要求AI在工具调用失败后等待几秒再重试,或记录错误到每日笔记。
提示词工程:为了获得更快、更精准的响应,可以在
SOUL.md中为AI设定规则,例如:“在调用硬件工具前,先简要确认操作对象和参数”、“对于简单的信息查询,尽量不使用网络搜索工具”。这能减少不必要的工具调用轮次,提升效率。
这个项目最令我兴奋的一点是,它打开了一扇门,让我们可以用极低的成本和具身化的方式,去实验AI智能体与物理世界的交互。从简单的定时提醒到复杂的条件化硬件控制,所有的逻辑都封装在这个巴掌大的设备里,不依赖持续的云端语音服务或庞大的手机App。它的每一个功能模块——文件记忆、任务队列、Cron调度、工具调用——都像乐高积木,你可以根据自己的需求重新组合和扩展。
