Giờ đây, các nhà phát triển có thể đảm bảo rằng JSON mà LLM trả về tuân thủ một cấu trúc đã được định nghĩa trước bằng cách kết nối các schema Zod vào Vercel AI SDK hoặc Anthropic’s tool-use API, giúp loại bỏ các lỗi runtime xảy ra khi mô hình thêm một trường không mong muốn.

Nhu cầu về một cơ chế bảo vệ cụ thể đã trở nên rõ ràng vào tháng Giêng, khi một bộ phân loại (classifier) được triển khai lên production bắt đầu trả về một khóa “explanation” thứ hai sau ba tuần hoạt động không lỗi. Mã nguồn chỉ mong đợi một trường duy nhất, vì vậy khóa bổ sung này đã gây ra một ngoại lệ (exception) — mà không cần bất kỳ một lần triển khai mã (code deploy) nào. Sự cố này minh họa cho một vấn đề rộng lớn hơn: hầu hết các hướng dẫn chỉ dừng lại ở JSON.parse(response), giả định rằng mô hình sẽ tuân thủ schema của prompt. Trong thực tế, các LLM thường xuyên đi chệch hướng — thay đổi kiểu chữ (casing), thêm các trường, hoặc bao bọc đầu ra trong các dấu ngoặc markdown — dẫn đến việc dữ liệu bị lỗi ngầm hoặc thất bại hoàn toàn.

Tại sao việc parse JSON thô lại không an toàn

Các LLM được huấn luyện để trở nên hữu ích, chứ không phải để phục tùng. Một prompt yêu cầu

{ "category": "string" }

không ràng buộc mô hình vào chính xác cấu trúc đó. Ngay cả một prompt được viết tốt cũng có thể bị ghi đè bởi các thuật toán heuristic nội bộ của mô hình, đặc biệt là khi cài đặt temperature khuyến khích sự sáng tạo hoặc khi một hướng dẫn tiếp theo thúc đẩy nó giải thích chi tiết hơn. Kết quả là một luồng văn bản trông giống như JSON nhưng lại sai lệch đủ để làm hỏng các bộ parser vốn mong đợi một cấu trúc nghiêm ngặt.

Khi sự không khớp như vậy chạm đến mã nguồn production, hậu quả sẽ đến ngay lập tức: một ngoại lệ bị ném ra, một yêu cầu thất bại, và có khả năng là một chuỗi các lỗi dây chuyền ở các bước sau. Trong các dịch vụ lớn, những phút downtime đó sẽ chuyển hóa thành doanh thu bị mất và niềm tin của người dùng bị xói mòn.

Zod + Vercel AI SDK: mạng lưới an toàn ba bước

Zod là một trình xác thực schema ưu tiên TypeScript, có thể mô tả chính xác hình dạng dữ liệu mà một mô hình nên tạo ra. Kết hợp với helper Output.object của Vercel AI SDK, việc xác thực sẽ diễn ra tự động sau khi mô hình tạo ra phản hồi của nó.

  1. Định nghĩa schema – viết một Zod object phản ánh đúng JSON mong muốn. Đối với một bộ phân loại đơn giản, nó có thể là z.object({ category: z.string() }); đối với một bộ trích xuất hóa đơn phức tạp, schema có thể lồng các object, array và discriminated unions.
  2. Truyền nó vào SDK – bao bọc schema bằng Output.object(schema). SDK sẽ chèn một prompt yêu cầu mô hình xuất ra một khối JSON khớp với schema và parse kết quả bằng safeParse của Zod.
  3. Xử lý thất bạisafeParse trả về một đối tượng kết quả thay vì ném ra lỗi. Nếu việc parse thất bại, hãy gửi lỗi ngược lại cho mô hình và thử lại. Mô hình có thể được hướng dẫn để sửa đổi đầu ra dựa trên thông báo xác thực chính xác, biến hầu hết các trường hợp biên (edge cases) thành một vòng lặp tự chữa lành (self-healing loop).

Vì SDK thực hiện việc prompting, parsing và logic thử lại tại một nơi, các nhà phát triển có thể thay thế một vài thao tác xử lý chuỗi tùy tiện bằng một lời gọi hàm duy nhất đã được kiểm tra kiểu (type-checked).

Anthropic tool use: ép buộc đầu ra có cấu trúc

Khi làm việc trực tiếp với API của Anthropic, sự đảm bảo tương tự có thể đạt được thông qua “tool use”. Một công cụ (tool) được định nghĩa là một hàm có schema đầu vào được thể hiện bằng JSON Schema; mô hình của Anthropic sẽ chỉ gọi công cụ nếu nó có thể đáp ứng schema đó. Bằng cách đặt tool_choice thành "any" (hoặc một tên công cụ cụ thể), mô hình bị buộc phải trả về một khối có cấu trúc thay vì văn bản tự do.

Quy trình làm việc tương tự như cách tiếp cận của Vercel:

  • Viết một Zod schema.
  • Chuyển đổi nó thành một payload JSON Schema cho định nghĩa công cụ.
  • Bao gồm công cụ trong yêu cầu và yêu cầu mô hình gọi nó.
  • Parse phản hồi của công cụ bằng zod.safeParse.

Nếu mô hình vẫn tạo ra dữ liệu sai định dạng, mô hình thử lại kèm phản hồi (retry-with-feedback) tương tự vẫn sẽ được áp dụng.

Khi việc xác thực vẫn thất bại

Ngay cả khi đã thực thi schema, thỉnh thoảng vẫn xảy ra sự không khớp. Các lý do bao gồm:

  • Model hallucination (Ảo giác mô hình): mô hình có thể tạo ra một chuỗi trông giống JSON nhưng chứa các lỗi cú pháp.
  • Prompt leakage (Rò rỉ prompt): các lượt hội thoại trước đó có thể làm rò rỉ các hướng dẫn định dạng, ghi đè lên yêu cầu schema.
  • Version differences (Khác biệt phiên bản): các bản phát hành mô hình mới hơn đôi khi thay đổi cách chúng diễn giải các lời gọi công cụ (tool calls).

Biện pháp giảm thiểu được khuyến nghị là một vòng lặp thử lại nhẹ nhàng. Khi việc parse thất bại, mã nguồn sẽ gửi một prompt tiếp theo như: “Đầu ra vừa rồi của bạn không phải là JSON hợp lệ. Nó chứa... Vui lòng chỉ trả về các trường đã được định nghĩa trong schema.” Vì lỗi xác thực là rõ ràng, mô hình có thể tự sửa lỗi mà không cần sự can thiệp của con người.

Các cân nhắc về hiệu suất và chi phí

Việc thêm xác thực Zod chỉ gây ra mức tiêu thụ CPU không đáng kể—thao tác safeParse chỉ mất vài micro giây đối với các payload thông thường. Độ trễ mạng không thay đổi; lượt truyền tải bổ sung (round-trip) để thử lại chỉ xảy ra trong trường hợp lỗi hiếm hoi. Trên thực tế, chi phí để ngăn chặn một ngoại lệ (exception) duy nhất lớn hơn nhiều so với sự gia tăng không đáng kể về thời gian yêu cầu.

Đối lập quan điểm: liệu việc thực thi schema có là quá mức cần thiết?

Một số nhà phát triển lập luận rằng các schema nghiêm ngặt sẽ làm hạn chế tính linh hoạt của mô hình, đặc biệt là khi các trường mới có thể cung cấp ngữ cảnh giá trị. Sự đánh đổi nằm ở giữa tính an toàn và tính mở. Trong các dịch vụ trọng yếu—như xử lý thanh toán, xác minh danh tính, báo cáo tuân thủ—tính có thể dự đoán được (predictability) luôn được ưu tiên. Trong các bản mẫu thử nghiệm, một cách tiếp cận nới lỏng hơn có thể được chấp nhận, nhưng ngay cả ở đó, một lớp bảo vệ tối thiểu (ví dụ: z.object({}).passthrough()) cũng có thể bắt được các lỗi phân tích cú pháp thảm khốc mà không làm mất đi các phần mở rộng hữu ích.

Những điều cần theo dõi tiếp theo

  • Sự tiến hóa của SDK: Lộ trình phát triển AI SDK của Vercel bao gồm các chính sách thử lại (retry policies) tích hợp sẵn và báo cáo lỗi chi tiết hơn, điều này sẽ giúp tinh gọn hơn nữa quy trình sửa lỗi (repair loop).
  • Tiêu chuẩn hóa công cụ: Khi có nhiều nhà cung cấp áp dụng các quy ước sử dụng công cụ (tool-use conventions) hơn, các bộ xác thực schema đa nhà cung cấp (cross-provider schema validators) có thể xuất hiện, giúp giảm bớt nhu cầu về các bộ chuyển đổi (adapters) dành riêng cho từng nhà cung cấp.
  • Các mô hình cộng đồng: Các thư viện mã nguồn mở đang bắt đầu đóng gói các Zod schema cùng với các mẫu prompt, biến quy trình làm việc “schema-first” thành một tài sản có thể tái sử dụng.

Bài học rút ra

Bằng cách coi một Zod schema như một bản hợp đồng mà mô hình không thể phá vỡ, các nhà phát triển chuyển từ những thủ thuật JSON.parse mong manh sang một quy trình (pipeline) mang tính xác định (deterministic), nơi các trường không mong muốn sẽ gây ra lỗi xác thực có kiểm soát thay vì làm sập hệ thống thực tế. Sự kết hợp giữa trình trợ giúp Output.object của Vercel và cơ chế sử dụng công cụ (tool-use) của Anthropic biến các LLM từ những bộ tạo văn bản không thể dự đoán thành những nhà cung cấp dữ liệu đáng tin cậy, cho phép các nhóm tập trung vào logic nghiệp vụ thay vì phải gỡ lỗi các trường hợp biên (edge-case) vô tận.