Câu hỏi mà Zero đặt ra
Tiền đề của Zero rất đơn giản: khi một AI agent, chứ không chỉ con người, đọc, viết và sửa code, thì bản thân ngôn ngữ nên trông như thế nào?
Các ngôn ngữ hiện có được thiết kế từ rất lâu trước khi agent biết viết code. Những ưu tiên của chúng, như cú pháp ngắn gọn, thành ngữ giàu biểu đạt, thư viện khéo léo, rất hợp lý với con người gõ phím trong editor. Chúng chấp nhận sự mơ hồ và chuyển đổi ngầm vì con người giỏi lấp chỗ trống. Agent thì không. Agent sinh ra văn bản chính xác từ các phân phối xác suất, và mỗi góc cạnh mơ hồ của ngôn ngữ đều khiến agent trả giá bằng một token sai ở đâu đó phía sau.
Zero bắt đầu lại với ràng buộc bị đảo ngược: thiết kế cho agent trước, chấp nhận rằng con người vẫn sẽ đọc code, và xem điều gì xuất hiện.
Nguyên tắc 1: bề mặt nhỏ và đều đặn
Hầu hết ngôn ngữ lập trình đều lớn dần theo thời gian. Mỗi phiên bản mới thêm một tiện ích nhỏ: một toán tử mới, một dạng cú pháp mới, một cách mới để diễn đạt điều mà ngôn ngữ vốn đã làm được. Mỗi thứ thêm vào đều đáng giá với sự tiện dụng cho con người. Nhưng mỗi thứ thêm vào cũng khiến agent tốn thêm: thêm một biến thể phải học, thêm một cách để sai.
Zero cố tình giữ bề mặt thật nhỏ:
- Một dạng khai báo biến (
let). - Một dạng hàm (
fun, có thể kèmpub). - Một vòng lặp ở thời điểm hiện tại (
while). - Một cách mô hình hóa kiểu tích (
shape). - Một cách mô hình hóa kiểu tổng có payload (
choice). - Một cách mô hình hóa kiểu tổng có nhãn (
enum). - Một cấu trúc so khớp mẫu (
match).
Không nạp chồng toán tử, không decorator, không macro, không chuyển đổi ngầm, không ép kiểu truthy, không toán tử ba ngôi. Mỗi thứ vắng mặt là một tính năng: nó xóa đi một chỗ mà agent có thể chọn nhầm biến thể.
Cái giá thì rõ ràng: ít tính năng tiện lợi hơn. Lợi ích là một agent học Zero ngay trong một phiên làm việc có thể hội tụ về cú pháp đúng mà không phải cân nhắc bảy phương án gần tương đương.
Nguyên tắc 2: hiệu ứng tường minh
Hầu hết ngôn ngữ cho phép bất kỳ hàm nào, ở bất kỳ đâu, thực hiện I/O. console.log trong JavaScript, printf trong C, print trong Python. Chữ ký của hàm không cho biết nó có thể ghi tệp hay gọi mạng hay không. Cách duy nhất để biết là đọc thân hàm, một cách đệ quy.
Zero chọn hướng ngược lại: mọi hiệu ứng của một hàm đều hiện ra trong chữ ký của nó.
- I/O được kiểm soát bởi capability
World. Một hàm không nhậnWorldthì không thể làm I/O. Hệ thống kiểu bắt buộc điều này. - Lỗi được kiểm soát bởi
raisesvàcheck. Một hàm có thể thất bại sẽ nói rõ trong chữ ký. Mọi nơi gọi đều phải thừa nhận điều đó bằngcheckhoặc một cấu trúc tường minh khác.
Chỉ từ chữ ký của một hàm, bạn trả lời được hai câu hỏi mà agent (hay công cụ phân tích tĩnh, hay người review code) đặc biệt quan tâm:
- "Hàm này có thể chạm tới thế giới bên ngoài không?": có khi và chỉ khi
Worldxuất hiện. - "Hàm này có thể thất bại không?": có khi và chỉ khi
raisesxuất hiện.
Tính chất đó không tồn tại trong các ngôn ngữ phổ biến, và có được nó không phải chuyện nhỏ.
Cái giá là phải truyền tham số khắp nơi. Giá trị World phải được truyền tới mọi chỗ cần I/O; mệnh đề raises lặp lại ở mọi nơi lỗi đi qua. Zero chấp nhận đó là cái giá cho tính chất này.
Nguyên tắc 3: công cụ tất định
Nguyên tắc thứ ba là nguyên tắc nhắm thẳng vào agent nhất: mọi đầu ra của trình biên dịch đều là dữ liệu có cấu trúc.
Chẩn đoán dạng JSON là ví dụ tiêu biểu:
{
"code": "NAM003",
"message": "unknown identifier",
"line": 3,
"repair": { "id": "declare-missing-symbol" }
}
Ba tính chất khiến điều này khác với một thông báo lỗi biên dịch thông thường:
- Mã ổn định.
NAM003có cùng một nghĩa hôm nay và ngày mai, bất kể thông báo dành cho con người được diễn đạt ra sao. - Kế hoạch sửa lỗi có cấu trúc. Khi trình biên dịch cho rằng nó biết cách sửa một chẩn đoán, nó xuất ra kế hoạch dưới dạng dữ liệu: một danh sách chỉnh sửa, không phải một gợi ý bằng tiếng Anh.
- Nhiều kênh có cấu trúc. Chẩn đoán, đồ thị phụ thuộc, báo cáo kích thước và phần giải thích đều nằm sau các chế độ
--json.
Mục đích là một công cụ, agent hay không, không bao giờ phải phân tích tiếng Anh để hành động theo đầu ra của trình biên dịch. Tra một mã ổn định thì chính xác; phân tích văn xuôi thì mơ hồ. Zero coi điều thứ nhất là hợp đồng và điều thứ hai là sự tiện lợi cho con người.
Nguyên tắc 4: thư viện nằm ngay trong ngôn ngữ
Agent giỏi viết code theo các mẫu có sẵn. Chúng kém hơn khi phải chọn đúng một dependency bên ngoài giữa biển lựa chọn, tích hợp nó cho đúng và theo dõi khi API của nó thay đổi. Mỗi dependency bên ngoài là một nguồn ma sát.
Thiết kế của Zero đẩy các khả năng vào thư viện chuẩn: được ghi tài liệu rõ ràng, nhất quán và ổn định dần khi ngôn ngữ ổn định. Mục tiêu là một chương trình Zero hiếm khi cần với ra ngoài bản phân phối chuẩn cho các công việc thường ngày. Điều đó giữ cho phạm vi mà agent phải suy luận luôn có giới hạn.
Hiện tại đây là một khát vọng hơn là một trạng thái đã hoàn thành. Thư viện chuẩn trước 1.0 là có thật nhưng vẫn đang lớn dần. Nguyên tắc này là hướng đi, chưa phải đích đến.
Zero đánh đổi những gì
Mọi lựa chọn thiết kế đều có cái giá. Những đánh đổi thẳng thắn mà Zero chấp nhận:
- Dài dòng thay vì ngắn gọn. Hàm thuần không cần
World. Hàm có I/O thì cần. Lỗi hiện ra trên chữ ký. Kết quả là nhiều chú thích hơn so với phiên bản tương đương bằng JavaScript hay Python. - Tường minh thay vì phép màu. Không lập trình meta qua reflection, không decorator âm thầm bọc hành vi, không biến toàn cục ngầm. Những thứ trông như "tự chạy" trong ngôn ngữ động thì ở đây phải được nối bằng tay.
- Tĩnh thay vì động. Kiểu là bắt buộc với tham số, giá trị trả về và trường của shape. Trình biên dịch làm rất nhiều việc; cái giá là mọi chữ ký đều là thứ mà tác giả (hoặc trình sinh code) phải viết ra.
- Ổn định thay vì thay đổi nhanh. Ngôn ngữ đang ở giai đoạn trước 1.0 và thay đổi nhanh, nhưng ý định thiết kế là khóa cứng bề mặt khi nó đã ổn định. Cái giá là việc thêm một tính năng tiện lợi khéo léo về sau sẽ khó hơn, vì tiêu chuẩn để thêm là "điều này giúp agent nhiều hơn cái giá nó gây ra cho agent không?"
Những đánh đổi này có đáng hay không tùy vào bạn đang tối ưu cho điều gì. Nếu bạn là người viết một script dùng một lần, ma sát là thật còn lợi ích cho agent thì trừu tượng. Nếu bạn vận hành một agent tạo ra hàng nghìn chương trình nhỏ mỗi ngày, ma sát được bù lại gấp nhiều lần.
Những gì Zero không cố trở thành
Vài điều phủ định đáng nói rõ:
- Không phải "tương lai của mọi ngành lập trình". Zero là một giả thuyết, không phải một tuyên ngôn. Giả thuyết là các ràng buộc agent-first tạo ra một ngôn ngữ hữu ích. Việc các ngôn ngữ phổ biến có nên áp dụng những ràng buộc đó hay không là một câu chuyện khác, dài hơn.
- Không phải một tính năng của nền tảng triển khai Vercel. Dù đến từ Vercel Labs, Zero không gắn với Next.js hay hosting của Vercel. Nó là một ngôn ngữ hệ thống độc lập.
- Không phải thứ thay thế Rust, Go hay Zig trong môi trường production. Trước 1.0. Thử nghiệm. Hãy dùng nó để học và góp ý; đừng phát hành phần mềm cho khách hàng bằng nó lúc này.
- Chưa hoàn thiện. Các phần của thư viện chuẩn, cú pháp cho tính khả biến, các dạng xử lý lỗi và ràng buộc trên generic đều có thể thay đổi trước 1.0.
Điều thú vị ngay cả khi bạn không dùng nó
Kể cả khi bạn không bao giờ viết một dòng Zero nào, thử nghiệm này vẫn rất đáng học hỏi:
- Đây là ví dụ rõ ràng nhất về một hệ thống hiệu ứng dựa trên capability thật sự, chạy được, trong một ngôn ngữ hệ thống nhỏ. Mô hình tư duy (truyền quyền, thấy hiệu ứng trên chữ ký) có thể mang sang nơi khác.
- Câu chuyện chẩn đoán là điều mà mọi trình biên dịch lẽ ra nên làm từ cả chục năm nay. Đầu ra có cấu trúc luôn thắng văn xuôi, và cam kết về mã ổn định của Zero là thứ các công cụ khác có thể áp dụng mà không cần thay đổi ngôn ngữ.
- Nguyên tắc "mỗi việc một cách làm, bề mặt cố tình nhỏ" đi ngược với cách thiết kế ngôn ngữ thường thấy. Quan sát xem nguyên tắc đó giúp ích ở đâu và gây vướng ở đâu là điều hữu ích, bất kể ngày mai bạn viết bằng ngôn ngữ nào.
Đọc gì tiếp theo
Nếu bạn đã đọc hết phần còn lại của bộ tài liệu này, những tài liệu đáng đọc tiếp nhất nằm ở bên ngoài:
- Repository của Zero tại
github.com/vercel-labs/zero: ví dụ, mã nguồn vàAGENTS.md, nơi chính các maintainer nêu rõ ý định của họ. - Trang chính thức tại
zerolang.ai: hướng dẫn bắt đầu và phần giới thiệu chuẩn.
Cả hai đều đang phát triển. Những gì bạn tìm thấy ở đó sẽ mới hơn bất kỳ hướng dẫn nào của bên thứ ba. Các nguyên tắc trong tài liệu này là phần thay đổi chậm; cú pháp xung quanh chúng sẽ còn thay đổi trong lúc ngôn ngữ dần ổn định.
Câu hỏi thường gặp
Ngôn ngữ lập trình 'agent-first' nghĩa là gì?
Nghĩa là coi AI agent, chứ không chỉ con người, là người dùng chính của ngôn ngữ ngay từ đầu. Nhu cầu của agent (phân tích cú pháp một cách máy móc, sinh ra chương trình hợp lệ, đọc đầu ra lỗi như dữ liệu, áp dụng bản sửa một cách tất định) định hướng các lựa chọn thiết kế, bên cạnh những mối quan tâm quen thuộc về khả năng đọc và sự tiện dụng cho con người.
Vì sao các ngôn ngữ hiện có không phù hợp với agent?
Các ngôn ngữ hiện có được thiết kế cho con người. Ngữ pháp của chúng có những lối tắt, chuyển đổi ngầm và cấu trúc mơ hồ mà con người chấp nhận được nhưng lại làm khó các trình sinh code. Trình biên dịch của chúng in ra văn xuôi, không phải dữ liệu. Hệ thống hiệu ứng của chúng là ngầm định. Không điều nào trong số đó là chí mạng, agent có thể lách qua tất cả, nhưng một ngôn ngữ được thiết kế cho agent ngay từ đầu sẽ loại bỏ ma sát thay vì chỉ che đi.
Những nguyên tắc cốt lõi trong thiết kế của Zero là gì?
Một ngữ pháp nhỏ và đều đặn (mỗi việc chỉ có một cách làm), hiệu ứng tường minh qua capability World (không có I/O ngầm), lỗi tường minh qua raises/check (không có luồng điều khiển ẩn), và công cụ tất định (đầu ra của trình biên dịch là dữ liệu có cấu trúc với mã ổn định và kế hoạch sửa lỗi). Các nguyên tắc này cộng hưởng với nhau: mỗi nguyên tắc làm các nguyên tắc còn lại hữu ích hơn cho agent.
Zero phải từ bỏ những gì để trở thành agent-first?
Sự ngắn gọn và những tiện lợi ngầm định. Không có giá trị truthy ngầm, không có print toàn cục, không có try/catch âm thầm tháo ngăn xếp lời gọi. Hàm có nhiều tham số hơn và chữ ký mang nhiều chú thích kiểu hơn. Bù lại, những gì một hàm làm, kể cả những cách nó có thể thất bại, đều đọc được chỉ từ chữ ký của nó.
Zero có thay thế các ngôn ngữ lập trình do con người viết không?
Không, và đó cũng không phải mục tiêu. Zero là một thử nghiệm về việc thiết kế agent-first trông như thế nào, không phải tuyên bố rằng các ngôn ngữ khác nên áp dụng mọi lựa chọn của nó. Kết quả đáng chú ý là những gì thử nghiệm này dạy ta: ràng buộc nào giúp agent nhiều nhất, đánh đổi nào con người chấp nhận được, và ý tưởng nào có thể dần quay lại các ngôn ngữ phổ biến theo thời gian.