- Khi refactor từng bước lớp truy cập dữ liệu Rust dài 17.155 dòng do agent viết, số token đầu vào cần cho cùng một thay đổi tính năng đã giảm 83%, từ 159.564 xuống 27.360
- Tổng lượng mã gần như không đổi, nhưng bằng cách tách mã liên quan vào các tệp có độ kết dính cao, agent có thể chỉ đọc tập hợp tệp tối thiểu cần cho thay đổi
- Token đầu vào không giảm đáng kể cho đến khi tệp lớn nhất đủ nhỏ; cuối cùng lớp dữ liệu được chia thành 19 tệp Rust và kích thước tệp lớn nhất giảm từ 17.155 dòng xuống 3.695 dòng
- Token đầu ra và lượng triển khai tính năng gần như không đổi, và Claude cũng không tự chọn hoặc thực hiện refactoring phù hợp một cách ổn định, nên cần hướng dẫn chủ động của con người trong khâu lập kế hoạch và thực thi
- Với giá đầu vào của Sonnet 5 là $3/MTok, khoản tiết kiệm cho mỗi lần thay đổi chỉ khoảng $0,397, nhưng thí nghiệm xác nhận khả năng chi phí sẽ tiếp tục giảm lặp lại mỗi lần sửa lớp truy cập dữ liệu về sau
Tệp 17.155 dòng do agent tạo ra
- Ứng dụng hỗ trợ công việc có web UI cho phép cập nhật và truy vấn động, modal và tự động lưu, tích hợp hệ thống bên ngoài, machine learning và phân tích văn bản, tác vụ nền, cùng môi trường triển khai tự động
- Trong tổng cộng khoảng 150 nghìn dòng, Rust chiếm khoảng 120 nghìn dòng, phần còn lại là TypeScript và Terraform; phần lớn được agent viết bằng Claude Code và một phần bằng Cursor
- Ngoài những lúc thỉnh thoảng xem qua vì tò mò, lập trình viên không đọc hay review mã
- Lớp truy cập dữ liệu lặp lại cùng phần thiết lập HTTP request và mã hóa/giải mã JSON trong mọi query đọc/ghi, tăng lên hơn 6.000 dòng, và cuối cùng một tệp Rust đạt tới 17.155 dòng
- Module này không có loại bỏ trùng lặp hay ngôn ngữ nội bộ, việc trích xuất hàm còn hạn chế và hầu như không trích xuất class, nhưng có interface cần giữ nguyên và ranh giới rõ ràng nên phù hợp cho thí nghiệm refactoring
Cách đo bằng cách lặp lại cùng một thay đổi
- Mục tiêu là kiểm tra liệu việc đầu tư token vào refactoring hiện tại có thể giảm mức tiêu thụ token cho các thay đổi tính năng trong tương lai hay không
- Vì agent không học từ tác vụ trước đó, ở mỗi bước, một sub-agent mới được yêu cầu thực hiện chính xác cùng một thay đổi để tránh lẫn hiệu ứng học
- Thí nghiệm được tiến hành theo thứ tự sau
- Lập kế hoạch tổng thể theo các nguyên tắc refactoring nghiêm ngặt
- Định nghĩa một thay đổi đại diện bằng một prompt duy nhất
- Cho sub-agent thực hiện thay đổi và báo cáo lượng token tiêu thụ để đo giá trị nền
- Hủy kết quả thay đổi rồi áp dụng một bước refactoring
- Lặp lại việc thực hiện cùng thay đổi và hủy kết quả
- Ghi lại chi phí token, thời gian chạy và số dòng mã theo từng bước
- Vì Claude không cung cấp số token thời gian thực một cách đáng tin cậy, nó được yêu cầu báo cáo số ký tự gửi/nhận, rồi dùng tiktoken chia số ký tự cho 4 để xấp xỉ token
Kết quả đo theo từng bước
- Ở trạng thái nền, cả lớp truy cập dữ liệu và tệp lớn nhất đều có 17.155 dòng, toàn bộ mã Rust có 50.359 dòng, và thay đổi đại diện cần 159.564 token đầu vào, 1.705 token đầu ra, 342 giây
- Sau 15 bước, lớp truy cập dữ liệu còn 16.608 dòng, tệp lớn nhất 3.695 dòng, toàn bộ mã Rust 49.812 dòng; token đầu vào là 27.360, token đầu ra 2.113, thời gian chạy 454 giây
- Ở các bước trung gian, khi tệp lớn nhất nhỏ dần thì token đầu vào cũng giảm theo
- Sau bước 7, trích xuất
queries.rs, tệp lớn nhất còn 15.670 dòng, đầu vào giảm xuống 151.850 token - Sau bước 8, trích xuất
traits.rs, tệp lớn nhất còn 13.845 dòng, đầu vào là 132.558 token - Sau bước 12, tách
store/, tệp lớn nhất còn 9.269 dòng, đầu vào giảm xuống 104.080 token - Sau lần tách
store/cuối cùng, tệp lớn nhất còn 3.695 dòng, đầu vào giảm mạnh xuống 27.360 token
- Sau bước 7, trích xuất
- Lớp truy cập dữ liệu cuối cùng gồm 19 tệp Rust, và tệp lớn nhất trở thành thư viện test
- Cũng có thể áp dụng cùng phương pháp cho tệp test đó trong các lần refactoring bổ sung
Vì sao token đầu vào giảm 83%
- Token đầu vào cho cùng một tác vụ giảm từ 159.564 xuống 27.360, tiết kiệm 132.204 token
- Tổng lượng mã của lớp truy cập dữ liệu gần như không đổi, nên đây không phải là kết quả của việc bản thân lượng mã cần đọc bị giảm
- Agent đã xác định được tập hợp tệp tối thiểu cần cho tác vụ và chỉ đọc vùng mã ngày càng nhỏ hơn; điều này cũng được xác nhận trong phần suy luận của Claude Code và tóm tắt đọc tệp
- Nếu chỉ tùy tiện chia nhỏ tệp, agent sẽ phải đọc nhiều tệp để tìm mã liên quan, nên khó đạt hiệu quả tương tự
- Mức giảm lớn nhất xảy ra ở lần tách cuối cùng, nhưng việc tách tệp đó khả thi là nhờ các bước trước đã trích xuất phần trùng lặp và tạo ra cấu trúc cốt lõi lặp lại
- Thứ tự này không được thiết kế trước nhằm giảm chi phí, mà xuất hiện từ quy trình refactoring thông thường: loại bỏ trùng lặp cục bộ trước, làm lộ phần lõi chung, rồi phân rã thành các tệp nhỏ hơn
Token đầu ra và tác động tài chính
- Token đầu ra gần như không đổi khi viết thay đổi đại diện, nên refactoring không làm giảm kích thước thay đổi thực tế
- Giá token đầu ra gấp 5 lần token đầu vào, nhưng số lượng tuyệt đối nhỏ hơn nhiều
- Tính theo giá đầu vào Sonnet 5 là $3/MTok, khoản tiết kiệm cho mỗi thay đổi khoảng 39,7 cent
- Chưa xác nhận được liệu khoản tiết kiệm có tích lũy trong debugging, các tính năng phức tạp hơn, hay refactoring toàn bộ codebase hay không, cũng như chi phí của chính việc refactoring là bao nhiêu
- Cũng chưa rõ liệu có thể refactor để giảm cả token đầu ra hay không; trong thay đổi đại diện đơn giản, nhiễu từ việc sinh mã không tất định đã che khuất khác biệt do thay đổi cấu trúc
Refactoring cùng Claude
- Claude không tự chọn được kiểu refactoring cần áp dụng sau khi xem mã; kết quả thực tế tương ứng với những tác vụ được prompt chỉ thị trực tiếp
- Dù development harness có bước refactoring rõ ràng, Claude không dùng bước đó để cải thiện tệp 17.155 dòng
- Trong quá trình lập kế hoạch, Claude Code xác định trích xuất hàm là bước đầu tiên, trong khi Claude.ai nhận ra cả việc trích xuất toàn bộ class client
- Với các thay đổi mang tính cơ học, thí nghiệm dùng script Python chạy
grepvàsed, nhưng script thường bị rối vì vấn đề thụt lề - Việc tách tệp store có giá trị lớn nhất bị bỏ sót ở lần thử đầu và được áp dụng lại ở bước sau, nên số bước trong kết quả đo không khớp với các bước kế hoạch ở phụ lục
- Toàn bộ thí nghiệm mất khoảng 8 giờ và phần lớn chạy không cần giám sát
- Sau 6 giờ 40 phút, người thực hiện phát hiện bước bị thiếu và can thiệp một lần
- Nguyên nhân làm test chạy chậm đáng kể không phải Wi-Fi khách sạn chậm, mà là cache build tạm thời của Cargo đã phình quá lớn
Prompt thay đổi đại diện
- Mỗi sub-agent chỉ được cung cấp codebase và tài liệu kiến trúc, rồi triển khai cùng một public async trait
ItemWatchStore - Trait gồm ba method sau
watch_item(&self, item_id: &str, user_id: &str) -> Result<()>unwatch_item(&self, item_id: &str, user_id: &str) -> Result<()>watched_items_for_user(&self, user_id: &str) -> Result<Vec<String>>
- Thông tin watch được lưu trong collection
item_watchescủa Firestore với các fielditemId,userId,createdAt - Trả về
Vec<String>của item ID mà không có struct record Rust riêng - Thêm field
Vec<(String, String)>trong bộ nhớ vàoFakeStore, và triển khaiFirestoreStorebằng cách giữ nguyên mẫu HTTP hiện có - Ở cuối phản hồi, agent được yêu cầu in JSON gồm các tệp đã đọc, số ký tự, số ký tự phản hồi, và không commit mã
Kế hoạch refactoring đã áp dụng
-
Bước 1 — Trích xuất class
FirestoreClient- Tách trách nhiệm điều phối domain query và gửi HTTP tới Firestore
- Di chuyển
reqwest::Client,project_id,MetadataAuth, xử lý URL và header xác thực sang struct mới - Theo kế hoạch, giảm khoảng 1.200 dòng trong phần triển khai
FirestoreStorevà thêm khoảng 120 dòng vào client
-
Bước 2 — Trích xuất hàm
extract_doc_id,new_link- Dùng chung phần trích xuất ID trong 20 parser tài liệu và phần tạo
Linklặp lại 62 lần - Dự kiến tiết kiệm khoảng 500 dòng
- Dùng chung phần trích xuất ID trong 20 parser tài liệu và phần tạo
-
Bước 3 — Trích xuất hàm pipeline link query
- Dùng chung mẫu thu thập kết quả query ở khoảng 15 nơi và tra cứu ID mục tiêu đơn ở khoảng 8 nơi
- Dự kiến tiết kiệm khoảng 200 dòng
-
Bước 4 — Trích xuất hàm điều kiện link của
FakeStoreInner- Tách các biến thể
inner.links.iter()lặp lại trong khoảng 15 method thành hai method - Dự kiến tiết kiệm khoảng 120 dòng
- Tách các biến thể
-
Bước 5 — Giới thiệu hàm tạo giá trị Firestore
- Thay thế các biểu thức
json!cho chuỗi, timestamp, v.v. lặp lại hơn 128 lần bằng bốn lời gọi hàm - Thay macro nhiều dòng bằng lời gọi một dòng, dự kiến tiết kiệm khoảng 80 dòng
- Thay thế các biểu thức
-
Bước 6 — Trích xuất
FieldsBuilder- Gom mẫu tạo field map trong khoảng 20 encoder vào một builder
- Giảm encoder khoảng 40 dòng xuống còn khoảng 12 dòng, dự kiến tiết kiệm tổng cộng 500–600 dòng
-
Bước 7 — Tách
queries.rs- Di chuyển 32 hằng
LinkQueryvà các kiểu liên quan sang module riêng - Giảm khoảng 800 dòng khỏi
mod.rsmà không thay đổi phía gọi hiện có
- Di chuyển 32 hằng
-
Bước 8 — Tách
traits.rs- Di chuyển 17 public trait và các kiểu lỗi liên quan rồi re-export
- Giảm khoảng 1.900 dòng khỏi
mod.rs, nhưng tệp mới cũng dài khoảng 1.900 dòng
-
Bước 9 — Tách
traits/theo domain- Chia trait thành
planning.rs,content.rs,people.rs,system.rs - Giữ nguyên định nghĩa và phía gọi, đồng thời giới hạn kích thước mỗi tệp khoảng 300–650 dòng
- Chia trait thành
-
Bước 10 — Tách
codec.rs- Di chuyển encoder/decoder tài liệu, parser,
FieldsBuilder, các hàm tạo giá trị - Sau bước 6, module này dài khoảng 400–500 dòng và giảm khoảng 500 dòng khỏi
mod.rs
- Di chuyển encoder/decoder tài liệu, parser,
-
Bước 11 — Tách
fake_store.rs- Di chuyển
FakeStore,FakeStoreInnervà 18 implementation trait - Giảm khoảng 4.700 dòng khỏi
mod.rs
- Di chuyển
-
Bước 12 — Tách implementation
FirestoreStore- Giữ struct, constructor,
FirestoreClient,MetadataAuthtrongstore/mod.rs, còn implementation trait được chia thành các tệp theo domain - Biến tệp khoảng 10.000 dòng thành 10 tệp, mỗi tệp 120–650 dòng, và biến
mod.rsthành tệp re-export khoảng 100 dòng
- Giữ struct, constructor,
-
Bước 13 — Đặt test cùng module mục tiêu
- Không đổi mã test, chỉ di chuyển xuống dưới từng tệp implementation
- Giảm khoảng 2.000 dòng khỏi
mod.rs, đồng thời thêm 200–700 dòng test liên quan vào mỗi tệp
Hạn chế và thí nghiệm tiếp theo
- Vì không đếm riêng token dùng để lập và thực thi kế hoạch refactoring, không thể tính chính xác chi phí đầu tư refactoring
- Giới hạn trên dựa trên tổng mức sử dụng trong khung thời gian đó là 5 triệu token, nhưng con số này bao gồm cả việc lập kế hoạch hai lần, thiết kế thí nghiệm và thay đổi đại diện, cùng các công việc khác
- Đối tượng thí nghiệm vẫn ở giai đoạn greenfield và là một ứng dụng lớn duy nhất do một lập trình viên xây dựng/quản lý, nên không thể khái quát hóa kết quả
- Các bước tiếp theo cần đo chính xác token refactoring, thử thay đổi phức tạp hơn, refactoring trên phạm vi rộng hơn, refactoring liên tục, và so sánh giá trị tương đối giữa các cách tiếp cận
- Thí nghiệm này là điểm khởi đầu để đo đồng thời giá trị thời gian/tài chính do refactoring mang lại và chi phí của chính việc refactoring
1 bình luận
Ý kiến trên Hacker News
Thật thú vị khi thấy các best practice dành cho lập trình viên mà phần lớn công ty IT từng phớt lờ nay được tái phát minh thành best practice cho AI
Trước đây, nếu nói rằng hãy đặt tài liệu ngay trong code, đừng chỉ ném task Jira mà hãy cung cấp toàn bộ bối cảnh dự án, và hãy refactor vì năng suất dài hạn, thì thường bị xem là nhàm chán
Giờ đây, cùng nội dung đó—hãy đặt tài liệu AI trong code và CLAUDE.md, đừng kiểm soát li ti bằng prompt, và hãy refactor vì năng suất AI—lại được đón nhận một cách hào hứng
Con người dù biết cách làm đúng vẫn có thể bận rộn hoặc mất tập trung, còn agent thì không chán các công việc tẻ nhạt, nên những quy trình đã được chứng minh là hiệu quả với con người nhưng khó áp dụng đều đặn nay trở nên khả thi trong thực tế
Việc để các agent riêng viết implementation và test dựa trên một đặc tả chung, rồi để agent audit kiểm chứng nhằm tránh kết quả của bên này làm nhiễm bên kia, chính là áp dụng rộng rãi và nhất quán bằng AI mô hình cleanroom engineering mà IBM đã phát triển cho con người từ thập niên 1980
Đây không phải là việc đóng gói lại một thực hành cũ cho hợp trào lưu AI như thể nó là điều mới mẻ, mà là cho thấy bằng luận cứ rằng những best practice hơn 20 năm tuổi vẫn còn giá trị
Agent phải tiếp thu lại ngữ cảnh ở mỗi phiên, nên giá trị của các best practice lớn hơn nhiều và hiệu quả cũng xuất hiện ngay lập tức
Dù vậy, việc có thể cho CLI chạy 100 lần trong một giờ để thử độ dễ dùng của flag mới cũng rất hay
Ngược lại, nếu không có nền tảng như vậy, AI sẽ làm rất tệ hoặc hoàn toàn không hoạt động, nên các thực hành kỹ thuật lành mạnh không còn là biện pháp cải thiện dài hạn mà trở thành điều kiện tiên quyết bắt buộc
Ngay cả khi hiệu quả ròng thực tế bằng không, việc đưa AI vào workflow vẫn hữu ích ở chỗ nó tạo ra lý do chính đáng để áp dụng các thực hành phát triển đúng đắn
Mình thích ở bài viết này là nó phê phán cụ thể và có định lượng dựa trên cách các công cụ AI thực sự được sử dụng
Những bài cho thấy bằng số đo rằng AI không làm được gì hữu ích hơn nhiều so với các bài mơ hồ bàn về rủi ro xã hội mà không có ca sử dụng thực tế
Cũng vì lý do đó, báo cáo phỏng vấn các thành viên Boko Haram để tìm hiểu AI đã được dùng trong khủng bố như thế nào cũng rất ấn tượng
Mình thật sự thích tự làm refactoring mà không dùng AI
Không có thay đổi nhìn thấy được, nhưng cảm giác rất thỏa mãn khi khiến một website chưa thể hiện kết quả ngay lúc này trở nên dễ xử lý hơn nhiều trong tương lai
Quá trình tìm ra những đoạn mã vòng vèo kỳ quặc trong quá khứ đang giải lại các vấn đề vốn đã có pattern chuẩn, rồi chuyển chúng về phía best practice mà không tạo thêm nợ kỹ thuật mới, thú vị như giải đố
Mình đã tự triển khai mọi thứ một cách cẩu thả, kể cả xác thực, để học nguyên lý bên trong theo cách khó, và kết quả là cũng có thêm cả đống thứ để refactor trong 10 năm tới
Mình hiểu cụ thể hơn câu nói codebase là một hệ thống, và bắt đầu nhìn code ở cấp độ cao hơn như một tổ chức hay tấm lưới liên tục mà có thể kéo và nén
Việc AI có thể loại bỏ quá trình học này làm nổi bật vấn đề của lập trình viên junior. Muốn có trực giác thì chỉ còn cách tự đào sâu trực tiếp, và dù Naur đã cảnh báo 40 năm trước, bài học này vẫn cứ bị lãng quên
Tôi cho rằng khi agent thực hiện refactoring thì sự tham gia của con người là điều thiết yếu
Mô hình sinh có thể tập trung vào công việc ban đầu, còn mô hình rà soát có thể tìm ra những phần bị bỏ sót, nhưng vẫn đáng nghi ngờ liệu chúng có thực sự hiểu mục đích của toàn bộ dự án và cách mã kết hợp với nhau để nhận ra trùng lặp hoặc một cấu trúc thanh nhã hơn hay không
Giao việc refactoring cho coding agent cũng giống như nhờ bác sĩ phẫu thuật chấn thương cải thiện năng lực vận động; muốn làm đúng cần có góc nhìn toàn diện
Chỉ chia một file lớn thành nhiều file chỉ dừng ở refactoring bề mặt. Nếu không có lý thuyết về đoạn mã nào nên ở cùng nhau và cái gì nên được tách thành hàm utility, thì đó không phải là phân tích thừa số, mà gần giống việc tách một số lớn thành các số nhỏ rồi cộng lại
Agent đôi khi tạo ra hệ thống lưu lại và tính toán lại những giá trị vốn đã lấy từ API, còn con người có thể nhìn toàn bộ dự án và xác định chính xác rằng dữ liệu cần thiết đã có trong một khóa cụ thể của JSON
functools.partialthay vì data classKhái niệm rằng ranh giới file biểu thị ranh giới của các hệ thống con logic, giúp suy luận dễ hơn, và nội dung của các file khác mặc định được xem là mờ đục, cũng có rất nhiều trong dữ liệu huấn luyện
Tôi cho rằng lợi ích của cấu trúc này không chỉ là đặc tính ngẫu nhiên của nhận thức con người, mà còn có khía cạnh khách quan
Kinh nghiệm refactoring, cách từng xử lý codebase của người khác, và việc có thể giải thích ý định trước đây lẫn hiện tại với tư cách nhà thiết kế ban đầu đã giúp ích
Đó là một ngôn ngữ ít phổ biến, ít điểm yếu về dependency và dễ để LLM xử lý; sau khi loại bỏ thiên kiến về JavaScript và Python, tốc độ làm việc tăng lên đáng kể
Đây là một dự án JSR-223 viết script bằng nhiều ngôn ngữ phổ biến, nhưng tất cả đều chạy trên JVM theo yêu cầu môi trường: https://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform
Trong thị trường tuyển dụng này, cần sử dụng coding agent dựa trên các frontier model mới nhất và hiểu chính xác năng lực cũng như giới hạn của chúng; nếu đưa ra đánh giá ngược lại trong phỏng vấn, đó có thể là lý do bị loại
Ngữ cảnh súc tích không chỉ giảm tiêu thụ token mà còn cải thiện suy luận, cho phép đưa nhiều tầng hơn vào cùng một ngữ cảnh và xử lý chúng một cách thông minh
Refactoring hướng tới các abstraction tốt tạo ra phần mềm tổng quát hóa tốt hơn, có khả năng đúng không chỉ trong các trường hợp đã kiểm thử mà cả các trường hợp nội suy và ngoại suy
Có lý thuyết thông tin và toán Bayes hậu thuẫn điều này, và việc phần mềm hiệu quả hơn về kinh tế và năng lượng lại chính xác hơn trông như một sự trùng hợp tinh tế
Cốt lõi là giảm entropy của mã
LLM vốn đã suy luận ý nghĩa khá tốt ngay cả với ít ngữ cảnh
Việc bài viết đưa ra dữ liệu là điều thú vị, và phù hợp với cảm nhận của tôi rằng LLM hưởng lợi rất lớn từ mã được tách biệt tốt, nhưng bản thân chúng không đặc biệt giỏi tạo ra loại mã như vậy
Phần lớn lập trình viên con người có lẽ cũng tương tự
Nhìn chung lợi ích từ AI là lớn, nhưng cũng cần thời gian dọn dẹp, và tôi cho rằng vẫn phải đọc từng dòng
Để không chặn tiến độ của các nhóm khác, tôi đã hoãn một phần review và về sau đang phải trả một khoản technical debt lớn hơn bình thường, nhưng việc gỡ nút thắt trước là đáng giá
AI khiến việc vay technical debt dễ hơn theo mọi nghĩa, và nếu được hướng dẫn tốt thì cũng khá giỏi xử lý nợ. Tuy vậy, kết quả tùy từng người: https://news.ycombinator.com/item?id=49035455
Việc cho xem ví dụ về mã được tổ chức tốt hoặc các kho mã nguồn mở để minh họa điều nên làm và không nên làm giúp ích rất nhiều
Phần lớn lợi ích kinh tế của refactoring đến từ việc con người hiểu hệ thống tốt hơn, chứ không phải tiết kiệm token
Có thể xử lý cuộc gọi sự cố lúc 3 giờ sáng nhanh hơn, giảm lỗi lọt vào môi trường vận hành, và ra mắt nhanh hơn đối thủ
Quan trọng nhất, khi hiểu hệ thống, người ta sẵn lòng nhận trách nhiệm và quyền sở hữu hơn, nên khi có vấn đề sẽ sửa nhanh hơn và cũng chủ động lao vào những phần cần cải thiện
Ý chính là refactoring làm giảm tiêu thụ token, và việc định lượng hiệu quả thay vì chỉ bàn trừu tượng là điểm tốt
Nhưng Fowler đã nói trong cuốn 《Refactoring》 rằng điều kiện tiên quyết thiết yếu của refactoring là bộ test vững chắc, và tôi cho rằng lợi ích thật sự, không phụ thuộc AI, nằm ở đây
Test tốt ngăn hồi quy do con người hoặc robot tạo ra, đồng thời để lại đặc tả dưới dạng mã mà cả hai bên đều có thể đọc: https://www.oreilly.com/library/view/refactoring-improving-the/9780134757681/
Nếu tính giá Sonnet 5 là 3 USD mỗi MTok, khoản tiết kiệm cho những thay đổi tương lai đụng đến tầng truy cập dữ liệu là 39,7 cent
Xét đến việc OpenAI giảm giá, các mô hình mở, và xu hướng giá token dài hạn đi xuống, khoản này có thể không tương xứng với chi phí để một senior developer khoảng 100 USD/giờ hướng dẫn refactoring
Mã do agent tạo ra đã trở thành một khối khổng lồ đến mức chỉ agent mới có thể đọc và hiểu được; điều quan trọng không phải đó là tính năng, lỗi hay thuộc tính nổi lên, mà là chính thực tế này
Để xử lý mã được tạo bằng công cụ AI, chúng ta lại đang phụ thuộc vào công cụ AI
Tuy nhiên con người vốn cũng đã tạo ra những tệp khổng lồ kinh khủng và monorepo, và nhờ LLM, việc chỉnh sửa cũng như refactor chúng cuối cùng mới trở nên có thể kham nổi
Trong tình huống codebase đã quá lớn và lộn xộn để con người hiểu được, LLM có thể cứu chúng ta; cá nhân tôi ghét các tệp khổng lồ, nhưng thật cay đắng là các nguyên tắc dọn dẹp kiểu Fowler có thể không còn quan trọng nữa
Ngay cả một nhân viên ở mức trung bình, hoặc thỉnh thoảng làm tốt, trước đây không thể làm một số việc vì quy trình công ty, nay có thể thực hiện chúng nhanh như chớp, và vì thế lại bị biến thành một nhân viên tệ
Nếu agent tạo ra tệp hoặc hàm khổng lồ, chỉ cần bảo nó đừng làm vậy là nó sẽ làm theo
Tôi xem refactoring là một trong những dấu hiệu tốt nhất của một đội ngũ phát triển lành mạnh
Bản thân refactoring cũng có lợi ích, nhưng giá trị đó thường không dễ thấy với người phụ trách sản phẩm hay trong bảng công việc tính năng
Nếu đội ngũ refactor vì sức khỏe tổng thể của phần mềm, điều đó có nghĩa là các nhà phát triển có thể thoải mái đề xuất những việc tốt cho phần mềm, và các đề xuất đó được xem xét nghiêm túc
Sự mục ruỗng của phần mềm trở nên tệ nhất khi đội ngũ không có động lực hoặc thẩm quyền để hiện thực hóa tầm nhìn về phần mềm chất lượng cao; nếu đội ngũ có thể làm theo phán đoán của mình về sự xuất sắc thì nhìn chung đó là tín hiệu tốt
Tất nhiên cũng có những trường hợp thái quá như viết lại toàn bộ từ Ruby, Node, Rust rồi lại sang công nghệ thân thiện với agent, nhưng trong môi trường doanh nghiệp, việc các đội ngũ cảm thấy mình không được phép cải thiện phổ biến hơn nhiều