当AI成为编程语言的第一公民:Vercel Zero语言的设计哲学与未来
人类提出需求,Agent查询图、提交已检查的编辑、证明结果。这不是一句口号,而是一门语言的全部设计起点。
2026年,编程语言的版图上多了一个略显异类的名字:Zero。它由 Vercel Labs 以 Apache 2.0 协议开源,源文件用 .0 作为扩展名,编译为原生可执行文件,与 C、Rust 处于同一设计空间。但真正让它引发讨论的,不是语法,而是一句近乎挑衅的定位——这是一门为 AI Agent 而非人类设计的系统编程语言。发布仅两天,GitHub 便收获 1100+ Star。
这篇文章不打算复述新闻稿,而是从编程语言的演进逻辑出发,剖析 Zero 的图原生(graph-native)范式、Agent 优先的工具链契约,并探讨一个更深层的问题:当 AI 成为语言设计的第一公民,软件工程的底层逻辑正在发生怎样的位移。
从打孔卡到语义图:编程语言的演进逻辑
理解 Zero,需要先把它放回编程语言长达七十多年的演进脉络中。每一次语言范式的跃迁,本质上都是"谁在理解程序"这一问题的回答发生了变化。
机器码与汇编:机器理解人类
最早的程序是用打孔卡和二进制机器码写就的。那个时代,是机器在迁就人类笨拙的表达——人类必须把自己的意图翻译成机器能逐位执行的电平信号。汇编语言用助记符替代了二进制,但本质仍是"人向机器低头"。
高级语言:人类理解人类
Fortran、C、Pascal 的出现,让程序开始用接近人类思维的方式表达。编译器承担了"翻译官"的角色,把人类可读的代码转成机器指令。这个阶段的核心矛盾是抽象层次:我们不断发明更高层的抽象(面向对象、函数式、泛型),让人类能管理日益膨胀的复杂度。
AI时代:谁理解程序?
大语言模型的崛起,让"理解程序"的主体变得模糊。今天,大量代码由 AI 生成、由 AI 审查、由 AI 修复。但讽刺的是,这些 AI 仍在使用为人类设计的语言和工具链。错误信息是给人类读的散文,类型系统是人类发明的契约,依赖管理是人类维护的图。Agent 在这个体系里始终是个"二等公民"——它必须反复地把人类可读的文本解析成自己能操作的结构,而这个解析过程脆弱且昂贵。
Zero 的回答很直接:既然 Agent 已经成为代码的主要读者和写者,那就让语言从一开始就为它优化。
Zero是什么:一门为Agent而生的系统语言
先给 Zero 一个准确的定位。根据其官方仓库的描述,Zero 是一门实验性的图原生(graph-native)编程语言,旨在实现可靠的自主软件生成。它被优化为以下几个目标:
它在设计空间上与 C、Rust 并列:编译为原生可执行文件,提供显式的内存控制,面向底层环境。但关键的差异在于——编译器输出和工具链从第一天起就是为 AI Agent 设计的,而不是只为人类工程师。
这一点体现在一个朴素却深刻的设计取舍上。传统的编译器反馈循环是这样的:Agent 写代码,编译器吐出一段非结构化的错误文本,Agent 再去解析这段文本来判断哪里出了问题、如何修复。这个循环极其脆弱——错误信息的措辞会随版本变化,信息是写给人类阅读的,而且根本不存在"修复动作"这个一等概念。
Zero 的做法是让编译器默认输出结构化的 JSON 诊断,每条诊断都携带稳定的错误码、人类可读的消息、行号,以及一个带类型的"修复标识符"。人类读消息,Agent 读码和修复标识符。二者共用同一条 CLI 命令,无需切换模式,也无需额外的分析服务。
图原生:让程序成为可查询的数据库
如果说"Agent 优先"是 Zero 的立场,那么"图原生"就是它的方法论。这是 Zero 最具想象力,也最容易被低估的一点。
语义图即程序本身
在 Zero 的世界观里,语义图就是程序数据库。这不是一个比喻,而是一个工程事实。传统编译器内部当然也构建 AST(抽象语法树)和各种中间表示,但这些结构对开发者是不可见的内部实现细节。Zero 则把这张图提升为一等公民:程序的模块、导入、公开符号、能力、副作用、所有权事实,都作为图的节点和边被显式建模并对外暴露。
运行 zero graph --json,你能拿到一份结构化的程序地图:
zero graph --json examples/systems-package输出包含模块、导入边、公开符号、能力声明、效应信息、所有权事实,以及接口指纹。对 Agent 而言,这意味着它不必"猜测"一个程序的依赖关系,而是可以直接查询。
从"读源码"到"查数据库"
这里有一个范式级的转变值得深思。过去的 Agent 改代码,依赖的是把整个源文件塞进上下文,靠模型的语义理解去推断符号从哪来、改一处会不会影响别处。这是一种基于概率的"模糊推理",天然存在幻觉风险。
而图原生意味着,Agent 可以像一个查询数据库那样去查询程序的结构关系:
当这些关系是确定性的、可查询的图数据,而非模型脑补的猜测,Agent 生成代码的可靠性和可验证性就有了结构性的提升。人类提出需求,Agent 查询图、提交"已检查的编辑"(checked edits)、最后证明结果——这条工作流之所以成立,正是因为图本身是可信的程序事实来源。
Agent优先的四块基石
把 Zero 的设计拆开看,支撑"Agent 优先"的是四块互相咬合的基石。
结构化诊断:错误不再是散文
这是最直观的一块。运行 zero check --json,你得到的不是一段散文式的报错,而是一份契约化输出:
{
"code": "NAM003",
"message": "unknown identifier 'message'",
"expected": "visible local, parameter, function, or builtin",
"actual": "no matching visible symbol",
"repair": {
"id": "declare-missing-symbol"
}
}注意这里每个字段的职责分工:code(NAM003)是跨版本稳定的标识符,Agent 可以可靠地匹配它;message 是给人看的;expected 和 actual 把"期望与现实的差距"显式化,让 Agent 不必从措辞里猜;repair.id 则直接给出一个带类型的修复动作标识。
这种设计击中了 Agent 与传统编译器协作的最大痛点。传统编译器的错误信息是自然语言,措辞一变,Agent 的解析逻辑就失效。而稳定的错误码加结构化的"期望/实际"对照,等于把错误从一个模糊的语义问题,降维成一个确定性的模式匹配问题。
编译器即工具链:检查、解释、修复一体化
Zero 的第二块基石,是把所有 Agent 需要的能力收编进同一个编译器二进制。这不是简单的功能堆叠,而是一套精心设计的"工具链契约":
| 命令 | 契约内容 |
|------|----------|
| zero skills get language | 与编译器版本匹配的语言规则,随二进制分发 |
| zero check --json | 诊断码、span、期望/实际字段、修复安全性、编译期沙箱事实、目标就绪度 |
| zero parse --json | 稳定的解析摘要:声明、函数签名、body 节点类型 |
| zero graph --json | 模块、导入、公开符号、能力、效应、所有权、辅助函数使用 |
| zero fix --plan --json | 类型化修复计划,描述拟议改动而不直接改文件 |
| zero size --json | 保留的辅助函数、体积原因、后端事实、产物预算 |
其中两个命令尤其值得展开。zero explain --json TYP009 让 Agent 直接查询某个诊断码的详细解释,而不必去抓取可能已经过时的外部文档。zero fix --plan --json 则生成一份机器可读的修复计划——它告诉 Agent "应该怎么改",但不直接动文件,把最终决策权留给了 Agent 或人类。这是一种克制而聪明的边界划分:编译器负责"提议",Agent 负责"执行与证明"。
这套契约的价值在于确定性。Agent 不需要推理"该用哪个工具做哪件事",因为检查、解释、修复、查询都是同一组稳定子命令。在自主循环里,减少决策点就是减少出错点。
能力化I/O:显式效应与编译期保证
Zero 的第三块基石是显式效应系统。在 Zero 中,如果一个函数会写标准输出、访问文件系统或发起网络调用,它必须通过一个能力对象(capability object)声明这一点。
看这个标准的入口函数:
pub fn main Void world World !
if == answer() 42
check world.out.write "math works
"这里的关键约定是:world 是 World 类型的能力对象,它授予函数访问外部世界的权限。一个没有接收到 World(或从中派生能力)的函数,根本无法执行 I/O——这是编译期强制执行的,而非运行期检查。系统里不存在隐藏的全局进程对象,没有隐式的异步运行时,也没有魔法全局变量。
check 关键字负责处理可能失败的操作:如果 world.out.write 可能失败,check 会把失败沿调用栈上抛。而函数签名末尾的 ! 标记则表明该函数会传播错误——错误路径因此被写进签名,而非埋在运行时异常里。
对 Agent 而言,这是一个巨大的可靠性红利。当效应是签名的一部分,Agent 在调用一个函数之前就能从类型签名知道它会产生哪些副作用,而不必通读函数体去"嗅探"隐藏的 I/O。这让静态推理成为可能,也让"证明结果"这件事有了可验证的依据。
随版本匹配的"技能":Agent的自我说明书
最后一块基石解决的是一个看似琐碎却极其要命的问题:文档与编译器的同步。
传统生态里,Agent 要么靠训练时记住的(可能已过时的)文档,要么靠实时抓取外部文档,但外部文档和实际运行的编译器版本经常对不上。Zero 的解法是 zero skills——把与当前编译器版本匹配的 Agent 指南直接随二进制分发:
zero skills list
zero skills get language
zero skills get diagnostics
zero skills get stdlib这意味着 Agent 拿到的语言规则、诊断解释、标准库说明,与它正在使用的编译器是同源的、版本对齐的。zero skills get zero --full 会返回覆盖语法、诊断、构建、包、标准库、测试和 Agent 编辑循环的聚焦工作流。文档不再是外挂,而是工具链的内生部分。
Zero语法速览:前缀表达式与极简主义
了解了理念,我们来看 Zero 的语法面貌。它有意保持极简,追求"规整的模式优先于语法的便利"。下面是 README 中给出的官方示例:
fn answer i32
ret + 40 2
pub fn main Void world World !
if == answer() 42
check world.out.write "math works
"几个值得注意的语法特征:
+ 40 2 表示 40 + 2,== answer() 42 表示判断 answer() 是否等于 42。前缀表达式对 Token 友好、无歧义、无需优先级规则,这对 Agent 尤其有利。fn answer i32 声明返回类型为 i32;pub fn main Void world World ! 中 Void 是返回类型,world World 是能力参数,! 标记可传播错误。ret 显式返回:没有隐式的"最后一个表达式即返回值",一切显式。基于这种风格,我们可以合理推测一个带参数和结构体的程序大致长这样(以下为依据官方语法的风格化示例,非官方片段):
fn add a i32 b i32 i32
ret + a b
type Point
x f64
y f64
fn length p Point f64
ret sqrt + sq p.x sq p.y注意 length 中 sqrt 和 sq 同样是前缀调用,整段代码的信息密度高、结构规整、歧义极少。这正是 Zero 在 Token 效率上的考量:让每一个 Token 都承载确定性的语义,而非语法糖的噪音。
系统语言横向对比:Zero、C、Rust、Go
把 Zero 放回系统语言的坐标系里,能更清楚地看到它的定位与取舍。
| 维度 | C | Rust | Go | Zero |
|------|----|------|----|------|
| 主要读者 | 人类 | 人类 | 人类 | AI Agent |
| 内存控制 | 手动(malloc/free) | 所有权+借用检查 | GC | 显式,无强制GC |
| 副作用建模 | 隐式(函数指针/全局) | 显式(部分,如unsafe) | 隐式 | 显式能力对象,编译期强制 |
| 错误信息 | 非结构化文本 | 人类可读文本(部分结构化) | 人类可读文本 | 结构化JSON+稳定错误码+修复ID |
| 修复闭环 | 无内置概念 | 外部工具(clippy等) | 无内置概念 | zero fix --plan原生支持 |
| 程序结构可见性 | 内部AST | 编译器内部 | 内部 | 图原生,zero graph对外暴露 |
| 二进制体积 | 小 | 中等 | 较大 | 小(亚10KiB级别) |
| 工具链形态 | 分散(gcc/make/cmake) | cargo一体化 | go一体化 | 单一zero二进制 |
| 版本同步文档 | 无 | 外部docs.rs | 外部pkg.go.dev | zero skills随二进制 |
| 稳定性 | 稳定 | 稳定(edition演进) | 稳定 | 故意不稳定(pre-1.0) |
这张表揭示了一个核心事实:C、Rust、Go 都把"人类理解程序"作为默认假设,结构化信息和修复能力是事后补丁或外部工具的职责;而 Zero 把这些从第一天起就内建进编译器。它不是在已有语言上加一层 Agent 友好的壳,而是从地基开始重新浇筑。
代价同样明显:最后一行"故意不稳定"。Zero 明确声明,在 1.0 之前会为了 Agent 目标而接受破坏性变更,不保留遗留行为。这意味着它的生态成熟度远不及另外三者,今天写的代码明天可能就编译不过。
"AI第一公民"到底意味着什么
"AI 第一公民"这个词容易被滥用成营销话术,但在 Zero 的语境里,它有三层可以被工程化验证的含义。
第一层:信息契约的第一受众。 当编译器输出一份诊断,它的首要消费者是 Agent。稳定错误码、结构化字段、带类型的修复标识符——这些都是为了让 Agent 能可靠地匹配和行动,而不是为了让人类读得舒服。人类依然能读 message 字段,但语言不再围绕"人类读得爽"来做取舍。
第二层:学习方式的第一假设。 传统语言假设人类会去读一本厚厚的语言规范、踩几个月坑、形成肌肉记忆。Zero 假设它的"用户"是 Agent,而 Agent 的学习方式是即时查询——zero skills get 随取随用,随版本对齐。这暗含一种哲学转变:语言的复杂度不再由"人类记忆容量"来约束,而是由"可被即时查询和理解"来约束。规整的模式优先于语法便利,正是因为模式化意味着可预测、可查询、可生成。
第三层:信任模型的重建。 传统的 Agent 编程依赖概率——模型"觉得"这段代码是对的,但缺乏可证明的依据。Zero 试图用结构化的图、显式的效应、编译期的能力检查,把"猜测"变成"查询",把"可能对"变成"可证明"。zero check 的修复安全性字段、编译期沙箱事实、目标就绪度,都是在为"证明结果"提供机器可验证的证据。人类提出需求,Agent 提交已检查的编辑并证明结果——这是一条从概率到确定性的信任升级路径。
风险、挑战与冷思考
对一项实验性技术保持热情的同时,必须清醒地看到它的风险。
成熟度风险是首要的。 Zero 目前处于 v0.3.x,官方明确警告应预期破坏性变更和安全漏洞,"不应在生产系统、敏感数据或可信基础设施上运行"。它的编译器部分用 C 编写(位于 native/zero-c/,作为 bootstrap),部分用 Zero 自身编写(自托管编译器,位于 compiler/ 目录)——自托管是一个语言走向成熟的标志,但距离稳定还有相当的路程。
生态真空是第二重挑战。 Zero 没有包注册中心,交叉编译仅限文档化的目标子集,标准库覆盖仍在早期。一门语言的成败不只取决于语法设计,更取决于它能否吸引足够的库和开发者。而 Zero 的目标用户——Agent——本身不会"忠诚"于某门语言,它们只是完成任务。如果 Zero 不能让 Agent 更高效地完成任务,生态就无从谈起。
"Agent优先"是否会排斥人类,是更深层的隐忧。 如果一门语言过度为 Agent 优化,人类工程师阅读和调试它的成本会不会上升?前缀表达式、极简语法虽然对 Token 友好,但对习惯了中缀表达式的人类而言,可读性可能反而下降。Zero 需要回答:人类与 Agent 共同编写同一段代码时,谁该迁就谁?一个健康的未来,应该是人机都能高效协作,而非把人类挤出循环。
还有信任边界的悖论。 Zero 强调"已检查的编辑"和"证明结果",但这建立在编译器本身可信的前提上。如果编译器有 bug,或者图本身被污染,那么 Agent 据此做出的"证明"就是不可靠的。把信任从"模型的概率"转移到"编译器的确定性",只是转移了单点,并没有消除信任问题。如何审计这张图、如何防止图被恶意篡改,是图原生范式必须面对的安全课题。
写在最后:对每一位开发者的启示
Zero 可能成功,也可能像无数实验性语言一样沉入历史。但无论它的终局如何,它提出的问题都值得每一位开发者认真对待。
编程语言的受众正在扩容。 过去七十年,语言是为人类设计的,编译器是人类与机器之间的翻译官。未来,Agent 将成为代码的高频生产者和消费者,语言设计必须同时回应"人类能否读懂"和"Agent 能否可靠操作"两个约束。这不是要不要的问题,而是迟早的问题。
结构化优于自然语言,正在成为工具链的新共识。 Zero 的 JSON 诊断、稳定错误码、修复计划,本质上是把"人机自然语言沟通"升级为"机机结构化契约"。这个思路不局限于 Zero——任何想让 Agent 更可靠地使用的工具,都应该思考:你的输出,是不是给 Agent 准备的稳定契约?
确定性是 AI 可靠性的基石。 当 Agent 从"猜测"走向"查询"、从"可能对"走向"可证明",我们才能真正把关键软件的生成交给自主循环。Zero 的图原生和显式效应,指出了一个方向:把程序中那些模糊的、隐式的关系,变成可查询、可验证的结构化事实。
对开发者而言,Zero 最直接的启示或许是:不要只学一门语言,要理解语言设计背后的取舍。 当 AI 成为代码生态的参与者,语言层面的每一次设计选择——错误如何表达、副作用如何建模、结构如何暴露——都会被放大成 Agent 行为的可靠性差异。能看透这些取舍的人,才能在 AI 时代真正驾驭工具,而不是被工具驾驭。
Zero 还很远,但它指向的方向,已经清晰可见。
仓库地址:github.com/vercel-labs/zerolang/
安全提示:实验性项目,请在隔离环境中使用,勿用于生产。
💬 评论区 (0)
暂无评论,快来抢沙发吧!