Structured Outputs
Structured output giới hạn phản hồi của model AI theo một schema như JSON Schema trong quá trình giải mã, giúp ứng dụng phân tích cú pháp mọi câu trả lời một cách đáng tin cậy.
Đầu ra có cấu trúc là phản hồi của model bị ràng buộc theo một định dạng xác định trước, thường là JSON Schema nêu các khóa bắt buộc, kiểu dữ liệu và giá trị được phép, để phần mềm có thể phân tích cú pháp mọi câu trả lời mà không cần xử lý lại. Một mô hình ngôn ngữ lớn (LLM) được yêu cầu lịch sự trả về JSON thường sẽ tuân theo, nhưng vẫn có thể thêm một câu văn xuôi, viết sai khóa hoặc dừng giữa chừng khi đang tạo đối tượng, và mỗi tình huống đều làm hỏng chương trình đọc phản hồi. Đầu ra có cấu trúc loại bỏ rủi ro đó bằng giải mã có ràng buộc: ở mỗi bước tạo sinh, engine suy luận chỉ cho phép các token giúp đầu ra luôn hợp lệ theo schema. Khi OpenAI bổ sung tính năng này vào API vào tháng 8 năm 2024, công ty báo cáo gpt-4o-2024-08-06 với Structured Outputs đạt 100% trong đánh giá khả năng tuân theo JSON schema phức tạp, so với dưới 40% của GPT-4 (gpt-4-0613) khi không có tính năng này.
JSON Mode so với đầu ra có cấu trúc#
API của các nhà cung cấp đưa ra hai mức đảm bảo. JSON mode, được OpenAI giới thiệu vào tháng 11 năm 2023, chỉ đảm bảo phản hồi là JSON hợp lệ về cú pháp, vì vậy khóa vẫn có thể thiếu hoặc sai tên. Đầu ra có cấu trúc đảm bảo phản hồi khớp với schema được cung cấp. Trong API Structured Outputs của OpenAI, nhà phát triển định nghĩa schema dưới dạng model Pydantic trong Python hoặc đối tượng Zod trong JavaScript; trường hợp từ chối được trả về trong một trường riêng thay vì làm hỏng định dạng. Đầu ra có cấu trúc của Claude của Anthropic biên dịch từng schema thành ngữ pháp, làm tăng độ trễ khi schema được sử dụng lần đầu và lưu đệm ngữ pháp đã biên dịch trong 24 giờ. Cả hai nhà cung cấp chỉ hỗ trợ một tập con của JSON Schema; chẳng hạn, phiên bản của Anthropic không hỗ trợ schema đệ quy hoặc giới hạn số như minimum.
Cách thức hoạt động của giải mã có ràng buộc#
Ở mỗi bước, LLM tạo một điểm số, hay logit, cho từng token trong từ vựng; quá trình giải mã chọn token từ phân phối softmax thu được. Giải mã có ràng buộc trước tiên đặt điểm số của mọi token làm sai định dạng thành âm vô cực, nên các token đó không bao giờ được chọn. Brandon Willard và Rémi Louf chỉ ra cách thực hiện hiệu quả trong Efficient Guided Generation for Large Language Models: một biểu thức chính quy hoặc JSON Schema được biên dịch thành máy trạng thái hữu hạn, sau đó một chỉ mục được xây dựng một lần trên từ vựng sẽ liệt kê các token hợp lệ cho từng trạng thái, nhờ đó mỗi bước chỉ cần tra cứu. Thư viện mã nguồn mở Outlines triển khai phương pháp này; các engine phục vụ như vLLM cũng cung cấp khả năng tạo sinh theo ngữ pháp cho các model mở.
Ví dụ sau áp dụng ý tưởng này theo cách thủ công cho GPT-2 từ Transformers của Hugging Face. Phần văn bản cố định của schema—dấu ngoặc nhọn, khóa và dấu ngoặc kép—được mã viết ra; tại mỗi giá trị, model chỉ có thể chọn trong số các token được schema cho phép:
import json
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")
prompt = "Review: The battery died after two days and support never replied.\nJSON:"
# Giải mã tham lam không ràng buộc: không có gì buộc câu trả lời tuân theo schema
ids = tokenizer(prompt, return_tensors="pt").input_ids
free = model.generate(ids, max_new_tokens=16, do_sample=False, pad_token_id=tokenizer.eos_token_id)
print("free:", repr(tokenizer.decode(free[0, ids.shape[1] :])))
def choose(text, options):
"""Return the option GPT-2 scores highest after text, with every other token masked out."""
logits = model(tokenizer(text, return_tensors="pt").input_ids).logits[0, -1]
allowed = torch.tensor([tokenizer.encode(option)[0] for option in options])
masked = torch.full_like(logits, float("-inf"))
masked[allowed] = logits[allowed]
return tokenizer.decode(masked.argmax())
# Giải mã có ràng buộc: schema tạo ra các khóa, còn model chỉ có thể chọn các giá trị được phép
with torch.no_grad():
text = prompt + ' {"sentiment": "'
text += choose(text, ["positive", "negative"]) + '", "stars": '
text += choose(text, ["1", "2", "3", "4", "5"]) + "}"
print("constrained:", json.loads(text[len(prompt) :]))Ví dụ in ra free: ' The battery died after two days and support never replied.\n\nJSON: The' và constrained: {'sentiment': 'positive', 'stars': 1}. Khi để tự do, GPT-2 lặp lại phần đánh giá thay vì viết JSON, còn phiên bản có ràng buộc luôn phân tích cú pháp được. Kết quả đã phân tích cũng cho thấy giới hạn của kỹ thuật này: model 124 triệu tham số đánh giá pin hết và bộ phận hỗ trợ im lặng là tích cực, với một sao. Schema cố định định dạng, còn các giá trị bên trong vẫn đến từ đánh giá riêng của model.
Ứng dụng và đánh đổi#
- Trích xuất dữ liệu: Lấy tên, ngày tháng, tổng tiền và các dòng chi tiết từ hóa đơn, hợp đồng hoặc email đưa thẳng vào các hàng trong cơ sở dữ liệu.
- Gọi hàm: Lời gọi công cụ là đầu ra có cấu trúc với schema tương ứng các tham số của công cụ. Cơ chế sử dụng công cụ nghiêm ngặt trong API của OpenAI và Anthropic áp dụng cùng mức đảm bảo cho các đối số của công cụ.
- Quy trình tác tử: Biểu diễn quyết định định tuyến dưới dạng giá trị enum và truyền kết quả trung gian giữa các bước của chuỗi prompt dưới dạng đối tượng có kiểu.
- Model thị giác-ngôn ngữ: Trả về kết quả phát hiện dưới dạng danh sách nhãn và tọa độ hộp mà mã vẽ hoặc đánh giá có thể sử dụng trực tiếp.
Gán nhãn thông minh theo class prompt trong Ultralytics Platform phụ thuộc vào loại đầu ra cuối cùng đó. Tính năng này yêu cầu các model thị giác từ những nhà cung cấp như OpenAI, Anthropic và Google phát hiện các class trong dataset, rồi thêm mọi đối tượng được trả về dưới dạng bounding box có thể chỉnh sửa; do đó, mỗi phản hồi phải nêu tên class và cung cấp tọa độ ở định dạng mà code có thể phân tích. Các model này không trả về điểm confidence, nên Platform ẩn các thiết lập confidence và IoU khi một model như vậy được chọn. Bảng xếp hạng VLM so sánh độ chính xác khi các model này phát hiện đối tượng trong dataset thực tế, xếp hạng bounding box của từng model theo thứ tự được liệt kê.
Định dạng nghiêm ngặt có thể làm giảm độ chính xác trong các tác vụ suy luận. Trong Let Me Speak Freely?, Zhi Rui Tam và các đồng nghiệp phát hiện khả năng suy luận của LLM giảm đáng kể khi bị giới hạn định dạng, với các ràng buộc chặt hơn gây ra mức giảm lớn hơn. API của OpenAI tạo các khóa theo thứ tự được liệt kê trong schema, vì vậy một giải pháp phổ biến là đặt trường suy luận văn bản tự do trước trường câu trả lời, để model viết chuỗi suy nghĩ trước khi đưa ra câu trả lời bị ràng buộc.










