摘要:Redis 之父 Salvatore Sanfilippo 近日分享了自己的一次研发经历并直接表达了自己的观点:人类程序员仍比大模型更出色。“因为我们能够真正打破常规、设想出一些奇特且并不精确、但就是更有成效的解法,而这对大模型来说则极其困难。”
整理 | 褚杏娟 核子可乐
Redis 之父 Salvatore Sanfilippo 近日分享了自己的一次研发经历并直接表达了自己的观点:人类程序员仍比大模型更出色。“因为我们能够真正打破常规、设想出一些奇特且并不精确、但就是更有成效的解法,而这对大模型来说则极其困难。”
在社区中,大家更习惯称呼 Sanfilippo 为 Antirez。Antirez 在 2009 年启动了 Redis 项目,并在 2020 年卸任维护者职位,转而担任 Redis Labs 的技术顾问,继续为 Redis 的未来发展提供指导。Antirez 的分享迅速引发广大开发者的激烈讨论。
1 Antirez:AI 水平不错,但远落后人类智能
“今天我要分享一个人类为何仍比大语言模型更有优势的小故事。道德澄清,我并不反对 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 仍然发挥了重大作用。所以……我或许应该把它当成一位‘足够聪明的副手’看待,在讨论中逐步摸索出更好的答案。”
2 开发者:盲目自信的“AI 橡皮鸭”
“这与我的体验相符。实际上,我觉得大模型助手对我来说很大一部分价值在于,它像一个有一定智能的‘橡皮鸭’一样可以与我交流。现在这个‘鸭子’偶尔还会提出异议,甚至有时还能帮我完善思路。”开发者 mattnewton 提到。
编者注:小黄鸭调试(rubberducking)是一种通过用口头或书面自然语言清晰描述问题来调试代码的方法。其名称来源于《程序员修炼之道》中的一个故事,故事中程序员会随身携带一只小黄鸭,强迫自己逐行向鸭子解释代码,以此来调试代码。
“我也有过类似的想法”有其他开发者赞同道,“在结对编程时,有一个 AI 橡皮鸭可以让你倾诉和交流想法会很棒(这样你就不会在同事面前显得很笨,也不会浪费他们的时间)。”这个开发者做了一个支持自带 API key 的 VSCode 插件,它使用了 OpenAI 的实时 API,可以和一个橡皮鸭进行互动式语音对话。
可以看出,一些开发者已经可以把大模型当编程助手看待,但这个助手仍然让人“闹心”。
“这是一只极其自信的鸭子,其自信程度与它的能力完全不成比例。我已经看到太多的人因为与它交谈而误入歧途。”开发者 marcosdumay 指出。
有人跟贴赞同道,“这正是我很快关掉 JetBrains AI 助手的原因:多行补全功能严重干扰了我的思路,尤其是当它提供看起来正确、实际错误的建议时。为了判断这些建议是否正确而停下来分析,会彻底打断我的思路。”
还有开发者表示,大模型对其来说不是“橡皮鸭”,而是“错误答案”。“我让大模型做一些简单但繁琐的事,它却错得离谱。然后我被气得不行,都有劲儿自己动手干了。”
有开发者指出,有效利用大模型的关键主要取决于经验。“我写软件的时间够长了,所以当我给大模型一些代码和一个问题时,我能立刻判断大模型是否理解了,或者是不是被一些不相关的问题迷惑住了。但初级开发人员会很难受,因为大模型生成的代码表面上通常质量很高,即使功能完全错了也看不出来。”
“我是自学编程的,平时写代码也不多,但我觉得大模型对我帮助非常大。它们能给出具体的答案,而这些问题如果靠我自己查文档或看 Stack Overflow,可能要花很长时间才能搞明白。甚至有时候它们能生成代码片段,我只需要判断这些代码是否可行就行了。”开发者 cogogo 说道。但随后 cogogo 也指出,“我很难想象,如果一个人从一开始学编程就接触了大模型,那该怎么教他。用大模型太容易走捷径了,这样一来,学编程本来需要的那些关键性思维能力和解决问题的技巧就很容易丢掉。而恰恰这些能力,既是写代码所需的,也是能真正把大模型用好的前提。”
3 结束语
但 Antirez 说的情况在两年,甚至更久一些的时间后,还会成立吗?
NVIDIA 首席执行官黄仁勋在去年 2 月份时候声称,随着 AI 的迅速普及,编程可能已经“凉了”。对于任何想要进入科技行业的人来说,学习编程不应该成为优先事项。
今年 3 月份时,Anthropic CEO Dario Amodei 也加入了讨论,并指出软件工程是非常容易被 AI 自动化的领域:“编程是 AI 进展最快的领域之一。我们发现,再过三到六个月,我们可能就会进入一个由 AI 编写 90% 代码的世界。而再过 12 个月,AI 可能几乎能写出所有代码。”
而微软首席技术官 Kevin Scott 的预测则是,到 2030 年,95% 的编程代码将由 AI 生成。不过,他迅速澄清,这并不意味着软件工程的工作将完全由 AI 接管,人类依然会写代码,但这一变化会让我们从编程语言的输入大师,转变为 AI 指令的引导者。
无论 AI 能否写 100% 的代码,但像 IDE、版本控制、自动化测试一样,AI 正在逐渐成为每位开发者的关键工具,比如定期使用像 GitHub Copilot 这样的 AI 助手;借助 AI 查找 bug 和优化性能;利用 AI 快速进行原型设计与测试。不同之处在于:工程师不只是使用 AI,还要理解 AI。
至少当下,AI 抢不了程序员的饭碗,但确实改变了开发者的工作方式。AI 能生成代码、自动化任务,甚至调试软件,但它仍缺乏创造力、批判性思维与人类直觉。
因此,现在与其问“AI 是否取代软件工程师”,或许更好的问题是:“软件工程师如何随着 AI 而进化?”
参考链接:
声明:本文为 InfoQ 整理,不代表平台观点,未经许可禁止转载。
今日好文推荐
传字节跳动内部开始禁用Cursor了
模型下载量12亿,核心团队却几近瓦解:算力分配不均、利润压垮创新?
印度国家级大模型上线两天仅 300 余次下载,投资人直呼“尴尬”:韩国大学生模型都有20万!
Java 三十周年重磅发声:James Gosling 怒斥 AI 是“一场骗局”,是科技高管“疯狂压榨”程序员的新工具
来源:InfoQ