上周买了一个带触发屏的开发板,想探索一下之前的一个想法:AI 时代能不能加速传统行业的一些软件开发的范式?作为一个写过物联网书籍的“资深”硬件专家, 我很快从淘宝购买了一个带屏幕的 “ESP32” 开发板。顺着淘宝卖家给的链接,从官网下载了资料,然后成功地在 Arduino IDE 上连接上硬件, 跑了一下官方的 Hello World。
果然,如我过去开发硬件的经验一样快失败了,资源和板子对上了,但是示例代码和板子压根就对不上。
周末,我便想着让 Agent 能不能自动地帮我跑一下 demo,修正所有的 demo 代码。
于是初始化了个代码项目:https://github.com/phodal/vibe-hardware-coding 。 然后,给了他第一个提示词,然后就去哄娃睡觉了:
我买了个 Arduino 开发板:https://docs.waveshare.net/ESP32-S3-Touch-AMOLED-1.75C/ ,帮我结合他们的 SKILL,
帮我搭建完整的自动化开发环境吧:[arduino/arduino-cli](https://github.com/arduino/arduino-cli)
然后创建 skill 等,确保应用能在硬件上跑起来(已经在 Arduino IDE 可以连接上串口了)
## 验证
最后你可以使用 claude -p 来测试这个 SKILL, 是不是能把代码正确烧录进去
AI 花了约 40 分钟,就把我的活干完了:
arduino-cli 已安装:1.5.1esp32:esp32@3.3.5,匹配 Waveshare Arduino-v3.3.5 示例包甚至还解决了一个 Arduino CLI 的问题
一个关键发现:arduino-cli monitor 在这个 USB Serial/JTAG 口上会打开但抓不到数据,所以脚本默认改成 macOS raw serial:stty + cat。
如需强制回到 Arduino monitor,可设置 ARDUINO_CLI_MONITOR=1。
虽然,AI 代码跑起来,但是 AI 并没有验证是不是真的跑起来,他只能通过日志,而不是真的观察物理世界。于是抬头看到了我的显示器上的罗技摄像头, 来了第二个简单的提示词,就开始看《凡人修仙传》:
感觉写的 demo 太粗糙了,还花屏了,有没有可能调用我的摄像头,来识别上面的文字 ,以确保最后能在屏幕上正确显示???
很快,AI 开始去迭代了。桌上的圆形 AMOLED 屏幕亮起来时,我没有马上放心。
屏幕上有两行字:OK 和 Qoder。摄像头预览里能看到板子,亮度也够,裁剪区域大致对了。构建通过,固件上传成功,屏幕也真的显示了东西。按传统硬件
demo 的标准,这已经可以说“跑起来了”。
但 OCR 给出的结果很不稳定:.logs/camera-ocr-20260613-212736.txt 里是 { OK <n,后来 又把 Qoder 读成了 Goder:

这就是硬件验证里最容易被低估的地方:构建通过、上传成功、串口有响应,只能说明软件链路走到了设备边上。真实输出还在桌面上,在屏幕、摄像头、光线、角度、 字体和人眼之间。只要这些东西没有回到工程系统,自动化验证就还停在半路。
AI Coding 最容易制造一种错觉:既然代码生成变快了,工程交付也会自然变快。这个判断在原型阶段经常成立,因为 Agent 能快速补齐脚手架、修复编译错误、生成配置、改 README、写 smoke 脚本、接工具链。很多过去需要人慢慢推进的工作,现在可以在更短时间里出现。
但问题也正是在这里开始的:当变化变得便宜,判断就变得昂贵。过去开发慢,团队会被迫在实现之前讨论目标、边界、验收和风险;现在变化来得太快, 系统反而更容易在没有可靠验证方式的情况下不断前进。AI Coding 的风险不是“代码生成不出来”,而是“变化已经发生了,但系统不知道这些变化是否真的接近目标”。
传统 TDD 给过我们一个很好的起点。TDD 不是简单地“先写测试”,而是先把一个行为期望变成可执行的验证:测试先红,说明这个行为命题尚未成立;测试变绿, 说明当前实现至少让这个行为命题成立;随后重构,是在这个验证保护下改变结构。
只是到了硬件、文档、UI、Agent 任务流、长程自动化这些场景,完成条件并不天然存在于代码里。程序说自己已经画了 OK,不等于屏幕真的显示了
OK;文档文件能打开,不等于页面视觉上可信;Agent 把卡片移动到 Done,不等于目标真的被交付。软件世界里的“完成”,
到了这些场景里经常只是“意图抵达了系统边缘”。
所以,我们引入 Spec 或者 Plan 来在 AI 编码代码之前解决验证的问题。但是,它把我们局限在了前期的设计,我们又成为了 AI 的瓶颈。
在过去的两个月里,我一直在睡觉前通过 /goal 来探索让:AI 如何从零 UI 复刻某个软件?包含但是不限于:
从我的观察来看,AI 可以在一个晚上完成核心的 80% 的功能,但是剩下的 20% 功能,可能要花费一周乃至的时间。从表面上看,我们好像完成了这样的工作, 但是实际上,依旧有大量的细节在不同的地方,而我们的验证条件是固定的。
这种固定的验证条件,大大限制了 AI 的解空间。也就是我们不止需要的是动态调整目标,而是要调整我们的验证条件,不断地发散 —— 乃至于,我们应该使用 一个独立地 Agent 来完成这样的工作。
我想把这里缺失的能力叫作验证工程。它不是传统意义上多补几个测试,也不是最后写一份测试报告。更准确地说:
验证工程是把目标、测试、可验证和记忆等组织成一个能持续收敛的工程 Loop。
这个定义里,“验证”不是最后那个检查动作,而是让系统知道自己是否真的接近目标。
它们不是同一种证据,也不在同一层 Gate 上。把这些证据放在一起,才有可能形成一个可以推进的硬件 Loop。
门禁只是验证的一种用法:当验证结果被用于阻断或放行时,它就是门禁。但验证比门禁更宽。很多验证是探索性的、诊断性的、校准性的、回归性的。 它们的价值不是立刻宣布通过,而是告诉系统:下一轮应该修目标、修实现、修现场,还是修验证器本身。
在真实工程里,一次观察至少可能有几种结论:已验证、未验证、证据不足、验证器不稳定、需要更好的现场、需要人工复查。它们看起来都像“没过”,但下一轮动作完全不同。
要把验证工程落到项目里,不应该先列测试清单,而是先拆可验证命题。测试清单通常是工具视角,它会问我们能测什么;可验证命题是目标视角, 它会问这个目标里有哪些关键事实必须被证明。
比如“自研云端 AI 终端可用”这个目标,不能直接验证。它里面混着设备启动、屏幕显示、串口协议、host relay、麦克风采集、VAD、ASR、LLM、TTS 和扬声器输出。直接验证最终能力,失败时几乎无法归因。更好的做法,是把它拆成一组小命题:设备能启动;屏幕能显示状态;host relay 能和设备通信;摄像头能观察到稳定 token;麦克风指标能响应声音刺激;VAD 能触发;ASR 能返回文本;TTS 能播放声音。
每个命题只证明一个小事实,但这些小事实组合起来,才逐步逼近最终目标。任务拆解回答“要做什么”,可验证命题回答“哪些事实必须被证明”。 一个任务可以被完成,却没有证明关键命题;一个命题被证明,也不一定意味着整个任务完成。验证工程要做的,就是把这些关键命题显式化。
硬件里的 OK / Goder 就是一个很好的例子。最初的命题可能是“屏幕显示了预期文本”。但 OCR
漂移之后,这个命题应该被拆细:设备是否启动?屏幕是否亮起?摄像头是否看到了屏幕区域?图像处理是否保留了可读文本?OCR
是否能稳定识别当前 token?目标文本是否适合作为视觉验证对象?
命题不会自动被证明。它需要一个验证器,而验证器也不是一段孤立脚本。它至少包含观察方式、验证现场、证据结构和判定逻辑。
视觉命题需要摄像头、裁剪、旋转、图像处理和 OCR;音频命题需要声音刺激、采样窗口、RMS/peak 指标;串口命题需要稳定连接和日志采集;文档命题需要渲染环境、截图和视觉比较;Routa 里的任务交接命题,则需要卡片状态、 实现说明、验证命令、影响面和 review 结果。
这里最重要的是,验证要能解释自己。它不应该只输出 pass / fail,而应该至少留下三层证据:原始现场、处理结果、判断理由。
Qoder 被 OCR 读成 Goder 的那一轮,如果只留下 failed,下一轮很可能盲目改代码;如果留下原图、处理图、OCR 文本、裁剪参数和预期
token,系统就有机会判断:问题可能不在屏幕代码,而在视觉验证器本身。证据的价值,不是堆材料,而是让下一轮少猜一次。
但是,由于 AI 在 OCR 验证之后,又自己调用了摄像头,发现他就是 Qoder,帮我们纠正了这个 loop 的问题。
验证工程真正成熟的地方,不只是拆命题、留证据,而是验证结论能否改写下一轮动作。
一个结论如果只是被记录下来,它还只是历史;只有当它改变下一轮的目标、实现、现场或验证方式,它才真正进入循环。已验证的命题, 可以升级成回归检查;未验证的命题,要继续推进实现;证据不足,要补观察;验证器不稳定,要先修验证器;需要人工复查,就不要假装自动化已经覆盖这个判断。
所以 Loop 不是重复执行。Loop 是让偏差变成下一轮输入。传统自动化更关注任务是否能重复执行;AI Coding 的 Loop 还要关注执行结果能不能改变下一轮上下文。 如果失败没有留下可消费状态,下一轮 Agent 还是从头猜;如果成功没有留下完成边界,下一轮 Agent 可能重新证明已经证明过的事;如果经验没有写回项目, 整个系统只是把一次次执行保存成历史,而不是把历史变成能力。这也是为什么我越来越觉得,Loop Engineering 的核心不是让 Agent 继续做,而是让 Agent 不必重复做。
回到开头那块小屏幕,Qoder 被读成 Goder
并不是一个丢脸的错误。它提醒我,真实世界没有那么容易被塞进一次断言。屏幕、摄像头、光线、字体、裁剪、旋转、串口、麦克风、扬声器,它们都不是软件世界里干净的输入输出。
构建通过、上传成功、串口有响应,都只是不同层级的验证结果。它们很重要,但它们不能替代那个真正要证明目标成立的验证。
TDD 为代码行为建立验证。验证工程则为目标和循环建立会自我演进的验证。一个系统如果只迭代实现,不迭代验证,就会越来越擅长通过旧检查;一个系统如果能迭代验证,才会越来越接近真实目标。
所以,验证工程的终点不是“这次验证通过了”,而是“这次验证让下一次验证变得更可靠”。真正的闭环,不是 Agent 执行了下一步,而是上一次执行改变了下一次验证方式。只有当验证能够自迭代,AI Coding 才从代码生成进入工程化。
围观我的Github Idea墙, 也许,你会遇到心仪的项目