Mục Lục
- Giới Thiệu
- I. AI Engineering Là Gì?
- II. Giữ Một Cuốn Sách Luôn Cập Nhật Trong Một Lĩnh Vực Thay Đổi Từng Tuần
- III. Từ Dữ Liệu → Mô Hình → Sản Phẩm, Đến Sản Phẩm → Dữ Liệu → Mô Hình
- IV. Những Bước Đầu Tiên: Prompt, Ngữ Cảnh, và RAG
- V. Phép Thử BM25 — Vì Sao Truy Hồi "Cũ Kỹ" Vẫn Thắng
- VI. Fine-Tuning: Phương Án Cuối Cùng, Không Phải Đầu Tiên
- VII. Triển Khai AI Một Cách Thận Trọng — Trường Hợp Chăm Sóc Khách Hàng
- VIII. Tập Trung Vào Vấn Đề, Không Phải Tin Tức
- IX. Vì Sao Đánh Giá AI Càng Lúc Càng Khó Khi Mô Hình Càng Thông Minh
- X. Độ Chính Xác Chức Năng, LLM-as-Judge, và Đánh Giá So Sánh
- XI. Đo Lường Điều Người Dùng Thực Sự Muốn
- XII. Những Sai Lầm Thường Gặp Khi Làm GenAI
- XIII. Tư Duy Hệ Thống Không Bao Giờ Lỗi Thời
- XIV. Học AI Engineering Như Thế Nào
- XV. Vì Sao AI Không Phải Là Dấu Chấm Hết Cho Kỹ Thuật Phần Mềm
- XVI. Giáo Dục, Giải Trí, và Doanh Nghiệp
- XVII. Vòng Hỏi Nhanh
Giới Thiệu
Chip Huyen là nhà khoa học máy tính kiêm nhà văn, tác giả cuốn sách AI Engineering — hiện là đầu sách được đọc nhiều nhất trên nền tảng O'Reilly. Trước đây cô từng là nhà nghiên cứu tại Netflix, là một trong những người phát triển cốt lõi của NeMo (framework GenAI của NVIDIA), từng làm kỹ sư ML tại Snorkel AI, và sáng lập rồi bán lại một startup AI tên Claypot AI. Cô từng dạy môn thiết kế hệ thống machine learning tại Stanford, và cuốn sách hiện tại là cuốn thứ hai của cô về ML và AI engineering. Trong cuộc trò chuyện này, host Gergely Orosz và Chip bàn về AI engineering là gì, vì sao nó cảm giác "full-stack" hơn hẳn so với machine learning engineering trước đây, các bước điển hình để xây dựng một ứng dụng AI — từ chọn mô hình, dùng RAG, cho đến fine-tuning — và những cách thực tế để một kỹ sư phần mềm bắt đầu xây dựng ứng dụng AI.
GERGELY OROSZ: Chip, chào mừng bạn đến với podcast.
CHIP HUYEN: Chào mọi người, tôi là Chip. Tôi rất vui được có mặt ở đây.
GERGELY: Tôi đã theo dõi newsletter của bạn một thời gian rồi, nên tôi rất mong chờ buổi trò chuyện này. Trước hết, tôi thực sự muốn chúc mừng bạn về cuốn sách này. Tôi đã bắt đầu đọc — chưa đọc hết, nhưng đã đọc một số chương và đi sâu vào vài phần. Điều tôi nhận thấy là, khi nhìn vào mục lục, tôi nghĩ, ồ, cái này ổn đấy về mặt độ rộng — nó đi từ cách hiểu các mô hình nền tảng, cách đánh giá chúng, prompt engineering là gì, rồi đến những thứ như fine-tuning, RAG, xây dựng tập dữ liệu. Nhưng trong mỗi phần đó, nó lại bắt đầu đi rất sâu — có phần mở đầu, nhưng rồi càng lúc càng đào sâu hơn. Ví dụ, với chương về phương pháp luận đánh giá — chỉ nhìn vào mục lục thôi — tôi bắt đầu đọc và nghĩ, ừ thì mình biết đánh giá mô hình AI là quan trọng, biết là khó hơn, nhưng rồi bạn lại đi vào những thứ như LLM-as-judge, hay xếp hạng mô hình bằng đánh giá so sánh, và những thách thức của nó. Đó là những chỗ mà đôi lúc tôi phải chậm lại, phải tra cứu thêm. Nên nó thực sự đi sâu vào rất nhiều phần, điều mà tôi thấy khá thú vị — vừa có độ rộng, vừa có độ sâu. Đây chắc chắn không phải một cuốn sách đọc nhanh được, nhưng là kiểu sách tôi sẽ cứ quay lại đọc mãi.
CHIP: Cảm ơn bạn. Viết nó cũng chẳng nhanh chút nào — mất khá lâu, và rất nhiều tài liệu tham khảo. Tôi trích dẫn hơn một nghìn tài liệu tham khảo trong sách, nên lẽ ra tôi còn phải đọc nhiều hơn nữa. Tôi đã lục qua rất nhiều repo trên GitHub — tôi có một bảng theo dõi hàng nghìn repo, ít nhất 800 sao trở lên — nên tôi đã đi qua rất nhiều codebase như vậy, cùng rất nhiều bài blog, và cả những cuốn sách khác, có cuốn từ những năm bảy mươi, tám mươi, chín mươi. Tôi cũng công bố khoảng một trăm liên kết tham khảo mà tôi thấy thực sự hữu ích trong quá trình viết sách, nên nếu bạn chỉ muốn xem riêng phần tham khảo đó, chúng có trên GitHub của tôi.
GERGELY: Và tôi khá bất ngờ với một số nghiên cứu thực sự nguyên bản — không chỉ là bạn viết về những bài báo đó, hay đây là những gì tôi đã đọc, mà — như bạn vừa nhắc đến con số một nghìn repo — bạn thực sự có hẳn một phần nói về việc số lượng repo trên GitHub thay đổi theo thời gian như thế nào: những repo về hạ tầng, những repo ở tầng ứng dụng, và nhiều thứ khác. Bạn có hơn 900 repo được lập bản đồ ra. Tôi chưa từng thấy cái gì như vậy, và rõ ràng đó là công sức tự bạn phân tích, tự nghiên cứu.
CHIP: Vâng, tôi cảm thấy mình làm khá nhiều "lao động chân tay" theo kiểu đó. Tôi nghĩ mình nhận được rất nhiều giá trị từ việc làm mọi thứ theo cách không tối ưu. Tôi thấy nhiều người tập trung vào việc "cách nào nhanh nhất, cách nào là con đường ngắn nhất" — nhưng nếu bạn sẵn sàng bỏ công sức vào những việc mà nhiều người không sẵn lòng làm, tôi nghĩ bạn sẽ có được những hiểu biết mà người khác không có được.
I. AI Engineering Là Gì?
GERGELY: Có một điều khá thú vị về cuốn sách này — nó nói về AI engineering, mà lĩnh vực này lại thay đổi rất nhanh — chỉ trong một tuần chúng ta đã có một mô hình mới ra mắt, ví dụ như DeepSeek, thứ mà mọi người đã bàn tán mấy tuần nay. Bạn viết cuốn sách này như thế nào? Làm sao bạn có thể viết một cuốn sách về một ngành thay đổi nhanh đến vậy, để đến khi nó được phát hành — rõ ràng là vài tháng sau khi bạn viết xong — nó vẫn còn liên quan?
CHIP: Đó là một câu hỏi rất hay. Khi tôi bắt đầu viết cuốn sách, tôi cũng nghĩ y như vậy — tôi nghĩ đây không phải thời điểm đúng để viết, vì có quá nhiều thứ vẫn đang thay đổi. Nhưng rồi, khi ChatGPT thực sự ra mắt, giống như bao người khác, tôi rơi vào một cuộc khủng hoảng hiện sinh. Tôi ở trong một nhóm chat và mọi người đều kiểu, "ôi không, điều này có nghĩa gì với chúng ta, những kỹ sư." Tôi thấy mình gắn với hai vai trò — một là kỹ sư, hai là người viết. Và đoán xem, những use case mà AI làm tốt nhất chính là viết code, và viết lách. Nên tôi kiểu, ôi trời, vậy điều này có ý nghĩa gì với mình đây?
Thế là tôi bắt đầu phỏng vấn rất nhiều người, đọc rất nhiều, nói chuyện với vô số người, và ghi chép lại rất nhiều. Trong quá trình đó, điều tôi nhận ra là, rất nhiều thứ tưởng như mới thật ra các nền tảng cơ bản đã tồn tại từ lâu rồi. Mô hình hóa ngôn ngữ (language modeling) không phải là một tác vụ mới — Claude Shannon đã giới thiệu nó từ những năm 1950. Chúng ta cứ nói về RAG suốt, nhưng RAG cũng không mới — nó dựa trên retrieval-augmented generation (sinh văn bản có tăng cường truy hồi), và truy hồi (retrieval) là một công nghệ rất cũ, đã đang vận hành rất nhiều use case trên khắp internet rồi, như tìm kiếm hay hệ thống gợi ý. Cơ sở dữ liệu vector cũng đã tồn tại một thời gian, và tìm kiếm vector đã có sẵn rất nhiều thuật toán hay ho.
Nên tôi nghĩ, được rồi — trước hết, rất nhiều thứ thật ra không mới. Và thứ hai, tôi cố tập trung vào việc tự hỏi: đây là do một giới hạn nền tảng của AI, hay chỉ là do năng lực hiện tại, tạm thời của AI? Và nếu đó là do năng lực hiện tại, thì năng lực đó đang thay đổi nhanh cỡ nào? Ví dụ, trong những ngày đầu, rất nhiều người chia sẻ các mẹo prompt — kiểu, thử "hối lộ" mô hình, "này, nếu bạn trả lời đúng câu này tôi sẽ cho bạn 200 đô" — hay người ta nói về độ bền vững của prompt (prompt robustness), tức mô hình nhạy cảm thế nào với những thay đổi nhỏ trong prompt. Tôi đọc về điều này và cảm thấy mô hình đang ngày càng bền vững hơn với prompt — ví dụ, từ GPT-3 lên GPT-3.5, nó đã bền vững hơn rất nhiều, nghĩa là những thay đổi nhỏ trong prompt tạo ra ít biến động hơn hẳn trong hiệu năng mô hình. Nên tôi cảm thấy kiểu mẹo này sẽ không tồn tại lâu — các mẹo prompt sẽ không còn quan trọng bao lâu nữa. Và điều đó đã xảy ra ngay lúc mọi người đang nói về khả năng có một nghề gọi là "prompt engineer." Người ta đã thấy xu hướng đó đi xuống rồi.
Nên tôi nghĩ viết sách kiểu như đặt cược — khi bạn viết về một chủ đề, bạn đang cược xem nó có còn liên quan trong tương lai hay không. Tôi cố nhìn vào quỹ đạo tiến bộ để xem điều gì vẫn còn đúng sau một hai năm nữa. Một ví dụ khác là độ dài ngữ cảnh (context length) — người ta muốn ngữ cảnh dài hơn, nhưng tôi thấy nó tăng nhanh khủng khiếp, từ khoảng 8.000 token lên 128.000 chỉ trong vài tháng. Siêu nhanh. Nên tôi nghĩ, có lẽ câu hỏi không phải là độ dài ngữ cảnh, mà là hiệu quả sử dụng ngữ cảnh — liệu mô hình có thực sự dùng tốt ngữ cảnh đó không? Đó là những kiểu "cược" tôi đã đặt, và có những sự kiện xảy ra trong quá trình viết khiến tôi tự tin hơn vào các cược đó. Đa phương thức (multimodality) là một ví dụ khác — khi tôi viết về mô hình đa phương thức hồi 2023, người ta bảo tôi là quá sớm, rằng mọi người vẫn còn đang tập trung vào ngôn ngữ, chưa đến lúc đó đâu. Nhưng với tôi nó cảm giác là điều tất yếu — chúng ta đã học được cách làm việc với ngôn ngữ, nhưng tôi muốn làm nhiều hơn thế. Và giờ đa phương thức có ở khắp mọi nơi — gần như mọi mô hình bây giờ đều đa phương thức.
II. Giữ Một Cuốn Sách Luôn Cập Nhật Trong Một Lĩnh Vực Thay Đổi Từng Tuần
GERGELY: Tên cuốn sách là AI Engineering, và giờ chúng ta cũng có thuật ngữ "AI engineer" đang lan rộng như cháy rừng. Bạn định nghĩa AI engineer, hay AI engineering, như thế nào? Vì tôi cảm thấy nó đã trở thành một thuật ngữ khá "nặng" (loaded) dạo gần đây.
CHIP: Đúng vậy. Tôi cảm thấy rất nhiều thuật ngữ bây giờ trở nên "nặng" — bạn không được phép nói cái này nữa, không được dùng từ kia nữa. Khi tôi đang vò đầu bứt tai chọn tên cho cuốn sách, tôi biết chúng ta cần một thuật ngữ khác với "machine learning engineering." Lý do là, với các mô hình nền tảng, rất nhiều nền tảng cơ bản, các cách tiếp cận có hệ thống, vẫn giống với machine learning engineering, nhưng cũng có rất nhiều thứ mới.
Một điều là: trước đây, nếu bạn muốn xây một ứng dụng machine learning, bạn phải tự xây mô hình của riêng mình — nghĩa là bạn cần dữ liệu của riêng mình, và cần chuyên môn để huấn luyện và "chăm sóc" một mô hình. Ngày nay, nếu bạn muốn xây một ứng dụng tận dụng machine learning hay AI, bạn chỉ cần gửi thẳng một API call và có ngay quyền truy cập vào năng lực tuyệt vời này. Điều đó thực sự hạ thấp rào cản gia nhập — bạn không cần dữ liệu nữa, không cần bằng cấp AI hoành tráng gì nữa.
Điều thứ hai là: trước đây, bạn cần kênh phân phối, vì bạn triển khai ứng dụng machine learning như một phần của ứng dụng đã có sẵn. Nếu bạn xây một hệ thống gợi ý (recommender system), bạn cần một trang thương mại điện tử để gắn nó vào. Phát hiện gian lận (fraud detection) được triển khai như một phần của, chẳng hạn, ứng dụng ngân hàng hay thanh toán. Nhưng giờ bạn có thể tung nó ra như một ứng dụng độc lập — bạn không cần kênh phân phối có sẵn, dù có kênh phân phối vẫn rất hữu ích.
Một điều rất lớn khác là đây là một sự dịch chuyển — bớt machine learning đi, thêm engineering và sản phẩm vào. Trước đây, nếu bạn là một kỹ sư machine learning giỏi, bạn bắt đầu từ dữ liệu — bạn phải thu thập dữ liệu, có thể có gán nhãn của con người, rồi bạn huấn luyện mô hình, và khi mô hình đã tốt, bạn triển khai nó vào sản phẩm. Ngày nay, bạn thực sự bắt đầu bằng một bản demo — bạn có một ý tưởng hay, bạn nói, "thử xem nó có chạy không đã." Bạn bắt đầu từ sản phẩm, và khi nó hoạt động khá tốt rồi, bạn nói, "tôi muốn làm nó tốt hơn," thế là bạn bắt đầu thu thập thêm dữ liệu — có thể là thêm ví dụ cho prompt, hoặc, trong những trường hợp rất hiếm (tôi không khuyến khích hầu hết mọi người làm điều này ngay từ đầu), là fine-tuning. Rồi có thể bạn đang gửi rất nhiều API call đến OpenAI, Anthropic, Google, và bạn quyết định việc này ngày càng đắt đỏ, nên bạn bắt đầu tự host mô hình của mình, dùng một lựa chọn mã nguồn mở, hoặc fine-tune một mô hình.
Vậy nên trước đây, machine learning engineering đi từ dữ liệu, đến mô hình, đến sản phẩm. Còn bây giờ, với AI engineering, nó đi từ sản phẩm, đến dữ liệu, đến mô hình. Điều đó đặt trọng tâm nhiều hơn vào sản phẩm và dữ liệu, chính là nơi tạo ra lợi thế cạnh tranh khi mọi người đều dùng chung những năng lực AI nền tảng tương tự nhau. Tôi thực sự nghĩ chúng ta cần một thuật ngữ khác để tách biệt khỏi machine learning engineering, nhưng tôi không biết nên dùng từ nào — nên tôi nghĩ, thôi thì cứ hỏi mọi người. Tôi khảo sát một nhóm người mà tôi nghĩ đang làm công việc này — xây ứng dụng trên nền các mô hình nền tảng — và gần như tất cả đều nói "AI engineering." Nên tôi nghĩ, được rồi, nếu đó là cái mọi người đã đang gọi, thì cứ dùng nó thôi.
GERGELY: Vậy có phải tôi hiểu đúng là: sự khác biệt lớn nhất là các kỹ sư machine learning phải làm nhiều công việc nền tảng hơn — thu thập dữ liệu và xây mô hình — trong khi với AI engineering, bạn có sẵn nhiều thứ đó, ít nhất là ban đầu, thông qua API, nên nó mang hơi hướng engineering nhiều hơn, bạn "ráp" mọi thứ lại với nhau, và rồi theo thời gian, khi mọi thứ trở nên nghiêm túc hơn, hay sản phẩm lớn hơn, bạn mới làm nhiều hơn việc — bạn có thể tự xây mô hình, host nó, thậm chí một ngày nào đó tự xây mô hình riêng, nhưng nó đến muộn hơn nhiều. Nên rất nhiều công việc machine learning engineering chỉ xuất hiện nếu sản phẩm đủ lớn, nếu nó hoạt động, v.v., trong khi với AI engineering thì ngược lại — bạn bỏ hết công sức vào trước, rồi mới xem nó có chạy không.
CHIP: Đầu tiên, tôi cảm thấy mỗi công ty có một định nghĩa khác nhau về vai trò này — ngay cả trong cùng một công ty, người có cùng chức danh cũng có thể làm những việc rất khác nhau, nên nó không bao giờ là một định nghĩa rạch ròi. Thứ hai, tôi không nghĩ câu hỏi thực sự là "machine [learning] hay engineering." Trong đại đa số các hệ thống GenAI mà tôi từng thấy, vẫn có một thành phần machine learning truyền thống, hay bộ phân loại (classifier), rất mạnh. Hãy tưởng tượng bạn đang xây một chatbot chăm sóc khách hàng — mỗi khi tôi hỏi điều này tại một hội nghị, tôi thấy rất nhiều người giơ tay, đây là một ứng dụng GenAI kinh điển. Bạn nhận một yêu cầu từ khách hàng, và có thể có vài giải pháp khác nhau cho nó — nếu là câu hỏi dễ, bạn gửi đến một mô hình rẻ; nếu khó hơn, bạn gửi đến mô hình đắt hơn. Nhưng có thứ gì đó rất nhạy cảm, kiểu "này, sao tôi bị tính tiền hai lần trong hóa đơn tháng trước," bạn có lẽ muốn gửi đến một nhân viên hỗ trợ là con người. Nên bạn sẽ có một bộ định tuyến (router), hay một bộ phân loại ý định (intent classifier), để quyết định cái gì đi đâu — đó là một mô hình machine learning cổ điển, truyền thống mà bạn có thể tự xây. Hoặc, sau khi bạn nhận được phản hồi từ một mô hình AI, bạn có thể kiểm tra xem nó có chứa PII (thông tin định danh cá nhân) không, vì bạn không muốn gửi cho người dùng một phản hồi chứa thông tin riêng tư — phát hiện PII có thể là một bộ phân loại, phát hiện độc hại (toxicity) cũng có thể là một bộ phân loại. Truy hồi (retrieval) trong hệ thống RAG cũng vậy, tôi nghĩ nó thuộc phạm trù machine learning cổ điển mà bạn có thể tự xây được.
III. Từ Dữ Liệu → Mô Hình → Sản Phẩm, Đến Sản Phẩm → Dữ Liệu → Mô Hình
GERGELY: Những kỹ thuật phổ biến nhất khi xây dựng ứng dụng AI là gì — những thứ mà một kỹ sư phần mềm đang bước vào AI engineering nên biết? Giả định ở đây là bạn đã thử nhiều giải pháp khác, và giờ bạn nghĩ GenAI là giải pháp cho mình — vậy trước tiên nên làm gì?
CHIP: Tôi nghĩ những kỹ thuật đó đều hữu ích, và một khuôn mẫu phổ biến mà tôi thấy là một lộ trình phát triển nhất định. Ban đầu, điều đầu tiên tôi muốn nói là hãy cố hiểu thế nào là một phản hồi tốt và thế nào là một phản hồi tệ — bạn cần một mô hình tư duy (mental model) về điều đó, và nó không phải lúc nào cũng trực giác. LinkedIn có một ví dụ rất hay — họ xây một công cụ đánh giá mức độ phù hợp công việc cho ứng viên, và họ nhận ra rằng phần lớn thời gian của họ dành ra chỉ để hiểu điều ứng viên thực sự cần từ mô hình. Ban đầu họ tập trung vào tính đúng đắn, nhưng họ nhận ra ứng viên không thấy điều đó hữu ích — nếu một ứng viên hỏi mô hình, "tôi có phù hợp với công việc này không," và AI trả lời, "bạn hoàn toàn không phù hợp," thì ứng viên sẽ nghĩ, "được rồi, vậy tôi phải làm gì với thông tin này đây?" Điều ứng viên thực sự muốn là hiểu rõ hơn về những khoảng trống (gap), và làm sao để lấp đầy chúng, hoặc gợi ý những vai trò khác phù hợp hơn với họ ngay lúc này. Vậy nên khi đã có bức tranh đó, bạn xây một bộ hướng dẫn — với kiểu phản hồi này, hãy trả lời như thế này, hãy hữu ích, chỉ ra khoảng trống cho họ — một hướng dẫn rất rõ ràng cho mô hình, ngay trong prompt. Bạn thử các prompt đó, nhìn vào kết quả, thêm ví dụ, rồi tiếp tục cho đến khi có được những phản hồi thực sự tốt. Sau đó bạn đánh giá — có thể tạo một tập câu hỏi và phản hồi mong đợi, dùng cả các chỉ số tự động, như LLM-as-judge, lẫn đánh giá của con người, để đo tiến độ.
IV. Những Bước Đầu Tiên: Prompt, Ngữ Cảnh, và RAG
Sau khi đã làm xong phần prompting và thêm ví dụ, bạn có thể muốn làm hệ thống phức tạp hơn — cho mô hình thêm ngữ cảnh để nó trả lời tốt hơn. Vậy nên khi người dùng đặt câu hỏi, bạn có thể để mô hình lấy ra các tài liệu liên quan, hay các tin tuyển dụng, hay thông tin về công ty, hay hồ sơ (résumé) của ứng viên. Bạn xây một hệ thống tăng cường ngữ cảnh bằng tài liệu — đó là mô hình RAG. Tôi thực sự nghĩ RAG là một mô hình rất mạnh, và chẳng có gì cầu kỳ trong đó cả.
Điều thú vị là nhiều người đồng nhất RAG với tìm kiếm vector (vector search). Khi người ta nói "tôi muốn dùng RAG," câu hỏi tiếp theo họ hỏi luôn là "vậy tôi nên dùng cơ sở dữ liệu vector nào" — người ta nhảy thẳng vào vector search.
GERGELY: Đúng vậy, vì bạn có các đoạn văn bản (chunk), và embedding có thể được lưu dưới dạng vector, nên là kỹ sư, chúng ta kiểu, "tôi cần một cơ sở dữ liệu tìm kiếm vector."
CHIP: Người ta yêu database mà. Nhưng tôi không nghĩ giải pháp đầu tiên nên là nhảy thẳng vào truy hồi dựa trên embedding, vì bạn cần xây một mô hình embedding, và chất lượng phụ thuộc rất nhiều vào chất lượng của embedding đó — embedding tệ thì truy hồi cũng tệ. Cơ sở dữ liệu vector cũng có thể khá tốn kém để vận hành, và còn có độ trễ (latency) cần cân nhắc nữa. Và embedding có thể làm mờ đi một số từ khóa nhất định — nếu tôi tìm một mã lỗi cụ thể, tìm kiếm bằng embedding không nhất thiết sẽ cho ra đúng mã đó. Nên có những thách thức thực sự với cơ sở dữ liệu vector và vector search. Cách tiếp cận thông thường, phổ biến, là bắt đầu với thứ gì đó đơn giản như truy hồi theo từ khóa (keyword retrieval) — trích xuất từ khóa từ câu hỏi của người dùng và tìm những tài liệu khớp với nó. Rồi có thể tài liệu quá dài để vừa vào ngữ cảnh, đó là lúc bạn bắt đầu chunking — tìm cách chia nhỏ tài liệu sao cho vừa. Và chunking lại tạo ra những vấn đề riêng của nó — có thể một tài liệu nói về "Công ty X," nhưng lại ghi ngay từ đầu, "từ giờ trở đi, Công ty X sẽ được gọi là Công ty," nên phần còn lại của tài liệu không bao giờ nhắc đến chữ "X" nữa, và nếu bạn tìm chữ X, bạn sẽ bỏ lỡ những đoạn phía sau điểm đó. Vậy nên bạn có thể muốn trích xuất từ khóa, gắn thêm metadata vào từng đoạn, thêm tiêu đề tài liệu, hoặc thêm một bản tóm tắt — một số người làm vậy. Anthropic có một bài viết rất hay tên "contextual retrieval," trong đó họ để Claude tạo ra metadata ngữ cảnh quan trọng cho từng đoạn và gắn nó vào đầu đoạn, để bạn truy hồi đúng đoạn cần thiết. Việc chuẩn bị dữ liệu mang lại một cú hích hiệu năng rất lớn — tôi từng thấy nó tạo ra cú hích lớn hơn nhiều so với việc vò đầu bứt tai chọn cơ sở dữ liệu vector nào. Không phải là cơ sở dữ liệu vector không hữu ích, mà là ban đầu bạn nên thử thứ đơn giản nhất mang lại hiệu quả lớn nhất, rồi từ đó tăng dần độ phức tạp.
V. Phép Thử BM25 — Vì Sao Truy Hồi "Cũ Kỹ" Vẫn Thắng
CHIP: Về truy hồi, có người từng nói với tôi một điều hơi "gắt" nhưng rất thú vị — anh ấy nói, "tôi sẽ không coi trọng bất kỳ hệ thống truy hồi nào nếu họ không benchmark với BM25." BM25 là một phương pháp truy hồi khá cũ, hơn hai mươi năm rồi — truy hồi dựa trên từ khóa (term-based), không phải dựa trên embedding — và nó thực sự, thực sự rất khó để đánh bại. Rất nhiều lúc, khi bạn muốn phức tạp hơn, bạn kết hợp cả truy hồi dựa trên từ khóa lẫn giải pháp cơ sở dữ liệu vector, để có cả khía cạnh ngữ nghĩa từ embedding, lẫn khớp từ khóa chính xác từ phía term-based. Tìm kiếm lai (hybrid search) rất, rất phổ biến.
VI. Fine-Tuning: Phương Án Cuối Cùng, Không Phải Đầu Tiên
GERGELY: Vậy chúng ta đã nói về prompt engineering, thêm ví dụ, RAG — tôi đoán sau khi bạn đã tận dụng hết những thứ đó, việc này thường mất khá lâu, người ta mới bắt đầu cân nhắc fine-tuning.
CHIP: Tôi nghĩ thường có rất nhiều e ngại đối với fine-tuning, vì nó mang lại cả một loạt vấn đề mới bạn phải xử lý. Trước tiên, một khi bạn đã fine-tune một mô hình, bạn phải nghĩ cách host nó — rất nhiều mô hình này rất lớn, với rất nhiều tham số.
GERGELY: Tôi thực sự đã đọc phần này trong sách — bạn đi vào chi tiết các vấn đề về dung lượng bộ nhớ, và bạn cũng nói về các lựa chọn thay thế cần ít bộ nhớ hơn nhưng lại mang theo những đánh đổi riêng. Nên đây là đánh đổi trong đánh đổi trong đánh đổi — bạn giải quyết một vấn đề nhưng lại có thêm cả loạt vấn đề khác, và bạn phải quyết định liệu có đáng bỏ thời gian, công sức, tài nguyên hay không.
CHIP: Chính xác. Ngoài ra, một khi bạn fine-tune một mô hình, bạn "sở hữu" mô hình fine-tune đó, và câu hỏi trở thành làm sao để duy trì nó. Chúng ta đang sống trong một thế giới nơi rất nhiều người rất giỏi liên tục cho ra mô hình mới, năng lực tăng nhanh chóng, nên câu hỏi là: mô hình fine-tune của bạn có thể vượt trội hơn các mô hình mới ra trong bao lâu? Bạn có thể đổ rất nhiều công sức để fine-tune một mô hình, rồi chỉ trong nháy mắt, một công ty nào đó bạn chưa từng nghe tên tung ra thứ gì đó cực nhanh, cực tốt. Nên nó khá là thách thức. Fine-tuning là phương án cuối cùng, không phải tuyến phòng thủ đầu tiên.
GERGELY: Điều tôi nghe được, nếu tôi hiểu đúng, là: hãy đi theo một cách tiếp cận có hệ thống — bắt đầu với prompting, bắt đầu đơn giản, đạt được những phản hồi có ý nghĩa, rồi thêm dữ liệu. Bạn có thể làm điều này với RAG, với chunking, trích xuất từ khóa, chuẩn bị dữ liệu, việc này tạo ra khác biệt lớn hơn nhiều người nghĩ — rồi sau đó bạn mới chuyển sang những thứ nâng cao hơn. Có cả một loạt thứ bạn có thể làm, nhưng theo tôi hiểu, bạn sẽ đến đó dần dần theo thời gian. Ban đầu, những điều cơ bản sẽ khiến bạn bận rộn, và bạn có lẽ sẽ xây được một hệ thống khá tốt chỉ với những điều cơ bản và một chút kỹ thuật — và, quan trọng nhất, là hiểu vấn đề bạn đang cố giải quyết, thay vì xây bất cứ công nghệ hào nhoáng nào đang thịnh hành.
CHIP: Cách tiếp cận có thể hơi khác giữa một nhà phát triển cá nhân và một doanh nghiệp. Một điều tôi nhận thấy, đặc biệt ở giai đoạn đầu của một công nghệ, là việc mở ra những use case mới thường mang lại lợi nhuận cao hơn là cải thiện dần dần những use case đã có. Vậy nên thay vì đổ năng lượng vào việc vắt thêm chút hiệu năng bằng thứ gì đó phức tạp hơn, hãy dùng đúng cái stack bạn đang có và mở ra ứng dụng mới với nó. Đó là lý do vì sao tôi nghĩ nhiều công ty sẽ mất một thời gian mới đến được giai đoạn fine-tuning.
VII. Triển Khai AI Một Cách Thận Trọng — Trường Hợp Chăm Sóc Khách Hàng
GERGELY: Giả sử ở công ty tôi, chúng tôi quyết định xây một giải pháp AI — lấy ví dụ tự động hóa dịch vụ khách hàng. Những cách tiếp cận điển hình tôi nên biết là gì? Bạn cũng có nói về điều này trong sách.
CHIP: Với chăm sóc khách hàng, tôi nghĩ điều đầu tiên nên tìm hiểu là những điểm nghẽn (bottleneck) trong giải pháp hiện tại thực sự là gì. Ví dụ, tôi từng làm việc với một nơi gặp phải nhiều yêu cầu hỗ trợ khách hàng và không biết trả lời hết như thế nào. Giải pháp của họ khá thú vị — họ cố đưa nhiều câu hỏi vào một kênh chung, như một Discord công khai, để những người dùng khác có thể giúp trả lời, và trong tương lai, nếu ai đó có câu hỏi tương tự, bạn chỉ cần chỉ họ đến cuộc thảo luận trước đó. Một giải pháp khác khá phổ biến hồi 2018–2019 là định tuyến yêu cầu đến đúng bộ phận. Điểm nghẽn ở đó nằm ở khâu phân loại (triaging) — bạn nhận một yêu cầu và không biết gửi nó đến bộ phận nào. Một loạt startup đã cố xây hệ thống để dự đoán, đây là câu hỏi về tài chính, hay đây là câu hỏi hỗ trợ kỹ thuật — chỉ riêng việc định tuyến thông minh đã giảm rất nhiều ma sát.
Nếu bạn quyết định thực sự cần GenAI, tôi rất khuyến khích khuôn khổ mà Microsoft giới thiệu, gọi là "bò, đi, chạy" (crawl, walk, run) — đi từ triển khai rủi ro thấp lên rủi ro cao hơn. Nó không cần phải là một "cú nổ" thành công ngay từ ngày đầu — ban đầu bạn có thể để con người tham gia vào vòng lặp (human in the loop). Với mỗi yêu cầu, thay vì để nhân viên hỗ trợ viết phản hồi từ đầu, AI gợi ý một vài lựa chọn, và con người chọn một cái, hoặc dùng nó làm điểm khởi đầu rồi chỉnh sửa nhanh trước khi gửi đi. Khi bạn thấy tỷ lệ chấp nhận (acceptance rate) đang tăng cao — chẳng hạn 90% cho một loại câu hỏi nào đó — bạn sẽ tự tin hơn để mở rộng, có thể ra nhiều người dùng hơn, hoặc có thể triển khai nội bộ trước. Bạn cho nó nhiều quyền tự chủ hơn nhưng giữ phạm vi triển khai nhỏ, và khi bạn đã thực sự hài lòng, bạn mới mở rộng ra nhiều người dùng hơn.
GERGELY: Điều đó hay đấy, vì cái tôi đang mong đợi bạn nói là kiểu, "ồ, bạn cứ xây cái framework AI này, triển khai nó, rồi xem sao" — đây là điều tôi cảm thấy nhiều công ty đang làm. Rất nhiều đội nói kiểu, "ồ, GenAI, lấy một mô hình từ ChatGPT hay Anthropic, đưa nó vào, rồi tung ra." Nhưng tôi thực sự thích cách bạn mô tả không thực sự đặc thù cho GenAI — bạn nhìn vào bài toán kinh doanh, nhìn vào các lựa chọn, bao gồm cả machine learning truyền thống như bộ phân loại, không chỉ GenAI, rồi bạn kiểm tra xem những công cụ này có thực sự giải quyết được vấn đề của bạn trước khi triển khai, thay vì triển khai một cách mù quáng. Tất cả những điều này nghe như không thực sự mới — bạn có thể nói y hệt như vậy hai ba năm trước, trước khi có GenAI, chỉ khác là chúng ta chưa có những công cụ GenAI này để nghịch thôi.
CHIP: Đúng vậy — thực ra, trước buổi trò chuyện này, tôi có xem lại một trong những bài nói cũ của mình, về những thứ không thay đổi, những thứ cảm giác rất giống nhau qua các thời kỳ của kỹ thuật phần mềm. Việc đối mặt với một công nghệ mới là một trong những điều không bao giờ thay đổi. Mỗi lần có công nghệ mới ra mắt, tôi có thể nghe thấy tiếng thở dài tập thể của các kỹ sư kỳ cựu khắp nơi, kiểu, "không phải cái gì cũng là một cây đinh đâu" — người ta cứ cố làm cho công nghệ mới hoạt động với mọi thứ.
Tôi nghĩ một sai lầm rất phổ biến là nhảy thẳng vào GenAI khi bạn không thực sự cần GenAI. Có hai tiêu đề khác nhau ở đây: một là "tôi dùng AI," hai là "tôi giải quyết được vấn đề." Nếu bạn tập trung vào tiêu đề đầu tiên, chắc chắn, bạn dùng AI — nhưng nếu bạn muốn giải quyết vấn đề, bạn cần hiểu vấn đề thực sự là gì, những trở ngại là gì, và loại bỏ những trở ngại đó bằng giải pháp đơn giản nhất, không phải giải pháp hào nhoáng nhất.
GERGELY: Tôi cảm thấy có một nỗi sợ bị bỏ lại (FOMO) khá mạnh ở hầu hết các công ty công nghệ — ai cũng biết đây là một công nghệ mang tính chuyển đổi, nó mang lại rất nhiều năng lực mới đến mức chắc chắn sẽ quan trọng, ai cũng biết công ty mình sẽ dùng nó, nhưng giờ lại có nỗi sợ bị bỏ lại: nếu đội của tôi không xây nó thì sao, nếu ai đó vượt lên trước tôi thì sao? Nên rất nhiều đội đang xây nó, dùng một cây búa đi tìm đinh, dù có thể họ chưa cần đến nó lúc này. Tôi không chắc điều này nhất thiết là xấu, vì ít nhất người ta có được kinh nghiệm với nó — nhưng đây là một thời điểm rất thú vị, vì thường khi có một framework backend mới ra mắt, hay thứ gì đó giới hạn trong một lĩnh vực, chỉ một số người nhảy vào, nhưng đây là lần đầu tiên tôi thấy cả ngành cùng nhảy vào một lúc, ai cũng cố dùng nó, dù có hiệu quả hay không.
VIII. Tập Trung Vào Vấn Đề, Không Phải Tin Tức
CHIP: Tôi hoàn toàn đồng ý với bạn về FOMO này. Tôi nghĩ việc ai cũng nhảy vào thực ra là một điều khá tốt — năng lượng thật đáng kinh ngạc, tôi chưa từng thấy nhiều người thông minh cùng tập trung vào một vấn đề như vậy, và tiến bộ thật đáng kinh ngạc. Nhưng tôi nghĩ có một sự trớ trêu ở đây — càng cố không bỏ lỡ điều gì, chúng ta lại càng bỏ lỡ nhiều thứ hơn, vì nếu ta cố theo kịp tin tức, nhảy từ tin này sang tin khác, ta sẽ luôn chỉ ở tầng bề mặt, không bao giờ thực sự đi sâu vào bất cứ điều gì. Tôi thực ra không đọc tin tức nhiều — tôi thấy nó khá gây xao nhãng. Cách tiếp cận của tôi là: chọn một vấn đề bạn quan tâm, và chỉ để ý những gì giúp bạn giải quyết vấn đề đó. Nếu có tin gì mới, tôi hỏi, điều này có giúp tôi giải quyết vấn đề này không? Nếu không, nó có thể chờ — vì nếu điều gì đó thực sự quan trọng, nó vẫn sẽ quan trọng sau hai tuần nữa, một tháng nữa. Tôi không bỏ hết mọi việc để chạy đi tìm hiểu ngay lập tức. Tôi cố giữ bình tĩnh hơn với chuyện đó.
IX. Vì Sao Đánh Giá AI Càng Lúc Càng Khó Khi Mô Hình Càng Thông Minh
GERGELY: Khi xây một hệ thống AI, một trong những điều bạn sẽ gặp phải là bạn cần đánh giá đầu ra — nó hoạt động tốt đến mức nào, nó có giải quyết được vấn đề của bạn không. Vì sao việc đánh giá hệ thống AI lại khó, và những cách phổ biến để làm điều đó là gì?
CHIP: Đánh giá, tôi nghĩ, là một câu hỏi trị giá hàng tỷ đô — thậm chí hàng nghìn tỷ đô, xét theo mức đầu tư hiện nay. Bạn cần phải "chơi lớn," mà đã chơi lớn thì phải chơi thật lớn. Tôi nghĩ nó khó vì AI càng thông minh, con người càng khó đánh giá nó hơn. Trước đây, nếu AI trả lời thiếu mạch lạc, bạn có thể dễ dàng nhận ra phản hồi đó tệ — nghe nó cứ sai sai. Nhưng ngày nay nó khá mạch lạc — nếu bạn nhờ ChatGPT tóm tắt một cuốn sách, và bản tóm tắt nghe có vẻ thuyết phục, bạn thực ra không biết nó có phải là một bản tóm tắt tốt hay không — bạn có thể phải tự đọc cả cuốn sách mới đánh giá được. Với toán cũng vậy. Cá nhân tôi dùng AI để hỏi rất nhiều câu tôi không biết đáp án — và vì tôi không biết đáp án, tôi cũng không biết câu trả lời nó đưa ra có đúng hay không. Rất nhiều người có thể nói một lời giải toán lớp một có đúng hay không, nhưng rất ít người có thể nói một chứng minh cho một phương trình phức tạp là đúng hay sai. Tôi nhớ khi o1 ra mắt, Terence Tao — một trong những nhà toán học giỏi nhất thời đại chúng ta — đã dành thời gian đánh giá nó, và ông nói trải nghiệm dùng o1 giống như hướng dẫn một nghiên cứu sinh tầm tầm, không đến mức hoàn toàn kém cỏi. Điều đó khiến tôi nghĩ — nếu chúng ta thực sự cần những bộ óc xuất sắc nhất hiện nay để đánh giá AI, thì chẳng bao lâu nữa chúng ta sẽ hết người thực sự giỏi để đánh giá nó.
Vậy bước tiếp theo sẽ là gì? Trong một thời gian dài, chúng ta dùng con người làm chuẩn vàng (gold standard) cho hiệu năng AI — con người viết ra cách nên phản hồi, và AI cố sao chép con người. Nhưng giờ đây, với rất nhiều tác vụ, AI thực hiện tốt hơn con người rất nhiều. Tôi đã nghĩ về vài cách tiếp cận để xử lý điều này, và đó thực ra là lý do tôi tách nó ra thành hai chương trong sách — ban đầu tôi chỉ định viết một chương về đánh giá, nhưng càng viết tôi càng nhận ra có quá nhiều thứ, nên nó trở thành hai chương khá dài: chương đầu về phương pháp luận chung, chương sau về các kỹ thuật cụ thể để đánh giá một hệ thống AI.
X. Độ Chính Xác Chức Năng, LLM-as-Judge, và Đánh Giá So Sánh
CHIP: Một phương pháp luận là độ chính xác chức năng (functional correctness) — bạn đánh giá đầu ra của một ứng dụng dựa trên việc nó thực hiện tác vụ tốt đến đâu. Nếu bạn nói, "dùng AI để tiết kiệm năng lượng," bạn có thể thấy nó thực sự tiết kiệm được bao nhiêu năng lượng. Nếu bạn nói, "dùng AI để chơi trò chơi này," bạn có thể thấy điểm số. Một use case rất phổ biến cho việc này là viết code — tôi không nghĩ việc coding là một trong những use case phổ biến nhất là ngẫu nhiên, vì chúng ta thực sự biết cách đánh giá code được sinh ra. Chúng ta có thể chưa biết cách đánh giá một bài luận được sinh ra, nhưng chúng ta biết cách đánh giá code, vì chúng ta đã kiểm thử code từ lâu rồi. Với code, bạn có thể dùng độ chính xác chức năng — trước tiên, nó có biên dịch được không, có chạy được không; thứ hai, nó có cho ra kết quả như mong đợi không.
Cách tiếp cận thứ hai là dùng AI để đánh giá AI khác. Chúng ta đã dùng AI để tự động hóa rất nhiều ứng dụng, vậy liệu ta có thể dùng nó để tự động hóa cả việc đánh giá? Nó thực ra làm khá tốt. Ngay từ năm 2023, báo cáo "State of AI" của LangChain đã ghi nhận rằng phần lớn ứng dụng họ khảo sát đã có một dạng LLM-as-judge nào đó, và tôi nghĩ điều đó chỉ ngày càng tăng lên. Nó đang trở nên khá hiệu quả về chi phí và hữu ích, dù tất nhiên vẫn có nhiều thách thức xung quanh nó.
Một cách tiếp cận khác tôi thấy rất thú vị là đánh giá so sánh (comparative evaluation). Là con người, chúng ta khó cho một điểm số tuyệt đối cho một thứ gì đó, nhưng nếu bạn đưa cho chúng ta hai phiên bản của cùng một thứ, chúng ta thường có thể nói cái nào tốt hơn. Chúng tôi từng thấy các nghiên cứu cho thấy rằng ngay cả với những tác vụ mà AI đang thực hiện ở mức mà chuyên gia con người không thể đạt tới, con người vẫn có thể phát hiện ra sự khác biệt giữa hai đầu ra. Điều này đã và đang định hướng không chỉ việc đánh giá, mà cả việc phát triển mô hình.
GERGELY: Nghe như không có câu trả lời đơn giản nào cả — bạn phải đi qua tất cả những lựa chọn này và tìm ra, với trường hợp của bạn, điều gì hợp lý về chi phí, về những gì bạn có thể làm, liệu bạn có thể để con người tham gia vào vòng lặp hay không. Không có viên đạn bạc nào cả.
CHIP: Tôi không nghĩ có một giải pháp đơn giản. Đó là lý do tôi hơi hoài nghi về các công cụ đánh giá — rất nhiều thách thức trong việc đánh giá không phải vì ta không biết cách đánh giá, mà vì nó đòi hỏi kỷ luật và công sức, những thứ mà công cụ không thể tự động hóa được.
XI. Đo Lường Điều Người Dùng Thực Sự Muốn
CHIP: Một điều về đánh giá là chúng ta cần đánh giá một ứng dụng dựa trên điều người dùng thực sự muốn — và ta thường không làm vậy. Điều đó có nghĩa là phải đi nói chuyện với người dùng, phải nhìn vào cách họ tương tác, vì rất nhiều thứ ta nghĩ nên đo lường lại không phải là điều thực sự quan trọng. Ta phải đo cái gì thực sự có ý nghĩa. Tôi có vài ví dụ cho thấy điều này có thể phản trực giác đến mức nào — bạn nghĩ mình đang đo một thứ, nhưng người dùng lại thực sự quan tâm đến một thứ khác.
Tôi có một người bạn đang xây một ứng dụng khá lớn, về cơ bản là công cụ tóm tắt cuộc họp. Ban đầu họ cố đo tính đúng đắn — liệu bản tóm tắt có phủ hết nội dung cuộc họp không — và họ băn khoăn về định dạng, liệu người dùng muốn tóm tắt ba câu hay năm câu, vì họ nghĩ người dùng muốn tóm tắt ngắn hơn. Nhưng cuối cùng họ phát hiện ra người dùng không thực sự quan tâm đến toàn bộ nội dung cuộc họp — người ta chỉ muốn biết, đâu là việc tôi cần làm, tôi phải làm gì sau cuộc họp này. Vậy nên điều đó đã thay đổi mọi thứ: tính đúng đắn vẫn quan trọng, họ vẫn không muốn bản tóm tắt bịa đặt thông tin, nhưng trọng tâm thực sự trở thành việc không bỏ sót những việc cần làm dành riêng cho người hỏi.
Một ví dụ khác — một công ty làm phần mềm thuế khá lớn xây một chatbot để giúp người dùng chuẩn bị hồ sơ thuế, và phản ứng rất hờ hững. Họ đo lường mức độ sử dụng, và thấy người ta không thực sự dùng nó nhiều, họ tự hỏi vì sao — liệu có phải nó bịa thông tin, hay có vấn đề gì khác — họ cố đo các chỉ số riêng của mình. Nhưng cuối cùng, họ phát hiện ra người ta đơn giản là không dùng nó vì họ ghét gõ chữ. Và cũng vì, nếu bạn đối mặt với một lĩnh vực bạn không rành, bạn còn không biết phải hỏi gì — người ta dùng phần mềm thuế chính vì họ không biết nhiều về thuế. Nên họ không biết phải gõ gì, họ không hiểu lĩnh vực đó — họ tìm đến sản phẩm này vì họ muốn ai đó lo chuyện thuế giúp mình. Điều đội ngũ đó bắt đầu làm là cố hiểu người dùng thường hỏi những dạng câu hỏi nào, và gợi ý sẵn ngay từ đầu — hướng dẫn người dùng, kiểu "đây là câu hỏi bạn nên hỏi," rồi đưa ra câu trả lời, cứ thế tiếp diễn.
Nên tôi nghĩ rất nhiều trong số này quy về việc hiểu lĩnh vực bài toán của bạn — đi nói chuyện với người dùng, nhìn vào dữ liệu. Tôi vẫn nghĩ việc nhìn vào dữ liệu rất, rất quan trọng. Greg Brockman có một câu nói rất hay về điều này: kiểm tra dữ liệu thủ công là một trong những hoạt động có tỷ lệ giá trị trên uy tín cao nhất. Nghĩa là người ta thường không đánh giá cao việc kiểm tra dữ liệu thủ công — "để cho một thực tập sinh làm," "để tôi nghĩ cái gì đó cầu kỳ hơn, thuật toán gì đó" — nhưng nó thực sự có giá trị cực cao, vì bằng cách nhìn vào dữ liệu, bạn phát hiện ra các khuôn mẫu, hiểu được người dùng thực sự dùng sản phẩm như thế nào. Tôi thường khuyên các đội: đừng quên đánh giá của con người. Bạn dùng LLM-as-judge, nhưng "giám khảo" này có nhiều thách thức thực sự — chất lượng của nó phụ thuộc vào mô hình nền và prompt, khá là không xác định (non-deterministic), nên mọi thứ có thể thay đổi theo thời gian. Nhưng nếu bạn cũng có đánh giá của con người — rất nhất quán, hướng dẫn rất rõ ràng, mỗi ngày xem qua, chẳng hạn, 50 mẫu tương tác thực tế, hoặc nhiều hơn nếu bạn có nguồn lực, 500 hay cả nghìn — bạn sẽ có được một bức tranh thực về cách người dùng đang dùng sản phẩm của bạn, những thay đổi hành vi gắn với các sự kiện hiện tại, hoặc bạn có thể đối chiếu nó với các chỉ số tự động. Nếu điểm số của "giám khảo AI" bắt đầu lệch khỏi điểm số của giám khảo con người, đó là điều bạn cần điều tra.
XII. Những Sai Lầm Thường Gặp Khi Làm GenAI
GERGELY: Vậy, như bạn nói, bạn không thể bỏ qua công sức nếu muốn có kết quả tốt, và không thể loại bỏ hoàn toàn con người khỏi vòng lặp, ít nhất là ban đầu. Những sai lầm phổ biến bạn từng thấy khi các đội xây dựng ứng dụng AI là gì?
CHIP: Tôi không muốn nói theo kiểu như ai cũng ngốc cả — nhưng chúng ta đã chạm đến vài điều rồi. Một sai lầm rất phổ biến là dùng GenAI khi bạn không cần GenAI. Từng có một startup đến gặp tôi với ý tưởng dùng GenAI để giúp người dùng tối ưu hóa việc dùng điện — bạn kể cho chatbot nghe về những hoạt động tốn điện trong ngày, sạc xe, giặt đồ, và nó sẽ nói thời điểm tốt nhất để làm từng việc nhằm giảm hóa đơn tiền điện. Họ nói nghiên cứu của họ cho thấy bạn có thể tiết kiệm trung bình 30% — "tiền chùa mà, ai lại không muốn cái đó." Tôi hỏi họ mức tiết kiệm đó so với việc chỉ đơn giản tự lên lịch làm hoạt động tốn điện nhất vào giờ thấp điểm — kiểu, chỉ cần sạc xe lúc 10 giờ tối thôi. Họ nói, "chúng tôi chưa so sánh cái đó, nhưng sẽ thử và báo lại bạn" — và họ không bao giờ quay lại, sau này họ bỏ luôn ý tưởng đó. Rất nhiều bài toán tối ưu kiểu này có thể giải bằng thuật toán tham lam (greedy), không cần GenAI gì cả.
Ở đầu bên kia của phổ, tôi thấy nhiều công ty từ bỏ GenAI vì họ đã thử và không thành công — trong khi tôi thường bất ngờ khi thấy một công ty khác với use case rất tương tự lại thành công rực rỡ. Khi đào sâu vào, thường là do sản phẩm tệ — họ prompt không tốt, không hiểu người dùng, hoặc thậm chí không biết cách đánh giá đúng. Ví dụ, tôi từng làm việc với một công ty chuyên trích xuất thông tin từ hồ sơ (résumé) — ai đó nộp một hồ sơ (là file PDF, không phải văn bản thô), hệ thống trích xuất văn bản thô, rồi từ văn bản đó trích xuất ra các tổ chức người này từng làm việc. Tôi hỏi họ vận hành ra sao, họ nói tệ lắm — sai tổ chức khoảng 50% thời gian. Tôi hỏi công đoạn nào trong quy trình bị lỗi: bước chuyển từ PDF sang văn bản, hay bước từ văn bản sang tên tổ chức? Họ nói, "chúng tôi không biết, chúng tôi chưa kiểm tra cái đó." Nếu bạn không thể xác định được lỗi nằm ở đâu, bạn không thể sửa nó. Nghe như lẽ thường, nhưng chuyện này cứ lặp đi lặp lại mãi.
Một sai lầm khác là làm phức tạp hóa mọi thứ — nhảy thẳng vào những cơ sở dữ liệu vector hào nhoáng hơn, hay fine-tuning. Một sai lầm phổ biến khác dạo này là: bạn thấy một framework agent hào nhoáng và nghĩ, "dùng cái này đi, thử xem sao." Framework thì thực sự rất hay, tôi thực lòng biết ơn rất nhiều framework — chúng làm cuộc sống dễ dàng hơn — nhưng tôi nghĩ một framework nên mã hóa các thực hành tốt nhất (best practices) và được kiểm thử kỹ càng. Còn tôi nghĩ chúng ta vẫn đang ở giai đoạn tìm hiểu xem đâu là best practices, và rất nhiều framework có thể mang lại những lỗi khó chịu không cần thiết. Khi tôi lục qua codebase của nhiều framework phổ biến, tôi nhận thấy một điều khá thú vị — rất nhiều framework đi kèm những prompt mặc định để giúp bạn bắt đầu nhanh. Nhưng mỗi prompt mặc định đó đều có lỗi chính tả, và chúng cứ liên tục thay đổi — ai đó gửi một PR nhỏ để sửa lỗi chính tả nhưng nó chưa bao giờ vào bản phát hành chính thức. Nên nếu bạn dùng một trong những prompt mặc định đó, và hiệu năng ứng dụng của bạn đột nhiên thay đổi, bạn sẽ không biết vì sao, vì prompt đã thay đổi ngay dưới chân bạn.
GERGELY: Thú vị đấy, vì điều bạn đang mô tả — dùng công nghệ này khi không cần, từ bỏ nó vì những lý do mà một chút lẽ thường lẽ ra đã giải quyết được, dùng một framework mới không thực sự chất lượng hay không thực sự mã hóa best practices — tất cả những điều này nghe như bạn có thể thay từ "GenAI" bằng bất kỳ công nghệ hay stack mới nào và vẫn nghe những câu chuyện tương tự. Nó không thực sự mới, phải không — bất kỳ ai tự nhận là chuyên gia cũng chỉ mới có nhiều nhất một hai năm kinh nghiệm với nó, nó vẫn đang thay đổi liên tục, và chưa có thực hành tốt nhất nào được thiết lập chắc chắn.
XIII. Tư Duy Hệ Thống Không Bao Giờ Lỗi Thời
CHIP: Tôi hoàn toàn đồng ý. Dù công nghệ có thay đổi theo thời gian, tư duy có hệ thống — cách tiếp cận có hệ thống với vấn đề — thường thì không thay đổi. Nếu bạn muốn giải quyết một vấn đề, bạn bắt đầu bằng cách chia nhỏ vấn đề ra, xem thách thức thực sự nằm ở đâu, và đi qua các giải pháp khác nhau. Nghe có vẻ hiển nhiên, nhưng tôi nghĩ nhiều lúc FOMO xen vào — bạn biết đó là điều đúng cần làm, nhưng bạn cảm thấy cần kiểm tra thứ khác trước đã, và bạn cứ làm vậy ba lần một ngày, thế là hết ngày mà bạn chưa bao giờ thực sự có thời gian ngồi xuống suy nghĩ thật sâu về điều mình đang cố làm.
GERGELY: Vậy tôi đoán chúng ta sẽ thấy rất nhiều sai lầm tương tự những gì xảy ra với bất kỳ công nghệ mới nào, và nếu một số thính giả từng áp dụng công nghệ mới trước đây, họ có thể tái sử dụng những cách tiếp cận đó, chỉ cần "địa phương hóa" nó cho GenAI, và tránh được một số sai lầm này.
XIV. Học AI Engineering Như Thế Nào
GERGELY: Nói về việc học công nghệ mới — với tư cách một kỹ sư phần mềm muốn bước vào AI engineering, bạn khuyên nên học như thế nào? Mọi thứ thay đổi rất nhanh — bạn có nhắc đến tầm quan trọng của nền tảng cơ bản — vậy nên tập trung vào điều gì?
CHIP: Tôi có rất nhiều suy nghĩ về việc học, vì tôi thích học rất nhiều, và theo thời gian tôi cố quan sát ra một số khuôn mẫu — dù cách tôi học có thể không giống cách bạn học, mỗi người có phong cách học khác nhau. Nhìn chung, tôi nghĩ việc học có hai cách tiếp cận: học qua dự án (project-based) và học có cấu trúc (structured). Học qua dự án là: bạn chọn một dự án, làm việc trên đó, cố giải quyết mọi vấn đề trong dự án đó, và hoàn thành nó. Học có cấu trúc giống như khi bạn học một khóa học hay đọc một cuốn sách — ai đó đã sắp xếp sẵn những gì bạn cần học và theo thứ tự nào.
Có khá nhiều tranh luận về chuyện này. Có người gần đây kể tôi nghe rằng một người bạn tốt của họ nghĩ vấn đề ngày nay của những ai muốn trở thành kỹ sư là họ dành quá nhiều thời gian học và không đủ thời gian làm — quên hết khóa học đi, quên hết sách đi, chỉ cần chọn một dự án và bắt tay vào làm. Tôi thực sự nghĩ học qua dự án rất có giá trị. Nhưng nếu bạn nghĩ theo hướng, đây là một tập hợp kỹ năng và kiến thức tôi muốn xây dựng, thì học qua dự án có thể chạm được nhiều điểm trong đó, nhưng không phải lúc nào cũng chạm hết, và đôi khi nó có thể khiến bạn bối rối.
Một điều khác về học qua dự án là rất nhiều người thường đi theo các tutorial — ai đó đã hướng dẫn sẵn cách làm việc này. Tutorial rất hay, bản thân tôi cũng làm rất nhiều, nhưng tôi để ý rằng rất dễ để cứ vô thức bấm từ cell này sang cell khác, chạy hết cell này đến cell khác mà không bao giờ dừng lại để hỏi tại sao lại làm theo cách này, tại sao thư viện này lại quan trọng, tại sao đoạn code này lại được viết như vậy, tại sao batch size là 16 chứ không phải 64. Không có cơ chế nào ép bạn phải dừng lại — bạn chỉ muốn chạy đến cuối để xem kết quả, rồi thay đổi theo phỏng đoán tốt nhất của mình.
Có một chuyện khá buồn cười xảy ra khi tôi đang nghiên cứu thị trường cho một dự án mã nguồn mở tôi từng làm, tên là Ibis — tôi biết nếu ai muốn dùng nó, họ phải viết "import ibis." Nên tôi lục trên GitHub tìm những repo có dòng "import ibis," và tôi tìm thấy rất nhiều repo có dòng import đó nhưng Ibis lại không hề được dùng ở bất cứ đâu khác trong codebase. Tôi nhận ra rất nhiều repo đó đã sao chép từ một tutorial có dòng "import ibis" — có lẽ nhà phát triển gốc từng có dòng import đó, xóa mất phần code dùng nó, nhưng quên xóa luôn dòng import, rồi mọi người sau đó cứ thế sao chép lại y hệt. Đó là điều hơi nguy hiểm về việc học qua tutorial — nó rất hay, nhưng điều quan trọng là phải biết dừng lại và đặt câu hỏi, và đôi khi học có cấu trúc giúp bạn biết nên hỏi câu hỏi gì.
Vậy nên trước khi bắt đầu, tôi khuyên nên kết hợp cả hai: chọn một dự án — không cần lớn hay hào nhoáng, chỉ cần chọn một cái — và song song với đó, bổ sung bằng học có cấu trúc: một cuốn sách, một khóa học cùng bạn bè, đọc bài báo khoa học. Tôi nghĩ đọc bài báo hơi thú vị, vì nó là một kỹ năng riêng, có thể khá tốn thời gian, và bạn cần biết mình muốn lấy được gì từ đó. Nhưng, hãy bắt đầu một dự án, và bổ sung nó bằng cấu trúc.
Cũng có một bài tập tôi thấy rất hữu ích, ít nhất với tôi, khi mới bắt đầu: trong một tuần, hãy quan sát mọi việc bạn làm, ghi chú lại, và nghĩ xem bao nhiêu phần trăm trong đó có thể được AI tự động hóa. Rồi thử dùng AI để làm những việc đó. Nó cho tôi rất nhiều ý tưởng về use case — bạn chỉ cần nghĩ về điều gì quan trọng với bạn, và nếu có một ứng dụng giải quyết được dù chỉ một vấn đề cho bạn, thế đã là tuyệt vời rồi.
GERGELY: Tôi nghĩ đó là một cách nhìn hơi khác thường, nhưng là một cách hay, vì nó cũng có thể giúp bạn vượt qua nỗi sợ "AI sẽ làm gì với công việc của tôi," vì bạn thực sự thấy điều gì xảy ra khi bạn tự động hóa mọi thứ. Điều đó dẫn tôi đến câu hỏi tiếp theo — có rất nhiều nỗi sợ hãi thái quá về việc AI sẽ là dấu chấm hết cho kỹ thuật phần mềm, vì AI rất giỏi viết code, giỏi hơn hẳn nhiều lĩnh vực khác. Quan điểm của bạn là gì — khi AI ngày càng giỏi hơn, liệu nó có thực sự chấm dứt kỹ thuật phần mềm, thay đổi nó, hay không thay đổi nhiều lắm?
XV. Vì Sao AI Không Phải Là Dấu Chấm Hết Cho Kỹ Thuật Phần Mềm
CHIP: Tôi nghĩ điều này quay lại câu hỏi kỹ thuật phần mềm thực sự là gì. Một phép loại suy có thể giúp giải thích — việc viết lách. Chúng ta có xu hướng nhầm lẫn giữa hoạt động dễ nhận thấy nhất của một thứ gì đó với chính bản chất của nó. Với viết lách, ngày xưa, viết có nghĩa là hành động vật lý đặt chữ lên giấy — và hồi đó, người ta thực sự tự hào về thư pháp, kiểu "ồ, chữ đẹp thế, chắc là thông minh lắm." Nhưng rồi ta có máy tính, và bây giờ viết không còn ám chỉ hành động vật lý đó nữa — viết ám chỉ quá trình sắp xếp ý tưởng thành một dạng đọc được. Tôi nghĩ điều tương tự cũng đúng với lập trình. Người ta hay nghĩ kỹ thuật phần mềm là hành động vật lý gõ code vào một trình soạn thảo nào đó, nhưng đó không phải là bản chất của kỹ thuật phần mềm. Kỹ thuật phần mềm là về giải quyết vấn đề — đây là vấn đề, làm sao tôi tạo ra một chương trình có thể chạy để giải quyết nó. Viết code chỉ là hành động vật lý của nó. Nên đúng, AI có thể tự động hóa việc viết code, nhưng tôi không nghĩ nó sẽ hoàn toàn tự động hóa việc giải quyết vấn đề, vì bạn vẫn cần biết vấn đề là gì, và chỉ có bạn mới thực sự hiểu vấn đề mình đang đối mặt.
Kỹ thuật phần mềm cũng là việc làm mọi thứ một cách rất chính xác. Lý do nghề kỹ sư phần mềm tồn tại là vì rất khó để chính xác, để nói được "ngôn ngữ" của máy tính — bạn di chuyển một câu lệnh if đi chỗ khác, hay đổi một biến, thế là chương trình sập ngay vì tràn ngăn xếp (stack overflow), điều mà tất nhiên bạn hiểu nếu bạn là kỹ sư phần mềm. Nhưng nếu bạn chỉ là một người dùng kinh doanh nói, "tôi muốn cái nút di chuyển sang khi thay đổi kích thước cửa sổ," điều đó dễ nói, nhưng với tư cách kỹ sư, bạn biết các trường hợp biên, biết môi trường, biết những sự kiện hệ thống cần lo, và bạn viết code cho tất cả những điều đó. Tôi chắc chắn chúng ta sẽ đến lúc AI có thể tạo ra rất nhiều phần trong số đó, nhưng nó có thể không tạo được hết, và ở một thời điểm nào đó, bạn vẫn cần một ai đó hiểu code và có thể tìm ra khoảng trống ở đâu — vì tiếng Anh không phải là một ngôn ngữ chính xác như một ngôn ngữ lập trình. Ngôn ngữ lập trình được sinh ra để chính xác và không mơ hồ — bạn có thể đi từ hợp ngữ (assembly) lên một ngôn ngữ lập trình cấp cao vì gần như có một ánh xạ một-một, nhưng đi từ tiếng Anh sang một ngôn ngữ lập trình lại rất mơ hồ.
Tôi nghĩ nghề này sẽ không biến mất. Với người dùng bình thường, nó có thể ổn cho những use case theo kiểu nghiệp dư — bạn nói một điều gì đó, bạn nhận được thứ gì đó gần đúng, bạn thử vài lần và hài lòng. Nhưng với một use case kinh doanh hay chuyên nghiệp, bạn sẽ cần những người có thể đảm bảo bạn có được chính xác thứ bạn muốn.
Thực ra tôi rất hào hứng với việc AI tự động hóa một phần việc viết code, vì nó giải phóng kỹ sư phần mềm để xây những phần mềm phức tạp hơn nhiều. Quay lại phép loại suy về viết lách — khi viết còn có nghĩa là sao chép chữ bằng tay lên giấy, một cuốn sách 5.000 hay 10.000 chữ đã được coi là lớn, vì việc chép tay tốn quá nhiều thời gian. Nhưng giờ chúng ta có những cuốn sách hàng trăm nghìn chữ, và tôi nghĩ điều đó khiến mọi thứ dễ dàng hơn nhiều. Với kỹ thuật phần mềm cũng vậy — nếu bạn không phải tự tay viết từng dòng code, bạn có thể biến ý tưởng thành chương trình chạy được nhanh hơn nhiều, và điều đó cho phép ta viết những phần mềm phức tạp hơn nhiều. Có thể một kỹ sư phần mềm sẽ có khả năng chỉ huy, gỡ lỗi, hay bảo trì một hệ thống phức tạp hơn nhiều, một mình — bởi vì hiện tại, một codebase triệu dòng thường cần nhiều kỹ sư, hiếm khi chỉ một người sở hữu nó, đó còn chưa tính đến các dependency. Đó sẽ là một sự chuyển dịch thú vị.
XVI. Giáo Dục, Giải Trí, và Doanh Nghiệp
GERGELY: Còn những use case nào khác bạn hào hứng, ngoài viết code?
CHIP: Tôi hào hứng với giáo dục. Tôi nghĩ AI có thể giúp con người học nhanh hơn nhiều. Một điều tôi nhận ra là ngày nay, nếu bạn đã biết câu hỏi, việc tìm câu trả lời khá dễ dàng — bạn hỏi AI và thường sẽ có một câu trả lời tốt, hoặc ít nhất là rất nhiều tài liệu tham khảo để đào sâu thêm. Nhưng cái vẫn còn khó là việc nghĩ ra đúng câu hỏi ngay từ đầu. Nên tôi nghĩ giáo dục cần tập trung vào việc xây thói quen đặt câu hỏi và thực sự hiểu vấn đề, và tôi nghĩ AI có thể khiến việc học trở nên hiệu quả hơn nhiều — người ta có thể học được nhiều hơn, nhanh hơn. Và nếu chúng ta học tốt hơn, nhanh hơn, chúng ta thực sự có thể làm được nhiều thứ hơn.
Một use case khác tôi hào hứng là giải trí. Chúng ta có xu hướng nghĩ giải trí và giáo dục là hai thứ tách biệt, nhưng tôi không thấy lý do gì ta không thể có những trò chơi giúp ta học — ví dụ trò chơi chiến thuật dạy về đàm phán, có thể sẽ rất vui. Hay nói chung, những nội dung kích thích trí tuệ hơn — phim ảnh hay chương trình không nhất thiết phải chỉ để giải trí thuần túy; tôi thích nội dung khiến mình phải suy nghĩ một chút, giúp mình hiểu thêm về những lĩnh vực khác nhau. AI có thể giúp tạo ra nội dung vừa giải trí vừa kích thích trí tuệ. Một ví dụ đơn giản, chúng ta đã có rất nhiều dạng chuyển thể giữa các loại hình — một cuốn sách trở thành phim, một bộ phim trở thành trò chơi, một bài báo khoa học trở thành podcast — và nếu AI có thể giúp chuyển thể nội dung qua lại giữa các loại hình như vậy, điều đó có thể rất thú vị.
Có rất nhiều bài toán nhỏ tôi cũng quan tâm. Tôi chưa nói nhiều về mảng doanh nghiệp, nhưng tôi thấy đó vẫn là nơi phần lớn tiền bạc nằm ở đó. Tôi nghĩ cấu trúc tổ chức của doanh nghiệp sẽ thay đổi. Hãy nghĩ xem công việc của quản lý cấp trung thực sự là gì — tổng hợp thông tin từ cấp dưới và truyền lên cho lãnh đạo, và ngược lại, truyền chỉ đạo từ lãnh đạo xuống các tầng thấp hơn. Nhưng việc tổng hợp thông tin là điều AI có thể làm rất tốt. Tôi nghĩ các công ty có thể trở nên hiệu quả hơn nhiều nhờ điều đó.
XVII. Vòng Hỏi Nhanh
GERGELY: Hãy kết thúc bằng vài câu hỏi nhanh — tôi sẽ đưa ra câu hỏi và bạn nói điều đầu tiên nảy ra trong đầu. Ngôn ngữ lập trình nào bạn dùng nhiều nhất khi xây ứng dụng AI, hay làm ML engineering, và vì sao?
CHIP: Python và JavaScript.
GERGELY: Cả JavaScript nữa? Sao vậy?
CHIP: Ồ, chắc chắn rồi — một phần lớn của việc xây sản phẩm là phải làm demo thật nhanh, và JavaScript rất tiện cho việc đó. Tôi không giỏi lắm — tôi luôn hơi sợ JavaScript — nhưng tôi thực sự biết ơn vì AI đã giúp tôi bắt đầu với nó dễ dàng hơn nhiều dạo này.
GERGELY: Mô hình LLM nào bạn thích nhất hiện giờ, và vì sao?
CHIP: Tôi không thực sự có mô hình yêu thích — tôi dùng những mô hình khác nhau cho những việc khác nhau. Tôi từng dùng ChatGPT theo thói quen, vì tôi đã có sẵn một loạt prompt được thiết lập từ trước. Tôi dùng Claude đôi khi cho việc viết sáng tạo, vì tôi thấy nó ít sáo rỗng hơn. Tôi đang đọc về R1 — ai mà không đọc về R1 dạo này chứ — chỉ để thử xem sao. Tôi cũng từng dùng vài mô hình Llama, như phiên bản thị giác, cho những use case thú vị kiểu như chuyển ảnh chụp màn hình thành code, chỉ để thử nghiệm, nghịch cho vui thôi. Nhưng tôi không thực sự "gắn bó cảm xúc" với bất kỳ cái nào cả.
GERGELY: Và một công cụ AI hay ho nào bạn từng dùng và thích?
CHIP: Tôi tự xây một công cụ giúp ích rất nhiều cho việc nghiên cứu. Khi tôi bắt gặp một liên kết đến một bài báo khoa học, tôi thường đi qua cùng một quy trình — đọc phần tóm tắt, tra cứu tác giả, tìm hiểu một chút, đặt câu hỏi, kiểm tra các trích dẫn — nên tôi xây một công cụ nhỏ tự động làm hết những việc đó và đưa cho tôi mọi thông tin cần thiết.
GERGELY: Một công cụ để "gãi đúng chỗ ngứa" của chính mình.
CHIP: Đúng vậy — tôi nghĩ đó chính là vẻ đẹp của AI bây giờ, bạn có thể xây một thứ như vậy trong một khoảng thời gian rất ngắn. Trước đây việc này sẽ mất cả tuần, nhưng giờ tôi chỉ cần xây một cái là xong. Đó là điều đáng để hào hứng.
GERGELY: Tôi đồng ý. Và một hoặc hai cuốn sách bạn đã đọc và muốn giới thiệu?
CHIP: Tôi giới thiệu rất nhiều sách, nhưng tôi cảm thấy việc giới thiệu sách đôi khi giống như ép người khác thích cái mình thích. Tôi thích những cuốn sách cho tôi một góc nhìn mới, hay một hiểu biết về những chủ đề tôi không biết nhiều. Tôi thực sự thích cuốn Complex Adaptive Systems — một cuốn sách rất thú vị về tư duy hệ thống, về cách thiết kế các động lực xã hội sao cho con người hướng đến những mục tiêu bạn muốn. Nó buộc bạn phải suy nghĩ về hệ thống. Tôi thích cuốn The Selfish Gene, vì nó khiến bạn suy nghĩ nhiều hơn về ý chí tự do — ý tưởng rằng bạn có thể "sống tiếp" qua gen, hoặc qua ý tưởng: gen sống tiếp qua con cái, qua sinh sản, nhưng mặt khác, ý tưởng cũng có thể tự nhân bản, giống như meme. Và tôi thích cuốn Antifragile — tôi nghĩ tác giả là một nhân vật rất thú vị, và tôi thực sự thích những cuốn sách của ông.
GERGELY: Cảm ơn vì những gợi ý đó, và cảm ơn bạn đã tham gia podcast. AI engineering là một lĩnh vực rất mới, và thật tuyệt khi được nghe từ một người đã đi rất rộng và cũng rất sâu, người đã ở trong lĩnh vực này từ trước khi nó được gọi là AI engineering. Cảm ơn bạn rất nhiều.
CHIP: Cảm ơn bạn rất nhiều vì đã để tôi được "tràng giang đại hải" trên show. Tôi thực sự trân trọng điều đó. Một điều tôi thực sự thích ở việc viết hay nói chuyện công khai là tôi nhận được phản hồi — đôi khi ai đó nói, "tôi không thực sự bị thuyết phục," đôi khi là "tôi đồng ý với bạn," điều đó thật tuyệt khi nghe nhưng không phải lúc nào cũng tốt cho cái tôi. Nhưng tôi thực sự thích những phản hồi trái chiều — "bạn chưa nghĩ đến điều này," "bạn quên mất điều kia" — nên nếu có điều gì bạn cảm thấy tôi đã bỏ sót, hãy cho tôi biết, tôi sẽ rất trân trọng điều đó.
Nguồn transcript: podcast "The Pragmatic Engineer", do Gergely Orosz dẫn dắt, phát hành ngày 5 tháng 2, 2025. Bản dịch tiếng Việt được biên tập, sắp xếp lại để dễ đọc từ bản ghi tiếng Anh gốc.


No comments:
Post a Comment