Khi nhà cung cấp AI của chúng tôi ngừng mô hình
Một lần đổi mô hình, những câu trả lời rỗng không kèm lỗi, và một hóa đơn bỗng cao gấp nhiều lần. Điều gì đã hỏng, và vì sao nguyên nhân lại khó thấy đến vậy.

Vào tháng 7 năm 2026, nhiều tính năng cùng lúc ngừng hoạt động: trò chuyện AI, câu trả lời AI trong ticket, tóm tắt ticket, trình tạo máy chủ, cùng với việc kiểm duyệt và dịch ý tưởng và báo cáo lỗi.
Nguyên nhân không nằm ở mã của chúng tôi. Nhà cung cấp AI của chúng tôi đã ngừng mô hình mà chúng tôi đang dùng.
Phần một: mô hình đã biến mất
Đó là phần hiển nhiên, và được sửa nhanh chóng. Nhà cung cấp ngừng một mô hình, bạn nhập mô hình kế nhiệm, xong.
Sự cố thực sự bắt đầu sau đó.
Phần hai: câu trả lời rỗng, không có lỗi
Sau khi đổi, các câu trả lời đã quay lại. Chỉ là đôi khi chúng rỗng. Không bị cắt cụt, không bị sai định dạng, mà là một câu trả lời hoàn toàn trống rỗng, không kèm bất kỳ lỗi nào.
Nguyên nhân nằm ở một khác biệt mà tên mô hình không tiết lộ: mô hình kế nhiệm là một mô hình suy luận. Trước câu trả lời thực sự, nó viết một chuỗi suy nghĩ nội bộ vào một trường riêng. Cả hai cùng rút từ một ngân sách token.
Nếu ngân sách bị phần suy nghĩ dùng hết, một câu trả lời quay về trông hoàn toàn hợp lệ về mặt hình thức: nhà cung cấp báo "đã đạt độ dài tối đa" và trường nội dung trống. Không có lỗi, không có gợi ý, không có gì mà một khối try/catch có thể thấy.
Chúng tôi đã tái hiện điều này bằng một bài kiểm tra thật: ngân sách năm token là đủ để tạo ra câu trả lời rỗng cho mọi yêu cầu.
Phần ba: hóa đơn
Ở điểm gọi tốn kém nhất, trình tạo máy chủ AI, chúng tôi đã đặt ngân sách rộng rãi vì ở đó sinh ra những câu trả lời dài. Vì vậy phần suy nghĩ không chạm giới hạn nào, nó cứ thế chạy.
Hậu quả ập đến từ hai phía cùng lúc. Các yêu cầu mất nhiều thời gian đến mức bị hết thời gian chờ. Và chúng tốn gấp nhiều lần, vì lần nào cũng phải trả tiền cho cả một chuỗi suy nghĩ vô hình. Cuối cùng là một thông báo lỗi chúng tôi chưa từng tính đến: số dư không đủ.
Cách sửa chỉ là một dòng. Có thể tắt chế độ suy nghĩ trong phần thân yêu cầu, và mô hình sẽ lại hành xử như mô hình cũ. Từ đó, dòng này phải có ở mọi điểm gọi, và trong kho mã có nhiều hơn vài điểm như vậy.
Phần bốn: những gì chúng tôi tìm thấy khi dọn dẹp
Nếu đằng nào bạn cũng chạm vào mọi điểm gọi AI, bạn sẽ nhìn kỹ chúng. Điều đó làm lộ ra một chủ đề thứ hai, không liên quan đến sự cố nhưng cũng tốn kém tương tự.
Các nhà cung cấp tính phí thấp hơn đáng kể cho một prompt có phần đầu giữ nguyên và có thể phục vụ từ bộ nhớ đệm. Chênh lệch giữa một lần trúng và một lần trượt bộ nhớ đệm là khoảng ba mươi lần.
Bạn không có được mức giảm đó nhờ một cờ. Chúng tôi đã kiểm tra riêng: một trường trong phần thân yêu cầu dành cho việc này có tác dụng bằng không, bộ nhớ đệm vốn đã tự động áp dụng. Đòn bẩy duy nhất là thứ tự bên trong prompt, từ ổn định đến biến động.
Bốn chỗ mà chúng tôi đã làm đúng điều ngược lại:
Một giá trị biến động nằm trong khối chỉ dẫn cố định. Bước kiểm tra trùng lặp cho báo cáo lỗi có tên mô-đun trong văn bản chỉ dẫn. Điều đó khiến một khối vốn giống hệt nhau có một dòng bộ nhớ đệm riêng cho mỗi mô-đun. Giá trị đó thuộc về phần biến đổi, nơi nó vốn đã thay đổi.
Cái mới đặt trước cái ổn định. Cũng bước kiểm tra đó gửi báo cáo lỗi mới trước tối đa năm mươi ứng viên để so sánh. Điều đó khiến prompt lớn nhất của API trượt bộ nhớ đệm hoàn toàn mãi mãi.
Dữ liệu theo từng người dùng nằm trong phần cố định. Trò chuyện AI công khai đặt ghi chú về từng người dùng trong khối chỉ dẫn, tức là trước lịch sử kênh dùng chung. Điều đó cho mỗi người dùng trong cùng một kênh một phần đầu riêng, và lịch sử dùng chung bị tính tiền riêng cho từng người.
Cửa sổ trượt trên lịch sử. Gửi N tin nhắn gần nhất với mỗi tin nhắn sẽ dịch chuyển phần đầu ở mọi tin nhắn. Khi đó toàn bộ lịch sử trượt bộ nhớ đệm vĩnh viễn. Cách đúng là cắt theo khối, tức là hiếm khi nhưng cắt nhiều.
Thêm một chi tiết trông như bới lông tìm vết nhưng không phải: một danh sách trong prompt chỉ được sắp xếp theo một tiêu chí có thể đổi thứ tự khi bằng nhau. Chỉ một dòng bị hoán đổi giữa khối chỉ dẫn cũng làm mất lần trúng bộ nhớ đệm cho mọi thứ phía sau nó. Việc sắp xếp trong prompt cần một tiêu chí phân định rõ ràng.
Điều chúng tôi rút ra
Đổi mô hình không phải là thay đổi cấu hình. Cái tên trông như một giá trị trong biến. Đằng sau nó là một hành vi khác, và chính hành vi đó đã làm hỏng mã của chúng tôi, không phải giao diện.
Lỗi nguy hiểm là lỗi âm thầm. Việc mô hình cũ biến mất lộ ra ngay lập tức và được sửa trong vài phút. Những câu trả lời rỗng quay về như các phản hồi hợp lệ về mặt hình thức và có thể đã cứ thế tồn tại vô thời hạn.
Khả năng đo lường thuộc về điểm gọi. Giờ chúng tôi ghi nhật ký tỷ lệ trúng bộ nhớ đệm ở mọi điểm gọi. Một điểm gọi được xây đúng sẽ ổn định ở tỷ lệ cao sau yêu cầu đầu tiên, một điểm gọi xây sai sẽ ở mãi con số không. Bạn thấy điều đó trong một dòng nhật ký và không ở đâu khác, vì cả hai đều chạy được.
Và kết luận khó chịu: dùng mô hình của người khác nghĩa là một phần sản phẩm của bạn phụ thuộc vào một quyết định được đưa ra ở nơi khác. Đó là lý do từ tháng 8, bất kỳ máy chủ nào cũng có thể trỏ các tính năng AI đến endpoint của riêng mình thay vì dựa vào endpoint của chúng tôi.
Bài viết khác
Theo dõi 4.000 máy chủ Discord: Grafana, PostHog và những gì chúng cho chúng tôi thấy
Một vòng lặp âm thầm tạo ra một nửa lưu lượng của chúng tôi, ba triệu yêu cầu vô ích mỗi ngày và một cuộc tấn công kết thúc sau một phút. Hệ thống giám sát của chúng tôi thấy gì, và cố ý không thấy gì.
Hậu trườngChạy bot trên hơn 2.000 máy chủ Discord đã dạy chúng tôi điều gì
Bốn điều diễn ra khác ở quy mô lớn so với những gì bạn giả định khi viết mã.
Hậu trườngLuật pháp bên trong mã nguồn của chúng tôi
Một nút hủy hợp đồng phải hoạt động mà không cần đăng nhập. Một biểu mẫu không bao giờ được từ chối bạn. Vì sao với chúng tôi, nghĩa vụ pháp lý là kiến trúc, không phải văn bản mẫu.