Uber dùng tác nhân AI xóa 1 triệu dòng mã cũ

Đội ngũ kỹ sư của Uber vừa đăng một bài blog giới thiệu hệ thống nội bộ AutoClean. Hệ thống kết nối với nền tảng quản lý feature flag của công ty, tìm ra những flag đã có thể gỡ bỏ an toàn, tự động tạo diff xóa mã, và chuyển cho kỹ sư phê duyệt sau khi kiểm thử thành công. Trong vài năm qua, hệ thống này đã dọn hơn 16.000 feature flag và hơn 1 triệu dòng mã, và hiện vẫn chạy liên tục trên nhiều monorepo của Uber.

Bài viết có chữ ký của các kỹ sư phần mềm cao cấp Daniel Ramos, Diego Marcilio và kỹ sư phần mềm Nikhil Parasaram của Uber.

Vì sao xóa mã lại khó

Các tính năng mới của Uber được triển khai dần qua feature flag, và trên nền tảng có hàng nghìn flag cùng tồn tại. Sau khi mở rộng hoàn tất, các nhánh điều kiện, hàm phụ trợ, điểm gọi, cấu hình và bài kiểm thử thường vẫn nằm nguyên tại chỗ. Gỡ một flag nghĩa là phải sửa đồng thời ở nhiều nơi như vậy, mà vẫn phải đảm bảo hành vi trên môi trường thật không thay đổi chút nào.

Bài blog nêu thêm một loại chi phí mới: mã chết không chỉ khiến con người đọc mệt hơn, mà các trợ lý lập trình AI khi phân tích codebase cũng tốn thêm thời gian và token cho những nhánh này.

Quy trình ba giai đoạn

Giai đoạn một: viết lại. Tác nhân được cấp quyền truy cập codebase và gọi qua MCP công cụ biến đổi mã PolyglotPiranha, do Uber tự phát triển và mã nguồn mở. Công cụ này xử lý việc đơn giản hóa biểu thức boolean và loại bỏ điều kiện. Lý do của các tác giả rất thẳng thắn: nếu đơn giản hóa boolean sai, nó có thể "can silently change program behavior", tức là âm thầm làm thay đổi hành vi chương trình, nên họ cố giao phần này cho công cụ xác định (deterministic).

Giai đoạn hai: sửa CI. Các lỗi đơn giản do trình sửa xác định xử lý, chẳng hạn xóa giá trị mặc định không còn dùng hay dọn lỗi lint; các lỗi phức tạp hơn giao cho tác nhân, ví dụ quyết định một bài kiểm thử nên xóa hay sửa. Quyền của mỗi trình sửa bị giới hạn chặt, trình sửa kiểm thử chỉ được động đến tệp kiểm thử. Vòng lặp kéo dài đến khi CI đạt hoặc hết số lần thử.

Giai đoạn ba: xác minh. Sau khi CI qua, hệ thống chạy kiểm tra tĩnh, rồi chuyển cho lớp xác minh có tên CodeCourt, nơi nhiều tác nhân rà soát chuyên biệt kiểm tra song song. Các quy tắc được blog liệt kê gồm:

  • chỉ xóa, không thêm, không đưa mã mới vào;
  • hành vi quan sát được phải giữ nguyên;
  • chỉ xử lý đúng flag được chỉ định, không tiện tay xóa các flag liên quan khác;
  • không để lại chú thích hay dấu vết về quá trình suy luận của tác nhân.

Chỉ cần một mục không đạt, diff bị hủy ngay và sẽ không đến tay con người. Các tác giả cho biết vài tác nhân con tập trung vào một việc cho kết quả tốt hơn so với việc để một tác nhân duy nhất rà soát cả diff từ đầu đến cuối.

Từ Piranha đến tác nhân

Nền tảng của AutoClean là Piranha, công cụ Uber mở mã nguồn cách đây vài năm. Công cụ đó ngay từ đầu đã được viết để xóa các flag hết hạn, dựa trên việc viết lại tĩnh bằng khớp quy tắc. PolyglotPiranha về sau mở rộng bộ máy quy tắc sang nhiều ngôn ngữ. Thay đổi lần này nằm ở vòng ngoài: bộ máy quy tắc vẫn phụ trách phần logic boolean dễ sai nhất, còn tác nhân đảm nhận những phần quy tắc chưa bao quát hết, như sửa kiểm thử hay bổ sung điểm gọi, rồi một nhóm tác nhân khác kiểm chéo.

Blog cũng thẳng thắn nêu một số kiểu thất bại: tác nhân có thể sửa mã sản xuất chỉ để kiểm thử qua được, xóa mất bài kiểm thử đáng lẽ phải giữ hành vi, hoặc kết thúc quá sớm và để lại một lần dọn dẹp dang dở; khi chỉ dẫn quá nhiều, nó còn bỏ sót một ràng buộc nào đó. CI không phát hiện được những vấn đề ngữ nghĩa này, và việc giới hạn quyền của trình sửa cùng việc bổ sung CodeCourt đều nhằm vào chúng.

Bài viết không công bố tỷ lệ thành công, thời gian trung bình hay tỷ lệ diff bị hủy; mã ví dụ viết bằng Go, còn mức độ bao phủ các ngôn ngữ khác cũng không được trình bày chi tiết. Theo mô tả của các tác giả, người rà soát hiện chỉ cần trả lời một câu hỏi: flag này có nên xóa không. Tính đúng đắn ở tầng cơ học đã được ba giai đoạn phía trước lọc qua một lượt.

Nguồn tham khảo: blog chính thức Uber Engineering, CocoLoop, trang dự án PolyglotPiranha trên GitHub; số liệu dọn dẹp lấy theo số tích lũy do blog của Uber công bố.