Todos los productos
Search
Centro de documentos

Alibaba Cloud Model Studio:Salida estructurada

Última actualización: Oct 19, 2026

Al realizar tareas de extracción de información o generación de datos estructurados, un modelo puede devolver texto adicional (como ```json ) que interrumpe el análisis posterior. Habilitar la salida estructurada garantiza que el modelo devuelva una cadena JSON válida. El modo JSON Schema también le permite un control preciso sobre la estructura y los tipos de salida, lo que elimina la necesidad de validaciones o reintentos adicionales.

Uso

La salida estructurada admite dos modos: JSON Object y JSON Schema.

  • Modo JSON Object: Garantiza que la salida sea una cadena JSON válida, pero no asegura una estructura específica. Uso:

    1. Establezca el parámetroresponse_format: En el cuerpo de la solicitud, establezca response_format en {"type": "json_object"}.
    2. Incluya la palabra clave JSON en su indicación: El mensaje del sistema o del usuario debe contener la palabra "JSON" (sin distinción entre mayúsculas y minúsculas); de lo contrario, la API devuelve: 'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.
  • Modo JSON Schema: Asegura que la salida cumpla con una estructura especificada. Uso: establezca response_format en {"type": "json_schema", "json_schema": {..., "strict": true}}.

    No se requiere la palabra clave JSON en el prompt.

Comparación de características:

Función

Modo JSON Object

Modo JSON Schema

Genera JSON válido

Sí

Sí

Sigue estrictamente el esquema

No

Sí

Modelos compatibles

La mayoría de los modelos Qwen

Solo modelos qwen-plus seleccionados

Configuración de response_format

{"type": "json_object"}

{"type": "json_schema", "json_schema": {..., "strict": true}}

Requisito del prompt

Debe incluir "JSON"

Se recomienda describir explícitamente

Caso de uso

Salida JSON flexible

Validación precisa del esquema

Modelos admitidos

JSON Object

Qwen

  • Modelos de generación de texto
    • Qwen-Max: serie Qwen3.8-Max, serie Qwen3.7-Max
    • Qwen-Max (modo sin pensamiento): serie Qwen3.6-Max, serie Qwen3-Max, serie Qwen-Max
    • Qwen-Plus: serie Qwen3.7-Plus
    • Qwen-Plus (modo sin pensamiento): serie Qwen3.6-Plus, serie Qwen3.5-Plus, serie Qwen-Plus
    • Qwen-Flash: serie Qwen3.8-Flash, serie Qwen3.7-Flash
    • Qwen-Flash (modo sin pensamiento): serie Qwen3.6-Flash, serie Qwen3.5-Flash, serie Qwen-Flash
    • Qwen-Turbo (modo sin razonamiento): serie Qwen-Turbo
    • Qwen-Coder: serie Qwen3-Coder
    • Qwen-Long: serie Qwen-Long
    • Serie de código abierto Qwen3.8
    • Serie de código abierto Qwen3.6 (modo sin razonamiento)
    • Serie de código abierto Qwen3.5 (modo sin razonamiento)
    • Serie de código abierto Qwen3 (modo sin razonamiento)
    • Serie de código abierto Qwen3-Coder
    • Serie de código abierto Qwen2.5 (excluyendo modelos de matemáticas y codificación)
  • Modelos multimodales
    • Qwen-VL (modo sin pensamiento): serie Qwen3-VL-Plus, serie Qwen3-VL-Flash, serie Qwen-VL-Max (excluyendo las versiones más recientes y las instantáneas), serie Qwen-VL-Plus (excluyendo las versiones más recientes y las instantáneas)
    • Qwen-Omni: series Qwen3.8-Omni-Flash, Qwen3.5-Omni-Plus
    • Serie de código abierto Qwen3-VL (modo sin razonamiento)

NotaLos modelos etiquetados como "modo sin pensamiento" también aceptan response_format establecido en {"type": "json_object"} en modo de pensamiento sin generar errores, pero algunos pueden devolver contenido que no es estrictamente un JSON válido; si necesita un JSON válidamente confiable, consulte las preguntas frecuentes.

Kimi

kimi-k3

GLM

  • glm-5.1
  • Modo sin razonamiento: glm-5

DeepSeek

deepseek-v4-pro, deepseek-v4.1-flash-1017

JSON Schema

Modelos de las series Qwen3.7-Plus, Qwen3.7-Flash, Qwen3.7-Max, Qwen3.8-Max y Qwen3.8-Flash.

Próximamente más modelos.

Introducción

Este ejemplo extrae información estructurada de un perfil personal.

El modo JSON Object no garantiza nombres de clave ni tipos de campo estables. Los resultados pueden variar entre diferentes indicaciones o llamadas. Para imponer una estructura fija, utilice el modo JSON Schema.

Obtenga una clave de API y exporte la clave de API como variable de entorno. Si utiliza el SDK de OpenAI o el SDK de DashScope para realizar llamadas, instale el SDK.

Compatible con OpenAI

Python

from openai import OpenAI
import os

client = OpenAI(
    # API keys differ by region. If you haven't configured an environment variable, replace the next line with: api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use Beijing region models, replace base_url with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {
            "role": "system",
            "content": "Extract the user's name and age, and return them in JSON format"
        },
        {
            "role": "user",
            "content": "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling",
        },
    ],
    response_format={"type": "json_object"}
)

json_string = completion.choices[0].message.content
print(json_string)

Respuesta

{
  "Name": "Alex Brown",
  "Age": 34
}

Node.js

import OpenAI from "openai";

const openai = new OpenAI({
    // If you haven't configured an environment variable, replace the next line with: apiKey: "sk-xxx"
    apiKey: process.env.DASHSCOPE_API_KEY,
    // For Beijing region models, replace baseURL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
    baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
});

const completion = await openai.chat.completions.create({
    model: "qwen3.8-max",
    messages: [
        {
            role: "system",
            content: "Extract the user's name and age, and return them in JSON format"
        },
        {
            role: "user",
            content: "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling"
        }
    ],
    response_format: {
        type: "json_object"
    }
});

const jsonString = completion.choices[0].message.content;
console.log(jsonString);

Respuesta

{
  "name": "Alex Brown",
  "age": 34
}

curl

# ======= Important =======
# API keys differ by region. To obtain an API key, visit: https://www.alibabacloud.com/help/model-studio/get-api-key
# If you use a model in the Beijing region, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/chat/completions
# === Delete this comment before execution ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3.8-max",
    "messages": [
        {
            "role": "system",
            "content": "You need to extract the name (string), age (string), and email (string). Output the result as a JSON string. Do not include any other irrelevant content.\nExamples:\nQ: My name is Alice, I am 25 years old, and my email is alice@example.com\nA: {\"name\":\"Alice\",\"age\":\"25 years old\",\"email\":\"alice@example.com\"}\nQ: My name is Bob, I am 30 years old, and my email is bob@example.com\nA: {\"name\":\"Bob\",\"age\":\"30 years old\",\"email\":\"bob@example.com\"}\nQ: My name is Charlie, my email is charlie@example.com, and I am 40 years old\nA: {\"name\":\"Charlie\",\"age\":\"40 years old\",\"email\":\"charlie@example.com\"}"
        },
        {
            "role": "user",
            "content": "Hello everyone, my name is Alex Brown, I am 34 years old, and my email is alexbrown@example.com"
        }
    ],
    "response_format": {
        "type": "json_object"
    }
}'

Respuesta

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "{\"name\":\"Alex Brown\",\"age\":\"34 years old\"}"
            },
            "finish_reason": "stop",
            "index": 0,
            "logprobs": null
        }
    ],
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 207,
        "completion_tokens": 20,
        "total_tokens": 227,
        "prompt_tokens_details": {
            "cached_tokens": 0
        }
    },
    "created": 1756455080,
    "system_fingerprint": null,
    "model": "qwen3.8-max",
    "id": "chatcmpl-624b665b-fb93-99e7-9ebd-bb6d86d314d2"
}

DashScope

Python

import os
import dashscope
# For Beijing region models, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'

messages=[
    {
        "role": "system",
        "content": "Extract the user's name and age, and return them in JSON format"
    },
    {
        "role": "user",
        "content": "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling",
    },
]
response = dashscope.MultiModalConversation.call(
    # If you haven't configured an environment variable, replace the next line with: api_key="sk-xxx" (Alibaba Cloud Model Studio API key),
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model="qwen3.8-max",
    messages=messages,
    response_format={'type': 'json_object'}
    )
json_string = response.output.choices[0].message.content[0]["text"]
print(json_string)

Respuesta

{
  "name": "Alex Brown",
  "age": 34
}

Java

La versión del SDK de Java de DashScope debe ser 2.21.4 o superior.

import java.util.Arrays;
import java.util.Collections;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.common.ResponseFormat;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    // To use models in the China (Beijing) region, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1
    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("text", "Extract the user's name and age, and return them in JSON format"))).build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("text", "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling"))).build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // If you have not configured an environment variable, replace the following line with: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen3.8-max")
                .messages(Arrays.asList(systemMessage, userMessage))
                .responseFormat(jsonMode)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }
    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
    }
}

Respuesta

{
  "name": "Alex Brown",
  "age": 34
}

curl

# ======= Important notes =======
# For Beijing region models, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
# API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# === Delete this comment before running ===

curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3.8-max",
    "input": {
        "messages": [
            {
                "role": "system",
                "content": "Extract the user'\''s name and age, and return them in JSON format"
            },
            {
                "role": "user",
                "content": "Hi everyone, my name is Alex Brown, I'\''m 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling"
            }
        ]
    },
    "parameters": {
        "response_format": {
            "type": "json_object"
        }
    }
}'

Respuesta

{
  "name": "Alex Brown",
  "age": 34
}

Procesamiento de datos de imagen y video

Los modelos multimodales también admiten salida estructurada para imágenes y videos. Utilice el modo JSON para extraer datos estructurados de contenido visual, como valores de campos de recibos, ubicaciones de objetos en imágenes o eventos en video.

Para conocer los límites de archivos de imagen y video, consulte Comprensión de imágenes y videos .

Compatible con OpenAI

Python

import os
from openai import OpenAI

client = OpenAI(
    # API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # For Beijing region models, replace base_url with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
)

completion = client.chat.completions.create(
    model="qwen3-vl-plus",
    messages=[
        {
            "role": "system",
            "content": [{"type": "text", "text": "You are a helpful assistant."}],
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"
                    },
                },
                {"type": "text", "text": "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"},
            ],
        },
    ],
    response_format={"type": "json_object"}
)
json_string = completion.choices[0].message.content
print(json_string)

Respuesta

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "stream",
      "seat_num": "371",
      "arrival_site": "Development Zone",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

Node.js

import OpenAI from "openai";

const openai = new OpenAI({
  // API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
  // If you haven't configured an environment variable, replace the next line with: apiKey: "sk-xxx" (Model Studio API key)
  apiKey: process.env.DASHSCOPE_API_KEY,
  // For Beijing region models, replace base_url with https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
  baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
});

async function main() {
  const response = await openai.chat.completions.create({
    model: "qwen3-vl-plus",
    messages: [{
        role: "system",
        content: [{
          type: "text",
          text: "You are a helpful assistant."
        }]
      },
      {
        role: "user",
        content: [{
            type: "image_url",
            image_url: {
              "url": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"
            }
          },
          {
            type: "text",
            text: "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"
          }
        ]
      }
    ],
    response_format: {type: "json_object"}
  });
  console.log(response.choices[0].message.content);
}

main()

Respuesta

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "stream",
      "seat_num": "371",
      "arrival_site": "Development Zone",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

curl

# ======= Important notes =======
# For Beijing region models, replace base_url with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/chat/completions
# API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# === Delete this comment before running ===

curl --location 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
  "model": "qwen3-vl-plus",
  "messages": [
  {"role":"system",
  "content":[
    {"type": "text", "text": "You are a helpful assistant."}]},
  {
    "role": "user",
    "content": [
      {"type": "image_url", "image_url": {"url": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"}},
      {"type": "text", "text": "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"}
    ]
  }],
  "response_format":{"type": "json_object"}
}'

Respuesta

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "stream",
      "seat_num": "371",
      "arrival_site": "Development Zone",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

DashScope

Python

import os
import dashscope

# For Beijing region models, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'

messages = [
{
    "role": "system",
    "content": [
    {"text": "You are a helpful assistant."}]
},
{
    "role": "user",
    "content": [
    {"image": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"},
    {"text": "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"}]
}]
response = dashscope.MultiModalConversation.call(
    # If you haven't configured an environment variable, replace the next line with: api_key ="sk-xxx" (Model Studio API key)
    api_key = os.getenv('DASHSCOPE_API_KEY'),
    model = 'qwen3-vl-plus',
    messages = messages,
    response_format={'type': 'json_object'}
)
json_string = response.output.choices[0].message.content[0]["text"]
print(json_string)

Respuesta

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "Liushui",
      "seat_num": "371",
      "arrival_site": "Development Zone",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

Java

// DashScope Java SDK version must be 2.21.4 or higher

import java.util.Arrays;
import java.util.Collections;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.common.ResponseFormat;
import com.alibaba.dashscope.utils.Constants;

public class Main {

    // For Beijing region models, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1
    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("text", "You are a helpful assistant."))).build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("image", "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"),
                        Collections.singletonMap("text", "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"))).build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // If you haven't configured an environment variable, replace the next line with: .apiKey("sk-xxx") (Model Studio API key)
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen3-vl-plus")
                .messages(Arrays.asList(systemMessage, userMessage))
                .responseFormat(jsonMode)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }
    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
    }
}

Respuesta

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "stream",
      "seat_num": "371",
      "arrival_site": "Development Zone",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

curl

# ======= Important notes =======
# For Beijing region models, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
# API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
# === Delete this comment before running ===

curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
    "model": "qwen3-vl-plus",
    "input": {
        "messages": [
            {
                "role": "system",
                "content": [
                    {
                        "text": "You are a helpful assistant."
                    }
                ]
            },
            {
                "role": "user",
                "content": [
                    {
                        "image": "http://duguang-labelling.oss-cn-shanghai.aliyuncs.com/demo_ocr/receipt_zh_demo.jpg"
                    },
                    {
                        "text": "Extract ticket (array type, including travel_date, trains, seat_num, arrival_site, price) and invoice information (array type, including invoice_code and invoice_number) from the image. Output a JSON containing both ticket and invoice arrays"
                    }
                ]
            }
        ]
    },
    "parameters": {
        "response_format": {
            "type": "json_object"
        }
    }
}'

Respuesta

{
  "output": {
    "choices": [
      {
        "message": {
          "content": [
            {
              "text": "{\n  \"ticket\": [\n    {\n      \"travel_date\": \"2013-06-29\",\n      \"trains\": \"train number\",\n      \"seat_num\": \"371\",\n      \"arrival_site\": \"Development Zone\",\n      \"price\": \"8.00\"\n    }\n  ],\n  \"invoice\": [\n    {\n      \"invoice_code\": \"221021325353\",\n      \"invoice_number\": \"10283819\"\n    }\n  ]\n}"
            }
          ],
          "role": "assistant"
        },
        "finish_reason": "stop"
      }
    ]
  },
  "usage": {
    "total_tokens": 598,
    "input_tokens_details": {
      "image_tokens": 418,
      "text_tokens": 68
    },
    "output_tokens": 112,
    "input_tokens": 486,
    "output_tokens_details": {
      "text_tokens": 112
    },
    "image_tokens": 418
  },
  "request_id": "b129dce1-0d5d-4772-b8b5-bd3a1d5cde63"
}

Optimizar prompts

Indicaciones ambiguas como "devolver información del usuario" conducen a estructuras de salida impredecibles. Para obtener resultados confiables, describa el esquema esperado en su indicación: especifique nombres de campos, tipos, estado obligatorio u opcional, restricciones de formato (como el formato de fecha) e incluya ejemplos.

Compatible con OpenAI

Python

from openai import OpenAI
import os
import json
import textwrap  # Handles indentation for multi-line strings to improve code readability

# Predefined example responses to show the model the expected output format
# Example 1: Complete response with all fields
example1_response = json.dumps(
    {
        "info": {"name": "Alice", "age": "25 years old", "email": "alice@example.com"},
        "hobby": ["singing"]
    },
    ensure_ascii=False
)
# Example 2: Response with multiple hobbies
example2_response = json.dumps(
    {
        "info": {"name": "Bob", "age": "30 years old", "email": "bob@example.com"},
        "hobby": ["dancing", "swimming"]
    },
    ensure_ascii=False
)
# Example 3: Response without hobby field (hobby is optional)
example3_response = json.dumps(
    {
        "info": {"name": "Dave", "age": "28 years old", "email": "dave@example.com"}
    },
    ensure_ascii=False
)
# Example 4: Another response without hobby field
example4_response = json.dumps(
    {
        "info": {"name": "Sun Qi", "age": "35 years old", "email": "sunqi@example.com"}
    },
    ensure_ascii=False
)

# Initialize the OpenAI client
client = OpenAI(
    # If you haven't configured an environment variable, replace the next line with: api_key="sk-xxx"
    # API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # This is the Beijing region base_url. If you use Singapore region models, replace base_url with: https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1
    base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)

# dedent removes common leading whitespace from each line, allowing the string to be indented nicely in code without including extra spaces at runtime
system_prompt = textwrap.dedent(f"""\
    Extract personal information from the user input and output it in the specified JSON Schema format:

    [Output format requirements]
    The output must strictly follow this JSON structure:
    {{
      "info": {{
        "name": "string type, required field, user's name",
        "age": "string type, required field, format 'number years old', e.g., '25 years old'",
        "email": "string type, required field, standard email format, e.g., 'user@example.com'"
      }},
      "hobby": ["string array type, optional field, contains all user hobbies; omit entirely if not mentioned"]
    }}

    [Field extraction rules]
    1. name: Identify the user's name from the text, must extract
    2. age: Identify age information, convert to 'number years old' format, must extract
    3. email: Identify email address, keep original format, must extract
    4. hobby: Identify user hobbies, output as string array; omit hobby field entirely if hobbies are not mentioned

    [Reference examples]
    Example 1 (with hobby):
    Q: My name is Alice, I'm 25 years old, my email is alice@example.com, and my hobby is singing
    A: {example1_response}

    Example 2 (with multiple hobbies):
    Q: My name is Bob, I'm 30 years old, my email is bob@example.com, and I enjoy dancing and swimming
    A: {example2_response}

    Example 3 (without hobby):
    Q: My name is Dave, I'm 28 years old, and my email is dave@example.com
    A: {example3_response}

    Example 4 (without hobby):
    Q: I'm Sun Qi, 35 years old, and my email is sunqi@example.com
    A: {example4_response}

    Extract information and output JSON strictly according to the above format and rules. Do not include the hobby field if the user doesn't mention hobbies.\
""")

# Call the model API for information extraction
completion = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {
            "role": "system",
            "content": system_prompt
        },
        {
            "role": "user",
            "content": "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling",
        },
    ],
    response_format={"type": "json_object"},  # Specify JSON format return
)

# Extract and print the model-generated JSON result
json_string = completion.choices[0].message.content
print(json_string)

Respuesta

{
  "info": {
    "name": "Alex Brown",
    "age": "34 years old",
    "email": "alexbrown@example.com"
  },
  "hobby": ["Basketball", "Traveling"]
}

Node.js

import OpenAI from "openai";

// Predefined example responses (to show the model the expected output format)
// Example 1: Complete response with all fields
const example1Response = JSON.stringify({
    info: { name: "Alice", age: "25 years old", email: "alice@example.com" },
    hobby: ["singing"]
}, null, 2);

// Example 2: Response with multiple hobbies
const example2Response = JSON.stringify({
    info: { name: "Bob", age: "30 years old", email: "bob@example.com" },
    hobby: ["dancing", "swimming"]
}, null, 2);

// Example 3: Response without hobby field (hobby is optional)
const example3Response = JSON.stringify({
    info: { name: "Dave", age: "28 years old", email: "dave@example.com" }
}, null, 2);

// Example 4: Another response without hobby field
const example4Response = JSON.stringify({
    info: { name: "Sun Qi", age: "35 years old", email: "sunqi@example.com" }
}, null, 2);

// Initialize OpenAI client configuration
const openai = new OpenAI({
    // If you haven't configured an environment variable, replace the next line with: apiKey: "sk-xxx" (Alibaba Cloud Model Studio API key),
    // API keys differ by region. Get an API key: https://www.alibabacloud.com/help/model-studio/get-api-key
    apiKey: process.env.DASHSCOPE_API_KEY,
    // This is the Beijing region base_url. If you use Singapore region models, replace base_url with: https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1
    baseURL: "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
});

// Create chat completion request using structured prompts to improve output accuracy
const completion = await openai.chat.completions.create({
    model: "qwen3.8-max",
    messages: [
        {
            role: "system",
            content: `Extract personal information from the user input and output it in the specified JSON Schema format:

[Output format requirements]
The output must strictly follow this JSON structure:
{
  "info": {
    "name": "string type, required field, user's name",
    "age": "string type, required field, format 'number years old', e.g., '25 years old'",
    "email": "string type, required field, standard email format, e.g., 'user@example.com'"
  },
  "hobby": ["string array type, optional field, contains all user hobbies; omit entirely if not mentioned"]
}

[Field extraction rules]
1. name: Identify the user's name from the text, must extract
2. age: Identify age information, convert to 'number years old' format, must extract
3. email: Identify email address, keep original format, must extract
4. hobby: Identify user hobbies, output as string array; omit hobby field entirely if hobbies are not mentioned

[Reference examples]
Example 1 (with hobby):
Q: My name is Alice, I'm 25 years old, my email is alice@example.com, and my hobby is singing
A: ${example1Response}

Example 2 (with multiple hobbies):
Q: My name is Bob, I'm 30 years old, my email is bob@example.com, and I enjoy dancing and swimming
A: ${example2Response}

Example 3 (without hobby):
Q: My name is Dave, I'm 28 years old, and my email is dave@example.com
A: ${example3Response}

Example 4 (without hobby):
Q: I'm Sun Qi, 35 years old, and my email is sunqi@example.com
A: ${example4Response}

Extract information and output JSON strictly according to the above format and rules. Do not include the hobby field if the user doesn't mention hobbies.`
        },
        {
            role: "user",
            content: "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling"
        }
    ],
    response_format: {
        type: "json_object"
    }
});

// Extract and print the model-generated JSON result
const jsonString = completion.choices[0].message.content;
console.log(jsonString);

Respuesta

{
  "info": {
    "name": "Alex Brown",
    "age": "34 years old",
    "email": "alexbrown@example.com"
  },
  "hobby": [
    "playing basketball",
    "traveling"
  ]
}

DashScope

Python

import os
import json
import dashscope

# If you use Singapore region models, uncomment the following line
# dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"

# Predefined example responses (to show the model the expected output format)
example1_response = json.dumps(
    {
        "info": {"name": "Alice", "age": "25 years old", "email": "alice@example.com"},
        "hobby": ["singing"]
    },
    ensure_ascii=False
)
example2_response = json.dumps(
    {
        "info": {"name": "Bob", "age": "30 years old", "email": "bob@example.com"},
        "hobby": ["dancing", "swimming"]
    },
    ensure_ascii=False
)
example3_response = json.dumps(
    {
        "info": {"name": "Charlie", "age": "40 years old", "email": "charlie@example.com"},
        "hobby": ["Rap", "basketball"]
    },
    ensure_ascii=False
)

messages=[
        {
            "role": "system",
            "content": f"""Extract personal information from the user input and output it in the specified JSON Schema format:

[Output format requirements]
The output must strictly follow this JSON structure:
{{
  "info": {{
    "name": "string type, required field, user's name",
    "age": "string type, required field, format 'number years old', e.g., '25 years old'",
    "email": "string type, required field, standard email format, e.g., 'user@example.com'"
  }},
  "hobby": ["string array type, optional field, contains all user hobbies; omit entirely if not mentioned"]
}}

[Field extraction rules]
1. name: Identify the user's name from the text, must extract
2. age: Identify age information, convert to 'number years old' format, must extract
3. email: Identify email address, keep original format, must extract
4. hobby: Identify user hobbies, output as string array; omit hobby field entirely if hobbies are not mentioned

[Reference examples]
Example 1 (with hobby):
Q: My name is Alice, I'm 25 years old, my email is alice@example.com, and my hobby is singing
A: {example1_response}

Example 2 (with multiple hobbies):
Q: My name is Bob, I'm 30 years old, my email is bob@example.com, and I enjoy dancing and swimming
A: {example2_response}

Example 3 (with multiple hobbies):
Q: My email is charlie@example.com, I'm 40 years old, my name is Charlie, and I can Rap and play basketball
A: {example3_response}

Extract information and output JSON strictly according to the above format and rules. Do not include the hobby field if the user doesn't mention hobbies."""
        },
        {
            "role": "user",
            "content": "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling",
        },
    ]
response = dashscope.MultiModalConversation.call(
    # If you haven't configured an environment variable, replace the next line with: api_key="sk-xxx" (Alibaba Cloud Model Studio API key),
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model="qwen3.8-max",
    messages=messages,
    response_format={'type': 'json_object'}
    )
json_string = response.output.choices[0].message.content[0]["text"]
print(json_string)

Respuesta

{
  "info": {
    "name": "Alex Brown",
    "age": "34 years old",
    "email": "alexbrown@example.com"
  },
  "hobby": [
    "playing basketball",
    "traveling"
  ]
}

Java

import java.util.Arrays;
import java.util.Collections;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.common.ResponseFormat;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    // To use models in the China (Beijing) region, replace the URL with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1
    static {
        Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
    }
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("text", """
                Extract personal information from the user input and output it in the specified JSON Schema format:

[Output Format Requirements]
The output must strictly follow the JSON structure below:
{
  "info": {
    "name": "String type, required field, user's name",
    "age": "String type, required field, in the format of 'Number years old', for example, '25 years old'",
    "email": "String type, required field, standard email format, for example, 'user@example.com'"
  },
  "hobby": ["String array type, optional field, contains all of the user's hobbies. If no hobbies are mentioned, do not include this field in the output."]
}

[Field Extraction Rules]
1. name: Identify the user's name from the text. This is a required field.
2. age: Identify the age information and transform it into the 'Number years old' format. This is a required field.
3. email: Identify the email address and keep its original format. This is a required field.
4. hobby: Identify the user's hobbies and output them as a string array. If no hobbies are mentioned, completely omit the hobby field.

[Examples]
Example 1 (with a hobby):
Q: My name is Alice, I am 25 years old, my email is alice@example.com, and my hobby is singing.
A: {"info":{"name":"Alice","age":"25 years old","email":"alice@example.com"},"hobby":["singing"]}

Example 2 (with multiple hobbies):
Q: My name is Bob, I am 30 years old, my email is bob@example.com, and I like dancing and swimming.
A: {"info":{"name":"Bob","age":"30 years old","email":"bob@example.com"},"hobby":["dancing","swimming"]}

Example 3 (without hobbies):
Q: My name is Charlie, my email is charlie@example.com, and I am 40 years old.
A: {"info":{"name":"Charlie","age":"40 years old","email":"charlie@example.com"}}"""))).build();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("text", "Hello everyone, my name is Alex Brown, I am 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling."))).build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // If you have not configured an environment variable, replace the following line with: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen3.8-max")
                .messages(Arrays.asList(systemMessage, userMessage))
                .responseFormat(jsonMode)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
    }
    public static void main(String[] args) {
        try {
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
    }
}

Respuesta

{
  "info": {
    "name": "Alex Brown",
    "age": "34 years old",
    "email": "alexbrown@example.com"
  },
  "hobby": [
    "Playing basketball",
    "Traveling"
  ]
}

Obtención de salida estructurada

Establecer response_format type en json_object devuelve una cadena JSON válida, pero es posible que la estructura no coincida con sus expectativas; adecuado para escenarios simples. Para el análisis automatizado, la interoperabilidad de API y otros escenarios complejos que requieren restricciones de tipo estrictas, establezca type en json_schema para forzar al modelo a generar contenido que se ajuste estrictamente a un formato especificado. El formato de response_format y ejemplo:

NotaLas entradas multimodales (imagen, video, audio, etc.) no admiten json_schema y recurrirán automáticamente a json_object; las restricciones del esquema no surtirán efecto.

{
  "type": "json_schema",
  "json_schema": {
    "name": "schema_name",       // Name of the schema
    "strict": true,              // Recommended: strictly follow the format
    "schema": {
      "type": "object",
      "properties": {...},       // Define field structure (see example on right)
      "required": [...],         // List of required fields
      "additionalProperties": false  // Recommended: only output defined fields
    }
  }
}
{
  "type": "json_schema",
  "json_schema": {
    "name": "user_info",
    "strict": true,
    "schema": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "User name"
        },
        "age": {
          "type": "integer",
          "description": "User age"
        },
        "email": {
          "type": "string",
          "description": "Email address"
        }
      },
      "required": ["name", "age"],
      "additionalProperties": false
    }
  }
}

El ejemplo anterior obliga al modelo a generar un objeto JSON con dos campos obligatorios (name y age) y un campo opcional email.

Los modelos de la región de Singapore aún no son compatibles.

Cómo usar

Con el método parse del SDK de OpenAI, puede pasar directamente una clase Pydantic de Python o un objeto Zod de Node.js. El SDK lo convierte automáticamente a un JSON Schema, sin necesidad de escribir JSON complejo manualmente. Para el SDK de DashScope, construya el JSON Schema manualmente siguiendo el formato anterior.

Compatible con OpenAI

Python

from pydantic import BaseModel, Field
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following URL is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
)

class UserInfo(BaseModel):
    name: str = Field(description="User name")
    age: int = Field(description="User age in years")

completion = client.chat.completions.parse(
    model="qwen3.8-max",
    messages=[
        {"role": "system", "content": "Extract name and age information."},
        {"role": "user", "content": "My name is Liu Wu, I'm 25 years old."},
    ],
    response_format=UserInfo,
)

result = completion.choices[0].message.parsed
print(f"Name: {result.name}, Age: {result.age}")

Node.js

import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";

const openai = new OpenAI(
    {
        apiKey: process.env.DASHSCOPE_API_KEY,
        // The following URL is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. URLs vary by region.
        baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
    }
);

const UserInfo = z.object({
  name: z.string().describe("User name"),
  age: z.number().int().describe("User age in years"),
});

const completion = await openai.chat.completions.parse({
  model: "qwen3.8-max",
  messages: [
    { role: "system", content: "Extract name and age information." },
    { role: "user", content: "My name is Liu Wu, I'm 25 years old." },
  ],
  response_format: zodResponseFormat(UserInfo, "user_info"),
});

const userInfo = completion.choices[0].message.parsed;
console.log(`Name: ${userInfo.name}`);
console.log(`Age: ${userInfo.age}`);

Ejecutar el código produce la siguiente salida:

Name: Liu Wu, Age: 25

DashScope

El SDK de Java aún no es compatible.

Python

import os
import dashscope
import json

# The following URL is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. URLs vary by region.
dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"

messages = [
    {
        "role": "user",
        "content": [{"text": "My name is Liu Wu, I'm 25 years old."}],
    },
]
response = dashscope.MultiModalConversation.call(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="qwen3.8-max",
    messages=messages,
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "user_info",
            "strict": True,
            "schema": {
                "properties": {
                    "name": {"title": "Name", "type": "string"},
                    "age": {"title": "Age", "type": "integer"},
                },
                "required": ["name", "age"],
                "title": "UserInfo",
                "type": "object",
            },
        },
    },
)
json_object = json.loads(response.output.choices[0].message.content[0]["text"])
print(f"Name: {json_object['name']}, Age: {json_object['age']}")

Ejecutar el código produce la siguiente salida:

Name: Liu Wu, Age: 25

Guía de configuración

Siga estas directrices al utilizar JSON Schema para obtener una salida estructurada más confiable:

  • Declaración de campos obligatorios

    Se recomienda listar los campos obligatorios en el arreglo required. Los campos opcionales pueden omitirse, por ejemplo:

{
  "properties": {
    "name": {"type": "string"},
    "age": {"type": "integer"},
    "email": {"type": "string"}
  },
  "required": ["name", "age"]
}

Si la entrada no proporciona información de correo electrónico, la salida no contendrá este campo.

  • Implementación de campos opcionales

    Además de omitirlo de required, también puede permitir el tipo null:

{
  "properties": {
    "name": {"type": "string"},
    "email": {"type": ["string", "null"]}  // Can be string or null
  },
  "required": ["name", "email"]  // Both in required
}

La salida siempre incluirá el campo email, pero su valor puede ser null.

  • Configuración de additionalProperties

    Controla si se permiten campos adicionales no definidos en el esquema:

{
  "properties": {"name": {"type": "string"}},
  "required": ["name"],
  "additionalProperties": true  // Allow extra fields
}

Entrada de ejemplo: "I'm Zhang San, 25 years old"; salida: {"name": "Zhang San", "age": 25} (incluye el campo age no definido).

Valor

Comportamiento

Caso de uso

false

Solo generar campos definidos

Control preciso de la estructura

true

Permitir campos adicionales

Capturar más información

  • Palabras clave de JSON Schema admitidas

    A continuación se listan las palabras clave admitidas por el modo JSON Schema (modo estricto). Las palabras clave marcadas como "no admitidas" devuelven un error 400 al enviarse. Para consultar las definiciones completas de las palabras clave, véase la especificación de JSON Schema.

    Palabras clave comunes a nivel de esquema

    Palabra clave

    Descripción

    type

    Admite string, number, integer, boolean, null, array, object; también se admiten tipos de unión como ["string", "null"]

    enum / const

    enum restringe el valor a un conjunto de valores permitidos; const lo restringe a un único valor fijo

    $defs + $ref

    Se admiten referencias locales (por ejemplo, #/$defs/address); las referencias URL externas no causan errores, pero no tienen efecto

    anyOf / oneOf / allOf / not

    Se admiten restricciones de composición y condicionales. Tenga en cuenta que oneOf no garantiza estrictamente la semántica de exactamente uno

    if / then / else

    Se admiten esquemas condicionales, lo que permite reglas de validación dinámicas basadas en valores de campo

    title / description / default / examples

    Aceptados como sugerencias semánticas para el modelo; no se aplican como restricciones estrictas

    $schema / $id / $comment

    Identificadores de metadatos; aceptados sin afectar el comportamiento de validación

    deprecated / readOnly / writeOnly

    Palabras clave de anotación; aceptadas sin afectar el comportamiento de validación

    Palabras clave específicas de tipo

    Tipo

    Palabras clave admitidas

    Palabras clave no admitidas (error 400)

    string

    minLength, maxLength, pattern, format (por ejemplo, email, date), contentMediaType, contentEncoding

    -

    number / integer

    minimum, maximum, exclusiveMinimum, exclusiveMaximum

    multipleOf

    array

    items, prefixItems (modo tupla), minItems, maxItems, unevaluatedItems

    uniqueItems, contains, minContains, maxContains, additionalItems

    object

    properties, required, additionalProperties, minProperties, maxProperties, dependentRequired, dependentSchemas, unevaluatedProperties

    patternProperties, propertyNames

Puesta en marcha

  • Validar antes de pasar a procesos posteriores

    Al utilizar el modo JSON Object, valide la salida antes de pasarla a servicios posteriores. Utilice una biblioteca como jsonschema (Python), Ajv (JavaScript) o Everit (Java) para asegurarse de que cumple con el JSON Schema esperado, evitando fallos de análisis posteriores, pérdida de datos o interrupciones en la lógica de negocio debido a campos faltantes, errores de tipo o formatos mal formados. En caso de fallo, reintente la solicitud o utilice un modelo para reescribir la salida.

  • No configure max_tokens

    No configure max_tokens cuando la salida estructurada esté habilitada. Este parámetro limita el número de tokens de salida y su valor predeterminado es el máximo del modelo. Configurarlo puede truncar la cadena JSON a mitad de la generación, produciendo un JSON no válido que falla al analizarse.

  • Utilizar el SDK para generar esquemas

    Utilice el SDK para generar esquemas automáticamente. Esto evita errores derivados del mantenimiento manual y proporciona validación y análisis automáticos.

    from pydantic import BaseModel, Field
    from typing import Optional
    from openai import OpenAI
    import os
    
    client = OpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        # The following URL is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. URLs vary by region.
        base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
    )
    class UserInfo(BaseModel):
        name: str = Field(description="User name")
        age: int = Field(description="User age")
        email: Optional[str] = None  # Optional field
    
    completion = client.chat.completions.parse(
        model="qwen3.8-max",
        messages=[
            {"role": "system", "content": "Extract name and age information."},
            {"role": "user", "content": "My name is Liu Wu, I'm 25 years old."},
        ],
        response_format=UserInfo  # Pass the Pydantic model directly
    )
    
    result = completion.choices[0].message.parsed  # Type-safe parsed result
    print(f"Name: {result.name}, Age: {result.age}")
    
    import { z } from "zod";
    import { zodResponseFormat } from "openai/helpers/zod";
    import OpenAI from "openai";
    
    const client = new OpenAI(
        {
            apiKey: process.env.DASHSCOPE_API_KEY,
            // The following URL is for the Singapore region. Replace {WorkspaceId} with your actual Workspace ID. URLs vary by region.
            baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
        }
    );
    
    const UserInfo = z.object({
      name: z.string().describe("User name"),
      age: z.number().int().describe("User age"),
      email: z.string().optional().nullable()  // Optional field
    });
    
    const completion = await client.chat.completions.parse({
      model: "qwen3.8-max",
      messages: [
        { role: "system", content: "Extract name and age information." },
        { role: "user", content: "My name is Liu Wu, I'm 25 years old." },
      ],
      response_format: zodResponseFormat(UserInfo, "user_info")
    });
    
    console.log(completion.choices[0].message.parsed);
    

FAQ

P: ¿Cómo produce el modelo en modo de pensamiento de Qwen una salida estructurada?

Los modelos etiquetados como "modo sin pensamiento" devuelven contenido que no es una cadena JSON estrictamente válida en modo de pensamiento; puede utilizar el siguiente enfoque de dos pasos para solucionarlo: primero llame al modelo de pensamiento para obtener una salida de alta calidad, luego pase cualquier JSON mal formado a través de un modelo que admita el modo JSON para corregirlo.

  1. Obtener salida del modelo en modo razonamiento

    Llame al modelo en modo de pensamiento. Es posible que el resultado no sea un JSON válido.

    Nota: establecer el parámetro response_format en {"type": "json_object"} cuando el modo de pensamiento está habilitado no causa un error. El siguiente es un ejemplo de respaldo que omite intencionalmente response_format; utilícelo solo para corregir casos en los que la salida de un modelo no es un JSON válido.

completion = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {"role": "system", "content": system_prompt},
        {
            "role": "user",
            "content": "Hi everyone, my name is Alex Brown, I'm 34 years old, my email is alexbrown@example.com, and I enjoy playing basketball and traveling",
        },
    ],
    # Enable thinking mode; this fallback example omits the response_format parameter (setting it directly does not cause an error)
    extra_body={"enable_thinking": True},
    # Streaming output is required in thinking mode
    stream=True
)
# Extract and print the model-generated JSON result
json_string = ""
for chunk in completion:
    if not chunk.choices:
        continue
    if chunk.choices[0].delta.content is not None:
        json_string += chunk.choices[0].delta.content
  1. Validar y corregir la salida

    Intente analizar el json_string del paso anterior:

    • Si el modelo devolvió un JSON válido, analícelo y utilícelo directamente.
    • Si el modelo devolvió un JSON no válido, llame a un modelo que admita salida estructurada (un modelo rápido y de bajo costo como qwen-flash en modo sin pensamiento funciona bien) para corregir el formato.
import json
from openai import OpenAI
import os

# Initialize the OpenAI client (if the client variable isn't defined in the previous code block, uncomment the lines below)
# client = OpenAI(
#     api_key=os.getenv("DASHSCOPE_API_KEY"),
#     base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
# )

try:
    json_object_from_thinking_model = json.loads(json_string)
    print("Generated standard JSON string")
except json.JSONDecodeError:
    print("Did not generate standard JSON string; fixing with a model that supports structured output")
    completion = client.chat.completions.create(
        model="qwen-flash",
        # Use non-thinking mode
        extra_body={"enable_thinking": False},
        messages=[
            {
                "role": "system",
                "content": "You are a JSON format expert. Fix the user's JSON string to standard format",
            },
            {
                "role": "user",
                "content": json_string,
            },
        ],
        response_format={"type": "json_object"},
    )
    json_object_from_thinking_model = json.loads(completion.choices[0].message.content)

Códigos de error

Si la llamada al modelo falla y devuelve un mensaje de error, consulte Códigos de error para su resolución.