2020 AI 時代的程式語言:自然語言成為新母語?#
案發現場#
2021 年 6 月,GitHub 發布 Copilot——一個由 OpenAI 的大型語言模型(LLM)驅動的自動程式生成工具。開發者只要寫下一行註解「// 快速排序」,Copilot 就能補完整個函數。2022 年 11 月,ChatGPT 上線;兩個月後,有研究者用它通過了 Google 的工程師面試。2023 年,GitHub 官方研究宣稱使用 Copilot 的開發者完成任務速度提升約 55%。
當時的未解之謎——而且是最根本的:
- 程式語言是給人讀的,還是給機器執行的? 七十年的程式語言史,本質上是一場「人類思維與機器執行之間的翻譯工程」:從機器碼、組合語言、Fortran 到 Python,每一代語言都在把翻譯工作更多地交給機器。那麼,翻譯工程的終點是什麼?如果機器能直接聽懂人話,程式語言還需要存在嗎?
- 誰遇到? 每一個開發者與每一個「想寫程式但不會」的人。軟體開發人力短缺是全球性的(估計數千萬人的缺口),而程式設計的學習曲線陡峭——七十年來,我們靠設計更好的語言來降低曲線,但曲線依然存在。
- 程式碼即訓練資料。 GitHub 上有數億行的公開程式碼,它們是人類七十年編程智慧的結晶——也成了訓練 LLM 的原料。這引發了新的爭議:用公開程式碼訓練模型、再生成程式碼,授權與著作權如何界定?程式碼的「作者」是誰?
為何重要?因為這可能是程式語言史上第一次,翻譯的方向被徹底反轉:過去是人類學機器的語言(程式語言),現在是機器學人類的語言(自然語言)。這是終點還是新章?
偵查過程#
AI 時代程式語言的推理,要從兩條線索的交會說起:
線索一:Python 主導 ML 生態。 2010 年代,深度學習崛起,Python 成為絕對霸主——PyTorch(2016,Facebook 的研究團隊,創始人 Soumith Chintala)、TensorFlow、NumPy、pandas。為何是 Python?推理路徑值得細看:
- Python 是「膠水語言」:科學計算的核心(NumPy 的矩陣運算、PyTorch 的 GPU kernel)其實是 C/C++/CUDA 寫的,Python 只負責描述與編排。高效能的部分給機器,表達力的部分給人類——這正是七十年翻譯工程的極致形態。
- 動態性適合研究:ML 研究需要快速實驗(改一行、跑一次),Python 的動態型別與 REPL 是最佳選擇。
PyTorch 的自動微分(autograd)是這個時代最重要的「語言級發明」——雖然它不是新語言,卻把「微積分」編入了程式語言的執行時期:
import torch
w = torch.tensor([1.0], requires_grad=True) # w 是可微分的
y = w * w
y.backward() # 自動計算 dy/dw
print(w.grad) # 2.0 —— 微積分成了程式語言的一部分
線索二:LLM 的架構革命。 2017 年 Google 的論文「Attention Is All You Need」提出 Transformer,核心是注意力機制:
關鍵推導:Transformer 讓「序列到序列」的翻譯(原文 → 譯文、需求 → 程式碼)可以純粹用資料驅動,不需要手工規則。2020 年 GPT-3 證明了「規模即能力」(scaling laws);2021 年 Codex(GPT-3 的程式碼特化版)證明了程式碼生成本質上是「自然語言到程式語言的翻譯」——七十年來的翻譯工程,第一次可以由機器獨立完成。
線索三:人機協作的新範式。 Copilot/ChatGPT 之後,開發者的工作流被重寫:
(舊範式)需求 → 人類寫程式 → 編譯/執行 → 除錯
(新範式)需求 → prompt(自然語言)→ LLM 生成程式 → 人類審查 → 執行
prompt 成為新的「程式碼」:它用自然語言描述意圖,由機器翻譯成可執行的程式。更進一步,AI agent(如各種程式設計代理)可以自主規劃、寫碼、跑測試、修 bug——人類的角色從「寫程式的人」變成「審查意圖的人」。
結案報告#
2020 年代的遺產仍在書寫中,但幾個方向已經清晰:
- 自然語言之辯:終點還是新章? 正方(終點論):如果機器能聽懂人話,程式語言只是過渡工具,如同組合語言之於 Fortran。反方(新章論):程式碼的價值不在於「給機器執行」,而在於精確、無歧義、可驗證——自然語言天生歧義,LLM 的生成結果需要測試與驗證,而「形式化的精確性」永遠需要程式語言。目前的共識偏向新章論:LLM 把開發者從打字員升級為架構師,但沒有取消架構師。
- Python 的地位反而更穩。 LLM 的訓練資料以 Python 為大宗(語法簡潔、生態龐大、範例豐富),生成品質也以 Python 最佳——見 2016-WebAssembly.md 中 Pyodide 讓 Python 進入瀏覽器,AI 時代的 Python 反而全方位擴張。
- 程式碼即訓練資料的爭議:GitHub Copilot 的著作權訴訟、模型訓練資料的授權問題——程式碼的「作者」概念正在被重寫。
- 語言設計的新課題:為 AI 而設計的語言特性(更規則、更少歧義、更好的工具鏈回饋)、AI 可讀性成為新的設計考量。諷刺的是,2009-Go.md 的極簡主義與 2010-Rust.md 的嚴謹型別系統,都意外地對 AI 生成有利——規則越清晰的語言,AI 越難寫錯。
- 七十年翻譯工程的收束:從機器碼到自然語言,翻譯的方向完成了完整的反轉。但歷史的教訓是:每一次翻譯的革新都沒有取消上一層——組合語言還在(嵌入式)、C 還在(核心)、Python 還在(ML)。AI 時代的程式語言史,不是終點,而是最寬闊的一章。
證據與工具#
以下用 Python 展示 ML 時代的核心發明——自動微分(autograd 的迷你實現):
# 極簡 autograd:鏈鎖法則的自動化(PyTorch 的核心機制)
class Var:
def __init__(self, value, parents=(), grad_fn=None):
self.value, self.parents, self.grad_fn = value, parents, grad_fn
self.grad = 0.0
def __add__(self, other):
return Var(self.value + other.value, (self, other), "add")
def __mul__(self, other):
return Var(self.value * other.value, (self, other), "mul")
def backward(self):
# 反向傳播:拓撲序 + 鏈鎖法則
order, seen = [], set()
def topo(v):
if v not in seen:
seen.add(v)
for p in v.parents: topo(p)
order.append(v)
topo(self)
self.grad = 1.0
for v in reversed(order):
if v.grad_fn == "add":
for p in v.parents: p.grad += v.grad # d(a+b)/da = 1
elif v.grad_fn == "mul":
a, b = v.parents
a.grad += v.grad * b.value # d(ab)/da = b
b.grad += v.grad * a.value
w = Var(1.0)
y = w * w + w # y = w^2 + w, dy/dw = 2w + 1
y.backward()
print(w.grad) # 3.0 —— 微積分自動化
再模擬 LLM 程式碼生成的核心機制——以簡化的「next-token 預測」展示翻譯的方向反轉:
# 模擬:根據 prompt 的 n-gram 統計,生成「下一個 token」
import re
from collections import defaultdict
def train(corpus):
model = defaultdict(list)
words = corpus.split()
for a, b in zip(words, words[1:]):
model[a].append(b)
return model
corpus = """
def quicksort xs: if xs return sorted
def sort list: return sorted list
def map f xs: return apply f each
"""
model = train(corpus)
def generate(prompt, n=3):
result = prompt.split()
for _ in range(n):
last = result[-1]
nxt = model.get(last)
if not nxt: break
result.append(nxt[len(result) % len(nxt)]) # 極簡的「取樣」
return " ".join(result)
print(generate("def quicksort")) # def quicksort xs: if
print(generate("def sort")) # def sort list: return
這個極簡模型道出了 AI 時代的本質:程式碼生成就是「根據前文預測下一個 token」——七十年來人類積累的程式碼,成了訓練這台預測機器的原料。而人類的角色,從寫下第一個 token 的人,變成寫下第一句 prompt 的人。程式語言史的翻譯工程,就此完成了方向的反轉——但故事,才剛剛翻開新的一頁。