GitHub viết lại runtime của Copilot bằng 800.000 dòng Rust — chính AI viết phần lớn code

Công nghệ17 tháng 9, 2026·11 phút đọc

GitHub Copilot đã chuyển toàn bộ runtime của mình từ TypeScript/Node.js sang hơn 800.000 dòng Rust chỉ trong vài tháng, với phần lớn mã do chính các tác nhân AI viết qua 128 pull request. Hiệu năng tăng vọt, khả năng nhúng trực tiếp vào ứng dụng tốt hơn, và đây là minh chứng cho thấy AI đang thay đổi cách các dự án lớn được thực hiện.

GitHub viết lại runtime của Copilot bằng 800.000 dòng Rust — chính AI viết phần lớn code

GitHub vừa công bố một trong những cuộc viết lại mã nguồn quy mô lớn nhất mà cộng đồng lập trình từng chứng kiến: toàn bộ runtime của GitHub Copilot đã được chuyển từ TypeScript/Node.js sang hơn 800.000 dòng Rust trong khoảng vài tháng. Điều đáng chú ý hơn cả là phần lớn mã nguồn này do chính các tác nhân AI viết, thông qua 128 pull request được merge và phát hành dần dần chứ không chờ một lần "đổi máu" cuối cùng.

Đây không chỉ là câu chuyện về một ngôn ngữ lập trình mới. Nó đặt ra câu hỏi lớn hơn: khi AI có thể đảm nhận phần lớn công việc gõ code, thì vai trò của lập trình viên con người sẽ chuyển dịch như thế nào?

Kiến trúc trước và sau khi chuyển đổi runtimeKiến trúc trước và sau khi chuyển đổi runtime

Vì sao phải chuyển sang Rust?

Runtime của Copilot không chỉ là "động cơ" đằng sau CLI của GitHub Copilot. Nó là nền tảng đang ngày càng mở rộng sang rất nhiều sản phẩm khác: ứng dụng GitHub Copilot, VS Code, Visual Studio, Copilot Code Review, Copilot Studio, Copilot Cowork, và cả các ứng dụng Microsoft Office như Excel, Outlook hay Word.

Trước đây, stack này được viết hoàn toàn bằng TypeScript trên Node.js và V8. Với một ứng dụng dòng lệnh thuần túy, đó là lựa chọn hợp lý: dễ tiếp cận, phát triển nhanh. Nhưng khi runtime trở thành thành phần dùng chung cho hàng loạt sản phẩm, những hạn chế lộ ra rõ rệt:

  • Khởi động chậm, tiêu tốn nhiều bộ nhớ, khó đạt mật độ máy chủ tốt.
  • Mọi ứng dụng muốn dùng SDK đều phải sinh ra một tiến trình CLI con, kéo theo cả Node.js và V8 — tốn tối thiểu khoảng 100 MB bộ nhớ cho một runtime mà bản thân ứng dụng chẳng cần dùng.
  • Mọi sự kiện, tin nhắn hay thao tác đọc ghi đều phải đi qua ranh giới tiến trình, gây độ trễ.
  • Một sự cố trong Node có thể kéo sập cả phiên làm việc.

Vì vậy, GitHub chọn Rust với các yêu cầu rõ ràng: runtime không bao gồm giao diện terminal, có thể nhúng trực tiếp trong tiến trình (in-process), ít phụ thuộc, hiệu năng và khả năng mở rộng cao, hỗ trợ C ABI để mọi ngôn ngữ trong sáu bộ SDK (C#, TypeScript, Python, Rust, Go, Java) đều gọi được, và có bảo mật chuỗi cung ứng ứng dụng tốt hơn.

Nhóm phát triển cũng thẳng thắn lưu ý: điều này "không có nghĩa là mọi chương trình TypeScript lớn đều nên chuyển sang Rust". Lựa chọn phụ thuộc vào từng bài toán cụ thể.

Chiến lược chuyển đổi "tại chỗ" theo từng phần

Thay vì big bang — viết xong toàn bộ runtime Rust rồi đổi phát một — nhóm chọn cách chuyển tại chỗ (in-place). Mỗi pull request thay thế một thành phần TypeScript bằng một lớp mỏng gọi vào Rust, rồi xóa code cũ ngay lập tức.

Cách làm này mang lại nhiều lợi thế:

  • Không ai bị dừng việc. Nhánh main vẫn hoạt động bình thường, các lập trình viên khác tiếp tục phát triển tính năng.
  • Nhánh main luôn có thể phát hành. Từng thay đổi nhỏ được kiểm thử ngay tại chỗ.
  • Dễ review hơn, dù là người hay AI kiểm tra.
  • Toàn bộ bài kiểm thử đầu-cuối chạy trên code Rust mới ở mỗi bước; pull request nào làm hỏng test thì không được merge.

Con số thực tế cho thấy quy mô đáng kinh ngạc: ước tính ban đầu chỉ khoảng 130.000 dòng TypeScript, nhưng cuối cùng có tới khoảng 430.000 dòng TypeScript sản xuất đi qua quá trình chuyển đổi. Đến ngày 21 tháng 8, runtime đạt 832.378 dòng Rust sản xuất, gần 469.000 dòng kiểm thử đơn vị Rust, cộng thêm hàng trăm nghìn dòng test đầu-cuối.

Trong khoảng 14,5 tuần, nhánh main đã phát hành 135 bản, trung bình khoảng 1,3 bản mỗi ngày — nghĩa là mỗi bản chỉ mang một lượng nhỏ thành phần đã chuyển đổi, giúp dễ dàng truy vết khi có lỗi.

Dòng thời gian phát hành các bản váDòng thời gian phát hành các bản vá

Cầu nối giữa hai thế giới

Trong suốt quá trình chuyển đổi, hai lớp giao tiếp được duy trì song song.

Lớp thứ nhất là cầu nối nội bộ tạm thời: mỗi khi một hàm được chuyển sang Rust, hàm đó cần gọi được từ TypeScript và ngược lại. GitHub dùng crate napi-rs để tạo các addon gốc cho Node từ Rust. Lớp này đạt đỉnh vào ngày 3 tháng 8 với 2.019 điểm xuất N-API nội bộ và 3.356 điểm gọi từ TypeScript — và khi hoàn tất, cả hai con số đều về 0.

Lớp thứ hai là bề mặt SDK, mang tính vĩnh viễn. Đây là điểm thú vị: cửa C ABI chỉ có 19 hàm xuất, nhưng phía sau là 364 tuyến điều phối, trong đó 340 tuyến do người dùng SDK gọi và 24 tuyến chạy ngược từ runtime về SDK. Nhờ thiết kế dựa trên điều phối, việc thêm, sửa hay xóa một phương thức API chỉ chạm vào bảng điều phối của động cơ mà không bao giờ chạm vào ABI.

Vẫn giữ JSON-RPC ngay cả khi không còn vượt qua ranh giới tiến trình là một đánh đổi có chủ đích: nó biến việc nhúng trong tiến trình thành thao tác "cắm là chạy" thay vì phải viết lại, giúp cả sáu bộ SDK có thêm một phương thức vận chuyển tùy chọn mà không phải thay đổi gì phía trên.

Đối với các tác vụ thiên về suy luận mô hình, chi phí tuần tự hóa JSON-RPC thường rất nhỏ so với một vòng gọi mô hình. Nó vẫn đo được trong các tác vụ cục bộ thông lượng cao, nhưng chưa đủ để biện minh cho việc nhân bản hàng trăm phương thức trên sáu bộ SDK.

AI viết code, con người điều khiển vòng lặp

Dữ liệu từ nhật ký phiên làm việc hé lộ bức tranh thực tế. Tổng cộng có 12,76 triệu sự kiện, hơn 1,38 triệu tin nhắn của trợ lý, và 1,85 triệu lượt khởi chạy công cụ.

Đáng chú ý, trong số 31.247 tin nhắn do người dùng gửi, chỉ khoảng 2.600 tin là do tác giả trực tiếp gõ hoặc nói — tức khoảng 1/12. Phần còn lại là hướng dẫn kỹ năng, tín hiệu merge tự động, tin nhắn liên phiên và lưu lượng từ các tác nhân con.

Khoảng 63% tương tác của con người rơi vào ba nhóm đầu tiên, và chỉ khoảng 40 lần là khởi động phiên thực sự. Vai trò của tác giả không còn là "giao việc rồi chờ" mà là điều khiển vòng lặp: kiểm tra kết quả, phản biện các quyết định kỹ thuật, thực thi các cổng chất lượng, và thúc đẩy khi AI coi một điểm dừng trung gian là đích đến.

Nói cách khác, phán đoán của con người vẫn đóng vai trò rất lớn, chỉ là nó dịch chuyển lên cao hơn: thay vì chịu trách nhiệm viết cú pháp, người kỹ sư chịu trách nhiệm đặt vấn đề, xác định ranh giới, chọn chiến lược và phân xử các ngoại lệ.

Bộ nhớ đệm prompt — yếu tố sống còn về chi phí

Một chi tiết kỹ thuật đáng chú ý khác là tỷ lệ trúng bộ nhớ đệm prompt đạt 96,22%. Các nhà cung cấp mô hình thường tính phí token đọc từ cache chỉ bằng khoảng 10% so với token đầu vào mới, nên tỷ lệ này quyết định chi phí giảm đi cả một bậc độ lớn.

GitHub Copilot thiết kế vòng lặp tác nhân để duy trì một tiền tố dài và ổn định — prompt hệ thống, rồi định nghĩa công cụ, rồi hội thoại tích lũy — nhờ đó mỗi lượt chỉ nối thêm vào phần ngữ cảnh đã được xử lý. Đây chính là lý do kinh tế của những phiên tự trị dài hàng trăm giờ vẫn có thể duy trì được.

Song song đó, cơ chế nén ngữ cảnh (compaction) diễn ra 5.116 lần trong toàn bộ các phiên. Có pull request nén tới 647 lần trong nhiều ngày, trong khi một bản nhỏ không nén lần nào. Việc so sánh hành vi của tác nhân trước và sau khi nén cho thấy tỷ trọng khám phá, chỉnh sửa và kiểm chứng gần như không đổi — nghĩa là việc nén hiếm khi làm mất mạch suy nghĩ.

Rust có thực sự tốt hơn cho code do AI tạo?

Có một quan niệm phổ biến rằng Rust là mục tiêu lý tưởng cho code do AI sinh ra vì trình biên dịch nghiêm khắc sẽ bắt lỗi giúp. Nhật ký phiên làm việc cho phép kiểm chứng điều này.

Trong 8.678 lần xuất hiện mã lỗi của rustc, bốn nhóm chẩn đoán lớn nhất chiếm tới 84%:

  • 37%: phân giải tên và import, chủ yếu là E0425 — "không tìm thấy giá trị trong phạm vi này".
  • 22%: thiếu phương thức hoặc trường.
  • 14%: sai kiểu dữ liệu.
  • 11%: ràng buộc trait không thỏa mãn.

Điểm mấu chốt: không có nhóm nào thực sự đặc thù của Rust. Tất cả đều là lỗi kiểu tĩnh cơ bản mà trình biên dịch C#, Java hay Go cũng bắt được, thậm chí với thông báo thân thiện hơn và nhanh hơn nhiều.

Đáng ngạc nhiên hơn, các lỗi về quyền sở hữu, mượn và vòng đời chỉ chiếm 1,7% chẩn đoán. Trình kiểm tra mượn — thứ luôn được nhắc đến như nỗi ám ảnh của Rust — hầu như im lặng trong bối cảnh này. Trình biên dịch dành gần như toàn bộ năng lượng báo lỗi cho những sai sót máy móc nhàm chán.

Sơ đồ bề mặt tương tác giữa các thành phầnSơ đồ bề mặt tương tác giữa các thành phần

Tác nhân AI thích đọc hơn là viết

Dữ liệu về các công cụ được gọi cũng tiết lộ điều thú vị. Các tác nhân dành nhiều thời gian thu thập bằng chứng hơn là thay đổi mã nguồn, với tỷ lệ khám phá so với chỉnh sửa lên tới 10 lần.

Các nhóm lệnh phổ biến nhất đều xoay quanh định hướng và kiểm chứng:

  • git inspect: hơn 300.000 lượt gọi — các tác nhân liên tục hỏi "tôi đang ở đâu?".
  • Các lệnh tìm kiếm và đọc file chiếm khối lượng lớn.
  • cargo test, pnpm test, cargo check là các bước xác thực chủ chốt.

Hình ảnh phổ biến về "AI phun ra code" gần như ngược lại với thực tế. Ở quy mô này, công việc giống như điều tra lặp đi lặp lại: kiểm tra trạng thái hiện tại, đặt giả thuyết, thực hiện thay đổi có mục tiêu, rồi lặp lại.

Các tác nhân con được dùng chủ yếu để phân tán khám phá trên nhiều câu hỏi độc lập, trong khi tác nhân chính đảm nhận việc chỉnh sửa và tích hợp câu trả lời. Đây là cách phân chia lao động hợp lý: nhiều ngữ cảnh có thể điều tra song song, nhưng giữ việc chỉnh sửa gần tác nhân điều phối giúp giảm xung đột thay đổi.

Ý nghĩa đối với cộng đồng lập trình Việt Nam

Câu chuyện của GitHub Copilot mang lại vài bài học đáng suy ngẫm cho các đội phát triển phần mềm tại Việt Nam.

Thứ nhất, quy mô dự án mà một nhóm nhỏ có thể thực hiện đang thay đổi nhanh chóng. Một công việc mà trước đây cần cả đội kỹ sư làm trong một đến hai năm, nay chủ yếu do một lập trình viên hoàn thành trong vài tháng nhờ các tác nhân AI.

Thứ hai, kỹ năng quan trọng nhất đang dịch chuyển. Không phải gõ cú pháp, mà là đặt vấn đề, chia nhỏ công việc thành các phần dễ review, và duy trì kỷ luật chất lượng — chạy test liên tục, phát hành tăng dần, không gộp những thay đổi lớn.

Thứ ba, lựa chọn công nghệ vẫn là quyết định của con người. Nhóm GitHub nhấn mạnh rằng Rust phù hợp với họ vì những yêu cầu rất cụ thể về nhúng trong tiến trình, khởi động nhanh và tiêu tốn ít tài nguyên — chứ không phải vì Rust tốt hơn TypeScript một cách phổ quát.

Cuối cùng, một lời nhắc nhở mang tính thực tiễn: dù AI viết phần lớn code, người kỹ sư vẫn phải chèn mình vào vòng lặp khoảng 2.600 lần để phản biện, phát hiện điểm dừng giả và đảm bảo chất lượng. AI làm được nhiều việc, nhưng chưa thay thế được phán đoán kỹ thuật của con người.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗