Engineering as Code

02. Software as Code: the First Prototype

软件工程是 Engineering as Code 的第一个完整参考实现。从机器码到高级语言、操作系统、协议栈与 CI/CD,回顾软件如何将构建行为本身纳入文本化与自动化体系。

在所有工程领域中,软件工程最早实现了“as Code”——这本就是一句同义反复,因为软件的本体即是代码。但“软件”并不天然等于“可计算、可复现、可协作、可治理的代码”。从打孔纸带到 AI 辅助编程,软件工程走过了一条漫长的自我编码之路:将构建软件这一工程行为本身,逐步纳入文本化、自动化、可计算化的体系。这条路上,编程语言、操作系统、协议栈、虚拟化与软件工程方法论层层叠置,最终让软件工程成为 Engineering as Code 的 第一个完整参考实现

我们称它为“参考实现”,是因为软件工程发生在一个 原子的重力被悬置 的领域:编译器替代了晶圆厂,测试套件替代了质检线,容器替代了物流与仓储。在这里,设计意图到执行结果之间的距离被压缩到最短,文本、验证与反馈几乎可以实时闭环。因此,软件不是 EaC 的“特例”,而是它的 零重力基准线(zero-gravity baseline):在排除一切物理约束之后,as Code 会收敛成什么形态。理解这一形态,才能看清当原子、材料、供应链与法律责任重新进入系统时,as Code 必须发生怎样的变形。

机器码的襁褓:当代码还无法被阅读

最早的“软件”是物理的:ENIAC 的编程通过插拔线缆和开关完成。稍后的存储程序计算机(如 EDVAC)将指令编码为二进制数字,这些数字以纸带或磁芯形式存在,是机器的母语。此时的“代码”没有文本,没有符号,没有结构——它只是机器状态的直接映射。改变程序意味着重接线或重打孔,错误修复的经济代价极高,知识无法积累,复用无从谈起。

从这个起点看,软件 as Code 的第一步是将代码从机器释放到符号。汇编语言用助记符(如 MOV, ADD)替代了二进制数字,宏汇编器又引入了简单的抽象能力。这看似微小,却完成了根本性的认知转向:代码不再是机器的物理属性,而是一种被书写、被保存、可被人类阅读的文本。文本的出现使得程序可以被编辑、比较和归档,为版本控制、协作和自动化铺平了道路。

高级语言的升维:意图的声明式表达

汇编仍是“过程式怎么做”的逐行翻译,高级语言(Fortran, Lisp, C)则是一次升维。它们允许程序员用接近数学或领域概念的方式表达意图,编译器负责将意图翻译为机器能执行的指令序列。这一“宣译分离”直接创造了现代软件工程的三重可能性:

  • 抽象与封装:算法、数据结构和模块成为可命名的单元,接口与实现分离。
  • 可移植性:同一份代码文本,经不同平台的编译器生成对应机器码,硬件差异被文本层面对齐。
  • 可分析性:类型系统、静态分析工具可以在编译期对意图的正确性进行验证,形成最早的“左移”。

语言本身也在进化。函数式语言(如 Haskell)将计算建模为表达式求值,声明式的色彩更浓;后期出现的领域特定语言(DSL)和建模语言(如 UML 的文本形式)直接让“意图”成为可执行代码,或至少是可解析的规格。这正是“需求即代码”的萌芽。

操作系统的抽象膜:将整个机器装入代码

高级语言解决了计算逻辑的表达,但程序仍需与硬件直接打交道——分配内存、读写磁盘、控制外设。操作系统的出现,将硬件资源的管理抽离为“服务”,并通过系统调用(system call)提供给应用程序。这使得整个计算机的底层资源也变成了可通过代码调用的接口。 更重要的是,Shell 和脚本语言(如 Unix Shell、Perl、Python)将操作系统的命令行本身变成了一种可编程环境。管理员可以将一系列操作写为脚本文件,自动执行系统配置、文件处理、进程调度。这孕育了“基础设施即代码”(IaC)的最原始形态:主机的运行环境第一次被文本化。

协议栈与网络:超越单机的可计算文本

单机的能力终究有限,互联网的诞生要求软件跨越物理边界。但真正让网络“成为代码”的,不是网线和电磁波,而是分层协议——尤其是以 RFC(Request for Comments)为代表的协议设计文化。RFC 本身是开放文本:协议规范、报文格式、状态机都以可读的英语文档发布,任何人可以据此实现兼容的代码。 TCP/IP 分层模型将复杂的通信过程拆解为物理层、链路层、网络层、传输层、应用层,每一层都有标准的接口语义(如 socket API),应用程序只需面对抽象的“流”或“数据报”,而无需关心底层路由。这形成了一种多层的文本化抽象栈:应用开发者调用 connect(),其下的协议握手、重传、拥塞控制皆由操作系统和中间件以代码方式自动完成。协议栈既是规范文本的可执行化身,也是分布式系统中“胶水代码”的典范。

软件工程化:让构建软件的过程 as Code

如果说前面几个阶段完成了“软件能做什么”的文本化,那么软件工程本身的自我编码,则是让“怎样做软件”也成为代码。这始于一系列方法论和工具的迭代:

  • 版本控制——从 SCCS 到 Git,源码的每一次变更都被记录为可追溯、可 diff、可合并的原子提交。Git 将“协作开发”这一社会活动转化为有向无环图,让历史成为可计算对象。
  • 自动化构建——make、cmake、Gradle 等工具将编译、链接、打包的步骤编码为脚本,消除手动构建的不确定性。构建过程本身成为代码仓库中的一等公民,任何环境只要具备工具链即可复现。
  • 测试即规格——TDD、BDD 将需求从静态文档转化为可执行的测试用例。单元测试、集成测试以代码形式定义预期行为,测试失败即代表“规格未被满足”。需求从此有了精确的、可自动验证的判据。
  • 持续集成与持续交付——Jenkins、GitLab CI、GitHub Actions 将构建、测试、部署的流水线定义为文本化的配置文件(通常为 YAML)。每次代码提交自动触发全流程,错误在数分钟内被拦截,形成闭环的反馈循环。
  • 基础设施即代码——Chef、Puppet、Ansible、Terraform 将服务器配置、网络拓扑、数据库设置全部声明为代码。环境的创建与销毁像软件一样可版本化、可审查、可自动化。那句古老的“在我的机器上能跑”被彻底消灭,因为机器本身也是代码的产物。

至此,软件开发的全生命周期——从需求定义到部署运维——都被吸收进了一个统一的、基于文本的计算体系。软件工程不再是围绕代码的手工作坊,而是通过代码治理代码的元工程。

虚拟化与容器:硬件本身的溶解

如果说操作系统抽象了单机资源,那么虚拟机和容器技术则将“裸机”本身也溶解为文本。 VMware、KVM 等允许将整个计算机硬件——CPU、内存、磁盘、网卡——模拟为软件定义的对象,虚拟机镜像文件就是硬件状态的完整快照。随后,Docker 引入的容器概念更进一步:它不模拟全硬件,而是将应用及其依赖打包为轻量、可移植的运行时,Dockerfile 正是这种环境的声明式文本。Kubernetes 随后以 YAML 文件编排成百上千的容器,整个数据中心成为可编程的“一台计算机”。 在这个层次上,“Engineering as Code”达到了一种极致的自反性:编写代码的机器、运行代码的集群、连接它们的网络、监控它们的仪表盘,全部源自某种文本化的配置或脚本。这种自反性提醒我们:软件领域的 as Code 之所以纯粹,是因为连“硬件”本身也被溶解为可复现、可丢弃、可版本化的文本对象。这里的“物理实现”不再是一个需要谈判、签约、等待和承担风险的独立环节,而是一个可以被 terraform applykubectl apply 瞬间调度的计算环境。

但这正是软件作为参考实现的边界所在。它所展示的,是 当物理约束趋近于零时 的 as Code 理想形态。一旦我们离开这个领域,原子的重力会立刻把同样的逻辑拉回地面。

AI 工程中的 Co-pilot:从自动代码到代码生成

近年的 AI 浪潮(尤其是大语言模型)并没有打破 as Code 的范式,反而强化了它。GitHub Copilot、Cursor 等工具使自然语言描述可以即时转化为代码片段;ChatGPT 能根据需求生成完整的测试套件、CI 配置文件乃至基础设施模板。这看似是“自然语言即代码”,但其底层逻辑依然是:AI 生成的产物必须是开放、可 diff、可编译、可测试的文本代码,才能被集成进现有的工程体系。 因此,AI 扮演的角色是将模糊的人类意图“编码”为严格的工程文本,就像高级语言编译器将抽象语法树翻译为机器码一样。这并没有消解 as Code,反而将“意图→代码”的翻译自动化,使得更多非编程背景的工程师也能驱动计算。

启示:其他工程领域的再编码

回顾软件工程的自我编码史,可以看出几条清晰的线索:符号化解放表达,抽象化隔离细节,规范文本统一接口,自动化围堵错误,虚拟化溶解实体。这些线索共同构成了 as Code 在 零重力条件下 的完整参考实现。

然而,这一参考实现不应被误解为所有领域的模板。软件工程的幸运在于:它的“制造”环节被压缩为编译与执行,它的“物理世界”是数据中心的 ephemeral 计算资源。当 as Code 进入半导体、机械、建筑、航空等原子领域时,同样的五项支柱不会原样平移,而会被 物理约束、制度契约与法律责任 重新锻造。

这正是下一篇要讨论的问题。半导体产业比任何其他工程领域都更早地遭遇了原子的重力:千亿级晶体管、数千人团队、横跨数十家公司的产业链,却没有一个上级指挥者。它如何在互不信任的寡头之间,将设计意图、工艺约束与验证规则编码为可执行的产业契约?当 as Code 离开零重力的软件世界,它会如何变形为一套 社会技术治理制度

软件工程给出了 as Code 的参考形态;半导体产业将告诉我们,as Code 在重力作用下如何成为文明。