星河避难所

返回

用 AI 重写了一个用了两年的 B 站直播机器人Blur image

上次写完《Skill 使用心得:从四处找插件,到建立自己的数字工具箱》之后,又过了一个月。

这一个月我大多数业余时间(除了打游戏的)都花在了一件事情上:用 Go 把之前那个 PHP 版本的 B 站直播机器人重写了一遍。

差不多月初开始动手,没过多久机器人的基本功能就已经跑起来了。这个速度放在一年前,我自己大概是不敢相信的。

这篇文章不聊协议逆向,那个我在《Bilibili直播信息流:连接方法与数据解析》里写过不少;也不聊单二进制部署的细节,那个我在《Go + Vue 打包成一个单二进制的后台系统》里写过。这篇只聊一件事:AI 在这次重写里到底干了什么,以及更重要的,它没干什么。

一个存在了很久的痛点#

PHP 版(php-bilibili-danmu)其实做得并不差。弹幕监控、签到、礼物答谢、积分商城、数据分析、词云,该有的功能基本都有,2024年底刚做出来的时候我还专门写过一篇介绍

但这个版本一直有一个比较让人难受的地方:部署。

这其实也不能怪当初的技术选型。

最开始做这个项目的时候,我的设计初衷其实是积分商城为主,直播机器人为辅。甚至一开始都没想过要把它正式放出来给别人用,所以技术方案优先考虑的是“我自己开发起来方便”。

后面项目真的放出来之后,问题就来了。

对于熟悉 PHP 的开发者来说,PHP + Composer + Workerman + MySQL 这些东西当然没什么,但对于一个只是想使用直播机器人的普通用户来说,部署一套这样的环境就已经是一件很麻烦的事情。

尤其是 Windows,本身就不是特别适合运行 Workerman 这一类常驻进程。真想在自己的电脑上跑起来,还得先装 PHP、装 MySQL,再处理 Composer 依赖、数据库迁移之类的事情。

而这恰恰又和很多用户真正想要的使用方式相冲突:他们并不想租一台服务器部署一个 PHP 网站,他们只是想在自己的电脑上打开一个程序,让它连接自己的直播间。

后面我也补过 Docker 一键部署方案,但 Docker 解决的主要是环境问题,数据库、前端构建以及整套部署流程依然在那里。对于不熟悉这些东西的人来说,门槛并没有真正消失。

所以后来我越来越确定,这个项目如果想让更多普通用户真正用起来,最终还是应该变成一个下载下来就能运行的客户端程序

而 Go 恰好非常适合解决这个问题。

为什么这次敢动手了#

其实我一直知道 Go 版才是更合适的解法:单二进制、下载即用,部署成本几乎为零,PHP 版那些环境依赖天然就不存在。

但“知道应该重写”和“真的开始重写”之间,隔着的还是一个完整项目的工程量。

协议对接、消息分发、后台管理、前端页面、登录鉴权、配置系统…这些东西单独拿出来都不算特别困难,但堆在一起,就是一个很容易让人拖着不想动手的项目。

转折点是这半年我和 Claude Code 的磨合。

《不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code》《从网页聊天到 Claude Code:一个 Skill 改变了什么》,再到《Skill 使用心得》,我逐渐摸清了一件事:Claude Code 最适合干的活,恰恰是这种已经有大量既有资料,但实现过程又非常繁琐的重写工作

因为这个项目其实已经有了非常完整的“参考答案”。

PHP 版本是现成的代码,之前写过的协议分析文章是现成的资料,我自己的开发规范和架构习惯也是已经明确的东西。

所以这次重写并不是从零开始设计一个直播机器人,而更像是:

我负责确定它应该长什么样,AI 负责把中间那些繁琐的工作做完。

协议怎么组织、模块边界怎么划、数据应该怎么流转、哪些东西应该复用、哪些东西应该独立,这些我先规划好;剩下大量重复性高、但又非常耗时间的实现工作,则交给 AI 在这个框架里完成。

以前可能需要几个月才能慢慢磨完的东西,现在终于有了一个真正可以动手的理由。

AI 具体干了什么#

协议移植:既有代码和资料都是 AI 的输入#

B 站直播弹幕走的是 WebSocket 二进制协议,PHP 版时期我已经把这一套东西研究过一遍。

所以这次 Go 版并不是让 AI 自己去猜 B 站协议,而是把已有的 PHP 实现、协议分析资料以及实际运行结果一起交给它。

protobuf 编码的礼物消息、zlib 和 brotli 压缩的弹幕包、数据包的解析,这些东西 AI 都可以直接参考已有实现完成迁移。

我需要做的事情反而变成了验收:代码写出来之后,拿真实直播间跑一遍,看看数据是不是正确,和原来的 PHP 版本行为是不是一致。

这种工作方式和从零研究协议完全不是一回事。

以前我要自己研究“它到底是怎么工作的”,现在更多是在确认“它有没有按照已经确定的规则正确实现”。

架构定调:我画框,AI 填空#

这次重写里,我并没有把整个项目丢给 AI 让它自由发挥。

项目采用什么分层方式、依赖应该怎么流动、哪些东西属于基础设施、哪些属于业务逻辑,我会先把这些边界规划好。

比如 DDD 分层、repository 和 service 的职责、handler 与 DTO 的关系,以及 bootstrap 最终负责什么,这些东西在项目开始之前就已经比较明确。

AI 的作用就是在这些规范确定之后,把一个个模块实现出来。

这其实是我现在比较喜欢的一种开发方式:

不是告诉 AI “帮我写一个项目”,而是先把项目的骨架搭好,再让它把骨架里面那些费时间的东西填起来。

这样既不会让 AI 完全失去约束,也不用自己把每一行代码都亲手写出来。

项目治理:拆分 CLAUDE.md#

这次我还比较满意的一点,是把 CLAUDE.md 按照项目结构进行了拆分。

不是所有规则都塞进根目录的一份大文档里,而是针对不同模块分别设计对应的 CLAUDE.md。

这样做有两个好处。

第一,AI 在修改某个模块的时候,只需要阅读和这个模块相关的规范,不需要把整个项目的所有规则都重新塞进上下文里,能够减少上下文消耗。

第二,其实这也逼着我把模块边界想得更清楚。

当你需要为 repository、service、handler、DTO 这些东西分别写规则的时候,你会很自然地开始思考:这个东西到底应该负责什么?不应该负责什么?

所以 CLAUDE.md 对我来说已经不只是“告诉 AI 怎么写代码”的说明书了,它本身也变成了一种项目设计工具。

提交规范:终于不用为写报告发愁了#

这次还继续用了之前做的 git-commit skill。

代码完成之后,让 AI 自己分析当前 diff 和修改意图,再按照 Conventional Commits 规范拆分提交、生成提交信息,我确认之后直接提交。

这个体验其实挺舒服的。

写过稍微正式一点项目的人应该都懂:工作是工作,写报告是写报告。

代码明明已经写完了,还得停下来想“这次到底应该写个什么 commit”,以前要么费劲吧啦地憋一句看起来很正式的话,要么最后就变成 fixupdate 这种东西。

现在这些信息可以让 AI 根据实际修改内容自己整理出来,提交历史自然就规范了很多。

踩坑修复:AI 更擅长处理那些“看起来不该出问题”的问题#

重写过程中,我也遇到过一些比较隐蔽的问题。

比如某些第三方库的默认行为和项目实际需求之间存在冲突,表面上看代码完全合理,但组合到一起之后才会出现问题;又比如一些异步处理和生命周期之间的关系,如果只看单个函数,很难意识到真正的问题出在调用链的另一端。

这种问题以前我通常需要自己不断缩小范围:到底是自己的代码、第三方库、运行环境,还是某个默认行为出了问题。

现在我可以直接把现象、相关代码和运行日志丢给 AI,让它顺着调用链一起分析。

它不一定第一次就能猜对,但在这种“已经有明确现象,只差找到原因”的问题上,AI 确实能帮我省掉大量排查过程。

省下来的其实不只是写代码的时间,更重要的是定位问题的时间

AI 帮不上的地方#

写这部分不是想装客观,而是想提醒一句:别被“半个月重写完一个项目”这种叙事忽悠了,AI 没有看起来那么万能。

实现细节永远需要人来把关#

AI 最大的问题不是不会写,而是它经常能把一个错误的方向写得非常完整

如果边界没有设置好,或者我们给它的指引不够明确,它就可能做出一些看起来完全合理,但实际上会给后续维护带来麻烦的东西。

比如一个项目里已经有可以复用的能力,它可能没有意识到应该复用,而是重新实现一套类似的东西;反过来,有些看起来相似的东西其实应该保持独立,如果边界没有说清楚,它又可能为了复用而强行抽象。

这种问题最麻烦的地方在于:代码刚写出来的时候拿去测试一点问题都没有,甚至代码没有一行行仔细看都有可能看不出有什么问题。

真正到了后面需要调整某个功能,才发现当初为了“复用”做出来的抽象把几个本来应该独立的模块绑在了一起,最后一个很小的修改反而变成了一堆连锁修改。

所以我现在越来越觉得,AI 编程真正重要的能力不是“怎么让它写更多代码”,而是怎么把边界讲清楚

验证成本一点没省#

AI 能帮我把代码写得很快,但这些代码写完之后,该测还是得测。

尤其是直播机器人这种东西,有些问题单元测试根本覆盖不到。

弹幕协议是否正确、不同类型的消息能不能正常解析、礼物答谢的实际表现是不是符合预期、多个消息同时到来的时候会不会出现问题,这些最终还是要一点点拿真实环境验证。

AI 让“写”的速度快了很多,但“这个东西到底对不对”,依然只能靠我们自己确认。

AI 可以帮你完善规则,但不能替你决定边界#

这一点我现在的感受比较深。

AI 其实非常适合参与规则设计。

比如我只知道“这里应该有一个礼物答谢策略”,它可以帮我把可能涉及的情况列出来;我只想到一个基本的签到规则,它也可以提醒我有没有遗漏边界条件。

这种情况下 AI 反而很有价值,因为它可以帮我们把一个比较模糊的想法逐渐整理完整。

但最后哪些情况应该支持、哪些情况应该忽略,哪些功能应该复用现有能力、哪些功能应该独立存在,依然需要人来做决定。

AI 很适合帮你把一个问题想完整,但不适合替你决定这个问题应该怎么定义。

成品与部署对比#

现在 Go 版已经基本实现了 PHP 版机器人的核心功能,弹幕监听、签到、礼物答谢、上舰答谢、定时广告、PK 播报、自动回复、黑名单、积分等功能都已经迁移过来,管理后台也重新做了一套。

但这次重写真正改变体验的,其实不是功能,而是部署方式

Go 版的前端管理后台、Swagger 文档、i18n 语言包等内容都会直接打包进最终的二进制文件,同时支持本地化数据库。Windows、Linux、macOS 都有对应的构建版本,下载下来、解压、运行,就可以直接使用,基本不需要再准备任何运行环境。

而 PHP 版就完全是另一套体验:需要自己准备 PHP 环境、安装 Composer 依赖、配置数据库,前端还需要单独构建,再处理常驻进程和 Web 服务这些东西。对于只是想在自己电脑上运行一个直播机器人的人来说,这些准备工作本身就已经成了门槛。

更重要的是,这次 Go 版并没有因为做成“个人电脑上直接运行的程序”就牺牲掉服务器部署能力。

它本质上还是一个完整的 Web 应用,放到服务器上依然可以作为网站运行。以后无论是把积分商城补回来,还是增加其他需要服务器的功能,架构上都可以继续往这个方向扩展。

所以它最终可以同时满足两种使用方式:

放在本地,就是一个下载即用的个人程序;放到服务器上,就是一个可以持续扩展的网站。

对于我来说,这才是这次重写最重要的结果:降低了普通用户的使用门槛,但没有降低项目本身的扩展性。

写在最后#

项目还在继续:数据分析、积分商城已经在路线图上,直播会话记录和定时任务这些刚完成的功能也还需要继续跑一阵子验证。

AI 没帮我想出“要重写”这件事,那是我自己在这个项目上积累了足够多的问题之后做出的决定。

但它确实让我第一次觉得,重写一个已经用了很久、功能又不少的项目,并不是一件遥不可及的事情。

以前面对这种项目,我脑子里想的是“这么多东西,得写多久”。

现在更多想的是:

哪些东西我需要自己想清楚,哪些东西可以交给 AI 去做?

当这两个问题被分开之后,很多以前觉得工程量太大的事情,好像突然就没那么难了。

老规矩,欢迎来 GitHub 看看,给个 star:

免责声明:本项目仅供学习交流使用,请遵守平台相关规则。

用 AI 重写了一个用了两年的 B 站直播机器人
https://hejunjie.life/blog/ce58b441
作者 何俊杰
发布时间 2026年8月17日
版权信息 CC BY-NC-SA 4.0
评论似乎卡住了,尝试刷新?✨