AI 为什么不绕过编程语言直接写机器码?

一个看似简单的技术追问,揭开的是 AI 与人类文明之间那条隐秘的脐带。


一、一个被反复提起的疑问

前不久,一位朋友在讨论 AI 编程的发展方向时,突然抛出一个让我愣了一下的问题:

“既然 AI 这么聪明,为什么不绕开 Python、Java 这些编程语言,直接面向计算机输出机器码?那样执行效率不是更高吗?”

这问题问得极好。它的逻辑线条非常直接:中间商赚差价,砍掉中间商,利润最大化。编程语言是人和机器之间的翻译层,AI 既然能理解人的意图,直接把意图编译成 CPU 能吃的 0101,不是既省事又高效?

当时我解释了一通技术原因:大语言模型的训练数据是文本、编译器比 AI 更擅长做优化、纯二进制代码人类无法调试等等。聊到最后,对方听完,沉默了几秒,给了一句让我至今印象深刻的总结:

“所以归根结底,只是为了更好地继承人类的知识财产而已。”

那一瞬间我有一种被闪电击中的感觉。对,这才是问题的真正内核。所有那些技术层面的“不能”或者“不值当”,背后都指向同一个更深的逻辑:AI 使用编程语言,不是在妥协,而是在延续——延续人类五十年积累下来的、以文本为载体的文明对话方式。

这篇文章,就是想把这个“闪电时刻”记录下来,展开讲一讲:为什么 AI 不绕开编程语言,为什么这件事关乎的远不止技术效率,而是人类知识财产的继承、人类思维的可见性,以及我们在智能时代的身份认同。


二、AI 的本质不是“编译器”,是“读者”

先从一个冷冰冰的技术事实讲起。

今天我们所谈论的“AI 编程”,本质上是大语言模型在发挥作用。无论是 GPT-4、Claude 还是 DeepSeek,它们的核心能力来源于对海量文本数据的训练。请注意这个词——文本

这些模型阅读了 GitHub 上数万亿行代码,阅读了 Stack Overflow 上数千万个问答,阅读了无数技术文档和博客文章。它们学会的不是“如何让 CPU 执行某个操作”,而是“在人类的代码书写传统中,当遇到某个需求时,接下来最可能出现的字符序列是什么”。

所以对于大模型来说,Python 不是一门需要翻译成机器码的外语,恰恰相反,Python 是它的母语。一个训练充分的代码模型,预测 def factorial(n): 后面的缩进块里应该写什么,就像一位中文作家预测“床前明月光”后面接“疑是地上霜”一样自然。

但如果你让它直接输出 x86-64 架构的机器码——那些像 48 89 E5 5D C3 一样的十六进制序列——情况就完全不同了。在模型的“眼中”,这不是一种有语法、有结构、有语义的语言,而是一个几乎完全随机的、稀疏的符号序列。预测下一个十六进制数字是 A 还是 B,对于模型来说,就像让你预测一个随机数生成器的下一个输出。不是因为模型不够聪明,而是因为这串符号里没有承载人类思维的结构性信息。

这就揭示了一个根本性的认知错位:

我们以为“绕开编程语言”是抄近道,但对于 AI 而言,编程语言本身就是那条最近的道。绕开它,反而要穿越一片它完全不熟悉的荒漠。

更有意思的是,这个现象反向证明了一个事实:编程语言之所以能成为 AI 的“母语”,恰恰是因为在过去五十年里,无数人类程序员用它们写下了数以百亿行的代码,这些代码构成了人类历史上规模最大的、结构化的、可被机器学习的知识文本之一。 这不是冷冰冰的指令集合,这是人类逻辑思维的化石沉积层。AI 能够学会编程,正是因为人类已经用编程语言把自己解决问题的思维过程,一笔一划地刻在了数字世界的岩壁上。


三、编译器:一段被严重低估的文明史

现在让我们把目光转向那个“中间商”——编译器。

很多非技术背景的朋友可能对编译器感到陌生。简单说,编译器就是一个翻译官,它把你写的 print("Hello World") 翻译成 CPU 能理解的二进制指令。这玩意儿已经存在了半个多世纪,从最早的 FORTRAN 编译器到今天的 LLVM、GCC,人类在这个领域投入的智慧总量,可能不亚于登月工程。

为什么说编译器是一段被严重低估的文明史?

因为编译器解决的绝不仅仅是“翻译”问题。它在翻译的过程中,会进行无数你想象不到的优化:它会分析你的循环结构,决定哪些变量应该放在速度最快的寄存器里;它会预测分支跳转的概率,重新排列指令顺序让 CPU 的流水线永远不空转;它会识别出你写了但从未用过的死代码,默默地帮你删掉。

这些优化策略,是 四十年、成千上万名顶尖计算机科学家和工程师的心血结晶。它们以算法和规则的形式固化在编译器中,每一次编译,都在以纳秒级的速度、接近零出错的概率运行。

现在假设我们让 AI 直接生成机器码。这意味着什么?这意味着我们要让一个 通用文本预测模型,去重新发明一遍 人类在编译器领域积累的所有优化智慧

这不是不可能。理论上,如果给 AI 足够多的“需求描述 → 最优机器码”的配对数据,它也能学会。但问题在于:

第一,这种数据的规模远远小于高级语言代码的数据规模。全世界有无数公开的 Python 代码,但“Python 代码 + 对应的最优机器码”这种成对数据,凤毛麟角。

第二,即使 AI 学会了,它的“编译”过程是一个黑箱。你给它一个需求,它给出一串机器码。如果这段机器码运行起来比预期慢十倍,你完全不知道为什么。是人类的需求描述不够精确?是 AI 在某个角落做了错误的优化决策?还是这个特定的 CPU 型号有某种 AI 不知道的硬件特性?你无从得知,因为 中间的推理链条消失了

而使用编译器,这个链条是透明的:AI 生成 Python 代码 → 人类审查 Python 代码 → 虚拟机运行 Python 字节码。每一步都有据可查,每一步都可以被人类理解和干预。

所以,保留编程语言这一层,本质上是保留了一条 从人类意图到机器执行的可审查路径。这条路径,是人类在复杂的软硬件系统中保持控制力的最后一道防线。


四、可读性:比执行效率更重要的文明基础设施

如果你愿意再往深想一层,编程语言的可读性,指向的是一个更宏大的命题:人类文明的延续,依赖于信息的可解码性。

设想一个场景。公元 4026 年,考古学家发掘出一块 21 世纪初的数字存储介质。他们用尽办法读取了其中的数据,发现是两个文件。

文件 A 是一段 Python 代码:

def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

文件 B 是一段 x86 机器码的十六进制转储:

554889E54883EC10897DFC8975F8837DFC01...

请问,哪一个文件更有可能被两千年后的文明理解?

答案不言而喻。即使 Python 作为一种具体的编程语言早已消亡,但它的语法结构、它的关键词(def, if, else, return)、它的缩进风格,依然保留着一种 人类逻辑思维的通用结构。未来的考古学家可以借助同时期保存下来的英语词典、数学教材,逐步推理出这段代码的含义——它在计算斐波那契数列。

而那段机器码呢?它只有在同时拥有了 x86 指令集手册、操作系统 ABI 规范、链接器格式说明等一系列已经失传的技术文档时,才能被勉强解码。否则,它就是一堆毫无意义的数字噪音。

这个思想实验揭示了一个残酷的事实:机器码是写给机器看的,编程语言是写给人看的。而人类的文明,本质上是围绕着“人”这个主体构建的。

当我们谈论“AI 编程”时,我们常常陷入一种工具理性的迷思,认为代码的唯一价值在于被执行。但事实上,代码的另一个同等重要的价值在于 被阅读、被理解、被修改、被传承

一个软件项目的生命周期中,代码被阅读的时间远长于被编写的时间,更远长于被执行的时间。每一次 Bug 修复,每一次功能迭代,每一次系统重构,都需要开发者首先 读懂 前人的代码。如果 AI 生成的是一段无法被人类理解的机器码,那么这个项目就变成了一个一次性消费品——能用则用,不能用则弃,永远无法积累、无法进化。

这让我想起一个经典的编程格言:

“程序是写给人看的,只是顺便让机器执行。”
—— Harold Abelson, 《计算机程序的构造和解释》

AI 不绕开编程语言,恰恰是对这句格言的最高致敬。


五、作为“环境适配器”的人类:一个无法被取代的角色

有人可能会说:如果 AI 将来足够强大,强大到能自己调试、自己优化、自己适配所有的硬件环境,那人类可读性不就不重要了吗?

这个问题触及了当前 AI 能力的根本边界。

今天的 AI,无论多么强大,都有一个致命的短板:它没有身体,没有感官,没有在物理世界中生活的直接经验。 它不知道用户是在一个安静的图书馆里用光纤宽带,还是在一辆颠簸的高铁上用 4G 网络;它不知道屏幕在阳光下会反光,不知道触摸屏在手指沾水时会失灵;它不知道有些国家的网络会屏蔽特定端口,不知道某些老旧设备的内存只有 512MB。

所有这些“不知道”,在软件开发中被称为 边界条件。而处理边界条件,恰恰是软件工程中最困难、最耗时的部分。

目前的 AI 编程模式,本质上是 AI 写草稿,人类做编辑。人类程序员在审查 AI 生成的代码时,绝不仅仅是在检查语法错误。他们是在用自己对于真实世界的理解,去校验这段代码是否能够在那个具体的、充满噪声和不确定性的环境中存活下来。

他们会问:这段网络请求代码在弱网环境下重试策略合理吗?这个递归调用会不会在某些极端输入下导致栈溢出?这个 UI 布局在屏幕旋转后会不会错位?这些问题,AI 无法凭自身能力回答,因为答案不在训练数据里,答案藏在那个具体的、物理的用户场景中。

只要这种“场景知识”的缺口存在,人类就必须能够 读懂 AI 生成的代码。而要让人类能读懂,代码就必须以人类熟悉的、高级的、结构化的编程语言来呈现。

这形成了一个有趣的悖论:

AI 的编程能力越强,生成的代码量越大,人类对于代码可读性的依赖反而越深。

因为当代码规模膨胀到一定程度时,没有任何一个人能凭记忆掌握全部细节。理解系统的唯一方式,就是阅读代码本身。如果代码是不可读的二进制,那么这个系统就变成了一个无人能够理解、无人敢于修改的“怪物”——它活着,但你不知道为什么活着;它出错,但你不知道怎么修复。


六、继承,而非颠覆

回到文章开头那位朋友的那句总结:

“只是为了更好地继承人类的知识财产而已。”

是的。AI 不绕开编程语言,不是因为技术上的不能,而是因为文明逻辑上的不必。

编程语言,从来就不只是一套让机器听话的指令集。它是人类对于“如何描述一个计算过程”这个问题的 集体智慧结晶。从 Fortran 到 Lisp,从 C 到 Python,从 Java 到 Rust,每一种语言的诞生,都代表着人类对于编程这一智力活动的新理解。它们共同构成了一个庞大而精密的知识体系——不仅是关于如何指挥机器的知识,更是关于如何 组织人类思维 的知识。

AI 使用编程语言来编程,意味着它选择了一条 融入 这个知识体系的路,而不是 绕开 它另起炉灶。它像一个谦逊的学徒,学会了人类师傅们的语言、习惯和思维框架,然后用这套框架去解决新的问题。

这样做的好处是显而易见的:

  1. 成果可以被人类继承:AI 写的代码,人类能看懂、能修改、能教学、能写进教科书。
  2. 错误可以被人类纠正:当 AI 犯错时,人类可以定位到具体的代码行,而不是面对一个崩溃的黑箱束手无策。
  3. 知识可以持续积累:AI 生成的优质代码,又可以作为新的训练数据,反哺下一代 AI,形成一个正向循环。
  4. 信任可以被建立:只有当人类能够审查 AI 的“思考过程”(以代码的形式呈现)时,人类才敢于把关键任务托付给它。

从这个角度看,AI 并没有“取代”程序员,而是成为了一名 超级实习生——它能以惊人的速度完成初稿,但它依然需要一位经验丰富的前辈(人类程序员)来 Review、把关和承担责任。

而编程语言,就是这对“师徒”之间交流的 共同语言


七、结语:在二进制与人类之间

在文章的结尾,我想用一个更具哲学意味的视角来收束这个讨论。

哲学家维特根斯坦说过一句著名的话:“我的语言的界限,意味着我的世界的界限。”

对于 AI 而言,它的训练数据构成了它的“世界”。这个世界里充满了人类用各种语言——自然语言和编程语言——写下的文本。在这个世界里,Python 的 import 和 JavaScript 的 require 不是随机的字符串,而是承载着人类关于“模块化”“复用”“抽象”等深刻思想的概念载体。

如果 AI 选择绕过编程语言,直接输出机器码,它就相当于主动放弃了这个丰富多彩的符号世界,退回到了一片只有 0 和 1 的荒漠。它在技术上可能走得通,但在文明的意义上,这是一场倒退。

因为在那片荒漠里,没有人类的足迹,没有可读的故事,没有可传承的智慧。有的只是电流的涌动和晶体管的开合。而人类的编程,从来就不只是为了控制电流,更是为了表达思想。

所以,当下一次你看到 AI 生成的一段优雅的 Python 列表推导式时,请意识到:你正在目睹的不只是一次高效的人机协作,更是一场跨越半个世纪的文明接力。AI 接过了人类递来的接力棒——那根叫做“编程语言”的接力棒——然后继续向前奔跑。

它没有另辟蹊径,因为它知道,真正的智慧不在于更快地抵达终点,而在于让身后的每一个人,都能看清来时的路。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐