Todos os produtos
Search
Central de documentação

Alibaba Cloud Model Studio:Saída estruturada

Última atualização: Nov 05, 2026

Ao executar tarefas de extração de informações ou geração de dados estruturados, um modelo pode retornar texto extra (como json ) que interrompe a análise posterior. Ativar a saída estruturada garante que o modelo retorne uma string JSON válida. O modo JSON Schema também oferece controle preciso sobre a estrutura e os tipos da saída, eliminando a necessidade de validações extras ou novas tentativas.

Uso

A saída estruturada suporta dois modos: JSON Object e JSON Schema.

  • Modo JSON Object: Garante que a saída seja uma string JSON válida, mas não assegura uma estrutura específica. Uso:

    1. Defina o parâmetroresponse_format: No corpo da solicitação, defina response_format como {"type": "json_object"}.
    2. Inclua a palavra-chave JSON no prompt: A mensagem do sistema ou do usuário deve conter a palavra "JSON" (sem distinção entre maiúsculas e minúsculas). Caso contrário, a API retorna: 'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.
  • Modo JSON Schema: Assegura que a saída esteja em conformidade com uma estrutura especificada. Uso: defina response_format como {"type": "json_schema", "json_schema": {..., "strict": true}}.

    Não é necessária a palavra-chave JSON no prompt.

Os parâmetros acima se aplicam à API Chat Completions. Se você usar a API Responses, defina text.format; o formato do valor é o mesmo. Consulte os exemplos abaixo. No modo JSON Object, a API Responses também exige que o prompt contenha a palavra "JSON"; caso contrário, um erro 400 é retornado.

Comparação de recursos:

Recurso

Modo JSON Object

Modo JSON Schema

Gera JSON válido

Sim

Sim

Segue estritamente o schema

Não

Sim

Modelos suportados

Maioria dos modelos Qwen

Apenas modelos qwen-plus selecionados

Configuração de response_format

{"type": "json_object"}

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

Requisito do prompt

Deve incluir "JSON"

Recomenda-se descrever explicitamente

Caso de uso

Saída JSON flexível

Validação precisa de schema

Modelos suportados

ObservaçãoOs modelos rotulados como "modo sem raciocínio" oferecem suporte a saída estruturada apenas no modo sem raciocínio.

JSON Object

Qwen

  • Modelos de geração de texto
    • Qwen-Max: séries Qwen3.8-Max, Qwen3.7-Max
    • Qwen-Max (modo sem raciocínio): séries Qwen3.6-Max, Qwen3-Max, Qwen-Max
    • Qwen-Plus: série Qwen3.7-Plus
    • Qwen-Plus (modo sem raciocínio): séries Qwen3.6-Plus, Qwen3.5-Plus, Qwen-Plus
    • Qwen-Flash: séries Qwen3.8-Flash, Qwen3.7-Flash
    • Qwen-Flash (modo sem raciocínio): séries Qwen3.6-Flash, Qwen3.5-Flash, Qwen-Flash
    • Qwen-Turbo (modo sem raciocínio): série Qwen-Turbo
    • Qwen-Coder: série Qwen3-Coder
    • Qwen-Long: série Qwen-Long
    • Série open-source Qwen3.8
    • Série open-source Qwen3.6 (modo sem raciocínio)
    • Série open-source Qwen3.5 (modo sem raciocínio)
    • Série open-source Qwen3 (modo sem raciocínio)
    • Série open-source Qwen3-Coder
    • Série open-source Qwen2.5 (excluindo modelos math e coder)
  • Modelos multimodais
    • Qwen-VL (modo sem raciocínio): séries Qwen3-VL-Plus, Qwen3-VL-Flash, Qwen-VL-Max (excluindo as versões mais recentes e snapshot), Qwen-VL-Plus (excluindo as versões mais recentes e snapshot)
    • Qwen-Omni: série Qwen3.5-Omni-Plus
    • Série open-source Qwen3-VL (modo sem raciocínio)

Kimi

  • Implantado no Alibaba Cloud Model Studio

    • kimi-k3.1-pro, kimi-k3
  • Implantado pela Moonshot AI

    • kimi/kimi-k3, kimi/kimi-k2.7-code-highspeed, kimi/kimi-k2.7-code, kimi/kimi-k2.6, kimi/kimi-k2.5

DeepSeek

  • Implantado no Alibaba Cloud Model Studio

    • deepseek-v4-pro
    • deepseek-v4.1-flash
    • deepseek-v4.1-flash-1017
  • Implantado pela Kuaishou Wanqing

    • vanchin/deepseek-v3.2-think, vanchin/deepseek-v3, vanchin/deepseek-ocr

GLM

  • glm-5.1
  • Modo sem raciocínio: glm-5

Stepfun

Modo de raciocínio híbrido: stepfun/step-3.7-flash

Qwen

  • Modelos de geração de texto
    • Qwen-Max: séries Qwen3.8-Max, Qwen3.7-Max
    • Qwen-Max (modo sem raciocínio): séries Qwen3.6-Max, Qwen3-Max, Qwen-Max
    • Qwen-Plus: série Qwen3.7-Plus
    • Qwen-Plus (modo sem raciocínio): séries Qwen3.6-Plus, Qwen3.5-Plus, Qwen-Plus
    • Qwen-Flash: séries Qwen3.8-Flash, Qwen3.7-Flash
    • Qwen-Flash (modo sem raciocínio): séries Qwen3.6-Flash, Qwen3.5-Flash, Qwen-Flash
    • Qwen-Turbo (modo sem raciocínio): série Qwen-Turbo
    • Qwen-Coder: série Qwen3-Coder
    • Qwen-Long: série Qwen-Long
    • Série open-source Qwen3.8
    • Série open-source Qwen3.6 (modo sem raciocínio)
    • Série open-source Qwen3.5 (modo sem raciocínio)
    • Série open-source Qwen3 (modo sem raciocínio)
    • Série open-source Qwen3-Coder
    • Série open-source Qwen2.5 (excluindo modelos math e coder)
  • Modelos multimodais
    • Qwen-VL (modo sem raciocínio): séries Qwen3-VL-Plus, Qwen3-VL-Flash, Qwen-VL-Max (excluindo as versões mais recentes e snapshot), Qwen-VL-Plus (excluindo as versões mais recentes e snapshot)
    • Qwen-Omni: série Qwen3.5-Omni-Plus
    • Série open-source Qwen3-VL (modo sem raciocínio)

Kimi

kimi-k3

GLM

  • glm-5.1
  • Modo sem raciocínio: glm-5

DeepSeek

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

JSON Schema

Modelos das séries Qwen3.7-Plus, Qwen3.7-Flash, Qwen3.7-Max e Qwen3.8-Max.

Mais modelos em breve.

Primeiros passos

Este exemplo extrai informações estruturadas de um perfil pessoal.

O modo JSON Object não garante nomes de chaves ou tipos de campos estáveis. Os resultados podem variar entre diferentes prompts ou chamadas. Para impor uma estrutura fixa, use o modo JSON Schema.

Obtain an API key e export the API key as an environment variable. Se você usar o OpenAI SDK ou DashScope SDK para fazer chamadas, install the SDK.

OpenAI-compatible Chat Completions API

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)

Resposta

{
  "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);

Resposta

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

curl

# ======= Important =======
# API keys differ by region. To obtain an API key, visit: https://www.alibabacloud.com/help/en/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"
    }
}'

Resposta

{
    "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"
}

OpenAI-Compatible Responses API

A API Responses é a evolução da API Chat Completions. A saída estruturada é configurada com o parâmetro text.format. Para obter detalhes sobre os parâmetros e o guia de migração, consulte Responses compatível com OpenAI.

Python

from openai import OpenAI
import os

client = OpenAI(
    # As chaves de API variam por região. Se você não configurou uma variável de ambiente, substitua a linha seguinte por: api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # Se você usar modelos da região de Pequim, substitua base_url por: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

response = client.responses.create(
    model="qwen3.8-max",
    input="Olá a todos, meu nome é Alex Brown, tenho 34 anos, meu e-mail é alexbrown@example.com e gosto de jogar basquete e viajar. Extraia o nome e a idade do usuário e retorne-os em formato JSON.",
    text={"format": {"type": "json_object"}},
)

print(response.output_text)

Resposta

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

Node.js

import OpenAI from "openai";

const openai = new OpenAI({
    // Se você não configurou uma variável de ambiente, substitua a linha seguinte por: apiKey: "sk-xxx"
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
});

const response = await openai.responses.create({
    model: "qwen3.8-max",
    input: "Olá a todos, meu nome é Alex Brown, tenho 34 anos, meu e-mail é alexbrown@example.com e gosto de jogar basquete e viajar. Extraia o nome e a idade do usuário e retorne-os em formato JSON.",
    text: { format: { type: "json_object" } }
});

console.log(response.output_text);

Resposta

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

curl

curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/responses \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3.8-max",
    "input": "Olá a todos, meu nome é Alex Brown, tenho 34 anos, meu e-mail é alexbrown@example.com e gosto de jogar basquete e viajar. Extraia o nome e a idade do usuário e retorne-os em formato JSON.",
    "text": {
        "format": {
            "type": "json_object"
        }
    }
}'

Resposta

{
    "id": "resp_3b59521f-fbef-9873-9c54-c3fdc94da946",
    "created_at": 1793277220,
    "model": "qwen3.8-max",
    "object": "response",
    "output": [
        {
            "id": "reasoning_3a4a1e6d-2a2f-4c3f-a3ea-0f0a5c1b9f11",
            "summary": [
                {
                    "text": "We need answer user request. Need output JSON only.",
                    "type": "summary_text"
                }
            ],
            "type": "reasoning"
        },
        {
            "id": "msg_acbe8467-497c-4c09-8584-dae4a1c97f9b",
            "content": [
                {
                    "annotations": [],
                    "text": "{\"name\": \"Alex Brown\", \"age\": 34}",
                    "type": "output_text",
                    "logprobs": null
                }
            ],
            "role": "assistant",
            "status": "completed",
            "type": "message"
        }
    ],
    "status": "completed",
    "text": {
        "format": {
            "type": "json_object"
        },
        "verbosity": null
    },
    "usage": {
        "input_tokens": 123,
        "output_tokens": 118,
        "output_tokens_details": {
            "reasoning_tokens": 95
        },
        "total_tokens": 241
    }
}

DashScope

Python

import os
import dashscope

# A configuração abaixo refere-se à região Singapura. Substitua {WorkspaceId} pelo ID real do seu workspace. O valor de region varia conforme a região.
# Para modelos da região China (Pequim), substitua region por: cn-beijing
client = dashscope.Client(
    # Se você não tiver configurado uma variável de ambiente, substitua a linha a seguir por: api_key="sk-xxx" (API Key do Model Studio da Alibaba Cloud),
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

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 = client.multimodal.chat.create(
    model="qwen3.8-max",
    messages=messages,
    response_format={'type': 'json_object'}
    )
json_string = response.choices[0].message.content
print(json_string)

Resposta

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

Java

A versão do DashScope Java SDK deve ser 2.21.4 ou 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());
        }
    }
}

Resposta

{
  "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/en/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"
        }
    }
}'

Resposta

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

Processamento de dados de imagem e vídeo

Modelos multimodais também suportam saída estruturada para imagens e vídeos. Use o modo JSON para extrair dados estruturados de conteúdo visual, como valores de campos de recibos, localizações de objetos em imagens ou eventos em vídeo.

Para limites de arquivos de imagem e vídeo, consulte Image and video understanding .

OpenAI compatible

Python

import os
from openai import OpenAI

client = OpenAI(
    # API keys differ by region. Get an API key: https://www.alibabacloud.com/help/en/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)

Resposta

{
  "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/en/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()

Resposta

{
  "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/en/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"}
}'

Resposta

{
  "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

# A configuração abaixo refere-se à região Singapura. Substitua {WorkspaceId} pelo ID real do seu workspace. O valor de region varia conforme a região.
# Para modelos da região China (Pequim), substitua region por: cn-beijing
client = dashscope.Client(
    # Se você não tiver configurado uma variável de ambiente, substitua a linha a seguir por: api_key="sk-xxx" (API Key do Model Studio)
    api_key = os.getenv('DASHSCOPE_API_KEY'),
    workspace = "{WorkspaceId}",
    region = "ap-southeast-1",
)

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 = client.multimodal.chat.create(
    model = 'qwen3-vl-plus',
    messages = messages,
    response_format={'type': 'json_object'}
)
json_string = response.choices[0].message.content
print(json_string)

Resposta

{
  "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());
        }
    }
}

Resposta

{
  "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/en/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"
        }
    }
}'

Resposta

{
  "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"
}

Otimize os prompts

Prompts ambíguos como "retornar informações do usuário" levam a estruturas de saída imprevisíveis. Para obter resultados confiáveis, descreva o schema esperado no seu prompt: especifique nomes de campos, tipos, status obrigatório versus opcional, restrições de formato (como formato de data) e inclua exemplos.

OpenAI compatible

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/en/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)

Resposta

{
  "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/en/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);

Resposta

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

DashScope

Python

import os
import json
import dashscope

# A configuração abaixo refere-se à região Singapura. Substitua {WorkspaceId} pelo ID real do seu workspace. O valor de region varia conforme a região.
# Para modelos da região China (Pequim), substitua region por: cn-beijing
client = dashscope.Client(
    # Se você não tiver configurado uma variável de ambiente, substitua a linha a seguir por: api_key="sk-xxx" (API Key do Model Studio da Alibaba Cloud),
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

# Respostas de exemplo predefinidas (para mostrar ao modelo o formato de saída esperado)
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 = client.multimodal.chat.create(
    model="qwen3.8-max",
    messages=messages,
    response_format={'type': 'json_object'}
    )
json_string = response.choices[0].message.content
print(json_string)

Resposta

{
  "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());
        }
    }
}

Resposta

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

Obtendo saída estruturada

Definir o type de response_format como json_object retorna uma string JSON válida, mas a estrutura pode não corresponder às suas expectativas — adequado para cenários simples. Para análise automatizada, interoperabilidade de API e outros cenários complexos que exigem restrições rigorosas de tipo, defina type como json_schema para forçar o modelo a gerar conteúdo estritamente em conformidade com um formato especificado. Formato e exemplo de response_format:

{
  "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
        }
      }
    }

O exemplo acima força o modelo a gerar um objeto JSON com dois campos obrigatórios (name e age) e um campo opcional email.

Modelos da região Singapore ainda não são suportados.

Como usar

Com o método parse do OpenAI SDK, você pode passar diretamente uma classe Pydantic do Python ou um objeto Zod do Node.js. O SDK converte automaticamente para um JSON Schema — sem necessidade de escrever JSON complexo manualmente. Para o DashScope SDK, construa o JSON Schema manualmente seguindo o formato acima.

OpenAI-compatible Chat Completions API

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}`);

Executar o código produz a seguinte saída:

Name: Liu Wu, Age: 25

OpenAI-Compatible Responses API

A API Responses configura a saída estruturada com o parâmetro text.format, que aceita os tipos json_schema e json_object. O método parse do SDK da OpenAI também funciona: passe uma classe Pydantic ou um objeto Zod para text_format.

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

client = OpenAI(
    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"
)

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

response = client.responses.parse(
    model="qwen3.8-max",
    input="My name is Liu Wu, I'm 25 years old.",
    text_format=UserInfo,
)

result = response.output_parsed
print(f"Name: {result.name}, Age: {result.age}")

Executar o código produz a seguinte saída:

Name: Liu Wu, Age: 25

Para obter detalhes sobre os parâmetros, consulte o parâmetro text da API Responses.

DashScope

Java SDK ainda não é suportado.

Python

import os
import dashscope
import json

# A configuração abaixo refere-se à região Singapura. Substitua {WorkspaceId} pelo ID real do seu workspace. O valor de region varia conforme a região.
client = dashscope.Client(
    # Se a variável de ambiente não estiver configurada, substitua a linha a seguir por: api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
)

messages = [
    {
        "role": "user",
        "content": [{"text": "My name is Liu Wu, I'm 25 years old."}],
    },
]
response = client.multimodal.chat.create(
    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.choices[0].message.content)
print(f"Name: {json_object['name']}, Age: {json_object['age']}")

Executar o código produz a seguinte saída:

Name: Liu Wu, Age: 25

Guia de configuração

Siga estas diretrizes ao usar JSON Schema para obter uma saída estruturada mais confiável:

  • Declaração de campo obrigatório

    Recomenda-se listar os campos obrigatórios no array required. Campos opcionais podem ser omitidos, por exemplo:

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

Se a entrada não fornecer informações de e-mail, a saída não conterá este campo.

  • Implementando campos opcionais

    Além de omitir do required, você também pode permitir o tipo null:

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

A saída sempre incluirá o campo email, mas seu valor pode ser null.

  • Configuração de additionalProperties

    Controla se deve permitir campos extras não definidos no schema:

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

Exemplo de entrada: "I'm Zhang San, 25 years old"; saída: {"name": "Zhang San", "age": 25} (inclui o campo age não definido).

Valor

Comportamento

Caso de uso

false

Gera apenas campos definidos

Controle preciso da estrutura

true

Permite campos extras

Capturar mais informações

  • Tipos de dados suportados: string, number, integer, boolean, object, array, enum.

Indo para produção

  • Valide antes de passar para serviços downstream

    Ao usar o modo JSON Object, valide a saída antes de passá-la para serviços downstream. Use uma biblioteca como jsonschema (Python), Ajv (JavaScript) ou Everit (Java) para garantir que ela esteja em conformidade com o JSON Schema esperado, evitando falhas de análise downstream, perda de dados ou interrupções na lógica de negócios devido a campos ausentes, erros de tipo ou formatos malformados. Em caso de falha, tente novamente a solicitação ou use um modelo para reescrever a saída.

  • Não defina max_tokens

    Não defina max_tokens quando a saída estruturada estiver ativada. Este parâmetro limita o número de tokens de saída e tem como padrão o máximo do modelo. Defini-lo pode truncar a string JSON no meio da geração, produzindo um JSON inválido que falha na análise.

  • Use o SDK para gerar schemas

    Utilize o SDK para gerar schemas automaticamente. Isso evita erros de manutenção manual e fornece validação e análise automáticas.

    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);
    

Códigos de erro

Se a chamada do modelo falhar e retornar uma mensagem de erro, consulte Error codes para resolução.