终端还能这么玩?一个80×24的字符网格里,有扑翅膀的蝴蝶、随风摇摆的花、飘浮的花粉粒子,还有两层会倾斜的草地——全部用Python和ANSI转义码实现,没有GUI,没有浏览器。

这是开发者Aditya Madhok在Hermes Agent挑战赛中的作品。这个开源比赛提供1000美元奖金池,要求用Hermes Agent做出有意思的东西。Madhok原本没指望能做出多复杂的效果,结果搞出了一个完整的"蝴蝶花园"终端动画。

打开网易新闻 查看精彩图片

先说说这玩意儿到底在显示什么:一只蝴蝶带着完整的状态机(寻找→降落→吸食花蜜→起飞),翅膀用精灵动画循环扑动;三朵花(郁金香、雏菊、玫瑰花苞)用正弦波模拟风效轻轻摇晃;闪光粒子飘过画面;底部两层草地随风左右倾斜;还有一行实时叙事字幕,根据蝴蝶当前行为变化。

整个程序以约12fps运行,采用双缓冲渲染——每帧计算全新的字符和颜色缓冲区,然后一次性写入终端。没有闪烁,没有画面撕裂。启动命令就是简单的python butterfly_garden.py,按Ctrl+C优雅退出,光标和颜色自动恢复。

但Madhok坦承,这个项目的真正推手不是他自己。

他有想法:终端动画,蝴蝶访花。他也知道大致框架。但他没有时间去手动调物理参数、精灵时机、状态机转换和正弦波草地。这时候Hermes Agent介入了。

Hermes Agent是一个开源的智能体系统,主打规划、工具使用和多步推理,跑在自己的基础设施上。Madhok描述需求,让它帮忙逐块梳理架构:

他提要求:"我想要一只蝴蝶,能真实地寻找花朵、降落、吸食花蜜,然后飞向下一朵。"

Agent回应:建议用四状态机(SEEKING、LANDING、RESTING、TAKEOFF),配合基于弹簧的物理实现平滑移动,再加一层扑动噪声让飞行看起来有机自然。

Madhok强调,这种架构层面的帮助能把模糊想法快速变成结构化代码。Agent不只是自动补全代码行,而是帮他思考问题本身。

技术上值得注意的细节有几个。双缓冲终端渲染:每帧构建两个完整的80×24网格,一个存字符,一个存ANSI颜色码,然后用单次sys.stdout.write()刷新,避免逐行打印导致的局部帧闪烁。

弹簧物理加扑动噪声:蝴蝶不会瞬移到目标点,而是使用弹簧物理模型。代码片段显示target_x, target_yspring_k等参数控制运动,加上噪声层让轨迹更自然。

精灵系统:蝴蝶翅膀用多帧ASCII精灵循环,配合颜色状态实现动画。花朵也有独立的摇摆动画,基于正弦波偏移。

状态机:蝴蝶行为用显式状态管理,每个状态有进入、更新、退出逻辑,决策基于距离检测和计时器。

粒子系统:轻量级花粉/闪光粒子,带生命周期、漂移速度和淡出效果。

这个项目最终获得挑战赛奖项。Madhok的收获很明确:Hermes Agent把"周末项目"变成了"周六上午项目",省下的时间可以用来迭代视觉效果和打磨细节,而不是卡在基础架构上。

他把完整代码开源在GitHub,README里有GIF演示和本地运行指南。核心依赖只有Python 3.7+和标准库,额外功能可选安装colorama

终端作为媒介的有趣之处在于它的限制:80×24字符,有限的颜色,没有真正的图形。这些约束反而催生了创造性解决方案——双缓冲、精灵动画、物理近似。Madhok的蝴蝶花园证明,即使在最简陋的显示环境里,精心设计的系统也能产生令人意外的生命力。

而Agent的角色也值得玩味。它不是替代开发者,而是压缩了从想法到可运行原型的时间。Madhok仍然需要理解弹簧物理、状态机设计、ANSI转义码的工作原理——但他不需要从零开始摸索这些知识的组合方式。

对于想尝试类似项目的开发者,Madhok的建议很直接:从明确的状态机开始,先让核心循环跑起来,再叠加视觉效果。双缓冲是终端动画的关键,没有它,复杂画面会闪得让人头疼。最后,善用Agent处理架构决策和样板代码,把人的注意力放在创意和调参上。

终端蝴蝶或许是个小玩具,但它背后的工作流——人提出愿景,Agent加速实现——可能是更持久的信号。