执行信息抽取或结构化数据生成任务时,大模型可能返回多余文本(如 ```json
)导致下游解析失败。开启结构化输出可以确保大模型输出标准格式的 JSON 字符串。
支持的模型
通义千问Max 系列: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及之后的快照模型
通义千问Coder 系列:qwen3-coder-plus、qwen3-coder-plus-2025-07-22、qwen3-coder-flash、qwen3-coder-flash-2025-07-28
通义千问VL 系列:qwen-vl-max、qwen-vl-plus(不包括最新版与快照版模型)
通义千问Turbo 系列(非思考模式):qwen-turbo、qwen-turbo-latest、qwen-turbo-2024-09-19及之后的快照模型
Qwen 开源系列
Qwen3(非思考模式)
Qwen3-Coder
Qwen2.5 系列的文本模型(不含math与coder模型)
思考模式的模型暂不支持结构化输出功能。
模型的上下文、价格、快照版本等信息请参见模型列表与价格。
如何使用
前提条件
您需要已获取API Key并配置API Key到环境变量。如果通过OpenAI SDK或DashScope SDK进行调用,还需要安装SDK。
开启方法
开启结构化输出功能需要以下三点:
选择模型:在支持的模型中选择。
文本处理:推荐使用通义千问Plus 系列或通义千问Flash 系列模型。通义千问Plus 系列模型效果、速度、成本均衡;通义千问Flash 系列模型成本低,速度快,性价比较高。
图片、视频数据处理:请选择
qwen-vl-max
或qwen-vl-plus
模型。qwen-vl-max
模型能力强,qwen-vl-plus
模型在效果、成本上比较均衡。
设置参数:设置请求参数
response_format
为{"type": "json_object"}
以启用结构化输出功能。提示词指引:System Message 或 User Message 中需要包含 "JSON" 关键词(不区分大小写),否则会报错:
'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.
快速开始
以从个人简介中抽取信息的简单场景为例,介绍快速使用结构化输出的方法。
OpenAI兼容
Python
from openai import OpenAI
import os
client = OpenAI(
# 如果没有配置环境变量,请用API Key将下行替换为:api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
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"
apiKey: process.env.DASHSCOPE_API_KEY,
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
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": "你需要提取出name(名字,为string类型)、age(年龄,为string类型)与email(邮箱,为string类型),请输出JSON 字符串,不要输出其它无关内容。\n示例:\nQ:我叫张三,今年25岁,邮箱是zhangsan@example.com\nA:{\"name\":\"张三\",\"age\":\"25岁\",\"email\":\"zhangsan@example.com\"}\nQ:我叫李四,今年30岁,我的邮箱是lisi@example.com\nA:{\"name\":\"李四\",\"age\":\"30岁\",\"email\":\"lisi@example.com\"}\nQ:我叫王五,我的邮箱是wangwu@example.com,今年40岁\nA:{\"name\":\"王五\",\"age\":\"40岁\",\"email\":\"wangwu@example.com\""
},
{
"role": "user",
"content": "大家好,我叫刘五,今年34岁,邮箱是liuwu@example.com"
}
],
"response_format": {
"type": "json_object"
}
}'
返回结果
{
"choices": [
{
"message": {
"role": "assistant",
"content": "{\"name\":\"刘五\",\"age\":\"34岁\",\"email\":\"liuwu@example.com\"}"
},
"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
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
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;
public class Main {
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());
}
System.exit(0);
}
}
返回结果
{
"姓名": "刘五",
"年龄": 34
}
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" \
-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"
}
图片、视频数据处理
除了文本信息,qwen-vl-max
与qwen-vl-plus
模型还支持针对图像、视频数据进行结构化输出,实现视觉信息抽取、定位、事件监测等功能。
OpenAI兼容
Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
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"
apiKey: process.env.DASHSCOPE_API_KEY,
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"}
});
const jsonString = completion.choices[0].message.content
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
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
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;
public class Main {
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());
}
System.exit(0);
}
}
返回结果
{
"ticket": [
{
"travel_date": "2013-06-29",
"trains": "流水",
"seat_num": "371",
"arrival_site": "开发区",
"price": "8.00"
}
],
"invoice": [
{
"invoice_code": "221021325353",
"invoice_number": "10283819"
}
]
}
curl
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": "```json\n{\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}\n```"
}],
"role": "assistant"
},
"finish_reason": "stop"
}]
},
"usage": {
"input_tokens_details": {
"image_tokens": 418,
"text_tokens": 65
},
"prompt_tokens_details": {
"cached_tokens": 0
},
"total_tokens": 599,
"output_tokens": 116,
"input_tokens": 483,
"output_tokens_details": {
"text_tokens": 116
},
"image_tokens": 418
},
"request_id": "9261e910-b810-91e9-88cf-9f7e0eb3750c"
}
优化提示词
模糊的提示词(如“返回用户信息”)会使模型生成非预期结果。建议在提示词中准确描述预期 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=os.getenv("DASHSCOPE_API_KEY"),
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",
apiKey: process.env.DASHSCOPE_API_KEY,
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
# 预定义示例响应(用于向模型展示期望的输出格式)
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;
public class Main {
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());
}
System.exit(0);
}
}
返回结果
{
"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:通义千问 API 支持根据提示词生成有效的 JSON 字符串,但暂时无法根据提供的 JSON Schema 生成。建议在提示词中通过自然语言明确描述所需 JSON 的键值结构和数据类型,并提供标准数据样例,可帮助大模型生成符合预期 Schema 的数据。
错误码
如果模型调用失败并返回报错信息,请参见错误信息进行解决。