用 AI 焊了个桌面红绿灯:踩坑3天,AI再强也不能当甩手掌柜!

全程AI写代码、AI调bug,用ESP32-C3搓实体硬件红绿灯的血泪实录。某国产、Codex/OpenCode、GLM轮番上阵,本以为是躺着收工,结果踩了一肚子坑。

一、起因:给AI整个「在岗状态牌」

平时用Hermes Agent写代码,我习惯把任务一丢就切去干别的。但有个巨难受的痛点:你根本不知道它这会儿在干嘛
是在吭哧干活?是卡壳死循环了?还是卡在审批节点等我拍板?总不能每隔两分钟切回终端看一眼吧——那我用AI图啥。

桌面指示灯是最直接的解法:瞟一眼颜色就懂状态,完全不打断思路。

  • 🟢 绿灯:空闲摸鱼中,随便打扰
  • 🟡 黄灯:正在跑任务,稍等会儿
  • 🔴 红灯:出状况了,急需人工介入

光有桌面软件挂件不够有那味儿,要玩就玩实体的——放个真·红绿灯在桌上,物理存在感拉满,沉浸式摸鱼(不是)。

于是掏出15块钱的ESP32-C3 SuperMini,翻出三颗LED灯珠,立下flag:
全程让AI写代码、查bug、调硬件,我一行代码都不手写,看看能不能从零搓出成品。

AI拍胸脯说简单。然后我就踩了整整三天的坑。
在这里插入图片描述
在这里插入图片描述

二、整条链路长啥样

思路本身真不复杂,一句话就能说清:Agent状态变了 → 告诉桌面程序 → 桌面程序发指令给硬件灯。

完整架构长这样:

┌─────────────┐  Hook写状态文件  ┌──────────────────┐
│  Hermes CLI │ ──────────────→ │ .hermes-light-   │
│  (Agent)    │  工具调用/审批前 │ state.json       │
└─────────────┘                 └────────┬─────────┘
                                         │ 每秒轮询读取
                                 ┌───────▼─────────┐
                                 │ 桌面指示器EXE    │
                                 │ (Python tkinter)│
                                 └───────┬─────────┘
                                         │ HTTP请求控灯
                                 ┌───────▼─────────┐
                                 │ ESP32-C3硬件灯  │
                                 │ GPIO5/6/7接LED  │
                                 └─────────────────┘

逻辑简单到离谱,AI也是这么说的。
然后坑就一个接一个炸了。


三、三位AI选手,各有各的翻车姿势

前后换了三套模型来搞这个项目,每个都有自己的绝活,也各有各的死穴。

AI模型定位实战战绩
某国产Hermes默认主力写得快改得勤,越改bug越多
OpenCode / Codex备选方案方案写得天花乱坠,一用就配额不够
GLM备胎兜底闷声把所有坑都填上了

3.1 某国产:勤奋型选手,越改越乱

作为我日常用的主力模型,写普通代码稳得很。但这个项目里,它完美演绎了什么叫「每轮都在改,每次都不对」。

经典翻车循环:

  • 第一轮:咔咔写出tkinter桌面指示器,能跑,但一带emoji就GBK编码崩溃
  • 第二轮:说换WinForms重写,结果生成了一堆跑不起来的GDI+错误代码
  • 第三轮:切回tkinter修编码,修好了emoji,又把串口通信搞崩了
  • 第四轮:说打包成exe就没事了,结果编译命令版本不兼容,直接生成失败

它最大的问题是会话失忆:今天修好的bug,明天新开个会话就全忘了。同一个config.yaml文件,不同会话的AI各改各的,互相覆盖,越改越回退。
属于态度满分,效果零分,忙忙碌碌瞎折腾。

3.2 OpenCode/Codex:PPT王者,实战躺平

这货是真的会写方案。
一份opencode-红绿灯方案.md写得漂漂亮亮,架构图、接线表、API定义、异常处理一应俱全,看完你觉得这项目明天就能上线。

然后一到实际写代码跑调试:

配额不足。

属于「理论满分,但是我用不起」的典型,好看但没用。

四、四个经典踩坑名场面,每个都差点送走我

坑1:GBK编码地狱,卡了整整3天

现象:Hook触发了但红灯死活不亮,翻日志看到一行刺眼的报错:'gbk' codec can't encode character '\U0001f7e2'

谁能想到,灯不亮不是硬件坏了,是emoji搞的鬼?

完整的离谱连锁反应:

  1. Windows下Hermes用GBK编码捕获子进程输出
  2. 我给Agent人设里加了🟢🟡🔴这些emoji
  3. Hook调用的Python脚本收到带emoji的输入,直接被GBK编码干崩溃
  4. 脚本崩了,状态文件就没更新,灯自然不亮

前面AI给的修复方案,全折在Windows的奇葩环境上:

  • PYTHONIOENCODING=utf-8前缀:Windows cmd不认POSIX语法,直接把环境变量当文件名
  • set命令设环境变量:Hermes的subprocess不识别cmd语法
  • -X utf8参数:只对Python内部生效,父进程读输出还是用GBK

最后解法:去掉所有shell层面的环境变量前缀,直接用python -X utf8执行命令,同时补上hooks_auto_accept: true配置,从根上绕开了编码陷阱。
就这么一行改动,卡了我三天。

坑2:配置文件灵异回退,改完就炸

现象:明明刚把config.yaml改好,红灯也亮了,关了终端重开一次,又坏了。
翻日志时间线能给你气笑:

21:20:15  会话A  写入 set PYTHONIOENCODING=utf-8 &&   ← 刚修好的版本
21:29:04  会话B  写入 PYTHONIOENCODING=utf-8          ← 又变回旧版了
21:36:56  会话C  写入 set PYTHONIOENCODING=utf-8 &&   ← 又修一次
21:45:39  会话D  写入 python -X utf8                   ← 又换新方案

根因:两个问题叠在一起了。
一是关终端窗口时,桌面指示器程序不会跟着退出,后台留着孤儿进程抢硬件;二是每个会话的AI都只知道自己改了配置,不知道别的会话也在改同一份文件,互相覆盖。

说穿了就是:AI没有全局视角。它不知道「另一个自己」正在拆台。

坑3:ESP32串口玄学无输出,卡了一下午

现象:固件烧录成功,板子也亮了,串口监视器一片空白。AI一口咬定是setup()执行前就崩溃了。

常规排查全试了:

  • 换USB数据线 → 没用
  • 全擦除Flash重烧 → 没用
  • 改各种编译参数 → 没用
  • 差点以为板子烧了,都要下单买新的了

最后真相离谱到离谱:

// ❌ AI写的代码,说HWCDC模式会自动初始化串口
void setup() {
  Serial.println("启动成功");
}

// ✅ 实际必须手动初始化
void setup() {
  Serial.begin(115200);
  delay(2000); // 等Windows识别COM口
  Serial.println("启动成功");
}

ESP32-C3开了「USB CDC On Boot」,也不等于可以省掉Serial.begin()
就这么一行代码,AI猜了一下午供电、Flash、硬件损坏,谁都没往「串口没初始化」上想。

坑4:孤儿进程抢硬件,灵异冲突

关了终端窗口,Hermes主程序被杀了,但桌面指示器EXE还在后台活着。
再开一次,就有两个程序同时往ESP32发指令,你推我搡,谁都控不住灯。

$ tasklist | findstr hermes
hermes.exe         8604  正常运行
HermesLight.exe   32040  ← 上次关窗残留的孤儿进程
HermesLight.exe   29432  ← 刚启动的新进程

这种问题AI天生不会主动查——它默认「程序关了就是全死了」,根本想不到后台还能苟着一个旧进程。
最后还是我手动翻任务列表发现的。


五、折腾三天的真心话:AI再强,你也不能撒手不管

1. AI是搬砖的,不是掌舵的

AI5分钟就能写出一个能跑的桌面指示器,但它看不见这些坑:

  • 它不知道Windows祖传GBK编码是多少人的噩梦
  • 它不知道ESP32的CDC模式有这么反直觉的陷阱
  • 它不知道关窗口不会杀掉子进程
  • 它不知道另一个会话的自己正在偷偷改配置

所有这些「工程经验坑」,都得人来发现、来定位、来指着方向让它查。
它可以替你写代码,但替不了你判断方向。

2. 文档才是跨会话的唯一桥梁

踩完这些坑我总结出了一套固定流程:

1. 人发现问题 → 写MD文档记清现象、试过的方案、报错日志
2. AI读文档 → 诊断根因 → 给出修复代码
3. 人去验证 → 失败了就把新现象补进文档
4. AI再读更新后的文档 → 继续迭代

别信什么AI记忆、上下文继承。
一份写清楚的MD文档,比任何会话记忆都靠谱。不写文档,每个新会话的AI都会从零开始踩一遍旧坑。


六、项目当前状态

折腾完所有坑,终于全链路跑通了:

组件状态
ESP32-C3硬件固件✅ WiFi热点 + HTTP接口 + GPIO控灯
桌面指示器程序✅ tkinter实现 + 灯光呼吸动画
Hermes状态联动✅ 审批/澄清场景自动亮红灯

灯往桌上一放,Agent跑任务时黄灯慢悠悠呼吸,需要人工介入就亮红灯,体验是真的舒服。
就是这三天踩的坑,比写代码本身还累。


七、最后几句掏心窝子的

用AI搞硬件开发,远不是「丢需求过去等结果」这么简单。
想少踩坑,记住三句话:

  1. 别死磕一个模型。这个搞不定就换另一个,不同模型踩坑的思路不一样,这个卡壳的,换个说不定一眼就看穿了。
  2. 一定要写文档留痕。MD文件是不同会话之间唯一靠谱的交接方式,不然AI次次失忆,坑永远踩不完。
  3. AI永远是副驾,方向盘得攥在自己手里。它不会主动发现「后台有孤儿进程」「配置被别的会话改了」这种全局问题,这些都得人来盯。

AI很强,但真的不能放手不管。
毕竟代码跑不跑、硬件亮不亮,背锅的最后还是你自己。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐