Bỏ qua để đến nội dung

Structured Output

Level: L2 — Prompt & Context Engineering (Bài 6/10)

Sau bài này, bạn có thể:

  • Phân biệt rõ “yêu cầu JSON bằng lời” (best-effort, có thể sai) và “Structured Outputs” (ép buộc schema, gần như không thể sai).
  • Biết cả Anthropic và OpenAI đều có tính năng tương đương, dựa trên “JSON Schema + ràng buộc kỹ thuật ở tầng sinh văn bản”.
  • Nhận diện đúng tình huống cần Structured Output: khi kết quả sẽ được hệ thống khác xử lý tự động.
  • Biết các giới hạn kỹ thuật cụ thể để không kỳ vọng sai.
  • Structured Output — tính năng API ép buộc phản hồi AI tuân theo 1 JSON Schema cụ thể, đảm bảo output luôn hợp lệ và parse được [S62].
  • Cơ chế: constrained decoding — sinh theo “ngữ pháp” khiến model chỉ có thể sinh token khớp schema, khác hẳn cách “prompt-based” (chỉ yêu cầu model cố gắng theo định dạng) [S62].
  • Không phải đặc thù 1 vendor: cả Anthropic (Structured Outputs [S62]) và OpenAI (response_format [S63]) đều có tính năng tương đương — đây là khái niệm cấp ngành.
  • Yêu cầu JSON bằng lời văn (bài 14) không đảm bảo tuyệt đối. Nếu kết quả được 1 hệ thống khác xử lý tự động, 1 lần JSON lỗi cú pháp có thể làm sập cả quy trình.
  • Hiểu khác biệt “yêu cầu” và “ép buộc” giúp chọn đúng công cụ theo mức độ rủi ro.
  • Cầu nối quan trọng từ “dùng AI qua chat” sang “dùng AI như 1 thành phần trong hệ thống tự động” — nền tảng cho Level 8.

Theo Anthropic [S62], Structured Outputs gồm 2 thành phần: JSON outputs (output_config.format — ép response tuân theo JSON Schema) và Strict tool use (strict: true — validate schema cho tool khi AI gọi tool).

Không có Structured Outputs, model có thể sinh JSON lỗi cú pháp, thiếu trường, sai kiểu dữ liệu — buộc lập trình viên viết thêm logic retry. Với Structured Outputs, lỗi này về nguyên tắc không thể xảy ra vì constrained decoding chặn từ gốc.

OpenAI mô tả cùng ý tưởng [S63]: bản nâng cấp của “JSON mode” cũ, đảm bảo thêm tuân thủ đúng schema.

Giới hạn kỹ thuật [S62]: KHÔNG hỗ trợ schema đệ quy; KHÔNG hỗ trợ ràng buộc số học (minimum, maximum, độ dài chuỗi); có giới hạn quy mô theo thời điểm; nếu AI từ chối vì lý do an toàn, output có thể không khớp schema — an toàn luôn ưu tiên hơn tuân thủ schema.

Hình dung như “nhờ ai đó điền tờ khai” (yêu cầu bằng lời) so với “đưa họ 1 tờ mẫu in sẵn ô trống” (Structured Outputs): yêu cầu bằng lời — người điền có thể quên 1 mục, viết sai định dạng. Structured Outputs — về mặt vật lý người điền không thể bỏ sót ô nào, vì cấu trúc đã định sẵn.

  1. Xác định: kết quả sẽ được con người đọc hay hệ thống khác xử lý tự động? Nếu tự động, tiếp tục; nếu chỉ đọc bằng mắt, cách “yêu cầu bằng lời” (bài 14) thường đã đủ.
  2. Định nghĩa rõ JSON Schema: trường nào bắt buộc, kiểu dữ liệu từng trường.
  3. Kiểm tra schema có nằm trong giới hạn hỗ trợ không.
  4. Cấu hình Structured Outputs của vendor (output_config.format ở Anthropic [S62], response_format ở OpenAI [S63]) — bước kỹ thuật, cần code.
  5. Luôn có kế hoạch xử lý trường hợp AI từ chối (refusal).

Hệ thống tự động trích xuất thông tin liên hệ từ email khách hàng (tên, email, gói dịch vụ, có yêu cầu demo không) để đưa vào CRM. Chỉ yêu cầu “trả lời bằng JSON gồm các trường này” (bài 14) có thể khiến 1 số email cấu trúc bất thường trả về JSON thiếu trường hoặc sai kiểu ("có" thay vì true). Với Structured Outputs, schema quy định rõ 4 trường bắt buộc và đúng kiểu, output luôn parse được.

{
"type": "object",
"properties": {
"ten_truong_1": {"type": "string"},
"ten_truong_2": {"type": "boolean"},
"ten_truong_3": {"type": "number"}
},
"required": ["ten_truong_1", "ten_truong_2", "ten_truong_3"],
"additionalProperties": false
}

Nguyên tắc: liệt kê đủ mọi trường bắt buộc trong required, cân nhắc additionalProperties: false.

Yêu cầu bằng lờiCó thể quên ô, sai định dạngStructured OutputsKhông thể sai cấu trúc⚠️JSON hợp lệ 100%Parse được luônHệ thống downstreamKhông cần retry
Hình 2.5 — Structured Outputs: từ tờ khai miệng dễ lỗi tới tờ mẫu in sẵn không thể sai cấu trúc.
  1. Nghĩ ra 1 tác vụ trích xuất thông tin (ví dụ: trích tên/giá/danh mục từ mô tả sản phẩm).
  2. Viết 1 JSON Schema tối giản theo khung ở mục 8.
  3. Thử yêu cầu AI trả lời theo schema đó chỉ bằng lời văn với 3-5 input khác nhau, quan sát có lần nào JSON lỗi/thiếu trường không.

(Suy luận từ nguyên tắc trong [S62, S63], không phải khảo sát lỗi người dùng đã ghi nhận chính thức.)

  • Dùng Structured Outputs cho mọi tác vụ — có chi phí kỹ thuật (biên dịch schema, độ trễ lần đầu) [S62].
  • Thiết kế schema vượt quá giới hạn hỗ trợ (schema đệ quy) rồi bất ngờ khi không hoạt động.
  • Quên xử lý trường hợp refusal — giả định output luôn khớp schema 100% [S62].

13. Giới hạn & khi nào KHÔNG nên áp dụng

Phần tiêu đề “13. Giới hạn & khi nào KHÔNG nên áp dụng”
  • Nếu kết quả chỉ để con người đọc trực tiếp, yêu cầu bằng lời (bài 14) thường đã đủ.
  • Đây là tính năng ở tầng API/kỹ thuật, không phải thứ bật/tắt trong giao diện chat thông thường.
  • Với schema quá phức tạp, tính năng có giới hạn.

An toàn luôn được ưu tiên hơn tuân thủ schema [S62] — nếu AI cần từ chối trả lời, nó sẽ từ chối dù điều đó phá vỡ schema. Bất kỳ hệ thống nào dùng Structured Outputs để xử lý tự động phải có logic kiểm tra riêng cho stop_reason: "refusal" [S62] trước khi giả định output luôn parse được.

  1. Chỉ dùng Structured Outputs khi kết quả sẽ được hệ thống khác xử lý tự động.
  2. Thiết kế schema tối giản, đủ dùng.
  3. Luôn có logic xử lý riêng cho trường hợp refusal.
  4. Nhớ đây là khái niệm chung của ngành — không phải lý do để chọn vendor.
16. Nội dung nâng cao (không bắt buộc)
  • Anthropic hỗ trợ định nghĩa schema bằng kiểu dữ liệu bản địa (Pydantic cho Python, Zod cho TypeScript) [S62].
  • Grammar biên dịch cho schema được cache 24 giờ ở phía Anthropic — thay đổi schema làm mất cache và tăng độ trễ [S62].

[S62] Structured Outputs, Claude Platform Docs (Anthropic) · [S63] Structured model outputs, OpenAI API Docs (OpenAI).

2026-07-12. Khái niệm cốt lõi ổn định. Chi tiết kỹ thuật cụ thể (giới hạn số lượng, tên tham số API) thay đổi nhanh — tra lại tài liệu chính thức trước khi triển khai.