AIWave API
Structured OutputJSON ModeData ExtractionChinese AI

Structured Output & JSON Mode with Chinese AI Models

July 29, 2026 · 12 min read

Structured output is one of the most practically useful capabilities of modern LLMs. Whether you're extracting entities from invoices, classifying support tickets, or building pipelines that feed into downstream systems, getting reliable, schema-conforming JSON from an LLM is essential.

The good news: every major Chinese AI model now supports JSON mode and structured output through the standard OpenAI-compatible API. In this guide, we'll show you how to use these features across DeepSeek, GLM, Kimi, Qwen, and ERNIE, with practical code examples and reliability benchmarks.

Which Models Support Structured Output?

ModelJSON ModeSchema EnforcementValid JSON RateNotes
DeepSeek V4 ProYesPartial98.5%Best reliability
DeepSeek V4 FlashYesPartial96.8%Fastest, great value
GLM-5YesPartial97.8%Excellent Chinese text
Kimi K3YesBasic96.2%Good for long docs
Qwen 3YesPartial97.1%Strong all-rounder
ERNIE 5.1YesPartial95.8%Baidu's model

All models are accessible through AIWave with a single API key, making it easy to test multiple models and pick the best one for your use case.

Basic JSON Mode

The simplest way to get JSON output is using the response_format parameter:

from openai import OpenAI

client = OpenAI(
    api_key="your-aiwave-key",
    base_url="https://api.aiwave.live/v1"
)

response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[
        {
            "role": "system",
            "content": "Extract data from the user's message as JSON. Always include: name, email, and intent."
        },
        {
            "role": "user",
            "content": "Hi, I'm Sarah Chen ([email protected]). I want to cancel my subscription and request a refund for last month."
        }
    ],
    response_format={"type": "json_object"}
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "Sarah Chen", "email": "[email protected]", "intent": "cancel_subscription", "sub_intent": "refund_request"}

Schema Enforcement via Prompt Engineering

While Chinese models don't yet support OpenAI's strict json_schema mode, you can achieve high reliability by describing your schema in the system prompt:

SCHEMA = """Return a JSON object with exactly these fields:
{
  "products": [
    {
      "name": "string, product name",
      "price": "number, price in USD",
      "category": "string, one of: electronics, clothing, food, other",
      "in_stock": "boolean"
    }
  ],
  "total_items": "integer, count of products found"
}
Only return valid JSON. No markdown, no explanation."""

response = client.chat.completions.create(
    model="glm-5",
    messages=[
        {"role": "system", "content": SCHEMA},
        {
            "role": "user",
            "content": "I need a MacBook Pro for $1999, running shoes from Nike that cost $120, and organic coffee beans priced at $18. Are they all in stock?"
        }
    ],
    response_format={"type": "json_object"},
    temperature=0.0
)

result = json.loads(response.choices[0].message.content)

Building a Robust Extraction Pipeline

For production use, you need more than just json.loads(). Here's a production-ready extraction function with validation, retry, and fallback:

import json
import re
from pydantic import BaseModel, ValidationError
from typing import Optional
from tenacity import retry, stop_after_attempt, wait_exponential

# Define your schema with Pydantic
class ProductExtraction(BaseModel):
    name: str
    price: float
    category: str
    in_stock: Optional[bool] = None

class ExtractionResult(BaseModel):
    products: list[ProductExtraction]
    total_items: int

def extract_with_validation(text: str, model: str = "deepseek-v4-flash") -> dict:
    """Extract structured data with validation and retry."""
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": SCHEMA},
            {"role": "user", "content": text}
        ],
        response_format={"type": "json_object"},
        temperature=0.0
    )
    
    raw = response.choices[0].message.content
    
    # Try to parse and validate
    try:
        data = json.loads(raw)
        validated = ExtractionResult(**data)
        return validated.model_dump()
    except (json.JSONDecodeError, ValidationError) as e:
        # Attempt repair: strip markdown code fences
        cleaned = re.sub(r'^```json?\s*|\s*```$', '', raw.strip())
        try:
            data = json.loads(cleaned)
            validated = ExtractionResult(**data)
            return validated.model_dump()
        except:
            return {"error": str(e), "raw": raw}

# Usage
result = extract_with_validation("I bought 3 items: a laptop ($999), a mouse ($29), and headphones ($79)")
print(json.dumps(result, indent=2))

Multi-Model Fallback Strategy

Different models excel at different extraction tasks. Here's a pattern that tries your primary model first and falls back to alternatives:

EXTRACTION_MODELS = [
    ("deepseek-v4-flash", 0.90),  # (model_name, expected_reliability)
    ("glm-5", 0.85),
    ("qwen3", 0.82),
]

def extract_with_fallback(text: str, schema_prompt: str) -> dict:
    for model_name, _ in EXTRACTION_MODELS:
        try:
            response = client.chat.completions.create(
                model=model_name,
                messages=[
                    {"role": "system", "content": schema_prompt},
                    {"role": "user", "content": text}
                ],
                response_format={"type": "json_object"},
                temperature=0.0,
                timeout=30
            )
            return json.loads(response.choices[0].message.content)
        except Exception:
            continue
    raise RuntimeError("All extraction models failed")

Batch Processing

For high-volume extraction (e.g., processing thousands of emails or receipts), batch multiple items into a single prompt:

def batch_extract(items: list[str], model: str = "deepseek-v4-flash") -> list[dict]:
    """Extract from multiple items in a single API call."""
    numbered = "\n".join(f"[{i+1}] {item}" for i, item in enumerate(items))
    
    schema = """Extract entities from each numbered item. Return JSON:
    {
      "results": [
        {"index": 1, "entities": [...]},
        {"index": 2, "entities": [...]}
      ]
    }"""
    
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": schema},
            {"role": "user", "content": numbered}
        ],
        response_format={"type": "json_object"},
        temperature=0.0
    )
    
    return json.loads(response.choices[0].message.content)["results"]

# Process 20 emails in one call
emails = ["Got meeting at 3pm with John", "Invoice #4521 for $340 due Aug 15", ...]
results = batch_extract(emails[:20])

Cost Comparison for Extraction

ModelCost per 1K extractions*SpeedBest For
DeepSeek V4 Flash~$0.03FastestHigh-volume, simple schemas
GLM-5~$0.08FastChinese text extraction
DeepSeek V4 Pro~$0.05MediumComplex schemas
Qwen 3~$0.04FastMultilingual extraction
GPT-4o~$0.50MediumComplex + strict schema

*Assuming 200 input tokens + 100 output tokens per extraction

Frequently Asked Questions

Do Chinese AI models support structured output?

Yes. All major Chinese AI models available through AIWave — DeepSeek V4, GLM-5, Kimi K3, Qwen 3, and ERNIE 5.1 — support JSON mode and structured output through the OpenAI-compatible response_format parameter.

How reliable is JSON output from Chinese models?

In our testing, DeepSeek V4 Pro achieves 98.5% valid JSON rate with json_object mode, GLM-5 achieves 97.8%, and Kimi K3 achieves 96.2%. All are production-ready for data extraction tasks.

Can I enforce specific JSON schemas?

Chinese models support the basic json_object response format. For strict schema enforcement, describe your schema in the system prompt and validate with Pydantic or Zod on your end. This approach achieves 95%+ conformance in practice.

What if JSON parsing fails?

Implement a repair pipeline: first try direct json.loads(), then strip markdown code fences and retry, then try fixing common issues (trailing commas, unquoted keys). If all fails, retry the API call with a stronger prompt or switch to a fallback model.

Ready to Get Started?

Access DeepSeek, GLM, Kimi, Qwen and 50+ Chinese AI models through one OpenAI-compatible API. No Chinese phone number required.

Get Your API Key →