老万故事会

【老万】英语编程?Don't 被忽悠

本文是《从0开始学chatGPT》系列第十三篇,欢迎按需阅读:

~~~~

我头回接触到计算机的时候还在上初二。那天爸妈出门有事,临行叮嘱我自己做作业。我窝在阳台上瞄见他们出了院子,便蹿回屋打开电视机柜,在十来个频道间来回穿梭。我的意思是最好能调出个动画片爽一爽,再不然有个唱流行歌的也行。

结果那天没唤出擎天柱大战威震天,也没发现王洁实单挑谢莉斯。但我不是一无所获,因为中央台教育频道蹦出一位中年大叔在演示用英文打字机打飞机。

从大叔眼镜的年轮可以推断他是个教授。眼镜叔面无表情,念着:在改革春风吹拂下,我国要在各行各业推广微型电子计算机,也就是“微机”。什么是微机?微机就是一个箱子,接上电视和英文打字机就可以做算术、奏音乐、甚至玩电子游戏。要让微机做这些事,需要用一种叫 BASIC 的语言给它“编程”。

那时我刚学会了焊简单的晶体管收音机,对一切带电的东西都好奇。不用改电路,敲敲打字机就能给微机加上不同的功能,这太神奇了。

巷子口有个科技书店,我在里面发现了《BASIC游戏程序100例》,便买回家啃起来。天生我才必有用,等我有了知识储备,到有机可蹭那天就能实现电子游戏自由了。

母亲单位上一位阿姨知道我在学计算机语言,无不嘉许地说:等你学会了,跟班主任拿计算机的语言讲一段话祝他身体健康,他肯定会喜笑颜开交口称赞。

显然这位阿姨还不太清楚计算机语言和自然语言的区别。

~~~~

四十年一晃就过去了。今天机器已经学会了人类的语言,用自然语言控制电脑已经不稀奇。

在这战斗的一年里,大语言模型井喷式发展,遍地开花。大大小小的公司都不甘落后地往前挪起跑线,一拥而上做起了各种 AI 产品,生怕慢了半步被降维的友商打得满地找牙。

一时之间,百模大战风起云涌,群雄并起电闪雷鸣。

大浪淘沙,剩下的才是金子。这一波点子中必然有很多经不起时间的考验,会在漫长的季节里被人们遗忘。我大胆预言:英语编程就会是其中的一个。

我说的英语编程就是 Databricks 公司前几周宣布的 Spark 英文 SDK(https://www.databricks.com/blog/introducing-english-new-programming-language-apache-spark)。 

Spark 是什么?

Image

它是一个广泛使用的开源分布式数据处理引擎,支持批处理和流式大数据计算。用 Spark 编程,可以把计算过程描述成一个有向无环图,非常方便。熟悉谷歌技术的朋友可以把它理解为对标谷歌内部的 Flume。

SDK 的意思是 Software Development Kit,说白了就是一套软件开发的工具和框架。

所以 Spark 英文 SDK 的意思就是:外行不用学会 Spark 的编程接口,直接向它用英文发命令就能处理大数据。

Image

具体做法是:用户把数据处理算法用英文描述出来,大语言模型把这段英文转换成 PySpark(Spark 的 Python 接口)然后执行。

比如,这段英文代码可以滚动计算各部门的四周平均销售额:

transformed_df = df.ai.transform(    'get 4 week moving average sales by dept')

大家可能要问:这跟微软的 GitHub Copilot 有什么区别?

按 Spark 英文 SDK 团队的解释,是全自动驾驶和副驾驶的区别。

Copilot 可以从用户写的注释生成代码,也可以智能补全用户书写的不完整代码。使用时,用户不断给 Copilot 反馈,比如从 Copilot 产生的多个备选方案中选一个,或者手工改正自动生成的代码中的小错误,让 Copillot 根据用户修正的结果继续补全。整个过程,双方有来有往,好似那孟良与焦赞,又譬如郭德纲和于谦,相得益彰缺一不可。

Image

英文 SDK 不一样。它的用户只需给出英文指令,机器就会自动生成代码并执行。自始至终,用户不需要看到(也看不到)机器生成的代码是啥样。也就是说,彻底放权,无限信任。因为用户看不到代码,也就不需要懂编程语言。

Image

和使用英文 SDK 一样,使用 Copilot 也包含了从英文到代码的转换,但是用户最终提交的是和 Copilot 合作写出的代码,而不是英文提示本身。这是这两者最本质的区别。

听起来英文 SDK 确实是一件利国利民功在千秋的好事。据它的团队讲:它可以大幅降低使用 Spark 的门槛,让不懂编程的领导门外汉也可以有呼风唤雨的感觉。在让软件越来越傻瓜的年代,这难道不是顺应历史潮流的进步之举?

老话怎讲来着?闪光的不都是金子,可能它就是个五块钱的激光笔。

~~~~

所有认真的编程都有一个重要特性:它得有精确的语义。也就是说,一段代码的书写者、阅读者和执行者必须对代码的意思有共识。否则就会鸡同鸭讲。

事实上,有些编程语言的设计者对这一点没有清醒的认识,他们设计出来的语言没有严格清晰定义的语义。要是程序跑出来的结果不合程序员预期,很多时候都说不清是程序员错了还是编译器错了。

用这些语言的时候,你永远无法证明你的程序是正确的:有可能它只是碰巧通过了测试案例,保不齐哪天一个意外输入就会把它丢翻,让公司关门。

有人说,你讲的那些道理是不是太阳春白雪了?写程序的时候谁去管什么公式、证明、语义啊?还不是能用就行了。管它黑猫白猫,逮到耗子的还不是好猫?

错。

一个没有严格语义的系统就好像是在流沙之上建造的楼房,看起来很光鲜,稍有风吹草动就可能倾塌,轰然倒地。

躲得过初一躲不过十五,不按科学规律的操作只能中午进行,因为早晚要出事。

一个月前的新闻大家还记得吧?泰坦号潜水艇存在重大设计缺陷,但设计者兼船长一意孤行,结果在访问泰坦尼克残骸时发生内爆,赔上自己性命不说,还搭上了一帮无辜的付费用户。

Image

消息传来,《泰坦尼克号》导演喀麦隆痛心疾首:我早就说他们在瞎搞,他们不听劝啊!

用英语或者任何一门自然语言做辅助编程都没有问题。但自然语言的天性就是有歧义(比如谐音哏)、不精确(“统计每周销量” - 一周是从星期一还是星期天开始?按哪个时区算?碰上夏令时如何调整?等你把这些都讲清楚,你会发现英语可能并不比代码省事),并不适于取代编程语言。

尤其是系统稍微复杂之后,一千个人有一千个《罗刹海市》。到底谁的解读正确?莫衷一是。这种系统是没法维护的。

我们想一想,数学家为什么要发明一套书写记号?他们那些公式证明反正是写给其他数学家看的,就用英语不香吗?

有人说,就当你说的都是对的,那也不能否认英语编程有它的应用场景。只要我们把它限定在它的应用场景里面,它一样可以是个好工具。

这种想法本身没错,但你得看看它的应用场景有多大。如果一个东西仅仅适合于做 PPT 和几个玩具例子,那么它有个光闪闪的名字:噱头。

~~~~

大语言模型在马不停蹄地演化,速度惊人。然而有得就有失,做工程的人都知道,新系统不大可能在所有指标上都超越旧系统,尤其是大语言模型这样的黑箱子系统,难免顾此失彼,此长彼消。

比如我们可能发现:新训练出的模型在 90% 的任务上超过旧模型,但其它 10% 的任务退步了。这时,用新版取代旧版是明智的选择,也会得到大多数用户的支持。但如果你是退步的 10% 功能的重度用户,就只能怅然若失自认倒霉。

最近斯坦福大学和加州大学伯克利研究发现,短短三个月时间,chatGPT 4 做算术的能力就有了惊人的变化:今年三月,它的算术正确率是 97.6%。到了六月,正确率一跃而下,跌到 2.4%。有趣的是,这两个数加起来正好 100%。是不是会的和不会的正好掉了个个?

大多数正式软件对可重复性都有严格要求,别指望用户能容忍软件隔三差五尥蹶子。而英语编程的一大问题就是它不能保证结果的可重复性。且不说模型本身在不停演化,即便模型不变,同样的英文代码和同样的输入数据,两次运行的结果都可能不一样。为啥?因为模型生成结果的算法是基于概率的,天然有不确定性,即使把温度参数降到最低也无法完全消除。

我们来看看一个英语编程用户的日志:

  • 第一周:老板下达了这个季度的任务,要上线一个新系统统计每小时用户搜索的热门话题前十名,再找出这些话题变化的趋势。这个应该用 Spark 就可以搞定。Spark 我不会,但它不是有英文 SDK 吗?英语我是过了四级的。我去刷抖音先,晚上再跟王麻子涮海底捞。

  • 第二周:时间充裕。摸鱼。

  • 第三周:摸鱼。

  • 第四周:摸鱼。项目经理李花花问进度。花 15 分钟让 chatGPT 写了个设计文档,花花很满意。感谢 AI!

  • 第五周:摸鱼。

  • 第六周:摸鱼。

  • 第七周:摸鱼。

  • 第八周:还是摸鱼。

  • 第九周:李花花又来问进度。我跟她讲这次开发要用一些新技术,难度比较大,但我会加班争取搞定。继续摸鱼。

  • 第十周:李花花说老板问能不能按时做完。我说都加班好几周了,别来烦我,再问老子不干了。看来花花有点慌了。继续摸鱼。

  • 第十一周:让 chatGPT 把需求文档改写成英文 Spark 程序,两分钟搞定。跑了一下,完美。先不告诉其他人。继续摸鱼。感谢 AI!

  • 第十二周:给花花演示程序,花花大喜。继续摸鱼。

  • 第十三周:系统上线。给老板演示成功。顺便暗示老板这是我加班加点搞出来的,老板说他有数。感谢 AI!

  • 第十四周:英文程序突然跑不起来了,下游项目在线等我救火。听说是 OpenAI 升级了 Spark 英文 SDK 背后的模型。赶快改我的英文。也是遇到鬼了,改了几十版都达不到以前的效果,不晓得大模型哪根筋搭错了。老板脸色很难看,说明天他起床蹲坑的时候还搞不定就把我祭天。你姥姥的 AI!

~~~~

外界对程序员这一行常有一些误解,比如他们的日常就是生产代码。其实写新代码只是程序员工作的一小部分。更多的时候,他们是在做设计,分析方案,调试修改已有代码。软件开发成本的大头不在开发而在维护。

英语编程,确实可以很快搭建出一个系统的原型。如果需求非常简单,几句话就能说清楚,而且不需要多次执行,那么英语编程可以是提升效率的利器。然而大多数系统的需求都不简单,有各种附加条件。即便一开始需求简单,变复杂只是个时间问题。

不幸的是,对英文程序做微调是很麻烦的事。因为代码是由一个黑盒子产生,如果运行结果不合预期,你经常都不知道该咋改。你可以东边加一个定语,西边加一个从句,不行就试试换个同义词,瞎猫撞死耗子式调试。成了,不知道为啥成。不成,也不知道为啥不成。当领导催着给项目封顶而你却拿大模型一筹莫展,就能体会到什么是叫天不应叫地不灵了。

对比之下,用 Copilot 编程程序员看见的是实实在在的 SQL,Java,Python,C++ 等编程语言的代码,有无数工具可以验证、测试、调试、重构、修改这些代码。要是运行结果有错误,只要耐心细致地分析调试,总能找到症结所在,发现排除故障的方法。

~~~~

天下武功,唯快不破。

开发软件最怕反射弧太长。

小扎的 Meta 尝有豪言传世:move fast and break things。啥意思?大干快上,像公牛冲进瓷器店,不要怕碰破些瓶瓶罐罐。

碰瓷不是小扎的目的。他的意思:单次决策是否正确并不那么重要,关键是要快速迭代,试错成本要低。错了没关系,马上修正方向再来。

我们在用 Copilot 的时候,AI 生成的代码其实经常有 bug。但是没事,只有还有一个靠谱的程序员在虎视眈眈地审视,就能对开发过程提供快速反馈。有多快?我的经验:每次反馈只需几秒到一两分钟。

AI 的路子要是错了,用户点拨一下,它马上可以换个方向重来一次,毫无怨言。这个小弟虽然头脑不是顶聪明,但是手脚勤快,任劳任怨,还是满得力的。

反观用英语编程,用户写完英文“代码”,必须等程序跑一遍才知道对不对。这就慢了许多。更要命的是,通常程序要满足多个需求,从程序结果判断这些需求是否都满足不是件容易的事,可能需要用不同输入跑多次才有结论。用 Copilot 写代码,虽然最终还是要跑程序验证其正确性,但在此之前有很多机会通过观察代码排除明显错误,反射弧短了许多,省时省力。

更更要命的是,要是程序结果不对,用英语编程得到的只是间接反馈。比如:我们可能发现结果偏大。但为啥偏大?问题出在哪儿?You 问我我问 who 啊!

用 Copilot,因为代码直接可见,信息量大,用户经常可以通过逻辑分析定位,迅速找出修改之道。

英文编程,看起来光鲜,做个 demo 可以听取哇声一片。实战效果么,呵呵。

~~~~

那么理想的 AI 辅助编程应该是什么样子?在我看来应该是在 Copilot 的基础上进一步推进,从两个方向出发,在中间汇合。

第一:提高人工智能的准确性。今天,Copilot 出来的结果经常粗看有理,细看隐含不少问题。它像是一个头脑不太清醒的小弟,动作非常快,但出来的东西不一定是对的,需要大哥把握方向。这就要求大哥有经验有眼光,能够准确理解 AI 生成的代码,对代码的可用性、可维护性、可读性和正确性有正确判断。如果我们提升 Copilot  本身的质量,就可以为大哥省下为 AI 纠错的时间。

第二:编程语言的设计和开发本身也是一个非常有趣的领域,也在不断发展。几十年来,人类一直在程序语言的正确性、安全性和可用性提高之路上艰辛探索。今天大家还在讨论 C++ 的继任者到底是 Rust、Carbon 还是 Cpp2,说明我们离完美编程语言还距离甚远。

让程序语言更高级,更贴近人类的思维,更加宣告式(declarative),让程序员可以用更贴近问题领域的语言和概念描述自己想解决的问题,将是未来的方向,可以做的事还很多。设计完美的语言虽然是不可能的任务,但却是可以无限逼近的。借 AI 做工具,计算机科学家们一定可以更快更好地设计出新的类型系统、静态分析系统、程序语义和实现,让编程更轻松安全。

但注意,在这个过程中我们不能放弃编程语言必须要有精确语义这一根本要求,否则就会像英语编程一样买椟还珠,东施效颦,南辕北辙。

~~~~~~~~~~

猜你会喜欢:

~~~~~~~~~~

关注老万故事会公众号:

码字不易,呕心沥血只是希望更多人看到。如果喜欢这篇文章,请不吝订阅、转发、评论。谢谢!🙏