Tại sao hầu hết AI Agent thất bại khi đưa vào vận hành: Xây dựng theo tư duy ngược
Mô hình tốt không thể cứu vãn một kiến trúc tồi, và nhiều đội ngũ đã học được bài học này một cách đắt giá. Hầu hết các AI Agent thất bại không phải do thiếu khả năng, mà do kiến trúc hệ thống được xây dựng theo tư duy "ngược" từ mục tiêu xuống công cụ thay vì thiết kế các thành phần cốt lõi trước.

Lần đầu tiên tôi chứng kiến một hệ thống đa tác nhân (multi-agent system) thất bại nghiêm trọng trong môi trường sản xuất, nó không hề kịch tính. Không có lỗi hệ thống (crash), không có thông báo lỗi. Hệ thống chỉ tiếp tục chạy và tạo ra các kết quả trông có vẻ hợp lý cho đến khi ai đó đọc kỹ và nhận ra có gì đó không ổn.
Khi chúng tôi quyết định điều tra, đã mất đến hai ngày để gỡ lỗi (debug) và tìm ra nguyên nhân. Điều thú vị là, mô hình không bị ảo giác (hallucinating), và các công cụ nhập-xuất cũng trả về kết quả đúng.
Vấn đề, khi chúng tôi cuối cùng cũng tìm ra, nằm ở kiến trúc. Mô hình và các công cụ được thiết lập đúng, nhưng ý tưởng là khả năng suy luận sẽ kết nối mọi thứ lại với nhau. Và như bạn có thể đoán, nó đã thất bại.
Hóa ra là khả năng suy luận không thể đảm nhận vai trò đó.
Trải nghiệm đó luôn quay trở lại trong tâm trí tôi mỗi khi tôi nghĩ về lý do tại sao rất nhiều AI Agent hoạt động tốt trong bản demo nhưng không tồn tại được trong thực tế.
Đó không phải là vấn đề về khả năng.
Đó là vấn đề về kiến trúc.
Và nếu bạn đã đọc bài viết trước của tôi trên TDS, Tại sao các kỹ sư AI đang chuyển dịch từ LangChain sang các kiến trúc Agent nguyên bản, mô hình này sẽ nghe quen thuộc: các hệ thống được xây dựng từ trên xuống (top-down), từ mục tiêu đến công cụ rồi đến mô hình, với giả thuyết ngầm rằng hành vi thông minh sẽ lấp đầy các khoảng trống.
Giả thuyết đó chính là ý nghĩa của cụm từ "xây dựng ngược". Và nó phổ biến hơn nhiều so với hầu hết các đội ngũ nhận thức cho đến khi mọi thứ bị hỏng.
Agent không phải là Thực thể. Chúng là Hệ thống.
Một AI Agent trong môi trường sản xuất không phải là một thực thể thông minh duy nhất.
Thay vào đó, đó là một tập hợp các thành phần tương tác với các trách nhiệm, chế độ lỗi và mức độ quan sát (observability) khác nhau.
LLM chỉ là một trong những thành phần đó, không phải là toàn bộ hệ thống. Chỉ là một mảnh ghép.
Nó có thể nghe có vẻ hiển nhiên khi nói ra thành lời. Nhưng cách định hình "tác nhân tự chủ" (autonomous agent) chiếm lĩnh năm 2023 và phần lớn năm 2024 đã kéo các kỹ sư hướng tới một mô hình tư duy khác: một thực thể, một vòng lặp suy luận, mọi thứ được xử lý bởi mô hình.
Tất cả những gì bạn cần là công cụ, một câu lệnh hệ thống (system prompt) tốt, và hy vọng mọi thứ sẽ vào đúng chỗ.
Ngược lại, các kỹ sư đã tung ra các sản phẩm dựa trên AI thực tế hiếm khi mô tả hệ thống của họ theo cách đó. Những gì họ mô tả thực sự nghe giống nhiều hơn là kiến trúc hệ thống phân tán.
Không phải vì họ đọc một cuốn sách về các mẫu thiết kế, mà vì họ đã "bị phỏng" đủ nhiều lần để bắt đầu nghiêm túc đặt cấu trúc vào quy trình làm việc của mình.
Xây dựng theo hướng từ trên xuống, bắt đầu từ "tác nhân này nên làm gì" và ngược lại tìm ra công cụ và câu lệnh, rất nhanh để bắt đầu.
Đó cũng là cách bạn kết thúc với một hệ thống nơi mô hình phải chịu trách nhiệm quá nhiều, và không có gì có thể gỡ lỗi một cách riêng lẻ.
Kiến trúc được quyết định bởi mục tiêu, không phải bởi các yêu cầu kỹ thuật.
Đó chính là phần "ngược" của vấn đề.
Vậy thực sự Cái gì tạo nên một Hệ thống Sản xuất?
Phiên bản trừu tượng thì dễ gật đầu đồng ý. Dưới đây là cách nó thực sự trông như thế nào.
Mọi hệ thống AI sản xuất mà tôi từng thấy hoạt động trơn tru đều có một thứ gì đó giống như một lớp ra quyết định (decision layer), dù đội ngũ đó gọi nó là gì hay không. Đó là phần nơi mô hình sống và thực hiện công việc thực sự của nó.
Bản năng là đẩy mọi thứ vào lớp này: phân tích yêu cầu, quản lý bộ nhớ, xử lý thử lại (retry), giải quyết lỗi công cụ.
Điều này ổn nếu bạn đang làm việc trong một Jupyter notebook. Trong môi trường sản xuất, dưới tải nặng, với người dùng thực, đây trở thành phần của hệ thống nơi mọi thứ là lỗi của ai đó, và hầu hết thời gian, không có gì có thể gỡ lỗi được.
Lớp ra quyết định nên làm tốt một việc, và đó là quyết định làm gì tiếp theo, dựa trên một ngữ cảnh nhất định đã được chuẩn bị cho nó.
Đó là toàn bộ công việc.
Ai chuẩn bị ngữ cảnh? Một cái gì đó khác. Ai hành động dựa trên quyết định? Cũng là một cái gì đó khác.
Cái "ai đó khác" chính là lớp điều phối (orchestration layer), và trong hầu hết các hệ thống được xây dựng tốt, nó thực sự chỉ là mã: các điều kiện, trình chạy không đồng bộ, xử lý thử lại, định tuyến hàng đợi, thậm chí có thể là một máy trạng thái (state machine) tùy thuộc vào mức độ phức tạp của quy trình làm việc.
Kiến trúc hệ thống AI Agent
Thay vì mong đợi mô hình làm mọi thứ, hãy coi nó như một thành phần khác. Ở đây, mã tiêu chuẩn xử lý phần nặng nhọc về trạng thái và công cụ, để LLM chỉ phải lo lắng về việc đưa ra quyết định tiếp theo.
Nhiều đội ngũ tìm đến các khung công tác (framework) ở đây vì mã điều phối trần có vẻ quá đơn giản, chắc chắn phải có nhiều cơ sở hạ tầng hơn.
Thường thì không.
Càng ít "phép thuật" trong lớp này, bạn càng nhanh tìm ra lỗi khi chúng xuất hiện. Và chúng sẽ xuất hiện.
Từ kinh nghiệm, tôi đã học điều này một cách đau đớn trong một dự án nơi phần điều phối nằm bên trong mô hình thực thi của một framework. Có gì đó đang thử lại các cuộc gọi công cụ theo cách làm hỏng trạng thái ở hạ lưu.
Chúng tôi đã mất hai ngày để tìm ra vấn đề. Hai ngày cho một lỗi có thể được giải quyết ngay lập tức nếu logic thử lại là ba dòng Python do chính tôi viết.
Điều này dẫn chúng ta đến lớp công cụ và thực thi (tools and execution layer), nơi tất cả giao tiếp diễn ra.
Bây giờ, lớp công cụ và thực thi là nơi mọi thứ nói chuyện với thế giới bên ngoài. Lớp này thường chỉ có một công việc, và đó là lấy một đầu vào được xác định rõ rồi tạo ra một đầu ra có thể dự đoán được.
Nhưng lỗi mà tôi liên tục thấy, và lặp lại một cách trung thực, là các công cụ cố gắng hữu ích bằng cách làm nhiều hơn một việc. Một hàm duy nhất gọi API, cập nhật bộ nhớ đệm và làm những việc khác.
Trong một thiết lập như vậy, khi nó bị hỏng, bạn không biết ở đâu. Ngay cả khi bạn cố gắng thay thế API, bạn đang gỡ rối logic lẽ ra không bị rối vào nhau từ đầu.
Bộ nhớ và trạng thái (memory and state) là nơi tôi muốn nhấn mạnh nhất, vì đó là nơi hầu hết các đội ngũ kém chuẩn bị nhất.
Hầu hết các đội ngũ nghĩ về bộ nhớ là "những gì mô hình biết". Câu hỏi quan trọng hơn là hệ thống biết gì, và kiến thức đó có cập nhật không.
Tôi nhớ một buổi chiều đã mất để gỡ lỗi những gì dường như là một "ảo giác mô hình" đơn giản. Mô hình liên tục đề cập đến sở thích của người dùng, vốn đã được cập nhật hai mươi phút trước.
Đó không phải là vấn đề của mô hình.
Đó là vấn đề của hệ thống.
Và nó đáng ngạc nhiên là phổ biến.
Trong các hệ thống đa tác nhân cụ thể, trạng thái chia sẻ là nơi các lỗi tinh tế sinh sôi. Một tác nhân cập nhật cái gì đó. Những cái khác không biết.
Mọi người tiếp tục tự tin đi theo các hướng hơi khác nhau. Đầu ra trông gần đúng, điều đó gần như tệ hơn là trông sai.
Và sau đó là đánh giá và khả năng quan sát (evaluation and observability), điều mà hầu hết mọi người luôn trì hoãn cho đến khi có chuyện gì đó xảy ra. Tôi cũng từng có lỗi này.
Sự khác biệt mà tôi luôn ghi nhớ là ghi log (logging) cho bạn biết điều gì đã xảy ra. Khả năng quan sát cho bạn biết điều gì đã xảy ra có đúng không. Trong một hệ thống xác định, những thứ này gần như giống nhau.
Trong một hệ thống AI, thì không. Bạn phải có thể theo dõi yêu cầu cụ thể từ đầu đến cuối, bao gồm thông tin nào mô hình đã xem xét, quyết định nào nó đưa ra, cuộc gọi API bên ngoài nào nó kích hoạt, và nó đã hành động như thế nào đối với phản hồi đó.
Xây dựng theo Cách đúng
Nó bắt đầu với cách tiếp cận từ trên xuống: Tôi muốn một tác nhân làm X, vì vậy tôi sẽ cung cấp cho nó công cụ, một câu lệnh hệ thống hay ho, và nếu mô hình đủ thông minh, nó sẽ ổn.
Và chính xác là những gì mọi người sử dụng để tạo ra nguyên mẫu, và tại sao họ lại không làm vậy? Họ không sai.
Nhưng đây là vấn đề: vấn đề là nó coi kiến trúc là hệ quả của mục tiêu thay vì là thứ bạn thiết kế có chủ đích.
Sau đó hệ thống phát triển. Bạn biết đấy, nhiều công cụ hơn, nhiều quy trình làm việc hơn, nhiều trường hợp ngoại lệ hơn, nhiều người dùng hơn, và đột nhiên không có nền tảng thực sự nào dưới bất kỳ thứ nào trong số đó.
Cách tiếp cận từ dưới lên (bottom-up) tốn nhiều thời gian hơn, nhưng nó thoải mái hơn nhiều.
Bạn bắt đầu với các khối xây dựng cơ bản và đảm bảo chúng thực sự hoạt động. Sau đó bạn tìm ra mỗi phần nên giao tiếp cái gì, dữ liệu nó sở hữu gì, và nó chịu trách nhiệm cho gì.
Cuối cùng, hệ thống hình thành một cách tự nhiên từ sự tương tác của các phần của nó.
Đây không phải là lập luận "kỹ sư thực sự xây dựng mọi thứ từ đầu". Nó thậm chí không thực sự liên quan đến công cụ. Nó liên quan đến mô hình tư duy mà bạn đang xây dựng.
Tôi đã thấy các kỹ sư sử dụng các khung công tác tinh vi và xây dựng các hệ thống sạch sẽ vì họ hiểu rõ mỗi lớp cần làm gì.
Tôi cũng đã thấy các kỹ sư viết Python thuần và xây dựng một mớ hỗn độn không thể gỡ lỗi vì họ vẫn đang tư duy theo hướng "tác nhân quyết định mọi thứ". Các công cụ tuân theo mô hình trong đầu bạn, không phải ngược lại.
Hệ thống đa tác nhân mạnh mẽ nhất mà tôi có cơ hội làm việc chặt chẽ hầu như không có cơ sở hạ tầng đặc thù cho AI. Khi tôi lần đầu nhìn thấy kho lưu trữ (repo), tôi thực sự đã nghĩ mình đang nhìn sai codebase.
Một hàng đợi tin nhắn, các quy trình worker với phạm vi riêng biệt, lưu trữ trạng thái chia sẻ với các hợp đồng đọc/ghi rõ ràng, và một điều phối viên đưa ra các quyết định định tuyến.
Các truy vấn mô hình ngôn ngữ được thực hiện bởi chính các worker, mỗi worker nhận một tập hợp ngữ cảnh được tạo ra ở thượng nguồn bởi một quy trình khác.
Tất cả tổng cộng, cả thứ chỉ khoảng một nghìn dòng Python. Tôi đã thấy các tác nhân demo có nhiều code hơn thế. Mọi phần đều có thể truy xuất (traceable).
Khi có gì đó hoạt động bất ngờ, chúng tôi thường tìm thấy vấn đề trong vòng một giờ vì không có phép thuật nào để nhìn xuyên qua. Chỉ là code với một đường dẫn rõ ràng.
Hệ thống đó được xây dựng từ dưới lên. Mục tiêu được xác định, nhưng kiến trúc không được dẫn xuất từ nó. Các thành phần được thiết kế trước, được đánh giá riêng lẻ, và sau đó được kết hợp để triển khai chức năng mong muốn. Điều sau mới là khía cạnh quan trọng nhất, không phải điều trước.
Tôi nghĩ Nó sẽ đi về đâu
Xét cho cùng, hướng chúng ta đang đi là dần chuyển dịch từ các "khung tác nhân" sang cơ sở hạ tầng thích hợp, với các hệ thống để đánh giá, định tuyến mô hình, dự phòng và quản lý trạng thái.
Ít nhất một phần trong số đó đã tồn tại. Phần lớn vẫn chưa đến khi mọi người giải quyết các vấn đề sản xuất khó khăn trong lĩnh vực này.
Điều tôi thấy lặp đi lặp lại là những người xây dựng các hệ thống đáng tin cậy nhất hiếm khi sử dụng các mô hình tốt nhất. Thay vào đó, họ có sự hiểu biết rõ ràng về mọi thứ diễn ra bên trong hệ thống của họ.
Mô hình được sử dụng bởi hệ thống như vậy có thể là GPT-4, nhưng nó cũng có thể là một mô hình cục bộ nhỏ. Nó không quan trọng lắm khi mọi thứ khác hoạt động đúng cách.
Chúng ta đang chuyển từ việc coi mô hình là sản phẩm sang việc coi hệ thống là sản phẩm. Mô hình quan trọng, nhưng nó chỉ là một thành phần trong số nhiều thành phần.
Hầu hết các tác nhân không thất bại vì mô hình không đủ tốt. Chúng thất bại vì hệ thống xung quanh mô hình được thiết kế ngược, bắt đầu từ việc tác nhân nên làm gì và giả định kiến trúc sẽ tự giải quyết.
Nó không tự giải quyết được.
Xây dựng nó theo đúng hướng, thành phần trước, hành vi sau, là điều phân chia các hệ thống đứng vững với những hệ thống trông ấn tượng cho đến khi không còn nữa.


