Kỹ thuật phần mềm với tốc độ AI: Bài học từ dự án Claude Code đầu tiên

Phần mềm07 tháng 5, 2026·5 phút đọc

Adam Wolff từ Anthropic chia sẻ kinh nghiệm xây dựng công cụ lập trình Claude Code bằng chính AI. Bài viết phân tích cách AI thay đổi điểm nghẽn trong quy trình phát triển phần mềm (SDLC) từ việc viết mã sang ra quyết định kiến trúc, đồng thời đúc kết ba bài học thực tế về xử lý đầu vào, tích hợp shell và quản lý dữ liệu.

Kỹ thuật phần mềm với tốc độ AI: Bài học từ dự án Claude Code đầu tiên

Adam Wolff, kỹ sư tại Anthropic, đã có một bài thuyết trình thú vị về việc xây dựng Claude Code — một công cụ lập trình dựa trên tác nhân AI (agentic coding tool) — bằng chính chính công cụ này. Đây là một nghiên cứu điển hình về cách AI đang thay đổi hoàn toàn quy trình phát triển phần mềm (SDLC), nơi điểm nghẽn không còn nằm ở việc viết mã (implementation) mà chuyển sang việc ra quyết định kiến trúc và tốc độ học hỏi.

Theo Wolff, khoảng 90% mã nguồn mà đội ngũ Claude Code đẩy ra môi trường sản xuất là do AI viết hoặc hỗ trợ viết. Điều này cho phép họ thử nghiệm những ý tưởng táo bạo, nhưng cũng đặt ra những thách thức mới về quản lý sự phức tạp. Dưới đây là ba câu chuyện "thực chiến" từ quá trình phát triển Claude Code.

Câu chuyện 1: Xây dựng lại hệ thống đầu vào (Input)

Một trong những nhiệm vụ đầu tiên là xây dựng một lớp con trỏ (cursor class) tùy chỉnh để xử lý các lệnh đặc biệt như slash commands hoặc @ mentions. Trong giới lập trình, có một quan niệm phổ biến là "không bao giờ nên xây dựng lại hệ thống đầu vào" vì nó cực kỳ phức tạp, đặc biệt là khi phải xử lý các phím tắt và hành vi mặc định của terminal.

Tuy nhiên, đội ngũ Claude Code đã quyết định làm điều đó. Họ tạo ra một lớp con trỏ ảo hoàn toàn có thể kiểm thử (testable) và bất biến (immutable). Ban đầu, mọi thứ diễn ra suôn sẻ, họ thậm chí có thể thêm chế độ Vim mode một cách nhanh chóng nhờ kiến trúc kiểm thử tốt.

Nhưng vấn đề thực sự nảy sinh khi người dùng quốc tế bắt đầu sử dụng công cụ. Unicode, với các ký tự độ rộng kép (double-width characters) và các quy tắc chuẩn hóa (normalization) phức tạp, đã tạo ra vô số lỗi. Thay vì bỏ cuộc, họ đã liên tục sửa lỗi và tối ưu hóa hiệu suất (chuyển từ eager evaluation sang lazy evaluation). Kết quả là họ có một hệ thống đầu vào hoạt động hoàn hảo, chứng minh rằng đôi khi đi ngược lại quan niệm truyền thống là đúng đắn nếu có kiến trúc tốt.

Câu chuyện 2: Tái định nghĩa Shell

Ban đầu, Claude sử dụng một "Persistent Shell" (Shell liên tục) để thực thi các lệnh Bash/Zsh. Cách tiếp cận này đơn giản nhưng lại tạo ra nút thắt cổ chai vì nó buộc các lệnh phải chạy tuần tự (serial), trong khi hiệu năng của tác nhân AI phụ thuộc rất nhiều vào khả năng chạy song song (parallel).

Đội ngũ đã chuyển sang "Transient Shell" (Shell tạm thời), nơi mỗi lệnh được chạy trong một tiến trình riêng biệt. Điều này tăng tốc độ đáng kể nhưng lại nảy sinh vấn đề lớn: làm sao để duy trì môi trường của người dùng (biến môi trường, aliases, thư mục làm việc) giữa các lần chạy?

Giải pháp họ tìm ra là kỹ thuật "Snapshot". Họ chụp nhanh trạng thái môi trường của người dùng một lần và sau đó "phát lại" (replay) script đó mỗi khi khởi động một shell mới. Mặc dù việc triển khai rất phức tạp và mất 7 tháng để hoàn thiện, nhưng kiến trúc này mang lại khả năng kết hợp (composability) cao, cho phép tích hợp dễ dàng các tính năng như sandboxing.

Câu chuyện 3: Thử nghiệm và lùi lại với SQLite

Đây là một ví dụ về sự thất bại và tầm quan trọng của việc "hủy ship" (unshipping) nhanh chóng. Đội ngũ muốn thay thế hệ thống lưu trữ file JSONL hiện tại bằng SQLite để đảm bảo tính toàn vẹn dữ liệu và hỗ trợ migration tốt hơn.

Sau 15 ngày phát triển, họ nhận ra đây là một sai lầm. SQLite là một native dependency trong hệ sinh thái npm, gây ra vô số khó khăn trong việc phân phối cho người dùng cuối. Hơn nữa, cơ chế khóa của SQLite (khóa toàn bộ cơ sở dữ liệu khi ghi) không phù hợp với môi trường đa tiến trình của Claude Code. Đối với một công cụ dành cho nhà phát triển, tính sẵn sàng (availability) quan trọng hơn nhiều so với tính nhất quán (consistency).

Kết quả là họ đã gỡ bỏ hoàn toàn SQLite chỉ sau hai tuần và quay lại sử dụng JSONL. Wolff nhấn mạnh rằng trong kỷ nguyên AI, việc thử nghiệm và thất bại là một phần tất yếu. Quan trọng là bạn phải có khả năng nhận ra sai lầm và lùi lại nhanh chóng.

Bài học kinh nghiệm

Từ ba câu chuyện trên, Adam Wolff rút ra những bài học cốt lõi cho kỹ thuật phần mềm trong kỷ nguyên AI:

  1. Tốc độ học hỏi là lợi thế cạnh tranh duy nhất: Khi chi phí viết mã giảm xuống gần như bằng 0 nhờ AI, điểm nghẽn chuyển sang việc bạn học được gì từ việc ship sản phẩm. Thay vì tranh luận về thiết kế trong nhiều tháng, hãy ship code và để người dùng cũng như quy trình phát triển chỉ ra điều gì cần xây dựng.
  2. Kiến trúc quyết định kết quả: Một kiến trúc module hóa, không phụ thuộc (như lớp Cursor) giúp AI hỗ trợ phát triển cực kỳ hiệu quả. Ngược lại, các kiến trúc phức tạp với nhiều phụ thuộc bên ngoài (như native dependencies) sẽ cản trở tốc độ.
  3. Tối ưu hóa quy trình giao hàng: Hãy hướng tới triển khai liên tục (continuous deployment). Đảm bảo rằng bạn có thể dễ dàng rollback (quay lại phiên bản cũ) nếu có vấn đề phát sinh.
  4. Hãy sẵn sàng Unshipping: Đừng ngại ship những tính năng chưa hoàn hảo và sau đó gỡ bỏ chúng nếu không hiệu quả. Việc này đòi hỏi sự kiềm chế cái tôi, nhưng là chìa khóa để di chuyển nhanh.

Tóm lại, AI không giải quyết được mọi vấn đề của kỹ sư phần mềm, nhưng nó thay đổi cách chúng ta tiếp cận vấn đề. Thay vì sợ hãi sự phức tạp, hãy tận dụng sức mạnh của AI để thử nghiệm nhanh, thất bại nhanh và học hỏi nhanh hơn bao giờ hết.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗