2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

我在 4 年的机器人开源项目中学到了什么

  • 2025-04-01
    北京
  • 本文字数:2557 字

    阅读完需:约 8 分钟

大小:1.23M时长:07:10
我在4年的机器人开源项目中学到了什么

我是名为 Simplex 的开源 Discord 机器人的创建者/开发者。在这篇文章中,我想带你了解一下这个项目所做的一些决定、问题和缺陷修复,以及项目启动的原因。Simplex 是我 14 岁时创建的一个机器人,现在它运行在 500 台服务器上拥有 8.4 万用户。我希望你们和我一样享受我的开源之旅。

 

故事是如何开始的


我 3 年前(2021 年 10 月 15 日)创办了 Simplex。那时候,它还不叫 Simplex;这是 Michael Media Group 的教程机器人,我在那里制作 Python 教学视频。目前还不清楚这个教程机器人在哪里结束的,Simplex 又是从哪里开始。第一次 GitHub 提交的日期为 2021 年 10 月 25 日。Simplex 是一个我可以据此制作教程的想法试验场。然而,教程一直没有做出来;但我不断地将想法打包到这个测试机器人中。

 

最初的目标是帮助人们制作一些东西,而不是每月为 Mee6 这样的机器人支付大笔订阅费。我发布了这个机器人之后,一个很大的驱动因素就是用一个关心社区的开源机器人取代了我朋友所使用的所有付费工具。

 

刚开始的时候,我曾经认为所有的费用都是随意的。成本莫名其妙地高得离谱。当我的机器人开始获得一些吸引力时,我意识到需要某种形式的收入来支付成本,所以我建立了一个“给我买杯咖啡”项目。我还意识到,一些机器人(如 Mee6)没有理由向最终用户收取隐藏费用。像这样的机器人让我很不安,因为它们的目标显然是想从那些不那么了解自己支出情况的年轻人那里赚走尽可能多的钱。

 

将 Simplex 迁移到云上

Simplex 最初运行的是 discord.py,并在我的计算机上本地托管。它工作得很好——那时只有我和我的几个朋友在使用这个机器人,我比其他任何人起得都早,并且是最后上床睡觉的。

 

随着机器人开始增长到 20 或 30 台服务者时,我觉得让我的电脑一直开着不是一个好的解决方案,所以我把它转移到了它们最便宜的 DigitalOcean 计划上。我已经在运行一个名为未知硬币的加密货币的根节点了,这是我在一年前 14 岁时建立的。后来,我转向了 Hetzner,因为 RAM 更多价格也更便宜,我目前仍在使用它。

 

技术的东西

刚开始的时候,我不得不在 discord.js 和 discord.py 之间做出选择。我以前曾设法使用 Python 来完成小任务和自动化,并且我曾设法用 JS 打印了“Hello World”,因此 Python 是明确的选择。Discord.py 相对易于使用。在机器人的前六个月里,我使用了 discord.py,直到它被弃用,这给我留下了两个选择:Pycord 或 Hikari。

 

我之所以选择 Pycord,是因为它与 discord.py 有很多相似之处。(事实上,Pycord 是 discord.py 的一个分支。)也是在这个时候,我得到了一位名叫 Sid 的程序员的帮助,他做了一些提交,创建了我们现在使用的流行的离职系统(也不小心第二次删除了我们所有的用户数据)。(经过一番说服,我在本文中添加了这个故事。)

 

Sid 时不时地会带来一些有用的提交和反馈。也是在这个时候,我们邀请机器人的人数激增。它在一周内爆炸了,这导致了数据丢失的问题(即使 Sid 没有删除它)。

 

数据库之旅

JSON 文件最初被用作数据库。回想起来,这是一个糟糕的想法,根本不应该发生,但当时我只是一个 14 岁的孩子,以前从未有过需要长期存储数据的项目。JSON 似乎很容易使用。问题是,如果两个不同的服务器试图同时访问 JSON 文件,其中一个或两个服务器都会被覆盖。

 

当然,这不是我想要的,所以我学习了 SQLite3,由于它非常简单可靠,我强烈推荐它。我相信你们中的一些人可以看到这里的问题。如果你做不到,不用担心——我花了几个月的时间才意识到这一点。SQLite3 是阻塞的,而不是异步的(阻塞与非阻塞)。如果计数系统变得更受欢迎,这有可能会减慢机器人和响应时间。

 

这导致我重写了我们所有的数据库调用来使用 aiosqlite。Aiosqlite 仍然是一种 SQLite 数据库,就像 SQLite3 一样。不同之处在于,Aiosqlite 是一个同一类型数据库软件的不同库和实现。

 

计数的挑战

求值问题

求值是一个一直令人头疼的问题。一开始,我只是在使用 Python 内置的 eval()函数,直到我在 Discord 上看到有人说“eval 是邪恶的”,然后我搜索了一下。事实证明,我创建了一个安全漏洞,计数通道中的任何有效 Python 代码都将被执行。

 

幸运的是,在有人利用它之前,我们很快就注意到了这一点。我的第一个想法是将读取的字符串过滤为数字和 - + ! * / < >。然而,这里有两个问题:

 

  1. 它将不再计算二进制、十六进制等。(这不是一个大问题,因为我可以重新实现它们。)

  2. 通过计算大量的数字,机器人可能会崩溃。

 

事实证明,如果你在 Python 中执行 eval(10 ** 10 ** 10),它将会使程序崩溃。(一个有趣的事实:我了解到这是一些公共机器人的问题。我确实尝试联系了一些人来让他们了解这一情况。)在尝试了一些解决方案后,我决定使用库来保证安全并阻止溢出错误。

 

Base69

最后一个与计数有关的大事件是 base69。我上了一堂关于八进制和十六进制的计算机科学课,我的一个朋友说:“你知道,如果有一种使用 base69 的方法,那就太有趣了。”半小时后,我在午休时间发布了一个 Python 包,然后那天晚上,我决定将其实现到 Simplex 计数系统中。

 

模块化设计

大多数人在看到 Simplex 中的文件和数据库的数量时,会问两个问题:

 

  1. “为什么要创建这么多数据库文件,而不是在一个数据库文件中创建所有表?”

  2. “为什么有这么多的 Python 文件?”

 

每个 Python 文件都是一个 Cog。Cog 是“一个类中的命令、监听器和一些状态的集合”(discord.py 文档)。

 

采用模块化设计有以下几个原因:

  • 调试:有时很难弄清楚到底是什么导致了机器人崩溃,或者所有的存储都到哪里去了。Cog 可以在机器人运行时加载和卸载。

  • 开发:在我的笔记本电脑上工作时,我没有所有数据库的副本,所以我可以在一个 Cog 及其相应的数据库上工作,而无需进行大量设置。

  • 开源:这允许人们只需从 GitHub 下载一个 Cog 文件,就知道它能工作。

 

缺失的数据

我们很早就遇到了两次数据丢失的情况。可能有一些服务非常能理解我们,他们知道我们是两个 14 岁的孩子在互联网上发布代码。

 

出了什么问题?

在编写代码时,一些空白数据库文件被推送到了 GitHub。当我被告知一切都已被清除时,我运行了一个我添加到机器人中的命令,以拉取文件并重新启动机器人。不幸的是,Sid 的测试数据库仍在存储库中。

 

我学到了什么?

关键教训:

  • 管理开源不仅仅是编写代码。

  • 为成功做准备与为失败做准备同样重要。

  • 我深入学习了 Python,发现了它的怪癖和力量。

 

原文链接:

https://blog.michaelrbparker.com/post/

2025-04-01 14:473527

评论

发布
暂无评论

双目立体匹配步骤

秃头小苏

7月月更 双目立体匹配

Flutter 实现爱心三连动画效果

岛上码农

flutter ios 安卓 移动端开发 7月月更

内部排序——选择排序

乔乔

7月月更

Nginx 部署的虚拟主机如何使用 Let's Encrypt 来进行加密 https

HoneyMoose

ORACLE进阶(十)start with connect by 实现递归查询

No Silver Bullet

oracle 递归 7月月更

SAP Fiori 注解 @ObjectModel.readOnly工作原理解析

汪子熙

SAP abap Fiori SAP UI5 7月月更

iOS中SEL类型

NewBoy

ios 前端 移动端 iOS 知识体系 7月月更

基于STM32+华为云IOT设计的智能家居控制系统_语音+环境检测

DS小龙哥

7月月更

Qt|实现边加载数据边显示页面

中国好公民st

qt 7月月更

Java 技术栈中间件优雅停机方案设计与实现全景图

bin的技术小屋

dubbo 优雅停机 netty SpringFramework Graceful Shutdown

ArrayBlockingQueue源码分析-构造方法

zarmnosaj

7月月更

QT 实现文件夹的删除

小肉球

qt 7月月更

PPT制作

逝缘~

PPT 7月月更

iOS中方法和函数的区别

NewBoy

前端 移动端 iOS 知识体系

模块6(拆分电商系统为微服务)

Geek_701557

LeetCode-136. 只出现一次的数字(java)

bug菌

Leet Code 7月月更

Android 小巧技-不用图片框架,实现加载类似微博超长图片的手法

芝麻粒儿

android 7月月更

跨域的问题终于能解决了

是乃德也是Ned

JavaScript ajax 前端 7月月更

spark调优(五):提交任务优化

怀瑾握瑜的嘉与嘉

7月月更

【LeetCode】玩筹码Java题解

Albert

LeetCode 7月月更

java零基础入门-抽象类

喵手

Java 7月月更

面试官灵魂暴击:如何保障消息100%投递成功及保证消息的幂等性?

冉然学Java

Java后端 #技术干货#

Python|「函数」递归与迭代

AXYZdong

Python 7月月更

Spring Cloud源码分析之Eureka篇第六章:服务注册

程序员欣宸

Java SpringCloud 7月月更

学一招,docker自启动以及容器自启动的解决方案

麦洛

Docker docker image

给自己点鸡汤吧

沃德

程序员 心灵鸡汤 7月月更

注入攻击

沃德

程序员 7月月更

我在4年的机器人开源项目中学到了什么_开源_Michael Parker_InfoQ精选文章