Mọi tính năng LLM có đụng tới database đều bắt đầu giống nhau. Bạn nhờ model phân loại một ticket support, nó trả lời This looks like a billing issue, probably high priority. , và bạn viết một cái regex. Chạy được. Bạn ship. Hai tuần sau model đổi giọng thành I'd categorise this as billing-related , regex của bạn trả về None , nhánh if severity == "high" lặng lẽ false, và một ticket nghiêm trọng nằm im trong hàng đợi ưu tiên thấp ba ngày. Không có gì hỏng. Không exception nào được raise. Model cũng chẳng hallucinate. Nó chỉ diễn đạt một câu trả lời đúng theo cách khác, còn cái parser của bạn — vốn chưa bao giờ là parser, chỉ là một phỏng đoán về pattern — âm thầm không đồng ý. Cách sửa đầu tiên ai cũng nghĩ tới là xin gắt hơn: “chỉ trả về JSON, không markdown.” Cách đó có giúp, nhưng nó dời chỗ lỗi chứ không xóa lỗi. Cách sửa thật là ngừng coi response như văn bản cần diễn giải, và bắt đầu coi nó như một giá trị mà API bị ràng buộc phải sinh ra. Đó chính là thứ JSON S...
Bản demo lúc nào cũng chạy ngon. Bạn dán một input đẹp vào, model trả về thứ gì đó ấn tượng, bạn đem khoe ở standup, cả nhóm đồng ý là phải ship. Hai tuần sau nó nằm trên production và bạn đang đọc một ticket hỗ trợ trong đó model nói với khách rằng yêu cầu hoàn tiền của họ đã được duyệt. Bản demo là 20% dễ. 80% còn lại là tất cả những thứ ngăn một hàm xác suất kéo sập ứng dụng của bạn — không phải vì model tệ, mà vì bạn vừa cắm một thành phần không tất định vào một hệ thống được thiết kế trên giả định rằng hàm trả về đúng cái mà chữ ký của nó khai báo. Dưới đây là thứ tự tôi thật sự làm. Thứ tự quan trọng hơn từng kỹ thuật riêng lẻ, vì mỗi bước cho bạn biết bước kế tiếp có đáng làm hay không. Bỏ qua bộ eval thì bạn sẽ mất ba ngày tinh chỉnh prompt mà không có cách nào biết mình có cải thiện được gì không. Bỏ qua guardrail thì bạn sẽ biết về lỗi format output của mình qua lời người dùng. Không có gì ở đây gắn với một nhà cung cấp hay một framework cụ thể. Đây vẫn là kỷ luật bạn áp c...