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:
- Establezca el parámetro
response_format: En el cuerpo de la solicitud, establezcaresponse_formaten{"type": "json_object"}. - 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'.
- Establezca el parámetro
-
Modo JSON Schema: Asegura que la salida cumpla con una estructura especificada. Uso: establezca
response_formaten{"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 |
|
|
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 tiponull:
{
"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 |
|---|---|---|
| Solo generar campos definidos | Control preciso de la estructura |
| 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
typeAdmite
string,number,integer,boolean,null,array,object; también se admiten tipos de unión como["string", "null"]enum/constenumrestringe el valor a un conjunto de valores permitidos;constlo restringe a un único valor fijo$defs+$refSe admiten referencias locales (por ejemplo,
#/$defs/address); las referencias URL externas no causan errores, pero no tienen efectoanyOf/oneOf/allOf/notSe admiten restricciones de composición y condicionales. Tenga en cuenta que
oneOfno garantiza estrictamente la semántica de exactamente unoif/then/elseSe admiten esquemas condicionales, lo que permite reglas de validación dinámicas basadas en valores de campo
title/description/default/examplesAceptados como sugerencias semánticas para el modelo; no se aplican como restricciones estrictas
$schema/$id/$commentIdentificadores de metadatos; aceptados sin afectar el comportamiento de validación
deprecated/readOnly/writeOnlyPalabras 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)
stringminLength,maxLength,pattern,format(por ejemplo,email,date),contentMediaType,contentEncoding-
number/integerminimum,maximum,exclusiveMinimum,exclusiveMaximummultipleOfarrayitems,prefixItems(modo tupla),minItems,maxItems,unevaluatedItemsuniqueItems,contains,minContains,maxContains,additionalItemsobjectproperties,required,additionalProperties,minProperties,maxProperties,dependentRequired,dependentSchemas,unevaluatedPropertiespatternProperties,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_tokenscuando 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.
-
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_formaten{"type": "json_object"}cuando el modo de pensamiento está habilitado no causa un error. El siguiente es un ejemplo de respaldo que omite intencionalmenteresponse_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
-
Validar y corregir la salida
Intente analizar el
json_stringdel 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.