Em aplicações de chat em tempo real ou geração de textos longos, tempos de espera prolongados prejudicam a experiência do usuário e podem causar timeouts no servidor, resultando em falhas nas tarefas. A saída em streaming resolve esses problemas ao retornar continuamente fragmentos de texto à medida que o modelo os gera.
Como funciona
A saída em streaming utiliza o protocolo Server-Sent Events (SSE). Após o início de uma requisição em streaming, o servidor estabelece uma conexão HTTP persistente com o cliente. Sempre que o modelo gera um bloco de texto (chamado de chunk), ele o envia imediatamente por essa conexão. Quando todo o conteúdo é gerado, o servidor transmite um sinal de encerramento. O cliente escuta o fluxo de eventos, recebendo e processando os chunks de texto em tempo real — por exemplo, renderizando caracteres um a um na interface. Isso difere das chamadas sem streaming, que retornam todo o conteúdo de uma só vez.Os componentes acima são apenas para referência e não enviam requisições reais.
Faturamento
A saída em streaming segue a mesma regra de faturamento das chamadas sem streaming, cobrando com base no número de tokens de entrada e saída na requisição. Se uma requisição for interrompida, os tokens de saída serão contabilizados apenas para a parte gerada antes de o servidor receber a solicitação de encerramento.Como usar
As edições open source do Qwen3, as edições comercial e open source do QwQ, o QVQ e o Qwen-Omni suportam apenas saída em streaming.
Etapa 1: Configure sua chave de API e selecione uma região
Você deve ter obtained an API key e tê-la configurado como variável de ambiente.
Configurar sua chave de API como variável de ambiente ( DASHSCOPE_API_KEY ) é mais seguro do que codificá-la diretamente no código.
Etapa 2: Faça uma requisição em streaming
- OpenAI compatible
- DashScope
-
Como ativar
Defina
streamcomotrue. -
Visualizar uso de tokens
O protocolo OpenAI não retorna o uso de tokens por padrão. Defina
stream_options={"include_usage": true}para que o último chunk de dados retornado inclua informações sobre o uso de tokens.
- Python
- Node.js
- curl
Copy
import os
from openai import OpenAI
# 1. Prepare: Initialize the client
client = OpenAI(
# Configure the API key using an environment variable to avoid hard coding.
api_key=os.environ["DASHSCOPE_API_KEY"],
# The API key is tightly bound to a region. Ensure base_url matches the region of your API key.
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# 2. Make a streaming request
completion = client.chat.completions.create(
model="qwen-plus",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Please introduce yourself"}
],
stream=True,
stream_options={"include_usage": True}
)
# 3. Handle the streaming response
# Store response fragments in a list. Joining them at the end is more efficient than repeated string concatenation.
content_parts = []
print("AI: ", end="", flush=True)
for chunk in completion:
if chunk.choices:
content = chunk.choices[0].delta.content or ""
print(content, end="", flush=True)
content_parts.append(content)
elif chunk.usage:
print("\n--- Request usage ---")
print(f"Input Tokens: {chunk.usage.prompt_tokens}")
print(f"Output Tokens: {chunk.usage.completion_tokens}")
print(f"Total Tokens: {chunk.usage.total_tokens}")
full_response = "".join(content_parts)
# print(f"\n--- Full response ---\n{full_response}")
Resposta
Copy
AI: Hello! I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can answer questions, create content such as stories, official documents, emails, scripts, perform logical reasoning, programming, express opinions, play games, and more. I support multiple languages, including but not limited to Chinese, English, German, French, and Spanish. If you have any questions or need help, feel free to ask me anytime!
--- Request usage ---
Input Tokens: 26
Output Tokens: 87
Total Tokens: 113
Copy
import OpenAI from "openai";
async function main() {
// 1. Prepare: Initialize the client
// Configure the API key using an environment variable to avoid hard coding.
if (!process.env.DASHSCOPE_API_KEY) {
throw new Error("Set the DASHSCOPE_API_KEY environment variable");
}
// The API key is tightly bound to a region. Ensure baseURL matches the region of your API key.
// Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
const client = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
});
try {
// 2. Make a streaming request
const stream = await client.chat.completions.create({
model: "qwen-plus",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Please introduce yourself" },
],
stream: true,
// Purpose: Get token usage in the last chunk.
stream_options: { include_usage: true },
});
// 3. Handle the streaming response
const contentParts = [];
process.stdout.write("AI: ");
for await (const chunk of stream) {
// The last chunk contains no choices but includes usage information.
if (chunk.choices && chunk.choices.length > 0) {
const content = chunk.choices[0]?.delta?.content || "";
process.stdout.write(content);
contentParts.push(content);
} else if (chunk.usage) {
// Request complete. Print token usage.
console.log("\n--- Request usage ---");
console.log(`Input Tokens: ${chunk.usage.prompt_tokens}`);
console.log(`Output Tokens: ${chunk.usage.completion_tokens}`);
console.log(`Total Tokens: ${chunk.usage.total_tokens}`);
}
}
const fullResponse = contentParts.join("");
// console.log(`\n--- Full response ---\n${fullResponse}`);
} catch (error) {
console.error("Request failed:", error);
}
}
main();
Resposta
Copy
AI: Hello! I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can answer questions, create content such as stories, official documents, emails, scripts, perform logical reasoning, programming, express opinions, play games, and more. I support multiple languages, including but not limited to Chinese, English, German, French, and Spanish. If you have any questions or need help, feel free to ask me anytime!
--- Request usage ---
Input Tokens: 26
Output Tokens: 89
Total Tokens: 115
Requisição
Copy
# ======= Important notes =======
# Ensure the DASHSCOPE_API_KEY environment variable is set
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# === Delete this comment before running ===
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" \
--no-buffer \
-d '{
"model": "qwen-plus",
"messages": [
{"role": "user", "content": "Who are you?"}
],
"stream": true,
"stream_options": {"include_usage": true}
}'
Resposta
A resposta segue o protocolo SSE. Cada linha iniciada comdata: representa um chunk de dados.Copy
data: {"choices":[{"delta":{"content":"","role":"assistant"},"index":0,"logprobs":null,"finish_reason":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"finish_reason":null,"delta":{"content":"I am"},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"delta":{"content":" from"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"delta":{"content":" Alibaba"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"delta":{"content":"'s large-scale language"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"delta":{"content":" model, my name is Qwen"},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"delta":{"content":"."},"finish_reason":null,"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[{"finish_reason":"stop","delta":{"content":""},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":22,"completion_tokens":17,"total_tokens":39},"created":1726132850,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-428b414f-fdd4-94c6-b179-8f576ad653a8"}
data: [DONE]
data:: O payload da mensagem, geralmente uma string JSON.[DONE]: Indica o fim de toda a resposta em streaming.
-
Como ativar
O método para ativar a saída em streaming varia conforme o SDK ou ferramenta:
- SDK Python: Defina o parâmetro
streamcomoTrue. - SDK Java: Utilize a interface
streamCall. - cURL: Defina o cabeçalho
X-DashScope-SSEcomoenable.
- SDK Python: Defina o parâmetro
-
Ativar saída incremental
O protocolo DashScope suporta saída em streaming incremental e não incremental:
-
Incremental (recomendado): Cada chunk de dados contém apenas o conteúdo recém-gerado. Defina
incremental_outputcomotruepara ativar a saída em streaming incremental.Exemplo: ["Eu amo","comer","maçãs"]
-
Não incremental: Cada chunk de dados contém todo o conteúdo gerado anteriormente, desperdiçando largura de banda de rede e aumentando a carga de processamento do cliente. Defina
incremental_outputcomofalsepara ativar a saída em streaming não incremental.Exemplo: ["Eu amo","Eu amo comer","Eu amo comer maçãs"]
-
Incremental (recomendado): Cada chunk de dados contém apenas o conteúdo recém-gerado. Defina
- Visualizar uso de tokens Cada chunk de dados inclui informações de uso de tokens em tempo real.
- Python
- Java
- curl
Copy
import os
from http import HTTPStatus
import dashscope
from dashscope import Generation
# 1. Prepare: Configure the API key and region
# Configure the API key using an environment variable to avoid hard coding.
try:
dashscope.api_key = os.environ["DASHSCOPE_API_KEY"]
except KeyError:
raise ValueError("Set the DASHSCOPE_API_KEY environment variable")
# The API key is tightly bound to a region. Ensure base_url matches the region of your API key.
dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"
# 2. Make a streaming request
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Please introduce yourself"},
]
try:
responses = Generation.call(
model="qwen-plus",
messages=messages,
result_format="message",
stream=True,
# Key: Set to True for incremental output, which offers better performance.
incremental_output=True,
)
# 3. Handle the streaming response
content_parts = []
print("AI: ", end="", flush=True)
for resp in responses:
if resp.status_code == HTTPStatus.OK:
content = resp.output.choices[0].message.content
print(content, end="", flush=True)
content_parts.append(content)
# Check if this is the last packet
if resp.output.choices[0].finish_reason == "stop":
usage = resp.usage
print("\n--- Request usage ---")
print(f"Input Tokens: {usage.input_tokens}")
print(f"Output Tokens: {usage.output_tokens}")
print(f"Total Tokens: {usage.total_tokens}")
else:
# Handle errors
print(
f"\nRequest failed: request_id={resp.request_id}, code={resp.code}, message={resp.message}"
)
break
full_response = "".join(content_parts)
# print(f"\n--- Full response ---\n{full_response}")
except Exception as e:
print(f"An unknown error occurred: {e}")
Copy
AI: Hello! I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can help you answer questions, create content such as stories, official documents, emails, scripts, perform logical reasoning, programming, express opinions, play games, and more. I support multiple languages, including but not limited to Chinese, English, German, French, and Spanish. If you have any questions or need help, feel free to ask me anytime!
--- Request usage ---
Input Tokens: 26
Output Tokens: 91
Total Tokens: 117
Copy
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 io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import com.alibaba.dashscope.protocol.Protocol;
public class Main {
public static void main(String[] args) {
// 1. Get the API key
String apiKey = System.getenv("DASHSCOPE_API_KEY");
if (apiKey == null || apiKey.isEmpty()) {
System.err.println("Set the DASHSCOPE_API_KEY environment variable");
return;
}
// 2. Initialize the Generation instance
// The API key is tightly bound to a region. Ensure baseUrl matches the region of your API key.
Generation gen = new Generation(Protocol.HTTP.getValue(), "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");
CountDownLatch latch = new CountDownLatch(1);
// 3. Build request parameters
GenerationParam param = GenerationParam.builder()
.apiKey(apiKey)
.model("qwen-plus")
.messages(Arrays.asList(
Message.builder()
.role(Role.USER.getValue())
.content("Introduce yourself")
.build()
))
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.incrementalOutput(true) // Enable incremental output for streaming
.build();
// 4. Make a streaming call and handle the response
try {
Flowable<GenerationResult> result = gen.streamCall(param);
StringBuilder fullContent = new StringBuilder();
System.out.print("AI: ");
result
.subscribeOn(Schedulers.io()) // Execute request on IO thread
.observeOn(Schedulers.computation()) // Process response on computation thread
.subscribe(
// onNext: Handle each response fragment
message -> {
String content = message.getOutput().getChoices().get(0).getMessage().getContent();
String finishReason = message.getOutput().getChoices().get(0).getFinishReason();
// Output content
System.out.print(content);
fullContent.append(content);
// When finishReason is not null, it indicates the last chunk. Output usage info.
if (finishReason != null && !"null".equals(finishReason)) {
System.out.println("\n--- Request usage ---");
System.out.println("Input Tokens: " + message.getUsage().getInputTokens());
System.out.println("Output Tokens: " + message.getUsage().getOutputTokens());
System.out.println("Total Tokens: " + message.getUsage().getTotalTokens());
}
System.out.flush(); // Flush output immediately
},
// onError: Handle errors
error -> {
System.err.println("\nRequest failed: " + error.getMessage());
latch.countDown();
},
// onComplete: Completion callback
() -> {
System.out.println(); // New line
// System.out.println("Full response: " + fullContent.toString());
latch.countDown();
}
);
// Main thread waits for the async task to complete
latch.await();
System.out.println("Program execution complete");
} catch (Exception e) {
System.err.println("Request exception: " + e.getMessage());
e.printStackTrace();
}
}
}
Resposta
Copy
AI: Hello! I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can help you answer questions, create content such as stories, official documents, emails, scripts, perform logical reasoning, programming, express opinions, play games, and more. I support multiple languages, including but not limited to Chinese, English, German, French, and Spanish. If you have any questions or need help, feel free to ask me anytime!
--- Request usage ---
Input Tokens: 26
Output Tokens: 91
Total Tokens: 117
Requisição
Copy
# ======= Important notes =======
# Ensure the DASHSCOPE_API_KEY environment variable is set
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before running ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.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": "qwen-plus",
"input":{
"messages":[
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Who are you?"
}
]
},
"parameters": {
"result_format": "message",
"incremental_output":true
}
}'
Resposta
A resposta segue o formato Server-Sent Events (SSE). Cada mensagem inclui:- id: Número do chunk de dados.
- event: Tipo de evento, sempre "result".
- Informações do código de status HTTP.
- data: Dados formatados em JSON.
Copy
id:1
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"I am","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":27,"output_tokens":1,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
id:2
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"Qwen","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":30,"output_tokens":4,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
id:3
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":" from Alibaba","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":33,"output_tokens":7,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
...
id:13
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"or need help, feel free to","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":90,"output_tokens":64,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
id:14
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"ask me!","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":92,"output_tokens":66,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
id:15
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":92,"output_tokens":66,"input_tokens":26,"prompt_tokens_details":{"cached_tokens":0}},"request_id":"d30a9914-ac97-9102-b746-ce0cb35e3fa2"}
Saída em streaming para modelos multimodais
Modelos multimodais permitem adicionar imagens, áudio e outros conteúdos às conversas. A implementação de saída em streaming desses modelos difere dos modelos apenas de texto nos seguintes aspectos:- Construção da mensagem do usuário: As entradas de modelos multimodais incluem não apenas texto, mas também imagens, áudio e outras informações multimodais.
- Interface do SDK DashScope: Use a interface MultiModalConversation no SDK Python do DashScope. Utilize a classe MultiModalConversation no SDK Java do DashScope.
Para modelos multimodais, consulte Image and video understanding , Text extraction , Audio understanding—Qwen3-Omni-Captioner , Kimi , entre outros. O modelo Qwen-Omni suporta apenas saída em streaming porque sua saída pode incluir texto ou áudio e outros conteúdos multimodais. A análise de seus resultados difere de outros modelos. Para detalhes, consulte Omni-modal .
- OpenAI compatible
- DashScope
- Python
- Node.js
- curl
Copy
from openai import OpenAI
import os
client = OpenAI(
# If you haven't configured an environment variable, replace the next line with your Model Studio API key: api_key="sk-xxx"
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
api_key=os.getenv("DASHSCOPE_API_KEY"),
# China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
model="qwen3-vl-plus", # Replace with other multimodal models as needed and adjust messages accordingly
messages=[
{"role": "user",
"content": [{"type": "image_url",
"image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},},
{"type": "text", "text": "What scene is depicted in the image?"}]}],
stream=True,
# stream_options={"include_usage": True}
)
full_content = ""
print("Streaming output content:")
for chunk in completion:
# If stream_options.include_usage is True, the last chunk's choices field is an empty list and should be skipped (token usage can be obtained via chunk.usage)
if chunk.choices and chunk.choices[0].delta.content != "":
full_content += chunk.choices[0].delta.content
print(chunk.choices[0].delta.content)
print(f"Full content: {full_content}")
Copy
from openai import OpenAI
import os
client = OpenAI(
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# If you haven't configured an environment variable, replace the next line with your Model Studio API key: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
model="qwen3-vl-plus", # Replace with other multimodal models as needed and adjust messages accordingly
messages=[
{"role": "user",
"content": [{"type": "image_url",
"image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},},
{"type": "text", "text": "What scene is depicted in the image?"}]}],
stream=True,
# stream_options={"include_usage": True}
)
full_content = ""
print("Streaming output content:")
for chunk in completion:
# If stream_options.include_usage is True, the last chunk's choices field is an empty list and should be skipped (token usage can be obtained via chunk.usage)
if chunk.choices and chunk.choices[0].delta.content != "":
full_content += chunk.choices[0].delta.content
print(chunk.choices[0].delta.content)
print(f"Full content: {full_content}")
Copy
import OpenAI from "openai";
const openai = new OpenAI(
{
// If you haven't configured an environment variable, replace the next line with your Model Studio API key: apiKey: "sk-xxx"
// API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
apiKey: process.env.DASHSCOPE_API_KEY,
// China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3-vl-plus", // Replace with other multimodal models as needed and adjust messages accordingly
messages: [
{role: "user",
content: [{"type": "image_url",
"image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},},
{"type": "text", "text": "What scene is depicted in the image?"}]}],
stream: true,
// stream_options: { include_usage: true },
});
let fullContent = ""
console.log("Streaming output content:")
for await (const chunk of completion) {
// If stream_options.include_usage is true, the last chunk's choices field is an empty array and should be skipped (token usage can be obtained via chunk.usage)
if (chunk.choices[0] && chunk.choices[0].delta.content != null) {
fullContent += chunk.choices[0].delta.content;
console.log(chunk.choices[0].delta.content);
}
}
console.log(`Full output content: ${fullContent}`)
Copy
import OpenAI from "openai";
const openai = new OpenAI(
{
// API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// If you haven't configured an environment variable, replace the next line with your Model Studio API key: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
// Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
baseURL: "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
}
);
const completion = await openai.chat.completions.create({
model: "qwen3-vl-plus", // Replace with other multimodal models as needed and adjust messages accordingly
messages: [
{role: "user",
content: [{"type": "image_url",
"image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},},
{"type": "text", "text": "What scene is depicted in the image?"}]}],
stream: true,
// stream_options: { include_usage: true },
});
let fullContent = ""
console.log("Streaming output content:")
for await (const chunk of completion) {
// If stream_options.include_usage is true, the last chunk's choices field is an empty array and should be skipped (token usage can be obtained via chunk.usage)
if (chunk.choices[0] && chunk.choices[0].delta.content != null) {
fullContent += chunk.choices[0].delta.content;
console.log(chunk.choices[0].delta.content);
}
}
console.log(`Full output content: ${fullContent}`)
Copy
# ======= Important notes =======
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before running ===
curl --location 'https://{WorkspaceId}.cn-beijing.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": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"
}
},
{
"type": "text",
"text": "What scene is depicted in the image?"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
Copy
# ======= Important notes =======
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/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": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"
}
},
{
"type": "text",
"text": "What scene is depicted in the image?"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
- Python
- Java
- curl
Copy
import os
from dashscope import MultiModalConversation
import dashscope
# China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
dashscope.base_http_api_url = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1"
messages = [
{
"role": "user",
"content": [
{"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},
{"text": "What scene is depicted in the image?"}
]
}
]
responses = MultiModalConversation.call(
# If you haven't configured an environment variable, replace the next line with your Model Studio API key: api_key="sk-xxx"
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
api_key=os.getenv("DASHSCOPE_API_KEY"),
model='qwen3-vl-plus', # Replace with other multimodal models as needed and adjust messages accordingly
messages=messages,
stream=True,
incremental_output=True
)
full_content = ""
print("Streaming output content:")
for response in responses:
if response.output.choices[0].message.content:
print(response.output.choices[0].message.content[0]['text'])
full_content += response.output.choices[0].message.content[0]['text']
print(f"Full content: {full_content}")
Copy
import os
from dashscope import MultiModalConversation
import dashscope
# Singapore region URL. 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": [
{"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},
{"text": "What scene is depicted in the image?"}
]
}
]
responses = MultiModalConversation.call(
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# If you haven't configured an environment variable, replace the next line with your Model Studio API key: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
model='qwen3-vl-plus', # Replace with other multimodal models as needed and adjust messages accordingly
messages=messages,
stream=True,
incremental_output=True)
full_content = ""
print("Streaming output content:")
for response in responses:
if response["output"]["choices"][0]["message"].content:
print(response.output.choices[0].message.content[0]['text'])
full_content += response.output.choices[0].message.content[0]['text']
print(f"Full content: {full_content}")
Copy
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
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 io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;
public class Main {
// China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
static {Constants.baseHttpApiUrl="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";}
public static void streamCall()
throws ApiException, NoApiKeyException, UploadFileException {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"),
Collections.singletonMap("text", "What scene is depicted in the image?"))).build();
MultiModalConversationParam param = MultiModalConversationParam.builder()
// If you haven't configured an environment variable, replace the next line with your Model Studio API key: .apiKey("sk-xxx")
// API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model("qwen3-vl-plus") // Replace with other multimodal models as needed and adjust messages accordingly
.messages(Arrays.asList(userMessage))
.incrementalOutput(true)
.build();
Flowable<MultiModalConversationResult> result = conv.streamCall(param);
result.blockingForEach(item -> {
try {
List<Map<String, Object>> content = item.getOutput().getChoices().get(0).getMessage().getContent();
// Check if content exists and is not empty
if (content != null && !content.isEmpty()) {
System.out.println(content.get(0).get("text"));
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
});
}
public static void main(String[] args) {
try {
streamCall();
} catch (ApiException | NoApiKeyException | UploadFileException e) {
System.out.println(e.getMessage());
}
System.exit(0);
}
}
Copy
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
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 io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
// Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
}
public static void streamCall()
throws ApiException, NoApiKeyException, UploadFileException {
MultiModalConversation conv = new MultiModalConversation();
// must create mutable map.
MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("image", "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"),
Collections.singletonMap("text", "What scene is depicted in the image?"))).build();
MultiModalConversationParam param = MultiModalConversationParam.builder()
// API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// If you haven't configured an environment variable, replace the next line with your Model Studio API key: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model("qwen3-vl-plus") // Replace with other multimodal models as needed and adjust messages accordingly
.messages(Arrays.asList(userMessage))
.incrementalOutput(true)
.build();
Flowable<MultiModalConversationResult> result = conv.streamCall(param);
result.blockingForEach(item -> {
try {
List<Map<String, Object>> content = item.getOutput().getChoices().get(0).getMessage().getContent();
// Check if content exists and is not empty
if (content != null && !content.isEmpty()) {
System.out.println(content.get(0).get("text"));
}
} catch (Exception e){
System.exit(0);
}
});
}
public static void main(String[] args) {
try {
streamCall();
} catch (ApiException | NoApiKeyException | UploadFileException e) {
System.out.println(e.getMessage());
}
System.exit(0);
}
}
Copy
# ======= Important notes =======
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# China (Beijing) region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before running ===
curl -X POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qwen3-vl-plus",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},
{"text": "What scene is depicted in the image?"}
]
}
]
},
"parameters": {
"incremental_output": true
}
}'
Copy
# ======= Important notes =======
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === 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' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qwen3-vl-plus",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},
{"text": "What scene is depicted in the image?"}
]
}
]
},
"parameters": {
"incremental_output": true
}
}'
Saída em streaming para modelos de raciocínio
Modelos de raciocínio retornam primeiroreasoning_content (o processo de pensamento) e depois retornam content (a resposta). Determine se o estágio atual é de raciocínio ou de resposta com base no status do pacote de dados.
Para detalhes sobre modelos de raciocínio, consulte Deep thinking , Image and video understanding , Visual reasoning .
Para a implementação de saída em streaming do Qwen3-Omni-Flash (modo de raciocínio), consulte Omni-modal .
- OpenAI compatible
- DashScope
Abaixo está o formato de resposta ao chamar o modo de raciocínio do modelo qwen-plus usando o SDK Python da OpenAI em modo streaming:
Copy
# Thinking stage
...
ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content='Cover all key points while')
ChoiceDelta(content=None, function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content='remaining natural and fluent.')
# Response stage
ChoiceDelta(content='Hello! I am **Qwen', function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content=None)
ChoiceDelta(content='** (', function_call=None, refusal=None, role=None, tool_calls=None, reasoning_content=None)
...
- Se
reasoning_contentnão for None econtentforNone, o estágio atual é de raciocínio. - Se
reasoning_contentfor None econtentnão forNone, o estágio atual é de resposta. - Se ambos forem
None, o estágio permanece o mesmo do pacote anterior.
- Python
- Node.js
- HTTP
Código de exemplo
Copy
from openai import OpenAI
import os
# Initialize the OpenAI client
client = OpenAI(
# If you haven't configured an environment variable, replace with your Alibaba Cloud Model Studio API key: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
messages = [{"role": "user", "content": "Who are you"}]
completion = client.chat.completions.create(
model="qwen-plus", # Replace with other deep-thinking models as needed
messages=messages,
# The enable_thinking parameter enables the thinking process. This parameter has no effect on models qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, and QwQ.
extra_body={"enable_thinking": True},
stream=True,
# stream_options={
# "include_usage": True
# },
)
reasoning_content = "" # Full thought process
answer_content = "" # Full response
is_answering = False # Whether in the response stage
print("\n" + "=" * 20 + "Thought process" + "=" * 20 + "\n")
for chunk in completion:
if not chunk.choices:
print("\nUsage:")
print(chunk.usage)
continue
delta = chunk.choices[0].delta
# Collect only thinking content
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
# Received content, start responding
if hasattr(delta, "content") and delta.content:
if not is_answering:
print("\n" + "=" * 20 + "Full response" + "=" * 20 + "\n")
is_answering = True
print(delta.content, end="", flush=True)
answer_content += delta.content
Resposta
Copy
====================Thought process====================
Okay, the user asked "Who are you," so I need to give an accurate and friendly answer. First, I should confirm my identity as Qwen, developed by Tongyi Lab under Alibaba Group. Next, explain my main functions, like answering questions, creating text, logical reasoning, etc. Keep the tone approachable and avoid overly technical terms so the user feels comfortable. Also, avoid complex jargon and ensure the answer is concise. Additionally, include some interactive elements to encourage further questions. Finally, check for any missing key information, such as my Chinese name "Tongyi Qianwen" and English name "Qwen," along with my company and lab. Make sure the response is comprehensive and meets user expectations.
====================Full response====================
Hello! I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can answer questions, create text, perform logical reasoning, programming, and more, aiming to provide high-quality information and services. You can call me Qwen or simply Tongyi Qianwen. How can I help you?
Código de exemplo
Copy
import OpenAI from "openai";
import process from 'process';
// Initialize the openai client
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // Read from environment variable
baseURL: 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
async function main() {
try {
const messages = [{ role: 'user', content: 'Who are you' }];
const stream = await openai.chat.completions.create({
// Replace with other Qwen3 models or QwQ models as needed
model: 'qwen-plus',
messages,
stream: true,
// The enable_thinking parameter enables the thinking process. This parameter has no effect on models qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, and QwQ.
enable_thinking: true
});
console.log('\n' + '='.repeat(20) + 'Thought process' + '='.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;
// Collect only thinking content
if (delta.reasoning_content !== undefined && delta.reasoning_content !== null) {
if (!isAnswering) {
process.stdout.write(delta.reasoning_content);
}
reasoningContent += delta.reasoning_content;
}
// Received content, start responding
if (delta.content !== undefined && delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Full response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
Resposta
Copy
====================Thought process====================
Okay, the user asked "Who are you," so I need to state my identity. First, I should clearly say I am Qwen, a large-scale language model developed by Alibaba Cloud. Next, mention my main functions, like answering questions, creating text, logical reasoning, etc. Also emphasize my multilingual support, including Chinese and English, so users know I can handle requests in different languages. Additionally, explain my application scenarios, such as helping with learning, work, and daily life. However, since the user's question is direct, detailed information might not be necessary—keep it concise. Also, ensure a friendly tone and invite further questions. Check for any missing key information, like my version or latest updates, but the user probably doesn't need that much detail. Finally, confirm the response is accurate and error-free.
====================Full response====================
I am Qwen, a large-scale language model independently developed by Tongyi Lab under Alibaba Group. I can handle various tasks like answering questions, creating text, logical reasoning, and programming, supporting multiple languages including Chinese and English. If you have any questions or need help, feel free to tell me anytime!
Código de exemplo
- curl
Para modelos open source do Qwen3, defina
enable_thinking como true para ativar o modo de raciocínio. O parâmetro enable_thinking não tem efeito nos modelos qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, QwQ .Copy
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": "qwen-plus",
"messages": [
{
"role": "user",
"content": "Who are you"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"enable_thinking": true
}'
Resposta
Copy
data: {"choices":[{"delta":{"content":null,"role":"assistant","reasoning_content":""},"index":0,"logprobs":null,"finish_reason":null}],"object":"chat.completion.chunk","usage":null,"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}
.....
data: {"choices":[{"finish_reason":"stop","delta":{"content":"","reasoning_content":null},"index":0,"logprobs":null}],"object":"chat.completion.chunk","usage":null,"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}
data: {"choices":[],"object":"chat.completion.chunk","usage":{"prompt_tokens":10,"completion_tokens":360,"total_tokens":370},"created":1745485391,"system_fingerprint":null,"model":"qwen-plus","id":"chatcmpl-e2edaf2c-8aaf-9e54-90e2-b21dd5045503"}
data: [DONE]
Abaixo está o formato de resposta em streaming ao chamar o modo de raciocínio do modelo qwen-plus usando o SDK Python do DashScope:
Copy
# Thinking stage
...
{"role": "assistant", "content": "", "reasoning_content": "High information density,"}
{"role": "assistant", "content": "", "reasoning_content": "making users feel helped."}
# Response stage
{"role": "assistant", "content": "I am Qwen", "reasoning_content": ""}
{"role": "assistant", "content": ", developed by Tongyi Lab", "reasoning_content": ""}
...
- Se
reasoning_contentnão for "", econtentfor "", o estágio atual é de raciocínio. - Se
reasoning_contentfor "", econtentnão for "", o estágio atual é de resposta. - Se ambos forem "", o estágio permanece o mesmo do pacote anterior.
- Python
- Java
- HTTP
Código de exemplo
Copy
import os
from dashscope import Generation
import dashscope
dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/"
messages = [{"role": "user", "content": "Who are you?"}]
completion = Generation.call(
# If you haven't configured an environment variable, replace the next line with your Alibaba Cloud Model Studio API key: api_key = "sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace with other deep-thinking models as needed
model="qwen-plus",
messages=messages,
result_format="message", # Qwen3 open-source models only support "message"; for better experience, we recommend setting this to "message" for other models too.
# Enable deep thinking. This parameter has no effect on models qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, and QwQ.
enable_thinking=True,
stream=True,
incremental_output=True, # Qwen3 open-source models only support true; for better experience, we recommend setting this to true for other models too.
)
# Define full thought process
reasoning_content = ""
# Define full response
answer_content = ""
# Determine if finished thinking and started responding
is_answering = False
print("=" * 20 + "Thought process" + "=" * 20)
for chunk in completion:
# If both thought process and response are empty, skip
if (
chunk.output.choices[0].message.content == ""
and chunk.output.choices[0].message.reasoning_content == ""
):
pass
else:
# If currently in thinking stage
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
# If currently in response stage
elif chunk.output.choices[0].message.content != "":
if not is_answering:
print("\n" + "=" * 20 + "Full response" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content, end="", flush=True)
answer_content += chunk.output.choices[0].message.content
# To print the full thought process and full response, uncomment the following lines and run
# print("=" * 20 + "Full thought process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Full response" + "=" * 20 + "\n")
# print(f"{answer_content}")
Resposta
Copy
====================Thought process====================
Okay, the user asked: "Who are you?" I need to answer this question. First, clarify my identity as Qwen, a large-scale language model developed by Alibaba Cloud. Next, explain my functions and purposes, like answering questions, creating text, logical reasoning, etc. Also, emphasize my goal of being a helpful assistant.
Keep the expression conversational, avoiding professional jargon or complex sentence structures. Add friendly phrases like "Hello there~" to make the conversation natural. Also, ensure accuracy and don't omit key points like my developer, main functions, and usage scenarios.
Consider possible follow-up questions from the user, such as specific application examples or technical details, so subtly hint at further inquiries in the response. For example, mention "Whether it's everyday questions or professional issues, I'll do my best to help," which is both comprehensive and open-ended.
Finally, check for fluency, repetition, or redundant information to keep the response concise. Maintain a balance between friendliness and professionalism so users feel both approachable and reliable.
====================Full response====================
Hello there~ I'm Qwen, a large-scale language model developed by Alibaba Cloud. I can answer questions, create text, perform logical reasoning, programming, and more, aiming to provide help and support. Whether it's everyday questions or professional issues, I'll do my best to help. How can I assist you?
Código de exemplo
Copy
// dashscope SDK version >= 2.19.4
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
}
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("====================Thought process====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (!content.isEmpty()) {
finalContent.append(content);
if (!isFirstPrint) {
System.out.println("\n====================Full response====================");
isFirstPrint = true;
}
System.out.print(content);
}
}
private static GenerationParam buildGenerationParam(Message userMsg) {
return GenerationParam.builder()
// If you haven't configured an environment variable, replace the next line with your Alibaba Cloud Model Studio API key: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model("qwen-plus")
.enableThinking(true)
.incrementalOutput(true)
.resultFormat("message")
.messages(Arrays.asList(userMsg))
.build();
}
public static void streamCallWithMessage(Generation gen, Message userMsg)
throws NoApiKeyException, ApiException, InputRequiredException {
GenerationParam param = buildGenerationParam(userMsg);
Flowable<GenerationResult> result = gen.streamCall(param);
result.blockingForEach(message -> handleGenerationResult(message));
}
public static void main(String[] args) {
try {
Generation gen = new Generation();
Message userMsg = Message.builder().role(Role.USER.getValue()).content("Who are you?").build();
streamCallWithMessage(gen, userMsg);
// Print final result
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================Full response====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
logger.error("An exception occurred: {}", e.getMessage());
}
System.exit(0);
}
}
Resposta
Copy
====================Thought process====================
Okay, the user asked "Who are you?", so I need to answer based on previous settings. First, my role is Qwen, a large-scale language model under Alibaba Group. Keep it conversational and simple.
The user might be new to me or confirming my identity. Start by directly stating who I am, then briefly explain my functions and purposes, like answering questions, creating text, programming, etc. Also mention multilingual support so users know I handle different languages.
Also, per guidelines, maintain human-like qualities, so use a friendly tone, maybe add emojis for warmth. Guide users to ask further questions or use my features, like asking what they need help with.
Avoid complex terms and keep it concise. Check for missing key points like multilingual support and specific capabilities. Ensure the response meets all requirements, including conversational style and simplicity.
====================Full response====================
Hello! I'm Qwen, a large-scale language model under Alibaba Group. I can answer questions, create text like stories, official documents, emails, scripts, perform logical reasoning, programming, express opinions, play games, and more. I'm proficient in multiple languages, including but not limited to Chinese, English, German, French, and Spanish. How can I help you?
Código de exemplo
- curl
Para modelos de raciocínio híbrido, defina
enable_thinking como true para ativar o modo de raciocínio. O parâmetro enable_thinking não tem efeito nos modelos qwen3-30b-a3b-thinking-2507, qwen3-235b-a22b-thinking-2507, QwQ .Copy
# ======= Important notes =======
# API keys differ by region. Get your API key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
# === Delete this comment before running ===
curl -X POST "https://{WorkspaceId}.ap-southeast-1.maas.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": "qwen-plus",
"input":{
"messages":[
{
"role": "user",
"content": "Who are you?"
}
]
},
"parameters":{
"enable_thinking": true,
"incremental_output": true,
"result_format": "message"
}
}'
Resposta
Copy
id:1
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"Hmm","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":14,"input_tokens":11,"output_tokens":3},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:2
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":",","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":15,"input_tokens":11,"output_tokens":4},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:3
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"user","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":16,"input_tokens":11,"output_tokens":5},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:4
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"asked","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":17,"input_tokens":11,"output_tokens":6},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:5
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"\"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":18,"input_tokens":11,"output_tokens":7},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
......
id:358
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"help","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":373,"input_tokens":11,"output_tokens":362},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:359
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":",","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":374,"input_tokens":11,"output_tokens":363},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:360
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"welcome","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":375,"input_tokens":11,"output_tokens":364},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:361
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"anytime","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":376,"input_tokens":11,"output_tokens":365},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:362
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"tell","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":377,"input_tokens":11,"output_tokens":366},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:363
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"me","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":378,"input_tokens":11,"output_tokens":367},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:364
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"!","reasoning_content":"","role":"assistant"},"finish_reason":"null"}]},"usage":{"total_tokens":378,"input_tokens":11,"output_tokens":367},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
id:365
event:result
:HTTP_STATUS/200
data:{"output":{"choices":[{"message":{"content":"","reasoning_content":"","role":"assistant"},"finish_reason":"stop"}]},"usage":{"total_tokens":378,"input_tokens":11,"output_tokens":367},"request_id":"25d58c29-c47b-9e8d-a0f1-d6c309ec58b1"}
Entrando em produção
- Gerenciamento de desempenho e recursos: Em serviços de backend, manter uma conexão HTTP persistente para cada requisição em streaming consome recursos. Configure seu serviço com tamanho adequado de pool de conexões e valores de timeout. Em cenários de alta concorrência, monitore o uso de descritores de arquivos para evitar exaustão.
-
Renderização no lado do cliente: Em frontends web, utilize as APIs
ReadableStreameTextDecoderStreampara lidar e renderizar fluxos de eventos SSE de forma fluida, garantindo a melhor experiência ao usuário. -
Model monitoring:
- Métricas principais: Monitore o Tempo até o Primeiro Token (TTFT), a métrica central para a experiência em streaming. Acompanhe também a taxa de erros da API e o tempo médio de resposta.
- Alertas: Configure alertas para taxas anormais de erros da API, especialmente erros 4xx e 5xx.
-
Configuração de proxy Nginx: Se utilizar o Nginx como proxy reverso, o buffer de saída padrão (proxy_buffering) compromete a natureza em tempo real das respostas em streaming. Para garantir que os dados sejam enviados aos clientes imediatamente, desative esse recurso definindo
proxy_buffering offno arquivo de configuração do Nginx.
Códigos de erro
Se a chamada do modelo falhar e retornar uma mensagem de erro, consulte Error codes para resolução.Perguntas frequentes
P: Por que não há informações de uso na resposta?
R: O protocolo OpenAI não retorna informações de uso por padrão. Defina o parâmetrostream_options para incluir informações de uso no último pacote retornado.
P: Ativar a saída em streaming afeta a qualidade da resposta do modelo?
R: Não. No entanto, alguns modelos suportam apenas saída em streaming, e chamadas sem streaming podem causar erros de timeout. Recomendamos o uso de saída em streaming.P: Qual é a diferença entre chamadas sem streaming e com streaming?
R: Principais diferenças:- Limite de timeout: Para chamadas sem streaming, o timeout máximo é de pelo menos 300 segundos e varia conforme a região e o modelo. Se não for concluída a tempo, a requisição é encerrada.
- Estrutura de saída: Chamadas sem streaming retornam a resposta completa (um único objeto JSON) de uma vez. Chamadas com streaming retornam chunks de dados progressivamente via protocolo SSE, com cada chunk contendo parte do conteúdo gerado. O cliente deve montar esses chunks.
- Compatibilidade de recursos: Ambos suportam recursos como JSON Mode e Function Call, sem diferenças funcionais.
P: A saída em streaming suporta JSON Mode (saída estruturada)?
R: Sim. Definastream como true e response_format como {"type": "json_object"} na requisição. O modelo retornará fragmentos de conteúdo formatados em JSON progressivamente. A saída final montada será um JSON válido.