Mời bạn thưởng thức Newsletter #138.
What I believe about the future of software development
Thorsten Ball đăng lại lên blog loạt dự đoán từng gây bão trên X, để ghi lại những gì tác giả tin vào tháng 9/2026. Theo tác giả, code review gần như đã chết: con người sẽ không còn tìm ra bug trong code do model viết, mà chỉ review hệ thống và cách các thành phần ghép lại. Unit test cũng có thể biến mất, vì model đã viết được 900 dòng Arduino C chạy đúng ngay lần đầu. Kỹ năng viết code sẽ mai một như nghề đóng giày thủ công, nhưng kỹ năng xây dựng phần mềm, tức giải bài toán kinh doanh, biết khi nào ship và lấy feedback, lại quan trọng hơn bao giờ hết. Phần lớn bug sẽ là bug “bạn yêu cầu sai thứ”, không phải bug viết code; còn tối ưu hiệu năng bởi con người vẫn chỉ là trường hợp hiếm.
Các nhận định gây tranh cãi hơn: terminal, shell và CLI sẽ không còn dành cho con người; token là mô hình tính toán mới của kỷ nguyên “hậu nhị phân”. Bộ ba PM/Design/Eng cùng Agile, SCRUM sẽ biến mất, kỹ sư chỉ làm “proxy bằng thịt” chuyển ticket cho agent sẽ mất giá trị. Khái niệm “good code” vốn phục vụ con người, nên chưa chắc còn quan trọng khi agent sửa phần lớn code. Người không đủ tiền mua token sẽ bị đẩy ra khỏi cuộc chơi, còn UI có thể được sinh ra tức thì. Dù vậy, tác giả thừa nhận sẽ mất cả một thế hệ để “phần mềm mới” thay thế “phần mềm cũ”, và 10 năm nữa vẫn có người được thuê viết code, chỉ là bạn có muốn công việc đó không.
Trying the Software Factory pattern.
Will Larson nhận xét rằng năm 2026, các pattern AI hiệu quả xuất hiện nhanh hơn tốc độ tác giả kịp áp dụng. Tại Imprint, năm nay: tháng 1 đưa mọi kỹ sư dùng Claude Code mỗi ngày, tháng 3 mở rộng sang mọi bộ phận với Claude Code hoặc Claude Cowork. Tháng 4, vì local development nghẽn ở mô hình worktree, đội tạo khoảng 10 workspace chứa bản checkout riêng của mọi repository để agent tạo pull request xuyên các monorepo. Tháng 6, cả công ty chuyển hẳn từ Jira sang Linear để agent có hệ thống task minh bạch, ít rắc rối phân quyền. Tháng 7, ra mắt harness điều phối nội bộ “Agent Fleet”, tương tự Minions của Stripe, cho các ticket nhỏ.
Bước tiếp theo là software factory pattern: lặp trên một mục tiêu rộng, để harness tự thúc đẩy tiến độ. Phiên bản đầu là skill /linear-project-loop, đọc một Linear project và kiểm tra xem đã có RFC trên Notion mô tả mục tiêu, cách đo và hướng tiếp cận, cùng dashboard Datadog hoặc query Snowflake đo tiến độ hay chưa; nếu thiếu, nó cùng bạn tạo ra. Sau đó nó rà metric và issue, thêm việc mới, rồi làm task không bị chặn như viết pull request, nhắc review, đặt câu hỏi. Khi mô tả project đã cũ, vòng lặp chạy lại từ đầu. Pattern này buộc tác giả nhận ra chỗ vô tình giữ thông tin mục tiêu cho riêng mình, và giúp theo dõi project sau khi release, như phát hiện ngay khi tỷ lệ lỗi của tính năng passkeys tăng. Cuối cùng, các mảnh ghép chỉ cộng hưởng khi có đủ nhau: Datadog MCP, Snowflake, Linear làm nguồn trạng thái duy nhất và một harness chạy độc lập với laptop.
Back to Coupling and Cohesion
Daniil Bastrich cho rằng người mới và những tín đồ clean code thường lạm dụng SOLID, GRASP hay KISS, khiến codebase ấn tượng nhưng khó bảo trì. Theo tác giả, các nguyên tắc này đều quy về việc quản lý coupling và cohesion ở mọi cấp độ. Coupling đo mức các component gắn với nhau đến đâu,, khiến sửa một cái buộc phải sửa cái khác; cohesion đo mức mọi phần trong một component cùng phục vụ một mục đích duy nhất. Để có số liệu, tác giả đề xuất thống kê từ công việc thực tế: với mỗi task, ghi lại effort trên từng component đã chạm vào; với mỗi component, ghi lại effort cho từng concern. Coupling được tính bằng 1 trừ tổng bình phương effort chia cho bình phương tổng effort, còn cohesion chính là tỷ số đó, tương tự chỉ số Gini-Simpson và Herfindahl-Hirschman.
Ví dụ, nếu rule độ dài mật khẩu được kiểm tra riêng ở form đăng ký (effort 4) và form đổi mật khẩu (effort 6), coupling của thay đổi là 0.48, còn cohesion mỗi form là 1. Cách đo này phản ánh ảnh hưởng thật lên công việc hằng ngày. Low coupling, high cohesion giúp tập trung vào ít thứ hơn, nên ít bug và dễ bảo trì hơn. Tác giả lần lượt quy các nguyên tắc về hai khái niệm này: Single Responsibility là high cohesion, Open/Closed, Liskov, Interface Segregation, Dependency Inversion, DRY và Law of Demeter đều nhằm giảm coupling hoặc tăng cohesion, còn KISS giảm lượng thông tin phải nhớ cùng lúc. Nguyên tắc này có giới hạn với hệ thống nhúng, ứng dụng low-latency hay script dùng một lần; đừng theo bất kỳ nguyên tắc nào chỉ vì chính nó.
Introducing System One Models & Jev
Diogo Almeida, founder của TypeSafe và từng tham gia nghiên cứu nền tảng cho ChatGPT tại OpenAI, đặt câu hỏi: model đã vượt con người ở khả năng chat nhiều năm nay, vậy tự động hóa ở đâu? Sau hai năm hoạt động bí mật, TypeSafe AI công bố System One Model, lớp frontier model mới đưa ra quyết định nhanh, có cấu trúc để phần mềm dùng trực tiếp. Stack gồm kiến trúc riêng, parallel sampler và phương pháp huấn luyện Reinforcement Learning for Calibrated Decisions (RLCD). Model đầu tiên là Jev, đang early access, được mô tả như một “function call trí tuệ frontier”: nhận trạng thái phi cấu trúc, trả về các quyết định có kiểu kèm xác suất đã được hiệu chỉnh. Jev từ bỏ việc sinh chuỗi, nên không thể có type error hay hallucinate, sinh mọi output song song trong một query, phản hồi trong 70–500ms và chỉ tốn $0.042 cho mỗi triệu input token, output thì miễn phí.
Để đánh giá, nhóm xây dựng workflow eval: mọi model chạy cùng một workflow trong code và được so với trung bình dự đoán của GPT-6 Astra và Fable 5.1. Kết quả, Jev nhanh hơn 193.6 lần, rẻ hơn 444.6 lần, dù nhóm thừa nhận con số này thuộc mức cao và có thể thiên lệch. Use case phù hợp là “smart if-statement” trong workflow, map-reduce trên dữ liệu lớn, ứng dụng real-time và kiểm duyệt output của LLM. Demo gồm một bot chơi Doom với 10 query mỗi giây, tốn khoảng $7/giờ, và Wikiracing giữa các trang Wikipedia. Cái tên System One lấy cảm hứng từ cuốn Thinking, Fast and Slow của Daniel Kahneman, còn Jev đặt theo William Stanley Jevons: trí tuệ càng rẻ, use case càng nhiều.
System One Models 🚦 Explained
Agam More giải thích System One model, với ví dụ Jev của TypeSafe AI, như một câu lệnh if nhanh, rẻ và biết mình chắc chắn đến mức nào. Bạn đưa vào một trạng thái cùng câu hỏi có kiểu, model trả về JSON kèm xác suất cho từng đáp án, giống một bài thi trắc nghiệm. Có ba loại câu hỏi: Choice chọn một lựa chọn trong tập cho trước, Score chấm điểm theo thang bạn định nghĩa, còn Noul trả về khả năng một mệnh đề là đúng. Ví dụ, với ticket than phiền tích hợp Stripe lỗi ba ngày, model định tuyến sang bộ phận technical với xác suất 0.85 và đánh dấu khẩn cấp. Jev được huấn luyện hai vòng như chat model, nhưng vòng hai dùng RLCD thưởng cho xác suất trung thực, với dữ liệu hoàn toàn synthetic. Model không thể trả giá trị nằm ngoài schema, nhưng vẫn có thể chọn sai.
Nên dùng Jev khi code hỏi LLM cùng một dạng câu hỏi đóng hàng nghìn lần, như định tuyến ticket hay lọc spam, rồi tự động hóa ca chắc chắn và chuyển phần còn lại sang review. Theo JevBench, Jev rẻ hơn 6 đến 7 lần mỗi quyết định so với GPT-5.6 Luna hay Gemini 3.1 Flash-Lite. Không nên dùng khi đáp án không nằm trong danh sách cố định, khi cần text, hoặc khi độ chính xác quan trọng hơn chi phí; Jev cũng không tự trả lời “không cái nào” nếu bạn không đưa lựa chọn đó. Đối thủ gồm SemIf, Laya, Kev, GLiNER2 và Outlines. Tác giả dự đoán calibration sẽ là phần khó nhất, và các ông lớn sớm muộn sẽ có model tương tự.
How Data Is Replicated In Distributed Systems | Raft From Scratch - Part 1
Sushant Dhiman mở đầu loạt bài hai phần bằng một bài toán quen thuộc: khi xây phần mềm phân tán có replication như database, bạn cần một hệ thống leader/follower, nhưng làm sao để năm node bầu ra đúng một leader? Câu trả lời là Raft, thuật toán consensus của Diego Ongaro và John Ousterhout, được thiết kế để dễ hiểu và dễ cài đặt hơn Paxos. Consensus giúp các replica đồng thuận về một chuỗi quyết định có thứ tự, tránh việc database này có 10 giao dịch còn database kia chỉ có 7 do network partition. Bài viết chỉ tập trung vào leader election. Raft có ba loại node: leader xử lý request và điều phối log replication, follower nhận RPC từ leader, còn candidate là follower đứng ra tổ chức bầu cử khi hết election timeout. Hai RPC chính là AppendEntries, dùng để replicate log và gửi heartbeat, và RequestVote, dùng để xin phiếu.
Khi leader chết, follower không nhận được heartbeat; sau một timeout ngẫu nhiên, ví dụ trong khoảng 150–300ms, nó trở thành candidate và thắng nếu được đa số phiếu. Timeout ngẫu nhiên giúp giảm khả năng chia phiếu, còn election term đóng vai trò logical clock: mỗi lần bầu cử, term tăng lên, mỗi node chỉ bầu tối đa một candidate trong một term, và node nào thấy term cao hơn sẽ lùi về làm follower. Nếu không ai thắng do chia phiếu, các candidate chỉ cần thử lại sau timeout mới. Phần cuối là một bản cài đặt học tập bằng Go và gRPC, gồm election loop, RequestVote, heartbeat qua AppendEntries và file proto, chạy ba node trên các port 5001 đến 5003. Bản này cố ý bỏ qua log replication, persistence và thay đổi thành viên cluster.
Jev means structured output is interesting again
Sean Goedecke vốn không viết về model mới, nhưng phá lệ với Jev, một “System One” model. LLM thông thường sinh output theo kiểu autoregressive, từng token một, nên rất linh hoạt nhưng chậm và đôi khi kỳ quặc. Jev nhận prompt bằng ngôn ngữ tự nhiên nhưng chỉ trả về structured output, và chính giới hạn đó mang lại đặc tính đáng giá. Jev luôn nhanh, phản hồi từ khoảng 70ms đến tối đa 500ms, vì không cần sinh từng token mà trả lời nhiều câu hỏi song song trong một forward pass. Ví dụ ấn tượng nhất là Jev chơi được Doom theo thời gian thực từ mô tả trạng thái game dạng text. Với tác giả, structured output nhanh có thể là một primitive tính toán mới: khi chèn 100ms trí tuệ siêu rẻ vào các điểm ra quyết định, ta có thể viết những chương trình không còn trông như chatbot.
Tuy vậy, tác giả cho rằng structured output nhanh vốn đã khả thi. Nó chậm chỉ vì ít ai quan tâm, và người quan tâm thường cần JSON lớn nên dùng grammar-constrained decoding. Với các lựa chọn giới hạn, chỉ cần prefill "choice": " rồi sinh đúng một token trong tập lựa chọn; tác giả thử với Qwen2.5-1.5B-Instruct và thấy nhanh gấp 2 đến 3 lần. Vì vậy Jev có lẽ không có “moat” kỹ thuật lớn, dù fine-tune riêng cho structured output vẫn là lợi thế. Jev cũng khó thông minh bằng frontier LLM vì không dùng được test-time compute, còn tuyên bố miễn nhiễm hallucination chỉ là cách chơi chữ, vì nó vẫn chọn sai được. Dù vậy, tác giả mong Jev thành công và thúc đẩy các lab lớn ra mắt phiên bản model riêng tối ưu cho structured output.
Why do we listen to people with no skin in the game?
Redowan Delowar, trong bối cảnh lập trình công nghiệp, tin rằng nếu không trực tiếp làm, ý kiến của bạn rất dễ sai; có ảnh hưởng không đồng nghĩa với đúng; và nói về code khác hẳn giao phần mềm dưới ràng buộc thực tế. Ví dụ điển hình là một director “nghiện AI” vọc LLM một buổi chiều, dựng vài ứng dụng dùng một lần rồi tin rằng software engineering đã được giải quyết, sau đó đòi năng suất gấp 10 lần, gạt đi mọi ma sát tổ chức. Tác giả dùng LLM rất nhiều nhưng cũng đụng phải giới hạn của chúng thường xuyên hơn người chỉ one-shot một ứng dụng todo. Bạn vẫn phải nghe theo quản lý nếu không muốn mất việc, nhưng điều đó không khiến họ đúng; muốn đúng, bạn phải là người cầm pager khi phần mềm “vibe-slop” sập lúc 3 giờ sáng.
Nhóm thứ hai là các software influencer với những tuyên bố chung chung như “viết lại mọi thứ bằng Rust”, “TypeScript nên chết đi” hay “Kotlin là Java hàng Temu”, vì đó là cách theo kịp thuật toán, và nói về phần mềm thì rất nhiều tiền. Khách mời podcast thường đáng học hỏi, nhưng lời khuyên của host nên nghe có chọn lọc. Những người bán kỹ năng AI hôm nay cũng chính là người từng bán khóa học JavaScript framework rồi nhảy sang blockchain và NFT. Các tuyên bố đó hiếm khi tính đến việc tổ chức chọn ngôn ngữ dựa trên nguồn nhân lực địa phương, tốc độ xây sản phẩm và ngôn ngữ founder biết, và LLM không thay đổi điều đó. Lời khuyên thì rẻ, hãy để ý động cơ của người đưa ra nó.
You can run git on object storage if you re-make packfiles
Xe Iaso đang xây objgit, một Git server mã nguồn mở chạy trên object storage của Tigris. Cách tiếp cận đầu tiên dùng một lớp filesystem làm trung gian, nhưng không chịu nổi các repository cỡ thực tế. Git về bản chất là một biển object định danh theo nội dung; repository Linux kernel có khoảng 11 triệu object, nên nếu mỗi lệnh GetObject tốn 10ms thì lấy hết sẽ mất hơn một giờ. Git giải quyết bằng packfile, gom object vào một file kèm index, nhưng format này được thiết kế cho đĩa local và mmap, nơi đọc chỉ tốn vài nano giây thay vì 10ms cho mỗi round trip mạng. Index chỉ ghi kích thước sau giải nén chứ không ghi kích thước nén, nên không thể dựng HTTP Range request để lấy riêng một object.
Lấy cảm hứng từ cặp file .bin và .cue khi backup đĩa CD, tác giả tự thiết kế một packfile format mới: object nằm nối tiếp nhau trong file .bin tối đa 128MiB, còn metadata nằm riêng trong cue sheet nhị phân, biến kho Git thành columnar store. Cue sheet lưu cả kích thước nén và chưa nén cùng offset, nên dễ dựng Range request, trong khi toàn bộ packfile được tải nền và các object ở cuối được Range-request cho đến khi bản tải về “đuổi kịp”. Format còn dùng zstd. Tự chế format nghe như phạm luật Chesterton’s Fence, nhưng vì Git phân tán nên nếu có sự cố, chỉ cần push lại. Kết quả rất ấn tượng: push repository Xe/x giảm từ 3 phút 29 giây xuống 14.3 giây và từ hơn 9.000 xuống 30 request S3. Dự án vẫn chưa có xác thực và phân quyền, nên chưa nên đưa lên Internet.
Why CAFEBABE?
Tháng 5/1996, khi đang viết bài “The Class File Lifestyle” cho JavaWorld, Bill Venners tò mò về magic number của file class Java. Bốn byte đầu tiên của mọi file class đều phải là 0xCAFEBABE, giúp công cụ nhận diện nhanh file class. Tác giả đăng câu hỏi lên newsgroup comp.lang.java, và trang này lưu lại toàn bộ chuỗi thảo luận. Nhiều người đưa ra phỏng đoán vui: số magic 32 bit dễ xử lý và ít trùng lặp, nhóm Java muốn gợi đến ẩn dụ cà phê nhưng hệ hex không có chữ J hay V, nên chọn cụm có chữ CAFE thay vì “A FAB CAFE”, “CAFE FACE” hay tệ hơn là “A BAD CAFE”. Có người còn gợi ý 0x00C0FFEE, đọc số 0 thành chữ O, thành “OO COFFEE”, tức Object Oriented coffee.
Chuỗi thảo luận cũng là bảo tàng nhỏ các giá trị hex nổi tiếng: Burroughs B6700 khởi tạo bộ nhớ chưa dùng bằng 0xBADBADBADBAD, các máy IBM cũ và AIX dùng 0xDEADBEEF cho vùng nhớ chưa khởi tạo, Macintosh đặt 0x50FFC001 ở địa chỉ 0 để truy cập con trỏ null là crash ngay, IRIX bắt đầu file arena bằng 0xdeadbabe, còn Solaris debug ghi 0xCAFEFEED vào khối nhớ đã giải phóng. Một người còn nhận ra NeXTSTEP từng dùng 0xCAFEBABE làm magic number cho fat binary, bên cạnh 0xfeedface. Câu trả lời thật đến từ Patrick Naughton, một trong những thành viên đầu tiên của nhóm Java: magic number được chọn từ rất lâu trước khi cái tên Java xuất hiện. Nhóm muốn một giá trị vui, độc đáo, dễ nhớ, và 0xcafebabe thắng ứng viên về nhì là 0xdeadbabe. Việc nó ngầm nhắc đến các barista ở quán Peet’s Coffee và báo trước cái tên Java chỉ là tình cờ.