2025-05-31 10:37:05
为什么人类程序员仍然比大语言模型(LLMs)强大? 作者:antirez 这是一个简短的小故事,告诉你为什么人类的编程能力仍然远远领先于当前的AI技术。请注意,我并不是反AI的人,熟悉我的朋友都知道这一点。我日常都会使用大语言模型(LLMs),包括今天也是如此。当我需要快速验证自己的想法、进行代码审查、了解是否有更好的实现方法,或者探索一些自己并不完全擅长的领域时,我都会用到它们。(两年前,当LLMs还没有流行起来的时候,我就曾经专门写过一篇博客,讲述自己如何用LLMs辅助编码。如今也许是时候再写篇新文章更新一下了,不过今天的重点不在这里。) 不过,我想强调的是,尽管当前的AI技术非常有用甚至很棒,但和人类的智慧相比,它依旧差得太远了。我特别想指出这一点,是因为最近关于AI的讨论越来越极端,很难有中立理性的观点。 遇到的问题 今天我在为Redis开发一个叫做向量集合(Vector Sets)的功能,遇到了一个非常棘手的Bug。事情是这样的: 在我之前离开Redis期间,同事们新增了一个防护功能,用来抵抗Redis数据文件(RDB)和恢复命令(RESTORE)的数据损坏问题,即使数据校验看起来是正常的。这个功能默认关闭,但用户如果想增强安全性,可以主动启用。 但这引发了一个巨大问题: 为了高效地保存和恢复数据,我把HNSW向量搜索算法的图结构序列化了,而不是直接保存向量元素的原始数据。如果直接存储原始向量数据,在加载时重新构建索引会非常慢(可能慢100倍以上)。所以我选择了一个巧妙的技巧——直接保存节点之间的连接关系(用整数表示节点编号),再在加载时恢复指针。 但问题在于,如果保存的节点连接数据出现了随机损坏,由于我改进的HNSW实现会强制节点之间的链接是双向的,以下问题就可能发生: 1. 我们加载了损坏的数据,比如节点A显示连接节点B,但节点B并没有反过来连接节点A(连接关系被破坏了)。 2. 删除节点B时,由于双向链接破坏,节点A的链接未被清除。 3. 当我们再次访问被删除的节点B链接到节点A时,就会导致使用已释放内存的严重Bug。 因此,加载数据之后,我必须检查每个连接是否双向有效。然而,用最简单的方法实现这个功能需要花费O(N²)的时间复杂度,这对于大数据量来说非常糟糕。 人类 vs 大语言模型(LLM) 一开始,我用最原始的方法实现了这个检查,虽然问题解决了,但加载2000万个向量的大型数据集时,速度从原来的45秒延长到90秒以上,这显然不能接受。 于是,我打开了Gemini 2.5 PRO(谷歌的LLM),向它询问有没有更好的方案。 Gemini建议了一个最好的方案——对节点的链接数组进行排序后再用二分搜索提高效率。这一点我早就知道,但链接数组长度只有16或32时,排序可能并没有什么性能提升。所以我继续问它,还有其他方案吗?Gemini表示没有更好的方案。 然后我告诉Gemini一个自己的想法: 我们在扫描链接时,每次看到节点A连接节点B,就把链接信息以A\:B\:X的格式存入哈希表(这里X是层级信息,A>B保持顺序统一)。第二次遇到同一链接时,就从哈希表删除它。最后如果哈希表非空,就说明有链接存在单向链接的问题。 Gemini认为我的方案不错,但担心构建哈希键的时间损耗,比如使用`snprintf()`来构建哈希键。于是我提醒它,这里完全可以用`memcpy()`来直接拷贝指针到固定大小的键中,Gemini同意我的想法。 突然,我意识到还能更进一步: > “等等!” 我告诉Gemini:“我们根本不需要哈希表!可以用一个固定的累加器,每次处理一个链接(A\:B\:X,总共12个字节)时,我们都对这12字节数据进行异或(xor)运算。如果链接存了两次,它们互相抵消,最终若累加器不为零,就知道链接出现了问题!” 但我同时也提醒Gemini,这种方案可能出现碰撞(多个链接偶然导致异或为零),并要求它评估这种风险。 Gemini对我的想法印象深刻,但也提出了担忧:因为指针通常结构类似,如果出现3个错误链接(L1、L2、L3),可能L1和L2异或后的结果刚好和L3相同,从而导致误判。此外,我也考虑到内存分配器分配的地址往往比较容易预测,可能容易被攻击者利用。 接着我向Gemini询问改善的方法,Gemini却想不出更好的方案。 于是我再次提出了改进方案: 1. 从`/dev/urandom`生成随机种子`S`,与链接信息一起构造为`S:A:B:X`。 2. 使用快速而可靠的哈希函数(如`murmur-128`)对`S:A:B:X`哈希。 3. 将哈希的128位结果异或到累加器中。 4. 最后检查累加器是否为零,若为零则说明所有链接都是双向正确的。 Gemini对此方案非常满意,认为这种方法不仅大大减少了误判的可能性,也极难被攻击者利用(因为随机种子`S`未知,而且指针难以被操控)。这本就是一种额外安全的保护措施,默认关闭,性能损耗也小。 我写这篇博客时刚完成了这个方案的评估,还没最终决定是否正式采用(但很可能会用)。不过,这次的经历清楚地表明: 人类在创造力和思维的“跳跃性”方面,仍然远远领先于AI。我们能提出许多“怪异但有效”的解决方案,这对LLMs来说太难了。但LLM确实也起到了重要的辅助作用,也许正是因为有了这个“智能小伙伴”的启发,我才得以想到这样的点子吧!
2025-05-31 10:37:05