Ba tháng trước, tôi nhận task nâng cấp pipeline trích xuất thông tin từ hợp đồng pháp lý cho một công ty logistics. Hệ thống cũ chạy GPT-4.1 với prompt thủ công, tỷ lệ parse JSON hỏng là 4,7% — tưởng nhỏ, nhưng khi nhân lên với 50.000 tài liệu/tháng thì thành 2.350 case phải xử lý tay, đốt khoảng 18 giờ kỹ thuật mỗi tuần. Khi chuyển sang GPT-5.5 với Structured Outputs, tôi kỳ vọng đẩy tỷ lệ lỗi xuống dưới 0,1%. Thực tế ban đầu vẫn còn 0,8% — và đó là lúc tôi hiểu: bật response_format mới chỉ là một nửa, cần cả một hệ thống ổn định hóa 4 lớp phía sau.

Bài viết này chia sẻ kiến trúc, code production và benchmark thực chiến tôi đã triển khai, đồng thời so sánh chi phí khi chạy qua gateway HolySheep (đăng ký tại đây) so với gọi trực tiếp. Tất cả số liệu dưới đây lấy từ log production trong 14 ngày liên tục, không phải test bench lý tưởng.

1. Tại sao JSON Mode vẫn "rò rỉ" dù đã bật response_format

Structured Outputs của GPT-5.5 đảm bảo 99,9% output conform schema trong tài liệu kỹ thuật. Nhưng production khác xa tài liệu — "rò rỉ" xảy ra ở 4 điểm tôi đã đo được:

2. Kiến trúc ổn định hóa 4 lớp

Hệ thống tôi xây dựng gồm 4 lớp tách biệt, mỗi lớp có trách nhiệm rõ ràng:

  1. Lớp Schema: validate JSON Schema bằng Pydantic ngay khi khởi tạo, bắt lỗi enum/required trước khi gửi request.
  2. Lớp Pre-validation: ước lượng token đầu vào bằng tiktoken, đặt max_tokens an toàn = 1,6× input + 256.
  3. Lớp Retry có backoff: tối đa 3 lần với exponential + jitter, chỉ retry khi lỗi thuộc nhóm "có thể recover" (timeout, parse fail, schema mismatch).
  4. Lớp Audit: log raw response, schema hash, latency, error code để trace và cải tiến schema liên tục.

3. Code production

3.1. Khai báo schema với Pydantic + Literal enum

from pydantic import BaseModel, Field, ConfigDict
from typing import List, Optional, Literal
import json

class ContractParty(BaseModel):
    model_config = ConfigDict(extra="forbid")
    ten: str = Field(..., min_length=1, max_length=200)
    vai_tro: Literal["ben_a", "ben_b", "ben_khac"]
    mst: Optional[str] = Field(None, pattern=r"^\d{10}(\d{3})?$")

class ContractClause(BaseModel):
    model_config = ConfigDict(extra="forbid")
    loai: Literal["gia_han", "hoa_don", "bao_mat", "vien", "khac"]
    noi_dung: str = Field(..., max_length=2000)
    rui_ro: Literal["thap", "trung_binh", "cao"]

class ContractExtraction(BaseModel):
    model_config = ConfigDict(extra="forbid")
    so_hop_dong: str = Field(..., pattern=r"^HD-\d{4,10}$")
    ngay_ky: str = Field(..., pattern=r"^\d{4}-\d{2}-\d{2}$")
    ben_tham_gia: List[ContractParty] = Field(..., min_length=2)
    dieu_khoan: List[ContractClause]
    tong_gia_tri: float = Field(..., ge=0)
    don_vi_tien: Literal["VND", "USD", "EUR", "JPY"]

SCHEMA = ContractExtraction.model_json_schema()
print(json.dumps(SCHEMA, ensure_ascii=False, indent=2)[:400])

3.2. Client production với retry + audit + token guard

import os, time, json, random, logging
import tiktoken
from openai import OpenAI

client = OpenAI(
    base_url="https://api.holysheep.ai/v1",
    api_key=os.environ["HOLYSHEEP_API_KEY"]
)
log = logging.getLogger("gpt55")
enc = tiktoken.encoding_for_model("gpt-4")

RETRYABLE = (json.JSONDecodeError, TimeoutError, ConnectionError)

def call_structured(prompt: str, schema_model, max_retries=3, base_delay=0.4):
    schema = schema_model.model_json_schema()
    in_tok = len(enc.encode(prompt))
    safe_max = min(4096, max(1024, int(in_tok * 1.6) + 256))
    last_err = None

    for attempt in range(max_retries):
        t0 = time.perf_counter()
        try:
            resp = client.chat.completions.create(
                model="gpt-5.5",
                messages=[
                    {"role": "system", "content": (
                        "Tra ve JSON hop le, khong markdown, "
                        "khon giai thich them."
                    )},
                    {"role": "user", "content": prompt}
                ],
                response_format={
                    "type": "json_schema",
                    "json_schema": {
                        "