JSON Mode

执行信息抽取或结构化数据生成任务时,大模型可能返回多余文本(如 ```json)导致下游解析失败。开启结构化输出可确保大模型输出标准格式的 JSON 字符串。

使用方式

  1. 设置response_format参数:在请求体中,将 response_format 参数设置为 {"type": "json_object"}

  2. 提示词包含"JSON"关键词:System Message 或 User Message 中需要包含 "JSON" 关键词(不区分大小写),否则会报错:'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.

支持的模型

通义千问

  • 文本生成模型

    • 通义千问Max 系列:qwen3-max、qwen3-max-2025-09-23、qwen3-max-preview(非思考模式)、qwen-max、qwen-max-latest、qwen-max-2024-09-19 及之后的快照模型

    • 通义千问Plus 系列(非思考模式):qwen-plus、qwen-plus-latest、qwen-plus-2024-09-19及之后的快照模型

    • 通义千问Flash 系列(非思考模式):qwen-flash、qwen-flash-2025-07-28及之后的快照模型

    • 通义千问Turbo 系列(非思考模式):qwen-turbo、qwen-turbo-latest、qwen-turbo-2024-09-19及之后的快照模型

    • 通义千问Coder 系列:qwen3-coder-plus、qwen3-coder-plus-2025-07-22、qwen3-coder-flash、qwen3-coder-flash-2025-07-28

    • 通义千问Long 系列:qwen-long、qwen-long-latest、qwen-long-2025-01-25

  • 文本生成开源模型

    • Qwen3(非思考模式)

    • Qwen3-Coder

    • Qwen2.5 系列的文本模型(不含mathcoder模型)

  • 多模态模型

    • 通义千问3-VL-Plus 系列(非思考模式):qwen3-vl-plus、qwen3-vl-plus-2025-09-23及之后的快照模型

    • 通义千问3-VL-Flash 系列(非思考模式):qwen3-vl-flash、qwen3-vl-flash-2025-10-15及之后的快照模型

    • 通义千问VL-Max 系列:qwen-vl-max(不包括最新版与快照版模型)

    • 通义千问VL-Plus 系列:qwen-vl-plus(不包括最新版与快照版模型)

  • 多模态开源模型

    • Qwen3-VL(非思考模式)

GLM

  • glm-4.6

  • glm-4.5

  • glm-4.5-air

说明

思考模式的模型暂不支持结构化输出功能。

模型的上下文、价格、快照版本等信息请参见模型列表

快速开始

以从个人简介中抽取信息的简单场景为例,介绍快速使用结构化输出的方法。

您需要已获取API Key配置API Key到环境变量。如果通过OpenAI SDKDashScope SDK进行调用,还需要安装SDK

OpenAI兼容

Python

from openai import OpenAI
import os

client = OpenAI(
    # 如果没有配置环境变量,请用API Key将下行替换为:api_key="sk-xxx"
    # 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen-flash",
    messages=[
        {
            "role": "system",
            "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
        },
        {
            "role": "user",
            "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
        },
    ],
    response_format={"type": "json_object"}
)

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

返回结果

{
  "姓名": "刘五",
  "年龄": 34
}

Node.js

import OpenAI from "openai";

const openai = new OpenAI({
    // 如果没有配置环境变量,请用API Key将下行替换为:apiKey: "sk-xxx"
    // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    apiKey: process.env.DASHSCOPE_API_KEY,
    // 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
});

const completion = await openai.chat.completions.create({
    model: "qwen-flash",
    messages: [
        {
            role: "system",
            content: "请抽取用户的姓名与年龄信息,以JSON格式返回"
        },
        {
            role: "user",
            content: "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"
        }
    ],
    response_format: {
        type: "json_object"
    }
});

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

返回结果

{
  "姓名": "刘五",
  "年龄": 34
}

curl

# ======= 重要提示 =======
# 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
# 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions
# === 执行时请删除该注释 ===
curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen-plus",
    "messages": [
        {
            "role": "system",
            "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
        },
        {
            "role": "user", 
            "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com"
        }
    ],
    "response_format": {
        "type": "json_object"
    }
}'

返回结果

{
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "{\"name\":\"刘五\",\"age\":\"34岁\""}"
            },
            "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": "qwen-plus",
    "id": "chatcmpl-624b665b-fb93-99e7-9ebd-bb6d86d314d2"
}

DashScope

Python

import os
import dashscope

# 若使用新加坡地域的模型,请释放下列注释
# dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1"
messages=[
    {
        "role": "system",
        "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
    },
    {
        "role": "user",
        "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
    },
]
response = dashscope.Generation.call(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model="qwen-flash", 
    messages=messages,
    result_format='message',
    response_format={'type': 'json_object'}
    )
json_string = response.output.choices[0].message.content
print(json_string)

返回结果

{
  "姓名": "刘五",
  "年龄": 34
}

Java

DashScope Java SDK 版本需要不低于 2.18.4。

// DashScope Java SDK 版本需要不低于 2.18.4

import java.util.Arrays;
import java.lang.System;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.common.ResponseFormat;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    // 若使用新加坡地域的模型,请释放下列注释
    // static {Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";}
    public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {
        Generation gen = new Generation();
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content("请抽取用户的姓名与年龄信息,以JSON格式返回")
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content("大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游")
                .build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        GenerationParam param = GenerationParam.builder()
                // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-flash")
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .responseFormat(jsonMode)
                .build();
        return gen.call(param);
    }

    public static void main(String[] args) {
        try {
            GenerationResult result = callWithMessage();
            System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent());
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            // 使用日志框架记录异常信息
            System.err.println("An error occurred while calling the generation service: " + e.getMessage());
        }
    }
}

返回结果

{
  "姓名": "刘五",
  "年龄": 34
}

curl

# ======= 重要提示 =======
# 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
# 以下为北京地域url,若使用新加坡地域的模型,需将url替换为:https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# === 执行时请删除该注释 ===
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen-flash",
    "input": {
        "messages": [
            {
                "role": "system",
                "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
            },
            {
                "role": "user", 
                "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"
            }
        ]
    },
    "parameters": {
        "result_format": "message",
        "response_format": {
            "type": "json_object"
        }
    }
}'

返回结果

{
    "output": {
        "choices": [
            {
                "finish_reason": "stop",
                "message": {
                    "role": "assistant",
                    "content": "{\n  \"姓名\": \"刘五\",\n  \"年龄\": 34\n}"
                }
            }
        ]
    },
    "usage": {
        "total_tokens": 72,
        "output_tokens": 18,
        "input_tokens": 54,
        "cached_tokens": 0
    },
    "request_id": "xxx-xxx-xxx-xxx-xxx"
}

图片、视频数据处理

除了文本信息,多模态模型还支持针对图像、视频数据进行结构化输出,实现视觉信息抽取、定位、事件监测等功能。

图片、视频文件限制请参见视觉理解

OpenAI兼容

Python

import os
from openai import OpenAI

client = OpenAI(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    # 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen-vl-max",
    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": "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"},
            ],
        },
    ],
    response_format={"type": "json_object"}
)
json_string = completion.choices[0].message.content
print(json_string)

返回结果

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "流水",
      "seat_num": "371",
      "arrival_site": "开发区",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

Node.js

import OpenAI from "openai";

const openai = new OpenAI({
  // 若没有配置环境变量,请用百炼API Key将下行替换为:apiKey: "sk-xxx"
  // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
  apiKey: process.env.DASHSCOPE_API_KEY,
  // 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
  baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
});

async function main() {
  const response = await openai.chat.completions.create({
    model: "qwen-vl-max",
    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: "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(数组类型,包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"
          }
        ]
      }
    ],
    response_format: {type: "json_object"}
  });
  console.log(response.choices[0].message.content);
}

main()

返回结果

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "流水",
      "seat_num": "371",
      "arrival_site": "开发区",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

curl

# ======= 重要提示 =======
# 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
# 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions
# === 执行时请删除该注释 ===
curl --location 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
  "model": "qwen-vl-max",
  "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": "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(数组类型,包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"}
    ]
  }],
  "response_format":{"type": "json_object"}
}'

返回结果

{
  "choices": [{
    "message": {
      "content": "{\n  \"ticket\": [\n    {\n      \"travel_date\": \"2013-06-29\",\n      \"trains\": \"流水\",\n      \"seat_num\": \"371\",\n      \"arrival_site\": \"开发区\",\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",
    "index": 0,
    "logprobs": null
  }],
  "object": "chat.completion",
  "usage": {
    "prompt_tokens": 486,
    "completion_tokens": 112,
    "total_tokens": 598,
    "prompt_tokens_details": {
      "cached_tokens": 0
    }
  },
  "created": 1755767481,
  "system_fingerprint": null,
  "model": "qwen-vl-max",
  "id": "chatcmpl-33249829-e9f3-9cbc-93e4-0536b3d7d713"
}

DashScope

Python

import os
import dashscope

# 若使用新加坡地域的模型,请释放下列注释
# dashscope.base_http_api_url = "https://dashscope-intl.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": "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(数组类型,包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"}]
}]
response = dashscope.MultiModalConversation.call(
    #若没有配置环境变量, 请用百炼API Key将下行替换为: api_key ="sk-xxx"
    api_key = os.getenv('DASHSCOPE_API_KEY'),
    model = 'qwen-vl-max',
    messages = messages,
    response_format={'type': 'json_object'}
)
json_string = response.output.choices[0].message.content[0]["text"]
print(json_string)

返回结果

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "流水",
      "seat_num": "371",
      "arrival_site": "开发区",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

Java

// DashScope Java SDK 版本需要不低于 2.21.4

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 {
    // 若使用新加坡地域的模型,请释放下列注释
    // static {Constants.baseHttpApiUrl="https://dashscope-intl.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", "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(数组类型,包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"))).build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-vl-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());
        }
    }
}

返回结果

{
  "ticket": [
    {
      "travel_date": "2013-06-29",
      "trains": "流水",
      "seat_num": "371",
      "arrival_site": "开发区",
      "price": "8.00"
    }
  ],
  "invoice": [
    {
      "invoice_code": "221021325353",
      "invoice_number": "10283819"
    }
  ]
}

curl

# ======= 重要提示 =======
# 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
# 以下为北京地域url,若使用新加坡地域的模型,需将url替换为:https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation
# === 执行时请删除该注释 ===
curl -X POST https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
    "model": "qwen-vl-max",
    "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": "提取图中ticket(包括 travel_date、trains、seat_num、arrival_site、price)和 invoice 的信息(数组类型,包括 invoice_code 和 invoice_number ),请输出包含 ticket 和 invoice 数组的JSON"}
                ]
            }
        ]
    },
    "parameters": {
        "response_format": {"type": "json_object"}
    }
}'

返回结果

{
  "output": {
    "choices": [
      {
        "message": {
          "content": [
            {
              "text": "{\n  \"ticket\": [\n    {\n      \"travel_date\": \"2013-06-29\",\n      \"trains\": \"流水\",\n      \"seat_num\": \"371\",\n      \"arrival_site\": \"开发区\",\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"
}

思考模型的结构化输出

启用思考模型的结构化输出功能后,模型会先推理,再生成 JSON。相比非思考模型,输出结果通常更准确。目前该功能仅支持 GLM 系列模型。

OpenAI兼容

Python

示例代码

from openai import OpenAI
import os

# 初始化OpenAI客户端
client = OpenAI(
    # 如果没有配置环境变量,请用阿里云百炼API Key替换:api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

messages=[
    {
        "role": "system",
        "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
    },
    {
        "role": "user",
        "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
    },
]

completion = client.chat.completions.create(
    model="glm-4.6",
    messages=messages,
    extra_body={"enable_thinking": True},
    stream=True,
    stream_options={
        "include_usage": True
    },
    response_format={"type": "json_object"}
)

reasoning_content = ""  # 完整思考过程
answer_content = ""  # 完整回复
is_answering = False  # 是否进入回复阶段
print("\n" + "=" * 20 + "思考过程" + "=" * 20 + "\n")

for chunk in completion:
    if not chunk.choices:
        print("\nUsage:")
        print(chunk.usage)
        continue

    delta = chunk.choices[0].delta

    # 只收集思考内容
    if hasattr(delta, "reasoning_content") and delta.reasoning_content is not None:
        if not is_answering:
            print(delta.reasoning_content, end="", flush=True)
        reasoning_content += delta.reasoning_content

    # 收到content,开始进行回复
    if hasattr(delta, "content") and delta.content:
        if not is_answering:
            print("\n" + "=" * 20 + "完整回复" + "=" * 20 + "\n")
            is_answering = True
        print(delta.content, end="", flush=True)
        answer_content += delta.content

返回结果

====================思考过程====================

1.  **分析用户请求:** 用户希望从给定的文本中“抽取用户的姓名与年龄信息”。输出格式要求为“JSON格式”。

2.  **解析输入文本:**
    *   **文本:** “大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游”
...
    *   键是描述性的(“name”、“age”)吗?是的。
    *   值的类型是适当的吗(姓名用字符串,年龄用数字)?是的。
    *   整体回复清晰且直接回答了用户的请求吗?是的。
====================完整回复====================

{  "姓名": "刘五",
  "年龄": 34
}
Usage:
CompletionUsage(completion_tokens=666, prompt_tokens=43, total_tokens=709, completion_tokens_details=None, prompt_tokens_details=None)

Node.js

示例代码

import OpenAI from "openai";
import process from 'process';

// 初始化 openai 客户端
const openai = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY, // 从环境变量读取
    baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1'
});

let reasoningContent = '';
let answerContent = '';
let isAnswering = false;

async function main() {
    try {
        const messages = [
            {
                "role": "system",
                "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
            },
            {
                "role": "user",
                "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
            },
        ];
        const stream = await openai.chat.completions.create({
            model: 'glm-4.6',
            messages,
            stream: true,
            enable_thinking: true,
            response_format: {type: 'json_object'},
        });
        console.log('\n' + '='.repeat(20) + '思考过程' + '='.repeat(20) + '\n');

        for await (const chunk of stream) {
            if (!chunk.choices?.length) {
                console.log('\nUsage:');
                console.log(chunk.usage);
                continue;
            }

            const delta = chunk.choices[0].delta;
            
            // 只收集思考内容
            if (delta.reasoning_content !== undefined && delta.reasoning_content !== null) {
                if (!isAnswering) {
                    process.stdout.write(delta.reasoning_content);
                }
                reasoningContent += delta.reasoning_content;
            }

            // 收到content,开始进行回复
            if (delta.content !== undefined && delta.content) {
                if (!isAnswering) {
                    console.log('\n' + '='.repeat(20) + '完整回复' + '='.repeat(20) + '\n');
                    isAnswering = true;
                }
                process.stdout.write(delta.content);
                answerContent += delta.content;
            }
        }
    } catch (error) {
        console.error('Error:', error);
    }
}

main();

返回结果

====================思考过程====================

1.  **分析用户请求:**
    *   **核心任务:** 从给定文本中提取特定信息。
    *   **目标信息:** “姓名”和“年龄”。
    *   **输入文本:** “大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游”
    *   **输出格式:** “JSON格式”。

2.  **将输入文本分解为关键信息片段:**
......
    *   我应该以一个干净、不包含额外文本、可直接使用的JSON格式呈现最终答案。除非用户另有说明,否则无需向JSON本身添加对话性填充内容。

这个过程从理解请求、分解输入、提取数据、选择正确的格式和结构,到最终组装,确保了满足用户的所有约束条件。
====================完整回复====================

{  "姓名": "刘五",
  "年龄": 34
}

HTTP

示例代码

curl

curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "glm-4.6",
    "messages": [
    {
            "role": "system",
            "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
        },
        {
            "role": "user", 
            "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"
        }
    ],
    "stream": true,
    "stream_options": {
        "include_usage": true
    },
    "enable_thinking": true,
    "response_format": {
        "type": "json_object"
    }
}'

DashScope

Python

示例代码

import os
from dashscope import Generation
import dashscope 

messages = [
    {
        "role": "system",
        "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
    },
    {"role": "user", "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"}
]

completion = Generation.call(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key = "sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="glm-4.6",
    messages=messages,
    result_format="message",
    enable_thinking=True,
    response_format={"type": "json_object"},
    stream=True,
    incremental_output=True
)

# 定义完整思考过程
reasoning_content = ""
# 定义完整回复
answer_content = ""
# 判断是否结束思考过程并开始回复
is_answering = False

print("=" * 20 + "思考过程" + "=" * 20)

for chunk in completion:
    # 如果思考过程与回复皆为空,则忽略
    if (
        chunk.output.choices[0].message.content == ""
        and chunk.output.choices[0].message.reasoning_content == ""
    ):
        pass
    else:
        # 如果当前为思考过程
        if (
            chunk.output.choices[0].message.reasoning_content != ""
            and chunk.output.choices[0].message.content == ""
        ):
            print(chunk.output.choices[0].message.reasoning_content, end="", flush=True)
            reasoning_content += chunk.output.choices[0].message.reasoning_content
        # 如果当前为回复
        elif chunk.output.choices[0].message.content != "":
            if not is_answering:
                print("\n" + "=" * 20 + "完整回复" + "=" * 20)
                is_answering = True
            print(chunk.output.choices[0].message.content, end="", flush=True)
            answer_content += chunk.output.choices[0].message.content

返回结果

====================思考过程====================
1.  **识别用户目标:**用户希望我从他们的句子中提取特定的信息(姓名和年龄),并以特定的格式(JSON)返回。
...
7.  **最终审查:**
    *   JSON是否包含姓名“刘五”?是的。
    *   JSON是否包含年龄34?是的。
    *   格式是有效的JSON吗?是的。
    *   它是否直接回答了用户的请求?是的。

这个过程很简单,因为它是一个直接的信息提取任务。关键在于解析中文句子以找到模式(“我叫...”,“今年...岁”),然后按照要求正确格式化提取的数据。
====================完整回复====================
{  "姓名": "刘五",
  "年龄": 34
}

Java

示例代码

// dashscope SDK的版本 >= 2.19.4
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import java.lang.System;
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.ResponseFormat;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    private static StringBuilder reasoningContent = new StringBuilder();
    private static StringBuilder finalContent = new StringBuilder();
    private static boolean isFirstPrint = true;

    private static void handleGenerationResult(GenerationResult message) {
        String reasoning = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
        String content = message.getOutput().getChoices().get(0).getMessage().getContent();

        if (!reasoning.isEmpty()) {
            reasoningContent.append(reasoning);
            if (isFirstPrint) {
                System.out.println("====================思考过程====================");
                isFirstPrint = false;
            }
            System.out.print(reasoning);
        }

        if (!content.isEmpty()) {
            finalContent.append(content);
            if (!isFirstPrint) {
                System.out.println("\n====================完整回复====================");
                isFirstPrint = true;
            }
            System.out.print(content);
        }
    }
    private static GenerationParam buildGenerationParam(List<Message> msgs) {
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        return GenerationParam.builder()
                // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("glm-4.6")
                .enableThinking(true)
                .incrementalOutput(true)
                .resultFormat("message")
                .messages(msgs)
                .responseFormat(jsonMode)
                .build();
    }
    public static void streamCallWithMessage(Generation gen, List<Message> msgs)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(msgs);
        Flowable<GenerationResult> result = gen.streamCall(param);
        result.blockingForEach(message -> handleGenerationResult(message));
    }

    public static void main(String[] args) {
        try {
            Generation gen = new Generation();
            Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("请抽取用户的姓名与年龄信息,以JSON格式返回").build();
            Message userMsg = Message.builder().role(Role.USER.getValue()).content("大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游").build();
            List<Message> msgs = Arrays.asList(systemMsg, userMsg);
            streamCallWithMessage(gen, msgs);
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            logger.error("An exception occurred: {}", e.getMessage());
        }
    }
}

返回结果

====================思考过程====================
1.  **分析用户的请求。**
    *   **用户的输入:** "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游" (大家好,我叫刘五,我今年34岁,我的邮箱是 liuwu@example.com,我喜欢打篮球和旅游。)
    *   **核心任务:** "请抽取用户的姓名与年龄信息" (请提取用户的姓名和年龄信息。)
    *   **输出格式:** "以JSON格式返回" (以JSON格式返回)。
...
6.  **审查和优化输出。**
    *   JSON格式正确吗?是的,它有花括号、双引号包裹的键、正确的值(字符串加引号,数字不加)以及键值对之间的逗号。
    *   它是否按要求包含了*仅*姓名和年龄?是的。
    *   摘取的信息是否准确?是的,“刘五”和“34”直接来自用户的文本。
    *   输出可以直接使用。无需额外的解释,除非我想增加一些礼貌性。像“好的,已为您提取信息:”这样的简单短语是很好的客户服务。我们加上这个吧。
    *   最终的响应应该是:
        *   一段简短、礼貌的开场白。
        *   包含在 ```json ... ``` 代码块中的JSON对象,以实现良好的格式化并防止转义问题。

这个思考过程从理解高层级需求,到分析输入、提取特定数据、设计输出格式、构建它,最后再为清晰和正确性进行审查。这是一个系统性的方法,确保准确性并遵循用户指令。
====================完整回复====================
{  "姓名": "刘五",
  "年龄": 34
}

HTTP

示例代码

curl

curl -X POST "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-SSE: enable" \
-d '{
    "model": "glm-4.6",
    "input":{
        "messages":[      
            {
                "role": "system",
                "content": "请抽取用户的姓名与年龄信息,以JSON格式返回"
            },
            {
                "role": "user",
                "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"
            }
        ]
    },
    "parameters":{
        "enable_thinking": true,
        "incremental_output": true,
        "result_format": "message",
        "response_format": {
            "type": "json_object"
        }
    }
}'

优化提示词

模糊的提示词(如“返回用户信息”)会使模型生成非预期结果。建议在提示词中准确描述预期 Schema,包括字段类型、必需性、格式要求(如日期格式),并提供示例。

OpenAI兼容

Python

from openai import OpenAI
import os
import json
import textwrap  # 用于处理多行字符串的缩进,提高代码可读性

# 预定义示例响应,用于向模型展示期望的输出格式
# 示例1:包含所有字段的完整响应
example1_response = json.dumps(
    {
        "info": {"name": "张三", "age": "25岁", "email": "zhangsan@example.com"},
        "hobby": ["唱歌"]
    },
    ensure_ascii=False
)
# 示例2:包含多个hobby的响应
example2_response = json.dumps(
    {
        "info": {"name": "李四", "age": "30岁", "email": "lisi@example.com"},
        "hobby": ["跳舞", "游泳"]
    },
    ensure_ascii=False
)
# 示例3:不包含hobby字段的响应(hobby非必需)
example3_response = json.dumps(
    {
        "info": {"name": "赵六", "age": "28岁", "email": "zhaoliu@example.com"}
    },
    ensure_ascii=False
)
# 示例4:另一个不包含hobby字段的响应
example4_response = json.dumps(
    {
        "info": {"name": "孙七", "age": "35岁", "email": "sunqi@example.com"}
    },
    ensure_ascii=False
)

# 初始化OpenAI客户端
client = OpenAI(
    # 若没有配置环境变量,请将下行替换为:api_key="sk-xxx"
    # 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# dedent的作用是去除每行开头的公共缩进,使字符串在代码中可以美观地缩进,但在运行时不会包含这些额外的空格
system_prompt = textwrap.dedent(f"""\
    请从用户输入中提取个人信息并按照指定的JSON Schema格式输出:

    【输出格式要求】
    输出必须严格遵循以下JSON结构:
    {{
      "info": {{
        "name": "字符串类型,必需字段,用户姓名",
        "age": "字符串类型,必需字段,格式为'数字+岁',例如'25岁'",
        "email": "字符串类型,必需字段,标准邮箱格式,例如'user@example.com'"
      }},
      "hobby": ["字符串数组类型,非必需字段,包含用户的所有爱好,如未提及则完全不输出此字段"]
    }}

    【字段提取规则】
    1. name: 从文本中识别用户姓名,必需提取
    2. age: 识别年龄信息,转换为"数字+岁"格式,必需提取
    3. email: 识别邮箱地址,保持原始格式,必需提取
    4. hobby: 识别用户爱好,以字符串数组形式输出,如未提及爱好信息则完全省略hobby字段

    【参考示例】
    示例1(包含爱好):
    Q:我叫张三,今年25岁,邮箱是zhangsan@example.com,爱好是唱歌
    A:{example1_response}

    示例2(包含多个爱好):
    Q:我叫李四,今年30岁,邮箱是lisi@example.com,平时喜欢跳舞和游泳
    A:{example2_response}

    示例3(不包含爱好):
    Q:我叫赵六,今年28岁,我的邮箱是zhaoliu@example.com
    A:{example3_response}

    示例4(不包含爱好):
    Q:我是孙七,35岁,邮箱sunqi@example.com
    A:{example4_response}

    请严格按照上述格式和规则提取信息并输出JSON。如果用户未提及爱好,则不要在输出中包含hobby字段。\
""")

# 调用大模型API进行信息提取
completion = client.chat.completions.create(
    model="qwen-plus",
    messages=[
        {
            "role": "system",
            "content": system_prompt
        },
        {
            "role": "user",
            "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
        },
    ],
    response_format={"type": "json_object"},  # 指定返回JSON格式
)

# 提取并打印模型生成的JSON结果
json_string = completion.choices[0].message.content
print(json_string)

返回结果

{
  "info": {
    "name": "刘五",
    "age": "34岁",
    "email": "liuwu@example.com"
  },
  "hobby": ["打篮球", "旅游"]  
}

Node.js

import OpenAI from "openai";

// 预定义示例响应(用于向模型展示期望的输出格式)
// 示例1:包含所有字段的完整响应
const example1Response = JSON.stringify({
    info: { name: "张三", age: "25岁", email: "zhangsan@example.com" },
    hobby: ["唱歌"]
}, null, 2);

// 示例2:包含多个hobby的响应
const example2Response = JSON.stringify({
    info: { name: "李四", age: "30岁", email: "lisi@example.com" },
    hobby: ["跳舞", "游泳"]
}, null, 2);

// 示例3:不包含hobby字段的响应(hobby非必需)
const example3Response = JSON.stringify({
    info: { name: "赵六", age: "28岁", email: "zhaoliu@example.com" }
}, null, 2);

// 示例4:另一个不包含hobby字段的响应
const example4Response = JSON.stringify({
    info: { name: "孙七", age: "35岁", email: "sunqi@example.com" }
}, null, 2);

// 初始化OpenAI客户端配置
const openai = new OpenAI({
    // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:apiKey: "sk-xxx",
    // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
    apiKey: process.env.DASHSCOPE_API_KEY,
    // 以下是北京地域base_url,如果使用新加坡地域的模型,需要将base_url替换为:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
});

// 创建聊天完成请求,使用结构化提示词来提高输出准确性
const completion = await openai.chat.completions.create({
    model: "qwen-plus",
    messages: [
        {
            role: "system",
            content: `请从用户输入中提取个人信息并按照指定的JSON Schema格式输出:

【输出格式要求】
输出必须严格遵循以下JSON结构:
{
  "info": {
    "name": "字符串类型,必需字段,用户姓名",
    "age": "字符串类型,必需字段,格式为'数字+岁',例如'25岁'",
    "email": "字符串类型,必需字段,标准邮箱格式,例如'user@example.com'"
  },
  "hobby": ["字符串数组类型,非必需字段,包含用户的所有爱好,如未提及则完全不输出此字段"]
}

【字段提取规则】
1. name: 从文本中识别用户姓名,必需提取
2. age: 识别年龄信息,转换为"数字+岁"格式,必需提取
3. email: 识别邮箱地址,保持原始格式,必需提取
4. hobby: 识别用户爱好,以字符串数组形式输出,如未提及爱好信息则完全省略hobby字段

【参考示例】
示例1(包含爱好):
Q:我叫张三,今年25岁,邮箱是zhangsan@example.com,爱好是唱歌
A:${example1Response}

示例2(包含多个爱好):
Q:我叫李四,今年30岁,邮箱是lisi@example.com,平时喜欢跳舞和游泳
A:${example2Response}

示例3(不包含爱好):
Q:我叫赵六,今年28岁,我的邮箱是zhaoliu@example.com
A:${example3Response}

示例4(不包含爱好):
Q:我是孙七,35岁,邮箱sunqi@example.com
A:${example4Response}

请严格按照上述格式和规则提取信息并输出JSON。如果用户未提及爱好,则不要在输出中包含hobby字段。`
        },
        {
            role: "user",
            content: "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游"
        }
    ],
    response_format: {
        type: "json_object"
    }
});

// 提取并打印模型生成的JSON结果
const jsonString = completion.choices[0].message.content;
console.log(jsonString);

返回结果

{
  "info": {
    "name": "刘五",
    "age": "34岁",
    "email": "liuwu@example.com"
  },
  "hobby": [
    "打篮球",
    "旅游"
  ]
}

DashScope

Python

import os
import json
import dashscope

# 若使用新加坡地域的模型,请释放下列注释
# dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1"

# 预定义示例响应(用于向模型展示期望的输出格式)
example1_response = json.dumps(
    {
        "info": {"name": "张三", "age": "25岁", "email": "zhangsan@example.com"},
        "hobby": ["唱歌"]
    },
    ensure_ascii=False
)
example2_response = json.dumps(
    {
        "info": {"name": "李四", "age": "30岁", "email": "lisi@example.com"},
        "hobby": ["跳舞", "游泳"]
    },
    ensure_ascii=False
)
example3_response = json.dumps(
    {
        "info": {"name": "王五", "age": "40岁", "email": "wangwu@example.com"},
        "hobby": ["Rap", "篮球"]
    },
    ensure_ascii=False
)

messages=[
        {
            "role": "system",
            "content": f"""请从用户输入中提取个人信息并按照指定的JSON Schema格式输出:

【输出格式要求】
输出必须严格遵循以下JSON结构:
{{
  "info": {{
    "name": "字符串类型,必需字段,用户姓名",
    "age": "字符串类型,必需字段,格式为'数字+岁',例如'25岁'",
    "email": "字符串类型,必需字段,标准邮箱格式,例如'user@example.com'"
  }},
  "hobby": ["字符串数组类型,非必需字段,包含用户的所有爱好,如未提及则完全不输出此字段"]
}}

【字段提取规则】
1. name: 从文本中识别用户姓名,必需提取
2. age: 识别年龄信息,转换为"数字+岁"格式,必需提取
3. email: 识别邮箱地址,保持原始格式,必需提取
4. hobby: 识别用户爱好,以字符串数组形式输出,如未提及爱好信息则完全省略hobby字段

【参考示例】
示例1(包含爱好):
Q:我叫张三,今年25岁,邮箱是zhangsan@example.com,爱好是唱歌
A:{example1_response}

示例2(包含多个爱好):
Q:我叫李四,今年30岁,邮箱是lisi@example.com,平时喜欢跳舞和游泳
A:{example2_response}

示例3(包含多个爱好):
Q:我的邮箱是wangwu@example.com,今年40岁,名字是王五,会Rap和打篮球
A:{example3_response}

请严格按照上述格式和规则提取信息并输出JSON。如果用户未提及爱好,则不要在输出中包含hobby字段。"""
        },
        {
            "role": "user",
            "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游", 
        },
    ]
response = dashscope.Generation.call(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model="qwen-plus", 
    messages=messages,
    result_format='message',
    response_format={'type': 'json_object'}
    )
json_string = response.output.choices[0].message.content
print(json_string)

返回结果

{
  "info": {
    "name": "刘五",
    "age": "34岁",
    "email": "liuwu@example.com"
  },
  "hobby": [
    "打篮球",
    "旅游"
  ]
}

Java

import java.util.Arrays;
import java.lang.System;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.common.ResponseFormat;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    // 若使用新加坡地域的模型,请释放下列注释
    // static {Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";}
    public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {
        Generation gen = new Generation();
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content("""
                请从用户输入中提取个人信息并按照指定的JSON Schema格式输出:

【输出格式要求】
输出必须严格遵循以下JSON结构:
{
  "info": {
    "name": "字符串类型,必需字段,用户姓名",
    "age": "字符串类型,必需字段,格式为'数字+岁',例如'25岁'",
    "email": "字符串类型,必需字段,标准邮箱格式,例如'user@example.com'"
  },
  "hobby": ["字符串数组类型,非必需字段,包含用户的所有爱好,如未提及则完全不输出此字段"]
}

【字段提取规则】
1. name: 从文本中识别用户姓名,必需提取
2. age: 识别年龄信息,转换为"数字+岁"格式,必需提取
3. email: 识别邮箱地址,保持原始格式,必需提取
4. hobby: 识别用户爱好,以字符串数组形式输出,如未提及爱好信息则完全省略hobby字段

【参考示例】
示例1(包含爱好):
Q:我叫张三,今年25岁,邮箱是zhangsan@example.com,爱好是唱歌
A:{"info":{"name":"张三","age":"25岁","email":"zhangsan@example.com"},"hobby":["唱歌"]}

示例2(包含多个爱好):
Q:我叫李四,今年30岁,邮箱是lisi@example.com,平时喜欢跳舞和游泳
A:{"info":{"name":"李四","age":"30岁","email":"lisi@example.com"},"hobby":["跳舞","游泳"]}

示例3(不包含爱好):
Q:我叫王五,我的邮箱是wangwu@example.com,今年40岁
A:{"info":{"name":"王五","age":"40岁","email":"wangwu@example.com"}}""")
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content("大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游")
                .build();
        ResponseFormat jsonMode = ResponseFormat.builder().type("json_object").build();
        GenerationParam param = GenerationParam.builder()
                // 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .model("qwen-plus")
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .responseFormat(jsonMode)
                .build();
        return gen.call(param);
    }
    public static void main(String[] args) {
        try {
            GenerationResult result = callWithMessage();
            System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent());
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            // 使用日志框架记录异常信息
            System.err.println("An error occurred while calling the generation service: " + e.getMessage());
        }
    }
}

返回结果

{
  "info": {
    "name": "刘五",
    "age": "34岁",
    "email": "liuwu@example.com"
  },
  "hobby": [
    "打篮球",
    "旅游"
  ]
}

应用于生产环境

  • 有效性校验

    当前暂不支持根据给定的 JSON Schema 生成 JSON 字符串。传递给下游业务前,建议使用工具对其进行有效性校验,如 jsonschema (Python)、Ajv (JavaScript)、Everit (Java)等确保其符合指定的 JSON Schema 要求,避免因字段缺失、类型错误或格式不规范导致下游系统解析失败、数据丢失或业务逻辑中断。失败时可通过重试、大模型改写等策略进行修复。

  • 禁用 max_tokens

    请勿在开启结构化输出时指定 max_tokens(控制模型输出 Token 数的参数,默认值为模型最大输出 Token 数),否则返回的 JSON 字符串可能不完整,导致下游业务解析失败。

常见问题

Q:是否支持根据给定的 JSON Schema 生成数据?

A:暂时无法根据提供的 JSON Schema 生成。建议在提示词中通过自然语言明确描述所需 JSON 的键值结构和数据类型,并提供标准数据样例,可帮助大模型生成符合预期 Schema 的数据。

Q:Qwen 的思考模式模型如何结构化输出?

A:Qwen 的思考模式模型暂不支持结构化输出。如需在思考模式下获取标准 JSON 字符串,可在 JSON 解析失败时引入支持 JSON Mode 的模型进行修复。

  1. 获取思考模式下的输出

    调用思考模式模型获取高质量的输出,但可能不是标准的 JSON 字符串。

    开启思考模式请勿设置response_format参数为{"type": "json_object"},否则会报错。
    completion = client.chat.completions.create(
        model="qwen-plus",
        messages=[
            {"role": "system", "content": system_prompt},
            {
                "role": "user",
                "content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com,平时喜欢打篮球和旅游",
            },
        ],
        # 开启思考模式,请勿设置response_format参数为{"type": "json_object"},否则会报错
        extra_body={"enable_thinking": True},
        # 思考模式下需要开启流式输出
        stream=True
    )
    # 提取并打印模型生成的JSON结果
    json_string = ""
    for chunk in completion:
        if chunk.choices[0].delta.content is not None:
            json_string += chunk.choices[0].delta.content
  2. 校验并修复输出

    尝试解析上一步获取的 json_string

    • 若模型生成了标准格式JSON字符串,可直接解析并返回。

    • 若模型生成非标准格式JSON字符串,可调用支持结构化输出的模型(建议选择速度快、成本低的模型,如非思考模式的qwen-flash)修复格式。

    import json
    
    try:
        json_object_from_thinking_model = json.loads(json_string)
        print("生成标准格式JSON字符串")
    except json.JSONDecodeError:
        print("未生成标准格式JSON字符串,通过支持结构化输出的模型进行修复")
        completion = client.chat.completions.create(
            model="qwen-flash",
            messages=[
                {
                    "role": "system",
                    "content": "你是一个json格式修复专家,请将用户输入的json字符串修复为标准格式",
                },
                {
                    "role": "user",
                    "content": json_string,
                },
            ],
            response_format={"type": "json_object"},
        )
        json_object_from_thinking_model = json.loads(completion.choices[0].message.content)

错误码

如果模型调用失败并返回报错信息,请参见错误信息进行解决。