
这是什么
一个开源、可 3D 打印的桌面机器人,把编码 agent 正在做的事用身体演出来——读书、思考、打字、收工——配上动作、一块小单色 OLED 上的脸,以及声音。它跑在 ESP32-C3 上、走 Wi-Fi,暴露一个朴素的 REST API,所以它身上没有任何东西是绑定某一个 agent 的:Cursor、Antigravity、Claude Code 各自作为一个小的适配器包发布,把那个工具的生命周期钩子翻译成 HTTP 调用,其余的也能手动接上。
谁做的克拉科夫的创客,博客在 jamro.net,二十八个公开仓库可追溯到 2012 年,大多是小项目:一个神经网络赛车沙盒、一个语音助手、一个 AI 运维聊天机器人、一个黄铜灯罩控制器。这个是他最受欢迎的项目,也是唯一一个难点在硬件上的。
制作过程
8 个阶段- 01
给出的理由是诚实的那个
README 用四个词开头——「give your AI coding agent a body」——然后不加修饰地解释自己。作者的问题是:agent 现在会独自工作很长时间,而他想知道自己的那个在干什么,又不想盯着 IDE,所以他没再做一个转圈图标或状态栏,而是做了一台坐在旁边、看得见地在读书、思考和打字的小机器人。他管它叫一台有点荒唐的桌面机器人,这个说法是得体的。行为集合很小、也很好读:reading、thinking、typing、attention、error、abort、sleep、wake-up、welcome、bell,以及 dead。每一个都是动作加表情,其中几个还有声音——仓库里带着六个 wav 文件,名字就是它们要宣告的事。
- 02
机器人被刻意做成笨的那一头
这个项目最重要的决定是:机器人对编码 agent 一无所知。它只暴露一个端点,接收一个动画名,其余全部住在仓库内以独立包形式发布的小适配器里,一个 agent 一个:给 Cursor 的 Node 命令行工具跑在它的钩子上,另一个接 Antigravity 的生命周期钩子,第三个接 Claude Code 的项目钩子。每个都把自己宿主的的事件映射到机器人的词汇上,然后向局域网发一个 HTTP 请求。README 把这个原则原样写了出来——Cursor 只是一个示例客户端,不是架构本身——而这类句子写起来容易、做到很难。它之所以做到了,是因为文档里的第四条路径干脆就是「自带」:Codex,或者任何别的东西,只需要一个脚本和一个 HTTP 请求。Claude Code 那个适配器里有个值得抄的细节:它的钩子声明为异步,于是一台关着机的机器人永远不会把工具调用卡住。
- 03
五个舵机、一块屏,以及一张有四种样式的脸
硬件是一块微雪 ESP32-C3-Zero、一片 PCA9685 驱动五个舵机(头、颈、双手和身体)、一块 128×32 的单色 OLED 当脸,以及一片 MAX98357A 功放加一个小喇叭。固件的组织比一台桌面玩具所需严谨得多,而这个组织方式才是有意思的地方。动画是一个状态一个文件、挂在注册表后面,于是一个状态的动作、眼睛和音频是各自独立的贡献,由一个名字把它们合到一起。眼睛自己有套两层结构:模式和样式——模式是眨眼、冲击、待机这类,样式决定一只眼看起来是什么样,有经典圆眼、点阵、一种把面板填满的 cover 样式(这样打印外壳上开任意形状的孔都还是亮的),以及由别人贡献的颜文字样式。眼睛样式待在自己的注册表后面,这正是那份贡献能落地而不用把动画系统分叉的原因。同一种直觉也出现在设置代码里:它拆成加载、保存、校验、缓存、重置和底下的 NVS 层;也出现在一个内嵌网页界面上——那个页面生成的单个文件是七万七千字节的 C++ 字符串。
- 04
为写软件的人写的硬件教程
文档里有一套本档案前所未见的东西:一套九讲的课程,叫「From Code to Circuits」,写给从没焊过任何东西的软件工程师。它依次走过电与单位、单片机与 ESP32、接线手艺与原理图、总线与协议、舵机与机械运动、3D 打印与机械装配、功率预算与安全,以及嵌入式调试工具,最后一篇把整体串起来。每一篇五到一万二千字符,整套大约是一本小书的长度。它之所以存在,是因为项目自己的说明开头就让新手去买、去打印、去接线、去烧录、去装配,而作者显然想清楚了:「接线」不是一个可以对软件工程师说的步骤。旁边还放着分开的参考页:元件、接口、引脚、供电、舵机、测试、接线,一份带十九张照片的装配指南,一页讲参数化设计,以及一份购物清单。
- 05
板子送去打样之后,收到了审查
电子部分原本是跳线连起来的独立模块,把它换成一块打样出来的板子,成了仓库里最曲折的一条线。一位贡献者先提交了一块用 Claude Code 设计的载板,尺寸是对着实际外壳量的而不是猜的,合了。接着作者设计了一块更完整的集成板,把 USB-C、舵机控制器、功放和配电都放上去,并说最新一版已经送去生产。一天之后,一位社区成员看了 KiCad 文件和器件手册(但没跑 KiCad)贴出了一份审查。真正要命的那条是启动阻塞:一个电阻把舵机控制器的输出使能脚拉高,但固件从来不驱动对应的 GPIO——引脚头文件里的标志是 false——于是十六路舵机输出全是关的,机器人根本不会动。同一份审查还给下一版列了:缺软启动电容、USB 数据线上没有 ESD 保护、地平铺到了 ESP32 天线的下方。作者的回复就是整个项目的一句话总结:这非常有用,尤其是板子已经在路上了。他说会先查使能脚那条,其余几点则视为「做下一版的理由」而不是「停掉这一批的理由」。
- 06
一个社区会对硬件项目做什么
五个人贡献者、七条共同作者尾注、一百三十七次提交,而外部的工作对这个年龄的仓库来说异常扎实。有一位贡献者对每一个导出的网格文件做了几何普查来补文档缺口——项目在三处写着螺丝长度没有记录——他检测符合直径的圆柱特征,用一个带标签的测试件验证检测器,最后产出一张表:十一个零件、二十七个螺丝位。同一份分析还确认了胸腔里五条深槽是舵机走线而不是螺丝孔、只有头部有舵机耳片螺柱、整台机器人大概需要三十颗某一长度的 M2 螺丝和五颗另一长度的。作者的回应是说他完全没料到有人会对所有导出模型做几何普查。另一位贡献者写了一个颜文字表情库,十六张动画脸、每张三十帧;还有一位重做了参数化底盖,让它对三种支持的舵机都成立,重新生成了二十七个导出文件。每个 pull request 都有机器人审查,仓库还带着一份许可合规文件和一份行为准则——对一台桌面玩具来说,公民基础设施相当齐备。
- 07
不体面的那一半
issue 里有一部分是做实体东西的寻常回路,而它比架构更有教益。有人报告舵机在孔里打转,上了螺丝也没用;作者解释舵机尺寸在厂商之间有差异,而熔融沉积打印在水平和垂直方向上公差不同,然后把轴径从 2.45 毫米改到 2.40 毫米,在自己的打印机上打了一件测试件才回话。有人报告头部好像有个大洞、本该是脖子的位置;得到的答复是那个洞是对的、是舵机变速箱的位置,并附了装配截图——这件事直接催生了那份装配指南。有人发现某个模型比它为之设计的舵机窄了 1.6 毫米,并提醒其他人先别继续打印,等修好再说。还有人注意到在参数化模型里更换舵机型号会静默删掉笔记本六十四个键里的六个。这些都不聪明。但正是它们,让一个不是作者本人的人也能把这东西做出来。
- 08
数字长什么样
五周一百三十七次提交,一个标记为「第一个可工作原型」的 release,七个未关闭 issue,四百三十颗星、五十六个 fork。仓库二百三十六 MB,而其中大部分不是代码:参数化模型为三个舵机家族各预生成了三种格式的网格文件,也就是说每个家族二十七个文件,因为作者认为做这个东西的人不该被迫拥有 Fusion。许可确实是多份的——根目录不是 GitHub 能识别的单一许可,因为软件和硬件分开授权,硬件用的是一种强互惠的开源硬件许可,另有一份合规文件列明哪些文件归哪一份。通读下来,印象是作者在两件决定「构建指南是否成立」的事上都很用心:陌生人能不能照着做出来,以及他们下载到的文件是不是被测试过的那一份。
相关档案
全部档案 →第 061 号
DeepSeek Harness
DeepSeek 的 agent 运行框架:模型适配器、工具注册表、会话日志、乃至 agent loop 本身,全都是插件——换掉它们靠的是改配置文件,而不是分叉源码。
第 060 号
VibeGame
用一句话描述一个游戏,一队 agent 就分头开工——架构师做计划、程序员实现、审计员拿代码对计划、而必须有一个「玩家」真的把它玩过,任务才算验收。
第 051 号
AI Job Search
一个跑在你自己机器上的求职框架:它拿你填好的画像给岗位打分,用 LaTeX 起草为你定制的简历与求职信,编译它们,再读回渲染出来的 PDF——然后停在「发送」这一步之前。