Thủ thuật
Công cụ phát triển phần mềm bắt buộc phải là mã nguồn mở
(giờ Việt Nam)
Tóm tắt AI
Với AI, lập trình viên có thể tự động hóa việc tải, xây dựng và cập nhật mã nguồn chỉ bằng vài câu lệnh. Cơ chế này giúp việc tùy biến công cụ cá nhân trở nên dễ dàng và linh hoạt hơn nhiều so với các plugin truyền thống.
Bản dịch AI

Năm năm trước, hầu hết các kỹ sư phần mềm mà tôi trò chuyện đều không có chương trình nào tự viết cho riêng mình. (Tôi thường đặt câu hỏi này như một phần trong nỗ lực tìm hiểu xem Tailscale có thể phù hợp với cuộc sống của các kỹ sư như thế nào.) Suốt cả ngày, ngày này qua ngày khác, các kỹ sư sử dụng những chương trình do người khác viết để tạo ra các chương trình cho người khác. Nhiều người trong chúng ta tùy chỉnh các chương trình mình sử dụng thông qua các tệp cấu hình (config files), plugin hoặc tiện ích mở rộng, và nhiều người trong chúng ta sử dụng các chương trình mình viết cho người khác với tư cách là người dùng. Thật là một điều thú vị hiếm hoi khi hỏi ai đó về những gì họ đã tự viết cho chính mình và biết được về phần mềm "may đo" đằng sau blog của họ, hệ thống tự động hóa ngôi nhà, hay homelab của họ, thay vì một trình tạo trang tĩnh (static site generator) hay thiết bị Zigbee mua sẵn vốn chỉ "gần đúng" với nhu cầu.
Tình trạng này hoàn toàn dễ hiểu đối với tôi. Trong nhiều năm, tôi đã viết rất nhiều phần mềm cho bản thân, nhưng lợi ích thu lại từ việc đó luôn là một dấu hỏi. Tôi chỉ có thể viết được một lượng nhất định trong ngày. Luôn có những việc quan trọng hơn cần làm (Công việc luôn có vấn đề), và việc quay lại một dự án sau một năm để bảo trì luôn là một cực hình. Đã có nhiều năm trong sự nghiệp, tôi từng vứt bỏ tất cả các phần mềm tùy chỉnh của mình và sử dụng những môi trường tiêu chuẩn nhất có thể để viết code. Trong những năm đầu làm kỹ sư tại Google, tôi thậm chí còn không sở hữu một chiếc máy tính cá nhân nào.
Đó là chuyện ngày xưa. Bây giờ mọi thứ đã khác.
Cách cá nhân hóa phần mềm
Ngày nay, việc cá nhân hóa phần mềm trở nên dễ dàng đến kinh ngạc. Có hai loại câu lệnh (prompt) tổng quát dành cho một tác nhân (agent) giúp biến tất cả những điều này thành hiện thực:
và quan trọng hơn là:
Cốt lõi của vấn đề này là nhận thức rằng các tác nhân không chỉ có thể viết nhanh một đoạn mã cho một mục đích cụ thể mà còn tự động quản lý quá trình đồng bộ hóa các thay đổi với các bản phát hành gốc (upstream releases). Điều này có nghĩa là các tác nhân thay đổi tỷ suất hoàn vốn (ROI) của việc tùy chỉnh phần mềm trên hai mặt trận cùng lúc: bắt đầu cá nhân hóa dễ dàng hơn nhiều và duy trì nó cũng dễ dàng hơn nhiều.
Một điều đáng kinh ngạc khác về hai câu lệnh trên để chỉnh sửa phần mềm là bạn có thể tích hợp trực tiếp chúng vào một tác nhân. Miễn là tác nhân đó là mã nguồn mở, bạn thậm chí không cần phải lập trình. Hai câu lệnh này có thể được tải vào một kỹ năng (tức là một số hướng dẫn bằng văn bản) và đặt ở nơi mà tác nhân có thể tìm thấy. Chúng tôi đã tích hợp điều này vào Shelley, vì vậy bây giờ nếu bạn muốn chỉnh sửa Shelley, bạn thậm chí không cần phần mở đầu hay cấu hình bộ hẹn giờ. Nó sẽ tự lo liệu cho bạn. Bạn chỉ cần nhập một câu lệnh như “làm cho giao diện của Shelley có độ tương phản cao” và bạn đã cá nhân hóa tác nhân của mình.
Một ví dụ thực tế về cá nhân hóa: Shelley và Meat
Tôi có một dự án cá nhân mà tôi đã thong thả mày mò trong tháng qua: meat.dev. Nguyên tắc là trong khi các tác nhân viết code, tôi vẫn đọc nó trước khi đẩy lên các hệ thống quan trọng của chúng tôi. Khi các mô hình nền tảng cải thiện, những gì tôi tìm kiếm cũng thay đổi. Những con người mà tôi đã dành hai mươi năm để review code luôn gặp khó khăn với các trường hợp biên (edge cases): liệu các lỗi có báo cáo thông tin hữu ích không; các kiểm tra nil (nil-checks) có được xử lý không, v.v. (Tất cả chúng ta đều làm vậy; khi viết code, tôi là một trong những người mắc lỗi tệ nhất.) Một trong những vai trò của tôi với tư cách là người review là tìm kiếm những chi tiết này. Trong sáu tháng qua, tôi phát hiện ra mình không cần phải đọc để tìm các trường hợp biên như vậy nữa: các mô hình cẩn thận hơn nhiều so với con người trong việc đảm bảo tính chính xác máy móc. Lỗi của chúng chỉ giới hạn ở kiến trúc, các trường hợp sử dụng bất ngờ, đầu ra hình ảnh mà môi trường thử nghiệm của chúng không phản hồi lại, v.v. Điều này có nghĩa là hầu hết các dòng code tôi review đều không hữu ích lắm. Vì vậy, tôi đã viết một công cụ lấy các diff (sự khác biệt giữa các bản code) và sử dụng LLM để loại bỏ những thứ không quan trọng. Tôi gần như không bao giờ cần phải xem các khối import, hay các kiểm tra nil, hay xử lý lỗi nữa, vì vậy hãy loại bỏ chúng khỏi màn hình để tôi có thể tập trung vào phần "thịt" (meat) của vấn đề.
Tôi thích công cụ này, nhưng nó có hai nhược điểm: thứ nhất, tôi thích đọc các diff của mình trong Shelley với giao diện đẹp, không phải trong terminal. Thứ hai, mất vài phút để một LLM tiêu hóa và tối giản một diff, và tôi không muốn chờ đợi. Vì vậy, lý tưởng nhất là tôi không chạy meat trên dòng lệnh, mà tích hợp nó vào Shelley và để nó xử lý trước các commit ngay khi chúng được tạo. Hóa ra tôi có thể làm điều đó chỉ với một câu lệnh duy nhất:
Hãy tích hợp meat.dev vào Shelley. Cài đặt phiên bản mới nhất vào PATH. Khi một git commit được tạo bởi Shelley, hãy bắt đầu xử lý meat trong nền trên commit đó. Thêm một nút chuyển đổi (toggle) vào chế độ xem Shelley Diffs cho meat. Nếu commit vẫn đang được xử lý, hãy hiển thị cho người dùng biết là nó đang trong quá trình xử lý.
Câu lệnh duy nhất này là tất cả những gì cần thiết để không chỉ thêm meat vào Shelley, mà còn xử lý trước các commit trong nền trước khi tôi quay lại phiên làm việc để review diff, giúp tôi không phải chờ đợi mô hình rút gọn diff nữa. Lựa chọn duy nhất không may mà mô hình đưa ra là sử dụng biểu tượng cảm xúc 🥩 cho nút chuyển đổi.
Hãy tưởng tượng sự khốn khổ phức tạp khi cố gắng cắm nó vào API tiện ích mở rộng của VS Code! Hoặc cố gắng đưa nó vào vimdiff. Chắc chắn là có thể, nhưng cơ chế để bắt đầu xử lý trước các commit ngay khi chúng xuất hiện sẽ gần như là không thể. Tôi thà triển khai một meatd ngoại vi (out-of-band) lắng nghe hệ thống tệp và cung cấp bộ nhớ đệm cho công cụ meat mà một API tùy chỉnh có thể sử dụng, vì các điểm mở rộng và cấu hình sẽ không có hình dạng phù hợp.
Và đó là sự khác biệt cơ bản giữa cấu hình/tùy chỉnh cổ điển và cá nhân hóa dựa trên tác nhân: bạn có thể làm được nhiều hơn thế. Tác nhân sẽ thực hiện công việc khó khăn là hiểu mã nguồn và thay đổi nó để phù hợp với tác vụ cụ thể mà bạn đang nghĩ đến. Phần mềm chúng ta sử dụng sẽ mạnh mẽ hơn nhiều với sự cá nhân hóa. Tất cả những gì bạn cần là mã nguồn.
Kỷ nguyên của phần mềm cá nhân hóa
Chi phí phát triển trước thời đại tác nhân có nghĩa là việc các phần mềm phức tạp đi kèm với các tệp cấu hình lớn, hệ thống tiện ích mở rộng và hệ thống plugin là điều hợp lý. Mã nguồn cốt lõi của ngay cả một dự án vừa phải như Vim cũng rất lớn và phức tạp, và mất hàng tuần để một con người có thể tiêu hóa được. Ý nghĩ rằng, khi muốn in số dòng theo mặc định, một kỹ sư sẽ tìm hiểu cơ sở mã và tự thêm nó vào cho riêng mình là điều không hợp lý. Tốt hơn là thiết kế nó để chia sẻ với người khác, điều này biện minh cho chi phí thực hiện bằng cách phân bổ nó cho nhiều người dùng. Khi các tính năng trong cơ sở mã phát triển, việc tìm kiếm các trừu tượng chung để tách ra một hệ thống tiện ích mở rộng hoặc plugin là điều hợp lý.
Giờ đây, chi phí để tìm hiểu mã và thực hiện thay đổi đã giảm đáng kể. Các tác nhân thực hiện những công việc nặng nhọc. Đối với một người dùng đơn lẻ—điều này ngụ ý các điều kiện cực kỳ hạn chế mà chương trình chạy—một tác nhân hàng đầu hiện nay thường có thể thêm một tính năng trong một lần thực hiện. Đối với phần mềm dành cho một người dùng, nhu cầu review code cẩn thận thường có thể được thay thế bằng câu hỏi “nó có vẻ hoạt động không?”.
Kết quả là phần mềm có thể cá nhân hóa không cần hệ thống plugin hay tệp cấu hình. Bạn muốn thay đổi kích thước phông chữ trong trình soạn thảo văn bản của mình? Hãy đưa mã nguồn cho tác nhân và bảo nó làm điều đó. Nếu đó là một giá trị được mã hóa cứng (hardcoded), nó sẽ tìm và chỉnh sửa. Nếu đó là một phông chữ bitmap được mã hóa cứng, nó sẽ tải xuống một phông chữ khác và thay thế, hoặc nó sẽ sử dụng Monobit để tạo cho bạn một cái! Bạn có những khả năng đáng kinh ngạc trong tầm tay.
Toàn bộ các danh mục sản phẩm phần mềm cần được tái tạo
Phần mềm cá nhân cũng áp dụng tốt cho các nhóm nhỏ. Tại sao một nhóm kỹ thuật lại mua một trình quản lý tác vụ (hoặc CMS hay CRM) cực kỳ dễ cấu hình, dành thời gian tìm hiểu và cấu hình nó, rồi phải gò ép nhóm của họ theo giới hạn của nó, trong khi họ có thể lắp ghép các tính năng họ muốn từ các khối xây dựng chung?
Cả chi phí cố định ban đầu và chi phí duy trì việc cá nhân hóa phần mềm đều đã biến mất.
Blog bạn đang đọc là phần mềm "may đo", được viết bằng Shelley, vì việc lắp ghép và cá nhân hóa các thư viện như Tiptap dễ dàng hơn nhiều so với việc cố gắng tùy chỉnh các sản phẩm phần mềm truyền thống. Để các sản phẩm dành cho người dùng cuối có ý nghĩa trong một công ty ngày nay, chúng cần phải có khả năng cá nhân hóa. Điều đó có nghĩa là chúng ta cần mã nguồn.
Nơi Codex và Claude Code khác biệt
Kỹ thuật dựa trên kỹ năng tương tự đã được áp dụng cho Shelley để làm cho nó có thể cá nhân hóa cũng có thể được áp dụng một cách đơn giản cho các tác nhân mã nguồn mở khác như Pi. (Đến mức tôi tự hỏi tại sao Pi cần một hệ thống tiện ích mở rộng được tích hợp sẵn. Mã nguồn chính là hệ thống tiện ích mở rộng.) Nó sẽ yêu cầu nhiều token hơn, nhưng bạn có thể làm điều tương tự với Codex, một tác nhân mã nguồn mở.
Tuy nhiên, nơi bạn sẽ gặp bế tắc là Claude Code. Đó là phần mềm mã nguồn đóng, vì vậy bạn không thể cá nhân hóa nó. Có rất nhiều hook tùy chỉnh kiểu cũ trong Claude Code. Hy vọng rằng cách bạn muốn một tác nhân hoạt động phù hợp với các hook của họ. Nếu không, hãy chuyển sang một tác nhân cho phép bạn cá nhân hóa nó.
Bài viết được AI dịch và tổng hợp tự động từ Hacker News Nổi bật (buzzing.cc bản dịch tiếng Trung). Liên kết bài gốc ở phía trên. Dữ liệu đồng bộ qua API công khai được ghi nguồn tại AI HOT (canonical) ↗. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.