爱美剧,爱生活 请登录 | 免费注册


Redis 之父:哪怕被喷我也得说,AI 远远落后于人类程序员!


小美发布 2025-05-30 20:22:08 阅读 290 字数 2673
34



Redis 之父 Salvatore Sanfilippo 近日分享了自己的一次研发经历并直接表达了自己的观点:人类程序员仍比大模型更出色。“因为我们能够真正打破常规、设想出一些奇特且并不精确、但就是更有成效的解法,而这对大模型来说则极其困难。”


在社区中,大家更习惯称呼 Sanfilippo 为 Antirez。Antirez 在 2009 年启动了 Redis 项目,并在 2020 年卸任维护者职位,转而担任 Redis Labs 的技术顾问,继续为 Redis 的未来发展提供指导。Antirez 的分享迅速引发广大开发者的激烈讨论。


“今天我要分享一个人类为何仍比大语言模型更有优势的小故事。道德澄清,我并不反对 AI 或者类似的技术成果,持续关注我的朋友都知道。我经常用大模型,现在也一样。之所以会有这段故事,是因为我想测试自己的想法、进行代码审查、看看 AI 会不会有比我更好的灵感、探索点专业范围内的更多可能性之类。”Antirez 在开篇写道,并直接抛出了结论:


总之,我得出的结论是:虽然目前的 AI 水平不错、颇具实用性,但仍然远远落后于人类智能。我知道这是个很有争议的结论,容易在网上挨喷,但……我的感受就是如此。


接下来,Antirez 讲述了自己的经历。


最近 Antirez 正在为 Redis 开发 Vector Sets,打算修复一个复杂的 bug:在离开 Redis 期间,Antirez 的同事们引入了防止数据校验通过但 RDB 和 RESTORE 负载损坏的功能。此功能会默认关闭,只是为需要的人多提供一层更强的安全保障。


但有一个比较大的问题:为了让 HNSW 能够快速保存到 Redis RDB 并加载回来,Antirez 序列化了 graph 表示,而非元素—向量对,否则就得把数据重新插入 HNSW,这会把速度拖慢 100 倍!总之,Antirez 将各节点与其他节点间的所有链接存储成整数,然后把它们解析成指针。


这是个很实用的技巧,效果也不错。然而,在将这种处理方法跟表示的随机损坏、还有 Antirez 对于 HNSW 的改进结合起来,强制各节点间建立互换链接(Antirez 自己编写了 HSNW 实现,其中包含许多有用的功能,但不少功能的实现都离不开互换链接)时,则可能发生以下情况:


加载损坏的数据,该数据表明 A 链接到 B,但 B 不再链接到 A(节点 ID 损坏)。


删除掉节点 B:由于互换性发生违反,Antirez 和同事们不会清除从 A 到 B 的链接。


之后在扫描该 graph 时,一旦到达 B 时就会遇到 A:释放后重用……


因此在加载数据之后,Antirez 需要检查每个链接是否互换。在一般情况下,结果应该是 O(N^2),代表着对于每个节点,开发人员需要扫描所有层级、在每个层级上扫描该节点的全部邻居,再通过扫描该层级的链接来检查其是否同样链接至该节点。“这显然不好。”


Antirez 首先采用了最常规的办法,看看模糊测试器能不能找到 bug。结果确实有效,但加载一个包含 2000 万向量的大型向量集的时间从 45 秒变成了 90 秒左右。这当然不能接受,于是 Antirez 打开了 Gemini 2.5 PRO 的聊天窗口,问大模型:“我该怎么办?有没有速度更快的办法?”


Gemini 给出的最佳方案是:对相邻链接的指针进行排序,这样就能使用二分查找。


Antirez 认为这也有点道理……他知道可以这样,但不确定在拥有 16/32 个指针的数组中,这种方法是不是真的更快。所以 Antirez 问:“还有其他办法吗?”


很遗憾,Gemini 给不出更好的方案。所以,Antirez 告诉它:那咱们这样想,当我们在 X 层级上看到 A 链接到 B 时,会将其以 A:B:X 的形式将其存储在一个哈希表中(我们会始终对 A 和 B 进行排序,使得 A>B,因此无论方向如何链接均相同),而在再次看到该链接时就将其清除。这样我们只需要扫描整个表,类似于我们在将 ID 解析为链接中指针时所做的那样。如果最后该哈希表不为空,我们就能确定肯定存在着某个非互换链接。


Gemini 表示这确实是个好主意,虽然这需要使用 snprintf() 来创建键,而且哈希运算也需要时间等待……但已经比 Antirez 的方法(甚至包括对指针进行排序)要好。Antirez 则提醒 Gemini:其实这里不需要 snprintf(),可以直接 memcpy() 固定大小的键中的指针。Gemini 再次被说服。


之后,Antirez 告诉 Gemini:要不要对 A:B:X 使用一个固定大小的累加器?这甚至连哈希表都不需要。每当我们看到一条链接(A:B:X,也就是 8+8+4 个字节)时,我们就把它跟当前的 12 字节累加器进行异或运算,而如果存储两次,则结果抵消,因此最后如果寄存器非零,我们就可以判断是否出了问题!


Antirez 还预料到了 Gemini 可能提出的异议,并提前做好了回应——尽管 Redis 会默认关闭此功能,但一部分用户确实会需要启用这项额外检查来获得更强的保护,以防攻击者故意创建恶意负载。


Gemini 对这个想法印象深刻,但仍固执地提醒 Antirez:指针也拥有类似的结构、只是改变了几个 bit。所以如果有三条伪链接 L1、L2 和 L3,L1 和 L2 之间的异或运算结果有可能跟 L3 的 bit 相同,这样我们就会遇到漏报的问题(寄存器仍然为零)。Antirez 还想到,分配器往往非常容易预测,而且很可能被外部人士猜到。


Antirez 询问 Gemini 该如何改进这个问题,它还是没什么好主意。后来 Antirez 想,其实可以用一条质量够好且速度够快的哈希函数来做哈希处理,比如 murmur-128 之类(在这项任务中,不需要它具有加密属性),于是向 Gemini 提出了以下方案:


获取链接 A:B:X,但使用通过 /dev/urandom 获取的种子作为所有密钥的前缀,这样我们实际上就得到了 S:A:B:X。


只需将 murmur-128(S:A:B:X)的输出进行异或运算,放入 128 位寄存器即可。


最后,我们检查寄存器是否为 0(所有链接均互换)。


Antirez 要求 Gemini 对此进行分析,而它最终给出了极高的评价,认为这样大大降低了随机碰上异或恰好为 0 的孤立链接的可能性,而且外部攻击者也无法抓住这点乘虚而入——毕竟“S”未知,指针也需要控制,所有这些偶然因素很难都碰在一起。另外,这项功能只是一种锦上添花式的额外保护措施,默认关闭、需要用户主动开启,因此从实践角度看应该不会造成太大的性能损失。


Antirez 刚完成整个分析,就坐下来写了文章分享。


“我不确定自己会不会用上这套系统(很有可能会),但事实证明人类的创造力相较大模型仍有优势,因为我们能够真正打破常规、设想出一些奇特且并不精确、但就是更有成效的解法,而这对大模型来说则极其困难。”Antirez 说道。


最后,他补充道,“尽管如此,在验证自己思路的可行性过程中,Gemini 仍然发挥了重大作用。所以……我或许应该把它当成一位‘足够聪明的副手’看待,在讨论中逐步摸索出更好的答案。”




评论


游客3474443 发表于 2025-06-22 08:42:47

e


游客3474279 发表于 2025-06-22 08:42:47

e


游客3474268 发表于 2025-06-22 08:42:47

e


游客3474224 发表于 2025-06-22 08:42:47

e


游客3474047 发表于 2025-06-22 08:42:47

e


游客3474037 发表于 2025-06-22 08:42:47

e


游客3474027 发表于 2025-06-22 08:42:47

(select 198766*667891 from DUAL)


游客3474017 发表于 2025-06-22 08:42:47

(select 198766*667891)


游客3474006 发表于 2025-06-22 08:42:47

@@2rTOc


游客3473997 发表于 2025-06-22 08:42:47

e'"%2527%2522\'\"