Trước đây có một người dùng mạng hỏi tôi quy trình phát triển AI của tôi là gì. Tình cờ vài ngày trước tôi đã dùng AI để hiện thực một tính năng nhỏ, rất đáng để mang ra làm ví dụ trình bày, và cũng có thể coi như một tài liệu tham khảo.
Nguồn gốc của tính năng này là do có người để lại bình luận trên phần Issues của GitHub cho tôi (Hình 1), hỏi liệu có thể bổ sung tính năng chuyển ghi âm từ xa cho app chuyển ghi âm/tịch bản và dịch phụ đề BaoCut mà tôi viết hay không.
Nói cách khác, tôi có hai máy tính: một máy có GPU NVIDIA tốc độ cao (máy A) và một máy chỉ dùng cho công việc hằng ngày (máy B). Tôi muốn tận dụng sức mạnh tính toán của máy A, nhưng thông thường tôi chỉ dùng máy B. Khi tôi dùng BaoCut trên máy B để chuyển ghi âm, thì phần công việc tiêu tốn năng lực tính toán sẽ được máy A hoàn thành.
Tôi vừa nhìn đã thấy đây là một nhu cầu rất hay, nhưng tôi chưa từng làm loại việc này và không biết liệu có khả thi hay không.
Vì vậy bước đầu tiên của tôi không phải là viết mã ngay, mà là phân tích tính khả thi.
I. Phân tích tính khả thi
Không làm phân tích mà lao vào làm bừa thì thiệt hại tôi từng gặp nhiều lắm. Nhiều khi công sức bỏ ra hoàn toàn vô ích. Ngoài ra, dù đã làm phân tích tính khả thi thì đôi khi vẫn có thể đưa ra phán đoán sai—ví dụ như mấy ngày trước tôi cũng làm một mô hình văn bản cục bộ để hỗ trợ tách và căn chỉnh (alignment). Khi phân tích tính khả thi thì thấy không có vấn đề, nhưng khi hoàn thành và trải nghiệm thực tế mới phát hiện kết quả tệ, cuối cùng vẫn phải cắt bỏ, lãng phí vài ngày thời gian và tốn khá nhiều token—may là chỉ tốn token.
Phân tích tính khả thi thường có hai lớp:
Một là từ góc độ sản phẩm: chức năng này có giá trị gì cho người dùng không, có phù hợp với định vị của app hay không.
Hai là từ góc độ kỹ thuật: chức năng này có khả thi về mặt kỹ thuật hay không, chi phí có kiểm soát được không.
Ở đây, từ góc độ sản phẩm, tôi thấy chức năng này có giá trị cho người dùng và phù hợp với định vị của sản phẩm. Vì vậy tôi tập trung chỉ vào phân tích tính khả thi về mặt kỹ thuật.
Tôi vào Claude Code, gửi yêu cầu gốc cho nó, để nó kết hợp với hiện trạng dự án mà làm phân tích tính khả thi (Hình 2). Sau khi phân tích, nó đưa ra kết luận là khả thi, đồng thời đề xuất một vài phương án (Hình 3).
Những phương án này có thể sẽ dễ hiểu hơn nếu có chút nền tảng kỹ thuật. Sau khi xem xong, tôi nhanh chóng đưa ra nhận định của riêng mình:
Phương án 0 và phương án C, dù không cần sửa code, nhưng đối với người dùng thì quá bất tiện—người dùng phải tự nghĩ cách dựng một máy chủ asr.
Phương án A thì có vẻ ổn: chỉ cần cài app là có thể khởi động dịch vụ chuyển ghi âm của riêng mình.
Phương án B không thân thiện với Windows.
Vì vậy tôi quyết định triển khai theo phương án A. Ngoài ra, dù phương án 0 không đáng tin, nhưng trong đó có cung cấp một http transcription API cũng là một chức năng bổ sung hay, có thể tận dụng để thêm vào luôn.
II. Viết tài liệu thiết kế
Sau khi xác định là khả thi, và đồng thời chốt luôn một phương án kỹ thuật ban đầu, tôi cũng không bắt đầu viết mã ngay, mà trước hết là viết tài liệu thiết kế.
Tài liệu thiết kế ở đây giống như sự kết hợp giữa tài liệu thiết kế sản phẩm và phương án thiết kế kỹ thuật. Đại khái là mô tả rõ ràng: yêu cầu, thiết kế kiến trúc, và tài liệu thiết kế UI.
Mục đích là để AI giúp mình hệ thống hóa rõ những công nghệ sẽ cần dùng để hiện thực, hiện trạng dự án hiện tại, và ghi lại tất cả vào tài liệu. Khi triển khai về sau sẽ có một tham chiếu tốt, còn khi bảo trì trong tương lai cũng có thể dùng làm tài liệu tham khảo. Quan trọng nhất là: con người có thể xác nhận xem hướng đi có đúng hay không. (tham khảo Hình 4)
Tất nhiên tôi thừa nhận ở đây tôi hơi lười: cho nó viết xong tài liệu rồi bắt đầu làm luôn. Chủ yếu là vì tôi thấy các phương án được đưa ra trước đó không có vấn đề lớn, và tôi khá tin vào Fable—nếu có điều kiện thì vẫn nên xem kỹ hơn.
III. Thiết kế nguyên mẫu
Sở dĩ tôi làm thiết kế nguyên mẫu trước khi viết code là vì muốn dùng nguyên mẫu để kiểm chứng nhanh nhu cầu với chi phí thấp, từ đó xác định nhanh thiết kế giao diện và tương tác. Ở đây tôi đã cài đặt baoyu-design skill (github.com/jimliu/baoyu-design), nên chỉ cần nói “thiết kế nguyên mẫu” là nó sẽ tự động kích hoạt.
App của tôi có một trang nguyên mẫu đi kèm. Mỗi khi thêm hoặc chỉnh sửa chức năng, tôi đều trước tiên cập nhật trang nguyên mẫu.
Với tài liệu thiết kế ở trên, việc thiết kế nguyên mẫu khá thuận lợi. Phiên bản đầu tiên (Hình 5) đã cho hiệu quả khá tốt: trong trang cài đặt thêm một trang tùy chọn mới, có thể bật dịch vụ và phát hiện node.
Lưu ý rằng nguyên mẫu ở đây thực chất là một nguyên mẫu độ chính xác cao kết hợp giữa nguyên mẫu và thiết kế UI—tức là nguyên mẫu chính là thiết kế UI. Đây cũng là một điểm đặc trưng của Claude Design.
Nguyên mẫu đã xong vẫn cần phải điều chỉnh. Lúc này con người cần dựa trên kết quả nguyên mẫu để đưa phản hồi để Agent chỉnh lại. Ví dụ như ở đây tôi đã phải chỉnh đi chỉnh lại nhiều lần. (tham khảo Hình 6)
Đầu tiên là đổi bố cục thành Tab, tách việc “bật dịch vụ” và “truy cập các node khác” ra, vì theo tôi đây là hai bối cảnh khác nhau. Ngoài ra còn thêm icon hiển thị trạng thái dịch vụ, giúp biết rõ dịch vụ đang được khởi động hay đã dừng chỉ qua icon. (tham khảo Hình 7)
Sau đó tôi phát hiện việc đặt nó trong trang cài đặt không tiện để theo dõi trạng thái dịch vụ, nên lại chuyển nó ra giao diện chính. Cuối cùng tôi cảm thấy gần như ổn rồi. (Hình 8, Hình 9)
IV. Hiện thực (Implementation)
Nếu bạn đã có tài liệu thiết kế, đã có thiết kế nguyên mẫu (UI), thì việc để AI viết code là chuyện rất đơn giản đối với Agent hiện tại.
Thông thường lúc này tôi sẽ kết hợp /goal, gửi cả tài liệu cho Claude Code (Fable 5) để triển khai. Nó sẽ thực hiện lần lượt theo các Milestones đã hoạch định trong tài liệu, và còn tự chụp màn hình để kiểm chứng kết quả. (Hình 10, Hình 11)
V. Kiểm thử và xác nhận
Mặc dù Agent sẽ giúp chúng ta xác nhận, nhưng điều đó không có nghĩa là có thể hoàn toàn tin vào kết quả do AI đưa ra. Tiếp theo vẫn phải tự tay chạy thử vài lần, những vấn đề phát hiện được thì đưa lại cho Agent để nó chỉnh. (Hình 12)
Sau vài vòng chỉnh như vậy thì gần như đã dùng được.
Xem thành phẩm cuối cùng (Hình 13, Hình 14)
Bạn hỏi tôi có Review code không?
Không. Tôi coi mình như một người làm QA, chỉ làm kiểm thử hộp đen. Tôi vẫn tin vào năng lực của Fable.
Nguồn gốc của tính năng này là do có người để lại bình luận trên phần Issues của GitHub cho tôi (Hình 1), hỏi liệu có thể bổ sung tính năng chuyển ghi âm từ xa cho app chuyển ghi âm/tịch bản và dịch phụ đề BaoCut mà tôi viết hay không.
Nói cách khác, tôi có hai máy tính: một máy có GPU NVIDIA tốc độ cao (máy A) và một máy chỉ dùng cho công việc hằng ngày (máy B). Tôi muốn tận dụng sức mạnh tính toán của máy A, nhưng thông thường tôi chỉ dùng máy B. Khi tôi dùng BaoCut trên máy B để chuyển ghi âm, thì phần công việc tiêu tốn năng lực tính toán sẽ được máy A hoàn thành.
Tôi vừa nhìn đã thấy đây là một nhu cầu rất hay, nhưng tôi chưa từng làm loại việc này và không biết liệu có khả thi hay không.
Vì vậy bước đầu tiên của tôi không phải là viết mã ngay, mà là phân tích tính khả thi.
I. Phân tích tính khả thi
Không làm phân tích mà lao vào làm bừa thì thiệt hại tôi từng gặp nhiều lắm. Nhiều khi công sức bỏ ra hoàn toàn vô ích. Ngoài ra, dù đã làm phân tích tính khả thi thì đôi khi vẫn có thể đưa ra phán đoán sai—ví dụ như mấy ngày trước tôi cũng làm một mô hình văn bản cục bộ để hỗ trợ tách và căn chỉnh (alignment). Khi phân tích tính khả thi thì thấy không có vấn đề, nhưng khi hoàn thành và trải nghiệm thực tế mới phát hiện kết quả tệ, cuối cùng vẫn phải cắt bỏ, lãng phí vài ngày thời gian và tốn khá nhiều token—may là chỉ tốn token.
Phân tích tính khả thi thường có hai lớp:
Một là từ góc độ sản phẩm: chức năng này có giá trị gì cho người dùng không, có phù hợp với định vị của app hay không.
Hai là từ góc độ kỹ thuật: chức năng này có khả thi về mặt kỹ thuật hay không, chi phí có kiểm soát được không.
Ở đây, từ góc độ sản phẩm, tôi thấy chức năng này có giá trị cho người dùng và phù hợp với định vị của sản phẩm. Vì vậy tôi tập trung chỉ vào phân tích tính khả thi về mặt kỹ thuật.
Tôi vào Claude Code, gửi yêu cầu gốc cho nó, để nó kết hợp với hiện trạng dự án mà làm phân tích tính khả thi (Hình 2). Sau khi phân tích, nó đưa ra kết luận là khả thi, đồng thời đề xuất một vài phương án (Hình 3).
Những phương án này có thể sẽ dễ hiểu hơn nếu có chút nền tảng kỹ thuật. Sau khi xem xong, tôi nhanh chóng đưa ra nhận định của riêng mình:
Phương án 0 và phương án C, dù không cần sửa code, nhưng đối với người dùng thì quá bất tiện—người dùng phải tự nghĩ cách dựng một máy chủ asr.
Phương án A thì có vẻ ổn: chỉ cần cài app là có thể khởi động dịch vụ chuyển ghi âm của riêng mình.
Phương án B không thân thiện với Windows.
Vì vậy tôi quyết định triển khai theo phương án A. Ngoài ra, dù phương án 0 không đáng tin, nhưng trong đó có cung cấp một http transcription API cũng là một chức năng bổ sung hay, có thể tận dụng để thêm vào luôn.
II. Viết tài liệu thiết kế
Sau khi xác định là khả thi, và đồng thời chốt luôn một phương án kỹ thuật ban đầu, tôi cũng không bắt đầu viết mã ngay, mà trước hết là viết tài liệu thiết kế.
Tài liệu thiết kế ở đây giống như sự kết hợp giữa tài liệu thiết kế sản phẩm và phương án thiết kế kỹ thuật. Đại khái là mô tả rõ ràng: yêu cầu, thiết kế kiến trúc, và tài liệu thiết kế UI.
Mục đích là để AI giúp mình hệ thống hóa rõ những công nghệ sẽ cần dùng để hiện thực, hiện trạng dự án hiện tại, và ghi lại tất cả vào tài liệu. Khi triển khai về sau sẽ có một tham chiếu tốt, còn khi bảo trì trong tương lai cũng có thể dùng làm tài liệu tham khảo. Quan trọng nhất là: con người có thể xác nhận xem hướng đi có đúng hay không. (tham khảo Hình 4)
Tất nhiên tôi thừa nhận ở đây tôi hơi lười: cho nó viết xong tài liệu rồi bắt đầu làm luôn. Chủ yếu là vì tôi thấy các phương án được đưa ra trước đó không có vấn đề lớn, và tôi khá tin vào Fable—nếu có điều kiện thì vẫn nên xem kỹ hơn.
III. Thiết kế nguyên mẫu
Sở dĩ tôi làm thiết kế nguyên mẫu trước khi viết code là vì muốn dùng nguyên mẫu để kiểm chứng nhanh nhu cầu với chi phí thấp, từ đó xác định nhanh thiết kế giao diện và tương tác. Ở đây tôi đã cài đặt baoyu-design skill (github.com/jimliu/baoyu-design), nên chỉ cần nói “thiết kế nguyên mẫu” là nó sẽ tự động kích hoạt.
App của tôi có một trang nguyên mẫu đi kèm. Mỗi khi thêm hoặc chỉnh sửa chức năng, tôi đều trước tiên cập nhật trang nguyên mẫu.
Với tài liệu thiết kế ở trên, việc thiết kế nguyên mẫu khá thuận lợi. Phiên bản đầu tiên (Hình 5) đã cho hiệu quả khá tốt: trong trang cài đặt thêm một trang tùy chọn mới, có thể bật dịch vụ và phát hiện node.
Lưu ý rằng nguyên mẫu ở đây thực chất là một nguyên mẫu độ chính xác cao kết hợp giữa nguyên mẫu và thiết kế UI—tức là nguyên mẫu chính là thiết kế UI. Đây cũng là một điểm đặc trưng của Claude Design.
Nguyên mẫu đã xong vẫn cần phải điều chỉnh. Lúc này con người cần dựa trên kết quả nguyên mẫu để đưa phản hồi để Agent chỉnh lại. Ví dụ như ở đây tôi đã phải chỉnh đi chỉnh lại nhiều lần. (tham khảo Hình 6)
Đầu tiên là đổi bố cục thành Tab, tách việc “bật dịch vụ” và “truy cập các node khác” ra, vì theo tôi đây là hai bối cảnh khác nhau. Ngoài ra còn thêm icon hiển thị trạng thái dịch vụ, giúp biết rõ dịch vụ đang được khởi động hay đã dừng chỉ qua icon. (tham khảo Hình 7)
Sau đó tôi phát hiện việc đặt nó trong trang cài đặt không tiện để theo dõi trạng thái dịch vụ, nên lại chuyển nó ra giao diện chính. Cuối cùng tôi cảm thấy gần như ổn rồi. (Hình 8, Hình 9)
IV. Hiện thực (Implementation)
Nếu bạn đã có tài liệu thiết kế, đã có thiết kế nguyên mẫu (UI), thì việc để AI viết code là chuyện rất đơn giản đối với Agent hiện tại.
Thông thường lúc này tôi sẽ kết hợp /goal, gửi cả tài liệu cho Claude Code (Fable 5) để triển khai. Nó sẽ thực hiện lần lượt theo các Milestones đã hoạch định trong tài liệu, và còn tự chụp màn hình để kiểm chứng kết quả. (Hình 10, Hình 11)
V. Kiểm thử và xác nhận
Mặc dù Agent sẽ giúp chúng ta xác nhận, nhưng điều đó không có nghĩa là có thể hoàn toàn tin vào kết quả do AI đưa ra. Tiếp theo vẫn phải tự tay chạy thử vài lần, những vấn đề phát hiện được thì đưa lại cho Agent để nó chỉnh. (Hình 12)
Sau vài vòng chỉnh như vậy thì gần như đã dùng được.
Xem thành phẩm cuối cùng (Hình 13, Hình 14)
Bạn hỏi tôi có Review code không?
Không. Tôi coi mình như một người làm QA, chỉ làm kiểm thử hộp đen. Tôi vẫn tin vào năng lực của Fable.