Mời bạn thưởng thức Newsletter #48.
TODOs aren’t for doing
Sophie Alpert phản bác hai cách xử lý phổ biến với comment TODO trong mã nguồn: bắt buộc mỗi TODO phải có một ticket tương ứng trong hệ thống theo dõi lỗi, hoặc tự động xóa những TODO đã tồn tại quá lâu. Theo bà, chỉ những TODO mang tính cấp bách như “Viết nốt nửa sau của file này để đợt ra mắt tuần sau không bị sập” mới thực sự cần được theo dõi như một đầu việc. Những TODO giá trị nhất lại không nhằm để làm: chúng ghi lại các trường hợp biên và gợi ý thiết kế, chẳng hạn “nếu người dùng nhấn ba lần liên tiếp vào nút này thì trình xử lý sự kiện sẽ lỗi” — một tình huống hiếm gặp mà người viết đã nhận ra nhưng chưa cần xử lý.
Giá trị thật của những comment này là lưu giữ lối suy nghĩ và ngữ cảnh của người viết ban đầu. Khi một lập trình viên khác đọc lại đoạn mã và tự hỏi liệu cấu trúc này có nên được viết khác đi không, một TODO đặt đúng chỗ sẽ trả lời ngay câu hỏi đó, giúp họ tự tin tái cấu trúc thay vì chần chừ giữ nguyên vì sợ tác giả cũ biết điều gì đó mà mình không biết. Với lập trình viên mới vào nghề, đây là một cách nhìn hữu ích: hãy coi TODO như một mẩu tài liệu nhỏ gửi đến người đọc tương lai, chứ không phải danh sách việc tồn đọng cần dọn sạch.
Automating Away Claude’s Bad Habits with Hooks
Claude Code thường để lại khoảng trắng thừa ở cuối dòng, vì mô hình ngôn ngữ sinh văn bản theo từng token mà không “nhìn thấy” kết quả hiển thị, còn việc dặn dò trong tài liệu hướng dẫn thì không đáng tin cậy. Tác giả Brian Cosgrove giải quyết triệt để bằng tính năng hooks — các lệnh shell do người dùng định nghĩa, tự động chạy tại những thời điểm nhất định trong vòng lặp làm việc của Claude. Cụ thể, anh cấu hình một hook PostToolUse chạy RuboCop với quy tắc Layout/TrailingWhitespace mỗi khi Claude sửa một file Ruby. Anh cố ý chọn công cụ chuyên cho từng ngôn ngữ thay vì dùng sed hay biểu thức chính quy chung chung, bởi cách đó có thể làm hỏng file nhị phân, phá vỡ ngắt dòng trong Markdown hoặc các định dạng nhạy cảm với khoảng trắng.
Ngoài PostToolUse, hooks còn có các sự kiện PreToolUse, Notification, Stop và SubagentStop, cho phép kiểm tra, biến đổi hoặc chặn hành động ở nhiều bước khác nhau: chạy công cụ phân tích mã, chạy kiểm thử, xác nhận mã biên dịch được, hay ngăn những thao tác rủi ro như commit khi chưa kiểm tra. Tác giả cũng cảnh báo rằng hooks chạy với toàn bộ quyền của người dùng, nên cần đọc kỹ mọi lệnh trước khi thêm vào, vì một hook độc hại có thể xâm hại hệ thống ngay trong những thao tác thường ngày của Claude. Đây là ví dụ thực tế về cách biến những “thói quen xấu” của AI thành việc được sửa tự động, thay vì phải nhắc đi nhắc lại.
Docs for AI Agents
Kayce Basques ghi lại suy nghĩ về tài liệu dành cho AI agent và mối quan hệ của nó với tài liệu kỹ thuật nội bộ mà nhóm phát triển viết cho chính mình, như RFC hay hướng dẫn xây dựng dự án. Agent docs giúp kết quả của agent nhất quán hơn, đúng quy ước dự án và chính xác hơn: khi mới dùng Claude Code, tác giả thấy công cụ đoán đúng trang web là Sphinx xây dựng bằng Bazel nhưng lại chạy sai lệnh; chỉ cần ghi lệnh đúng vào agent doc là từ đó nó luôn làm đúng. Mỗi công cụ tìm một file riêng ở thư mục gốc (CLAUDE.md cho Claude Code, GEMINI.md cho Gemini CLI, AGENTS.md cho Codex CLI), và nội dung file được chèn nguyên vẹn vào lời nhắc hệ thống ở mọi lần gọi mô hình, nên cần giữ thật cô đọng. Ngoài ra còn có agent doc cho thư mục con và cấp người dùng.
Câu hỏi lớn là có nên duy trì hai bộ tài liệu riêng không. Lý do để tách gồm văn phong khác nhau, nhu cầu cô đọng của agent trái ngược với mục tiêu đầy đủ của tài liệu cho con người, và việc mô hình vốn đã biết sẵn nhiều thứ; lý do để gộp là tránh trùng lặp và mâu thuẫn về lâu dài. Tác giả gợi ý vài hướng: dùng chính AI để đồng bộ hai bộ tài liệu, gộp hẳn làm một, nhúng chỉ dẫn cho agent dưới dạng comment trong tài liệu nội bộ rồi dùng script trích ra, dùng cú pháp @ để nhập file khác như CONTRIBUTING.md, hoặc dùng công cụ kiểm tra trước khi gộp mã để buộc các file liên quan được cập nhật cùng nhau.
Developers Are Using These AI Agents to Build Software 10x Faster
Bài viết tổng hợp các AI agent hỗ trợ lập trình đang giúp lập trình viên tăng tốc đáng kể trong năm 2025, kèm mô tả ngắn về cách mỗi công cụ góp phần tự động hóa quy trình làm việc. Danh sách gồm Cursor (trình soạn thảo lấy AI làm trung tâm, gợi ý theo thời gian thực), Emergent (điều phối nhiều agent để sinh tính năng và chuẩn bị triển khai), DeepDocs (tự động đồng bộ tài liệu trên GitHub với thay đổi mã nguồn qua GitHub Actions), Continue.dev (nền tảng mã nguồn mở để tự xây dựng IDE tích hợp AI), Trae của ByteDance (phát triển ứng dụng web toàn diện, hỗ trợ đầu vào đa phương thức), Cline (tiện ích VS Code cho các codebase lớn), Gemini CLI của Google và Cody CLI của Sourcegraph (trợ lý ngay trong terminal), OpenHands (khung mã nguồn mở có thể tự vận hành), Replit AI (môi trường đám mây hỗ trợ sẵn cơ sở dữ liệu), Augment Code (agent tích hợp vào IDE, có thể chạy mã và phát hiện vấn đề hiệu năng) và CodeRabbit (tự động xem xét pull request trên GitHub).
Thông điệp chính là các agent này đảm nhận những việc lặp đi lặp lại, giúp làm nhanh hơn và mã sạch hơn, từ lập trình viên cá nhân, startup đến doanh nghiệp lớn. Tác giả kết luận rằng đưa một vài công cụ như vậy vào bộ công cụ năm 2025 không chỉ giúp tăng năng suất mà đang dần trở thành điều bắt buộc. Với lập trình viên mới, đây là điểm khởi đầu tốt để khảo sát và chọn thử công cụ phù hợp.
What kind of work I want (in 2025)
Sean Goedecke liệt kê thẳng thắn kiểu công việc anh muốn làm trong năm 2025, một cách hay để mỗi kỹ sư tự định hình con đường sự nghiệp. Về môi trường, anh ưu tiên làm việc từ xa hoàn toàn, thỉnh thoảng gặp mặt trực tiếp, không muốn mô hình kết hợp bắt buộc; anh thích phong cách quản lý ít quy trình, tin tưởng nhân viên, không chuộng quá nhiều cuộc họp scrum, và muốn tiếp tục sống ở Úc. Về dự án, anh tìm những việc nằm ở trung tâm của công ty và được lãnh đạo quan tâm, kể cả những hệ thống không hào nhoáng như thanh toán; anh giỏi hoàn thành việc trong các codebase nguyên khối và thích cải tiến dần một giải pháp chưa hoàn hảo hơn là trau chuốt quá lâu.
Anh nhắm đến các công ty công nghệ lớn của Mỹ hoặc công ty Úc tương đương, tránh startup, muốn làm trên những hệ thống lớn mà nhiều người biết đến, và hiện rất quan tâm đến AI cả với vai trò công cụ lẫn công nghệ mang tính chuyển đổi. Ranh giới đạo đức được nêu rõ: không làm blockchain dùng cơ chế proof-of-work, cờ bạc trực tuyến, vũ khí tự động hay dịch vụ tài chính mang tính bóc lột, đồng thời coi trọng văn hóa đa dạng. Thay đổi lớn nhất so với năm 2021 là anh từ bỏ ý tưởng xây dựng sự nghiệp bền vững bằng việc bảo trì các hệ thống cũ, vì những vị trí đó dễ bị cắt giảm, và chuyển sang những dự án được ưu tiên cao; kỳ vọng của anh với người quản lý cũng đơn giản hơn: chỉ cần năng lực và sự trung thực.
Welcoming The Next Generation of Programmers
Armin Ronacher, tác giả của Flask, cho rằng các công cụ lập trình bằng AI sẽ mở rộng chứ không thu hẹp nghề lập trình: AI sẽ không làm số lập trình viên ít đi, thậm chí điều ngược lại có vẻ nhiều khả năng xảy ra hơn. Định nghĩa của ông rất bao quát: “Nếu bạn tạo ra một chương trình, dù tự tay hay với sự trợ giúp của agent, bạn là một lập trình viên.” Ông nhận thấy cộng đồng ngày càng đồng tình rằng người mới sẽ và nên viết mã do AI sinh ra, và nhắc lại truyền thống cởi mở của cộng đồng Python qua những sáng kiến như PyLadies như một hình mẫu để chào đón nhóm người học mới này.
Thách thức mà ông chỉ ra là trước đây người học lập trình thường có người hướng dẫn, còn những người học qua ChatGPT có thể thiếu hẳn mối kết nối đó. Thay vì coi thường những “vibe coder”, cộng đồng cần chủ động kèm cặp họ và mở ra con đường dẫn vào cộng đồng, để các công ty làm công cụ không biến họ thành những người dùng phụ thuộc, không có động lực học sâu hơn. Mục tiêu là biến những tương tác đơn độc giữa người và AI thành hành trình học hỏi cùng nhau, giúp thế hệ mới hình thành các thực hành kỹ thuật phần mềm đúng đắn.
Pattern-matching across different languages
Nicolas Fränkel so sánh cách pattern matching được hỗ trợ trong Java, Scala, Kotlin, Python và Rust, lấy lệnh switch kiểu C truyền thống làm điểm xuất phát. Mọi ví dụ dùng chung một hệ phân cấp hình học gồm Rectangle và Circle với hàm tính chu vi, kết hợp khớp theo kiểu và điều kiện bảo vệ để nhận biết hình chữ nhật nào là hình vuông. Java 23 dùng biểu thức switch với cú pháp mũi tên, hỗ trợ khớp kiểu và bộ lọc when, các nhánh được xét tuần tự như chuỗi if else. Kotlin gần giống Java với biểu thức when và phép kiểm tra is, nhưng điều kiện bảo vệ vẫn cần cờ biên dịch thử nghiệm. Python bổ sung lệnh match từ phiên bản 3.10, có thể phân rã thuộc tính theo tên rất gọn gàng. Rust cần nhiều mã phụ hơn vì việc ép kiểu xuống vướng ràng buộc của mô hình quản lý bộ nhớ, dù khả năng pattern matching tổng thể của Rust vượt xa phạm vi lệnh switch.
Scala là ngôn ngữ đầu tiên đưa pattern matching vào mệnh đề switch và vẫn nổi bật nhờ khả năng phân rã, trích thuộc tính của lớp ngay trong nhánh khớp mà không cần gán biến thêm; chính nó đã truyền cảm hứng cho các ngôn ngữ khác, và nay Java cùng Kotlin đã bắt kịp về tính năng. Kết luận của tác giả là pattern matching kết hợp với phân rã giúp mã dễ đọc và dễ bảo trì hơn đáng kể, một kỹ thuật đáng học khi làm việc với bất kỳ ngôn ngữ hiện đại nào trong số này.
A real-world AI coding case sample
Tác giả Korny chia sẻ một ví dụ thực tế khi dùng Claude để thêm tính năng cho một ứng dụng ASP.NET Core: gửi sự kiện PersonBusinessLink lên Kafka với loại “linked” hoặc “unlinked” mỗi khi một người liên hệ được gắn vào hay gỡ khỏi một doanh nghiệp. Dự án dùng các kiểu trả về dạng monad Result và Option, thiết kế hướng miền với repository và service, cùng Kafka chạy trong Docker và Test Containers cho kiểm thử tích hợp. Thay vì để Claude tự chạy, anh dẫn dắt từng bước: hỏi trước về các mẫu có sẵn trong mã nguồn, rồi mới yêu cầu tính năng với đặc tả chi tiết, xem lại mọi thay đổi trước khi commit và can thiệp khi Claude chọn sai topic hay khóa phân vùng Kafka. Khi Claude vật lộn với cấu trúc mã dựa trên monad, anh tự gỡ lỗi thay vì để nó loay hoay mãi.
Claude làm tốt việc học cách viết kiểm thử từ các file khác và xử lý những phần đơn giản, nhưng cần được chỉnh hướng ở các quyết định kiến trúc và không tự giải quyết được những lỗi sâu. Lời khuyên của tác giả là đối xử với AI như một lập trình viên mới vào nghề rất nhanh, nhiệt tình nhưng ngây thơ; công cụ hữu ích nếu được dẫn dắt cẩn thận, nhưng sẽ không “tự chạy” một cách đáng tin cậy với các tác vụ phức tạp. Anh cũng nêu những lo ngại nghiêm túc về chi phí môi trường, nguồn vốn thiếu bền vững và động cơ của các công ty đứng sau những công cụ này.
Clowns to the Left of Me…
Korny bàn về cuộc tranh luận phân cực quanh công cụ lập trình bằng AI và tự đặt mình ở giữa, đúng tinh thần bài hát “Stuck in the Middle With You” mà tiêu đề mượn lời. Một phía là những người cổ vũ nhiệt thành, tuyên bố năng suất tăng tới 50 lần, cổ xúy viết mã mà bỏ qua bảo mật và bị cuốn theo cảm giác phấn khích khi mã được sinh ra nhanh chóng, nên thường thổi phồng khả năng và xem nhẹ rủi ro. Phía còn lại là những người hoài nghi, có lý khi phản bác các tuyên bố phóng đại, nhưng đôi khi lại coi các nghiên cứu sơ bộ là bằng chứng chắc chắn và bác bỏ công cụ chỉ sau vài lần thử với rất ít ngữ cảnh.
Tác giả chọn cách nhìn thực dụng: công cụ thực sự giúp anh trong công việc thật như viết script Python, vẽ sơ đồ cho tài liệu hay phát hiện lỗ hổng bảo mật, nhưng đòi hỏi viết lời nhắc cẩn thận, kiểm chứng kết quả và chọn đúng trường hợp sử dụng. Điều quan trọng là học khi nào và bằng cách nào để dùng chúng hiệu quả; anh gợi ý theo dõi những người thực hành có góc nhìn cân bằng như Simon Willison và Birgitta Böckeler. Dù vậy, anh nhấn mạnh không được quên các vấn đề mang tính hệ thống: tiêu thụ năng lượng khổng lồ, tác hại môi trường do phụ thuộc nhiên liệu hóa thạch, nguồn vốn đầu tư mạo hiểm thiếu bền vững và quyền lực tập trung vào một số lãnh đạo công nghệ gây tranh cãi. Thông điệp cuối cùng: hãy đánh giá công cụ bằng bằng chứng và trải nghiệm thực tế.
Improving the prompt to the AI to get better code
Tác giả trên Vanilla Java Blog thử tối ưu một phương thức Java định dạng độ lệch múi giờ từ mili giây sang chuẩn ISO 8601 (±hh, ±hhmm hoặc ±hhmmss) sao cho tạo ra ít đối tượng nhất, phục vụ các ứng dụng yêu cầu độ trễ thấp. Những lời nhắc “một lần” ban đầu cho kết quả rất không đồng đều giữa các mô hình. Lời nhắc được tinh chỉnh nêu rõ yêu cầu cụ thể: dùng bộ đệm ThreadLocal, dùng phép toán đơn giản, tránh String.format và các thao tác tạo đối tượng, trả về chuỗi đã được intern(). Chỉ dẫn này giúp những mô hình yếu hơn cải thiện rõ rệt.
Bảy hệ thống được đánh giá gồm Gemini 2.5 Pro, o3-pro, o4-mini-high, Claude 4, Grok 3 Think, GitHub Copilot với GPT 4.1 và Microsoft Copilot với chế độ Think Deeper. Thời gian phản hồi dao động từ vài giây đến 18 phút mà chất lượng không tăng tương ứng. Đa số lời giải dùng mảng char trong ThreadLocal và thao tác trực tiếp trên từng chữ số, nhưng không mô hình nào gợi ý dùng byte[], dù chuỗi trong Java hiện đại được lưu nội bộ bằng mảng byte. Bài học rút ra: lời nhắc chi tiết giúp thu hẹp khoảng cách giữa các mô hình, suy nghĩ lâu hơn không đảm bảo kết quả tốt hơn, và AI vẫn có thể bỏ sót những kỹ thuật hiệu năng đặc thù; cách tốt nhất là thử nhiều mô hình và lặp lại với lời nhắc được cải tiến thay vì chỉ hỏi một lần.
Bài viết đã được viết lại bởi Claude Code với Opus 5.5 vào ngày 27/09/2026.