Conversas com múltiplas interações
Gerenciar o contexto do chat
O Qwen API é sem Estado e não salva o histórico de conversa. Para implementar conversas multi-turnos, você deve passar o histórico de conversa em cada pedido. Você também pode usar estratégias, como truncamento, resumo e recuperação, para gerenciar eficientemente o contexto e reduzir o consumo de fichas.
Este tópico descreve como implementar uma conversa multi-turnos usando o OpenAI compatível com a Completação de Chat ou API DashScope. A API Responses fornece uma alternativa mais conveniente, veja [OpenAI compatível - Responses] (/api-reference/chat/openai-responses).
Como funciona
Para implementar uma conversa multi-turno, você deve manter um messages Array. Em cada rodada, acrescente a última pergunta do usuário e a resposta do modelo a este conjunto. Então, use o array atualizado como a entrada para o próximo pedido.
Exemplo de como o messages O array muda durante uma conversa:
First round
Adicione a pergunta do usuário ao `messages` Array.
```json
// Use a text model
[
{"role": "user", "content": "Recommend a sci-fi movie about space exploration."}
]
// Use a multimodal model, for example, Qwen-VL
// {"role": "user",
// "content": [{"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
// {"type": "text", "text": "What products are shown in the image?"}]
// }
```
Second round
Adicione a resposta do modelo e a última pergunta do usuário para o `messages` Array.
```json
// Use a text model
[
{"role": "user", "content": "Recommend a sci-fi movie about space exploration."},
{"role": "assistant", "content": "I recommend 'XXX'. It is a classic sci-fi work."},
{"role": "user", "content": "Who is the director of this movie?"}
]
// Use a multimodal model, for example, Qwen-VL
//[
// {"role": "user", "content": [
// {"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
// {"type": "text", "text": "What products are shown in the image?"}]},
// {"role": "assistant", "content": "The image shows three items: a pair of light blue overalls, a blue and white striped short-sleeve shirt, and a pair of white sneakers."},
// {"role": "user", "content": "What style are they?"}
//]
```
Começando.
Responses API
A API de Respostas simplifica conversas multi-turnos. Passo. `previous_response_id` para ligar o contexto automaticamente - nenhum histórico manual de mensagens necessária. Para gerenciamento avançado de sessão, veja [Usando Conversas] (#using-conversations).
Use a resposta. `id` (Formato UUID, como `f0dbb153-117f-9bbf-8176-5284b47f3xxx`) como `previous_response_id`. Não use uma mensagem. `id` De onde você está? `output` - Array (como `msg_56c860c4-3ad8-4a96-8553-d2f94c259xxx`). A resposta `id` expira em 7 dias.
```python Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://maas.qwencloudapi.com/compatible-mode/v1",
)
# First round
response1 = client.responses.create(
model="qwen3.7-plus",
input="My name is John, please remember it."
)
print(f"First response: {response1.output_text}")
# Second round - use previous_response_id to link context
response2 = client.responses.create(
model="qwen3.7-plus",
input="Do you remember my name?",
previous_response_id=response1.id
)
print(f"Second response: {response2.output_text}")
```
```javascript Node.js
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://maas.qwencloudapi.com/compatible-mode/v1"
});
async function main() {
// First round
const response1 = await openai.responses.create({
model: "qwen3.7-plus",
input: "My name is John, please remember it."
});
console.log(`First response: ${response1.output_text}`);
// Second round - use previous_response_id to link context
const response2 = await openai.responses.create({
model: "qwen3.7-plus",
input: "Do you remember my name?",
previous_response_id: response1.id
});
console.log(`Second response: ${response2.output_text}`);
}
main();
```
```bash curl
# First round
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/responses \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"input": "My name is John, please remember it."
}'
# Second round - use the id from first response as previous_response_id
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/responses \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"input": "Do you remember my name?",
"previous_response_id": "response_id_from_first_round"
}'
```
**Responda exemplo (segunda rodada):**
```json
{
"id": "f0dbb153-117f-9bbf-8176-5284b47f3xxx",
"model": "qwen3.7-plus",
"status": "completed",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Yes, John! I remember your name. How can I assist you today?"
}
]
}
],
"usage": {
"input_tokens": 78,
"output_tokens": 16,
"total_tokens": 94
}
}
```
OpenAI compatible
```python Python
import os
from openai import OpenAI
def get_response(messages):
client = OpenAI(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://maas.qwencloudapi.com/compatible-mode/v1",
)
completion = client.chat.completions.create(model="qwen3.8-max", messages=messages)
return completion
# Initialize a messages array
messages = [
{
"role": "system",
"content": """You are a salesperson at the Bailian phone store. You are responsible for recommending phones to users. The phones have two parameters: screen size (including 6.1-inch, 6.5-inch, and 6.7-inch) and resolution (including 2K and 4K).
You can only ask the user for one parameter at a time. If the user does not provide complete information, you need to ask a follow-up question to get the missing parameter. When all parameters are collected, you must say: I have understood your purchase intention. Please wait.""",
}
]
assistant_output = "Welcome to the Bailian phone store. What screen size are you looking for?"
print(f"Model output: {assistant_output}\n")
while "I have understood your purchase intention" not in assistant_output:
user_input = input("Please enter: ")
# Add the user's question to the messages list
messages.append({"role": "user", "content": user_input})
assistant_output = get_response(messages).choices[0].message.content
# Add the model's response to the messages list
messages.append({"role": "assistant", "content": assistant_output})
print(f"Model output: {assistant_output}")
print("\n")
```
```javascript Node.js
import OpenAI from "openai";
import { createInterface } from 'readline/promises';
const BASE_URL = "https://maas.qwencloudapi.com/compatible-mode/v1";
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: BASE_URL
});
async function getResponse(messages) {
try {
const completion = await openai.chat.completions.create({
model: "qwen3.8-max",
messages: messages,
});
return completion.choices[0].message.content;
} catch (error) {
console.error("Error fetching response:", error);
throw error; // Re-throw the exception for handling by the upper layer
}
}
// Initialize the messages array
const messages = [
{
"role": "system",
"content": `You are a salesperson at the Bailian phone store. You are responsible for recommending phones to users. The phones have two parameters: screen size (including 6.1-inch, 6.5-inch, and 6.7-inch) and resolution (including 2K and 4K).
You can only ask the user for one parameter at a time. If the user does not provide complete information, you need to ask a follow-up question to get the missing parameter. When all parameters are collected, you must say: I have understood your purchase intention. Please wait.`,
}
];
let assistant_output = "Welcome to the Bailian phone store. What screen size are you looking for?";
console.log(assistant_output);
const readline = createInterface({
input: process.stdin,
output: process.stdout
});
(async () => {
while (!assistant_output.includes("I have understood your purchase intention")) {
const user_input = await readline.question("Please enter: ");
messages.push({ role: "user", content: user_input});
try {
const response = await getResponse(messages);
assistant_output = response;
messages.push({ role: "assistant", content: assistant_output });
console.log(assistant_output);
console.log("\n");
} catch (error) {
console.error("An error occurred while fetching the response:", error);
}
}
readline.close();
})();
```
```bash curl
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-max",
"messages":[
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello"
},
{
"role": "assistant",
"content": "Hello, I am Qwen."
},
{
"role": "user",
"content": "What can you do?"
}
]
}'
```
DashScope
```python Python
import os
from dashscope import Generation
import dashscope
dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'
def get_response(messages):
response = Generation.call(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
model="qwen3.8-max",
messages=messages,
result_format="message",
)
return response
messages = [
{
"role": "system",
"content": """You are a salesperson at the Bailian phone store. You are responsible for recommending phones to users. The phones have two parameters: screen size (including 6.1-inch, 6.5-inch, and 6.7-inch) and resolution (including 2K and 4K).
You can only ask the user for one parameter at a time. If the user does not provide complete information, you need to ask a follow-up question to get the missing parameter. When all parameters are collected, you must say: I have understood your purchase intention. Please wait.""",
}
]
assistant_output = "Welcome to the Bailian phone store. What screen size are you looking for?"
print(f"Model output: {assistant_output}\n")
while "I have understood your purchase intention" not in assistant_output:
user_input = input("Please enter: ")
# Add the user's question to the messages list
messages.append({"role": "user", "content": user_input})
assistant_output = get_response(messages).output.choices[0].message.content
# Add the model's response to the messages list
messages.append({"role": "assistant", "content": assistant_output})
print(f"Model output: {assistant_output}")
print("\n")
```
```java Java
import java.util.ArrayList;
import java.util.List;
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 java.util.Scanner;
import com.alibaba.dashscope.protocol.Protocol;
public class Main {
public static GenerationParam createGenerationParam(List<Message> messages) {
return GenerationParam.builder()
// If you have not configured the environment variable, replace the following line with your API key: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model("qwen3.8-max")
.messages(messages)
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.build();
}
public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
Generation gen = new Generation(Protocol.HTTP.getValue(), "https://maas.qwencloudapi.com/api/v1");
return gen.call(param);
}
public static void main(String[] args) {
try {
List<Message> messages = new ArrayList<>();
messages.add(createMessage(Role.SYSTEM, "You are a helpful assistant."));
for (int i = 0; i < 3;i++) {
Scanner scanner = new Scanner(System.in);
System.out.print("Please enter: ");
String userInput = scanner.nextLine();
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
messages.add(createMessage(Role.USER, userInput));
GenerationParam param = createGenerationParam(messages);
GenerationResult result = callGenerationWithMessages(param);
System.out.println("Model output: "+result.getOutput().getChoices().get(0).getMessage().getContent());
messages.add(result.getOutput().getChoices().get(0).getMessage());
}
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
e.printStackTrace();
}
System.exit(0);
}
private static Message createMessage(Role role, String content) {
return Message.builder().role(role.getValue()).content(content).build();
}
}
```
```bash curl
curl -X POST https://maas.qwencloudapi.com/api/v1/services/aigc/text-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-max",
"input":{
"messages":[
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello"
},
{
"role": "assistant",
"content": "Hello, I am Qwen."
},
{
"role": "user",
"content": "What can you do?"
}
]
}
}'
```
Para modelos multimodais
- Esta seção se aplica a modelos multimodais como Qwen3-VL e Qwen3.5. Por
Qwen-Omni, veja [Não-Realtime] (/developer-guides/speech/multimodal-speech). - Qwen-VL-OCR e Qwen3-Omni-Captioner são projetados para tarefas de turno único e não suportam conversas de turnos múltiplos.
Conversas multi-voltas para modelos multimodais diferem de modelos de texto:
- Construção de mensagens de usuário: Mensagens de usuário para modelos multimodais podem conter informações multimodais, como imagens e áudio, além de texto.
- DashScope SDK interface: Quando você usa o DashScope Python SDK, chame o
MultiModalConversationInterface. Para as chamadas de sincronização, use oAioMultiModalConversationInterface. Quando usar o DashScope Java SDK, ligue paraMultiModalConversation- Aula.
OpenAI compatible
```python Python
from openai import OpenAI
import os
client = OpenAI(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://maas.qwencloudapi.com/compatible-mode/v1"
)
messages = [
{"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
},
},
{"type": "text", "text": "What products are shown in the image?"},
],
}
]
completion = client.chat.completions.create(
model="qwen3-vl-plus", # You can replace this with other multimodal models and modify the messages as needed
messages=messages,
)
print(f"First round output: {completion.choices[0].message.content}")
assistant_message = completion.choices[0].message
messages.append(assistant_message.model_dump())
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": "What style are they?"
}
]
})
completion = client.chat.completions.create(
model="qwen3-vl-plus",
messages=messages,
)
print(f"Second round output: {completion.choices[0].message.content}")
```
```javascript Node.js
import OpenAI from "openai";
const openai = new OpenAI(
{
// If you have not configured the environment variable, replace the following line with your API key: apiKey: "sk-xxx",
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://maas.qwencloudapi.com/compatible-mode/v1"
}
);
let messages = [
{
role: "user", content: [
{ type: "image_url", image_url: { "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png" } },
{ type: "text", text: "What products are shown in the image?" },
]
}]
async function main() {
let response = await openai.chat.completions.create({
model: "qwen3-vl-plus", // You can replace this with other multimodal models and modify the messages as needed
messages: messages
});
console.log(`First round output: ${response.choices[0].message.content}`);
messages.push(response.choices[0].message);
messages.push({"role": "user", "content": "Write a poem describing this scene"});
response = await openai.chat.completions.create({
model: "qwen3-vl-plus",
messages: messages
});
console.log(`Second round output: ${response.choices[0].message.content}`);
}
main()
```
```bash curl
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"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/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
}
},
{
"type": "text",
"text": "What products are shown in the image?"
}
]
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "The image shows three items: a pair of light blue overalls, a blue and white striped short-sleeve shirt, and a pair of white sneakers."
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "What style are they?"
}
]
}
]
}'
```
DashScope
```python Python
import os
from dashscope import MultiModalConversation
import dashscope
dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'
messages = [
{
"role": "user",
"content": [
{
"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
},
{"text": "What products are shown in the image?"},
],
}
]
response = MultiModalConversation.call(
# If you have not configured the environment variable, replace the following line with: api_key="sk-xxx",
api_key=os.getenv('DASHSCOPE_API_KEY'),
model='qwen3-vl-plus', # You can replace this with other multimodal models and modify the messages as needed
messages=messages
)
print(f"Model first round output {response.output.choices[0].message.content[0]['text']}")
messages.append(response['output']['choices'][0]['message'])
user_msg = {"role": "user", "content": [{"text": "What style are they?"}]}
messages.append(user_msg)
response = MultiModalConversation.call(
# If the environment variable is not configured, please replace the following line with: api_key="sk-xxx",
api_key=os.getenv('DASHSCOPE_API_KEY'),
model='qwen3-vl-plus',
messages=messages
)
print(f"Model second round output {response.output.choices[0].message.content[0]['text']}")
```
```java Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
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.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://maas.qwencloudapi.com/api/v1";
}
private static final String modelName = "qwen3-vl-plus"; // You can replace this with other multimodal models and modify the messages as needed
public static void MultiRoundConversationCall() 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/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"),
Collections.singletonMap("text", "What products are shown in the image?"))).build();
List<MultiModalMessage> messages = new ArrayList<>();
messages.add(userMessage);
MultiModalConversationParam param = MultiModalConversationParam.builder()
// If you have not configured the environment variable, replace the following line with your API key: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model(modelName)
.messages(messages)
.build();
MultiModalConversationResult result = conv.call(param);
System.out.println("First round output: "+result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text")); // add the result to conversation
messages.add(result.getOutput().getChoices().get(0).getMessage());
MultiModalMessage msg = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "What style are they?"))).build();
messages.add(msg);
param.setMessages((List)messages);
result = conv.call(param);
System.out.println("Second round output: "+result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text")); }
public static void main(String[] args) {
try {
MultiRoundConversationCall();
} catch (ApiException | NoApiKeyException | UploadFileException e) {
System.out.println(e.getMessage());
}
System.exit(0);
}
}
```
```bash curl
curl -X POST https://maas.qwencloudapi.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen3-vl-plus",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"},
{"text": "What products are shown in the image?"}
]
},
{
"role": "assistant",
"content": [
{"text": "The image shows three items: a pair of light blue overalls, a blue and white striped short-sleeve shirt, and a pair of white sneakers."}
]
},
{
"role": "user",
"content": [
{"text": "What style are they?"}
]
}
]
}
}'
```
### Assincronia chama
Para usar conversas multimodais em um ambiente assincronizado, use o `AioMultiModalConversation` Interface:
```python Python
import asyncio
import os
import dashscope
from dashscope import AioMultiModalConversation
dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'
async def main():
messages = [
{
"role": "user",
"content": [
{"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"},
{"text": "What products are shown in the image?"},
],
}
]
response = await AioMultiModalConversation.call(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx",
api_key=os.getenv('DASHSCOPE_API_KEY'),
model='qwen3-vl-plus',
messages=messages)
print(f"Model first round output {response.output.choices[0].message.content[0]['text']}")
messages.append(response['output']['choices'][0]['message'])
user_msg = {"role": "user", "content": [{"text": "What style are they?"}]}
messages.append(user_msg)
response = await AioMultiModalConversation.call(
api_key=os.getenv('DASHSCOPE_API_KEY'),
model='qwen3-vl-plus',
messages=messages)
print(f"Model second round output {response.output.choices[0].message.content[0]['text']}")
asyncio.run(main())
```
Para pensar em modelos
Modelos de pensamento retornam dois campos: reasoning_content (o processo de pensamento) e content (a resposta). Quando atualizar o conjunto de mensagens, retenha apenas o content E ignore o reasoning_content Campo.
[
{"role": "user", "content": "Recommend a sci-fi movie about space exploration."},
{"role": "assistant", "content": "I recommend 'XXX'. It is a classic sci-fi work."}, # Do not add the reasoning_content field when you add to the context
{"role": "user", "content": "Who is the director of this movie?"}
]
Para mais informações sobre modelos pensantes, veja [Pensando] (/developer-guides/text-generation/thinking) e [Visão] (/developer-guides/multimodal/vision). Para conversas multi-turnos com Qwen3-Omni-Flash (modo de pensar), veja [Não-Realtime] (/developer-guides/speech/multimodal-speech).
OpenAI compatible
```python Python
from openai import OpenAI
import os
# Initialize the OpenAI client
client = OpenAI(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://maas.qwencloudapi.com/compatible-mode/v1"
)
messages = []
conversation_idx = 1
while True:
reasoning_content = "" # Define the complete thinking process
answer_content = "" # Define the complete response
is_answering = False # Determine whether to end the thinking process and start responding
print("="*20+f"Conversation Round {conversation_idx}"+"="*20)
conversation_idx += 1
user_input = input("Enter your message (type exit to end the conversation): ")
if user_input.strip().lower() == "exit":
print("Conversation ended.")
break
user_msg = {"role": "user", "content": user_input}
messages.append(user_msg)
# Create a chat completion request
completion = client.chat.completions.create(
# You can replace this with other deep thinking models as needed
model="qwen3.8-max",
messages=messages,
extra_body={"enable_thinking": True},
stream=True,
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Thinking Process" + "=" * 20 + "\n")
for chunk in completion:
# If chunk.choices is empty, print usage
if not chunk.choices:
print("\nUsage:")
print(chunk.usage)
else:
delta = chunk.choices[0].delta
# Print the thinking process
if hasattr(delta, 'reasoning_content') and delta.reasoning_content != None:
print(delta.reasoning_content, end='', flush=True)
reasoning_content += delta.reasoning_content
else:
# Start responding
if delta.content != "" and is_answering is False:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# Print the response process
print(delta.content, end='', flush=True)
answer_content += delta.content
# Add the content of the model's response to the context
messages.append({"role": "assistant", "content": answer_content})
print("\n")
```
```javascript Node.js
import OpenAI from "openai";
import process from 'process';
import readline from 'readline/promises';
// Initialize the readline interface
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Initialize the openai client
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // Read from environment variables
baseURL: 'https://maas.qwencloudapi.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [];
let conversationIdx = 1;
async function main() {
while (true) {
console.log("=".repeat(20) + `Conversation Round ${conversationIdx}` + "=".repeat(20));
conversationIdx++;
// Read user input
const userInput = await rl.question("Enter your message (type exit to end the conversation): ");
if (userInput.trim().toLowerCase() === "exit") {
console.log("Conversation ended.");
rl.close();
break;
}
messages.push({ role: 'user', content: userInput });
// Reset state
reasoningContent = '';
answerContent = '';
isAnswering = false;
try {
const stream = await openai.chat.completions.create({
// You can replace this with other deep thinking models as needed
model: 'qwen3.8-max',
messages: messages,
enable_thinking: true,
stream: true,
// stream_options:{
// include_usage: true
// }
});
console.log("\n" + "=".repeat(20) + "Thinking 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;
// Process the thinking process
if (delta.reasoning_content) {
process.stdout.write(delta.reasoning_content);
reasoningContent += delta.reasoning_content;
}
// Process the formal response
if (delta.content) {
if (!isAnswering) {
console.log('\n' + "=".repeat(20) + "Complete Response" + "=".repeat(20) + "\n");
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
// Add the complete response to the message history
messages.push({ role: 'assistant', content: answerContent });
console.log("\n");
} catch (error) {
console.error('Error:', error);
}
}
}
// Start the program
main().catch(console.error);
```
```bash HTTP
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.8-max",
"messages": [
{
"role": "user",
"content": "Hello"
},
{
"role": "assistant",
"content": "Hello! Nice to meet you. Is there anything I can help you with?"
},
{
"role": "user",
"content": "Who are you?"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"enable_thinking": true
}'
```
DashScope
```python Python
import os
from dashscope import MultiModalConversation
import dashscope
dashscope.base_http_api_url = "https://maas.qwencloudapi.com/api/v1/"
messages = []
conversation_idx = 1
while True:
print("=" * 20 + f"Conversation Round {conversation_idx}" + "=" * 20)
conversation_idx += 1
user_input = input("Enter your message (type exit to end the conversation): ")
if user_input.strip().lower() == "exit":
print("Conversation ended.")
break
user_msg = {"role": "user", "content": [{"text": user_input}]}
messages.append(user_msg)
response = MultiModalConversation.call(
# If you have not configured the environment variable, replace the following line with your API key: api_key="sk-xxx",
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qwen3.8-max",
messages=messages,
enable_thinking=True,
stream=True,
incremental_output=True
)
# Define the complete thinking process
reasoning_content = ""
# Define the complete response
answer_content = ""
# Determine whether to end the thinking process and start responding
is_answering = False
print("=" * 20 + "Thinking Process" + "=" * 20)
for chunk in response:
# Get the content of the current chunk
content_text = ""
raw_content = chunk.output.choices[0].message.content
if isinstance(raw_content, list) and raw_content:
content_text = raw_content[0].get("text", "")
elif isinstance(raw_content, str):
content_text = raw_content
reasoning_text = chunk.output.choices[0].message.reasoning_content or ""
# If both the thinking process and the response are empty, ignore
if content_text == "" and reasoning_text == "":
pass
else:
# If it is currently the thinking process
if reasoning_text != "" and content_text == "":
print(reasoning_text, end="",flush=True)
reasoning_content += reasoning_text
# If it is currently the response
elif content_text != "":
if not is_answering:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20)
is_answering = True
print(content_text, end="",flush=True)
answer_content += content_text
# Add the content of the model's response to the context
messages.append({"role": "assistant", "content": [{"text": answer_content}]})
print("\n")
# To print the complete thinking process and complete response, uncomment and run the following code
# print("=" * 20 + "Complete Thinking Process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(f"{answer_content}")
```
```java Java
// DashScope SDK version >= 2.19.4
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 {
Constants.baseHttpApiUrl = "https://maas.qwencloudapi.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 handleResult(MultiModalConversationResult message) {
if (message != null && message.getOutput() != null
&& message.getOutput().getChoices() != null
&& !message.getOutput().getChoices().isEmpty()
&& message.getOutput().getChoices().get(0) != null
&& message.getOutput().getChoices().get(0).getMessage() != null) {
String reasoning = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
List<java.util.Map<String, Object>> contentList = message.getOutput().getChoices().get(0).getMessage().getContent();
String content = "";
if (contentList != null && !contentList.isEmpty() && contentList.get(0).containsKey("text")) {
content = String.valueOf(contentList.get(0).get("text"));
}
if (reasoning != null && !reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================Thinking Process====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (!content.isEmpty()) {
finalContent.append(content);
if (!isFirstPrint) {
System.out.println("\n====================Complete Response====================");
isFirstPrint = true;
}
System.out.print(content);
}
}
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMsg1 = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "Hello"))).build();
MultiModalMessage assistantMsg = MultiModalMessage.builder().role(Role.ASSISTANT.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "Hello! Nice to meet you. Is there anything I can help you with?"))).build();
MultiModalMessage userMsg2 = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "Who are you"))).build();
List<MultiModalMessage> messages = new ArrayList<>(Arrays.asList(userMsg1, assistantMsg, userMsg2));
MultiModalConversationParam param = MultiModalConversationParam.builder()
// If you have not configured the environment variable, replace the following line with your API key: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model("qwen3.8-max")
.enableThinking(true)
.messages(messages)
.incrementalOutput(true)
.build();
Flowable<MultiModalConversationResult> result = conv.streamCall(param);
result.doOnError(throwable -> logger.error("Error: {}", throwable.getMessage(), throwable))
.blockingForEach(Main::handleResult);
} catch (ApiException | NoApiKeyException e) {
logger.error("An exception occurred: {}", e.getMessage(), e);
} catch (Exception e) {
logger.error("Unexpected error occurred: {}", e.getMessage(), e);
} finally {
System.exit(0);
}
}
}
```
```bash HTTP
curl -X POST "https://maas.qwencloudapi.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.8-max",
"input":{
"messages":[
{
"role": "user",
"content": [{"text": "Hello"}]
},
{
"role": "assistant",
"content": [{"text": "Hello! Nice to meet you. Is there anything I can help you with?"}]
},
{
"role": "user",
"content": [{"text": "Who are you?"}]
}
]
},
"parameters":{
"enable_thinking": true,
"incremental_output": true
}
}'
```
Usando conversas.
previous_response_id Funciona bem para conversas acorrentadas. Para gerenciamento de sessão do lado do servidor, continuidade de dispositivos cruzados, ou controle manual de mensagens, use a API de Conversações com o conversation parâmetro.
Crie uma conversa e converse.
Primeiro, crie uma conversa usando a API de Conversações, e depois passe o conversation parâmetro e instructions (Prompt sistema) para responses.create. O servidor gerencia o contexto automaticamente.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://maas.qwencloudapi.com/compatible-mode/v1",
)
# Create a conversation
conversation = client.conversations.create()
# First round
response1 = client.responses.create(
conversation=conversation.id,
model="qwen3.7-plus",
instructions="You are a travel advisor who specializes in recommending travel destinations.",
input="Recommend a city suitable for summer travel.",
)
print(f"First response: {response1.output_text}")
# Second round - context managed automatically by server
response2 = client.responses.create(
conversation=conversation.id,
model="qwen3.7-plus",
instructions="You are a travel advisor who specializes in recommending travel destinations.",
input="What are the must-try foods there?",
)
print(f"Second response: {response2.output_text}")
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://maas.qwencloudapi.com/compatible-mode/v1",
});
async function main() {
// Create a conversation
const conversation = await client.conversations.create();
// First round
const response1 = await client.responses.create({
conversation: conversation.id,
model: "qwen3.7-plus",
instructions: "You are a travel advisor who specializes in recommending travel destinations.",
input: "Recommend a city suitable for summer travel.",
});
console.log("First response:", response1.output_text);
// Second round - context managed automatically by server
const response2 = await client.responses.create({
conversation: conversation.id,
model: "qwen3.7-plus",
instructions: "You are a travel advisor who specializes in recommending travel destinations.",
input: "What are the must-try foods there?",
});
console.log("Second response:", response2.output_text);
}
main();
# Create a conversation
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/conversations \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# First round - use the conversation id returned above
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/responses \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"instructions": "You are a travel advisor who specializes in recommending travel destinations.",
"input": "Recommend a city suitable for summer travel.",
"conversation": "conversation_id_from_above"
}'
# Second round - use the same conversation id
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/responses \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"instructions": "You are a travel advisor who specializes in recommending travel destinations.",
"input": "What are the must-try foods there?",
"conversation": "conversation_id_from_above"
}'
Adicione mensagens a uma conversa.
Você pode adicionar itens de mensagem manualmente a uma conversa (como mensagens de usuário suplementares ou conhecimento externo).
items = client.conversations.items.create(
"conv_xxx", # Replace with your conversation id
items=[
{
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": "Additional info: I prefer coastal cities."}],
}
],
)
print(items.data)
const items = await client.conversations.items.create(
"conv_xxx", // Replace with your conversation id
{
items: [
{
type: "message",
role: "user",
content: [{ type: "input_text", text: "Additional info: I prefer coastal cities." }]
}
]
}
);
console.log(items.data);
curl -X POST https://maas.qwencloudapi.com/compatible-mode/v1/conversations/conv_xxx/items \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": "Additional info: I prefer coastal cities."
}]
}
]
}'
Veja o histórico de conversas.
Liste todos os itens de mensagem em uma conversa para ver o histórico completo de diálogo.
items = client.conversations.items.list("conv_xxx") # Replace with your conversation id
print(items.data)
const items = await client.conversations.items.list("conv_xxx"); // Replace with your conversation id
console.log(items.data);
curl -X GET "https://maas.qwencloudapi.com/compatible-mode/v1/conversations/conv_xxx/items?limit=20&order=asc" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY"
Notas importantes.
- ** Validade do ID**: Resposta
ide itens de mensagem em uma conversa são válidos por 7 dias. OconversationNão tem validade, mas itens expirados não participam mais do contexto. - Use a resposta de nível superior
idNão, não oidde mensagens dentro dooutputArray. - Cada vez que você passa
previous_response_id, o sistema automaticamente liga o contexto completo da conversa inicial à volta atual. - Exclusão Mutual
previous_response_ideconversationNão podem ser usados juntos. Caso contrário, você vai se enganar.[400] INVALID_REQUEST: Mutually exclusive parameters: Ensure you are only providing one of: previous_response_id or conversation. - A mensagem de conversação expira.
conversationNão tem validade e pode ser usado continuamente. No entanto, os itens de mensagem dentro dele expiram após 7 dias e não aparecerão mais no contexto de conversa. Recomendamos que o sistema passe através doinstructionsparâmetro em vez de através de itens ao criar uma conversa, para evitar perder instruções do sistema devido à expiração.
Qual abordagem escolher?
Aproxime-se # # Melhor para
| Aproxime-se. | Melhor para |
|---|---|
previous_response_id |
Conversas simples e acorrentadas sem criar uma sessão separada |
conversation |
Gerenciamento de sessão do lado do servidor, continuidade de dispositivos cruzados, ou mensagem manual add/delete |
Para mais operações de API de conversas (conversar, excluir conversas, apagar mensagens, etc.), veja [Conversas] (/api-reference/platform-api/conversations).
Indo ao vivo
Conversas multi-turnos podem consumir muitos símbolos e podem exceder o limite de contexto do modelo. Use essas estratégias para gerenciar os custos de contexto e controle.
1. Gestão de contexto
O messages O array cresce com cada rodada e pode exceder o limite de fichas.
1.1. Contexto truncado
Quando a história da conversa se torna muito longa, mantenha apenas as últimas rodadas de N de conversa. Este método é simples de implementar, mas resulta na perda de informações anteriores.
1.2. Resumo de rolamento
Para comprimir dinamicamente a história da conversa e controlar o comprimento do contexto sem perder informações essenciais, resumir o contexto à medida que a conversa progride:
A. Quando a história da conversa atinge um certo comprimento, como 70% do comprimento máximo do contexto, extrai uma parte anterior da história, como a primeira metade. Então, faça uma chamada de API separada para o modelo para gerar um "síntese de memória" desta parte.
B. Quando você construir o próximo pedido, substitua o longo histórico de conversação com o "sumário de memória" e adicione as últimas rodadas de conversa.
1.3. Recuperação de vetores.
Um resumo pode causar perda de informação. Para permitir que o modelo recorde informações relevantes de um grande volume de história de conversa, mude de contexto linear passando para recuperação sob demanda:
A. Depois de cada conversa, guarde a conversa em um banco de dados vetorial.
B. Quando um usuário faz uma pergunta, recupere registros de conversa relevantes baseados em similaridade.
C. Combine os registros de conversa recuperados com a entrada mais recente do usuário e envie o conteúdo combinado para o modelo.
- Dois. Controle de custos
Input tokens aumentam a cada rodada, aumentando os custos.
2.1. Reduzir fichas de entrada
Use as estratégias de gerenciamento de contexto descritas anteriormente para reduzir os tokens de entrada e reduzir os custos.
2.2. Use modelos que suportem o cache de contexto.
O messages O array é processado e faturado repetidamente./developer-guides/run-and-scale/context-cache(disponível para selecionar Qwen modelos incluindo Qwen-Max, Qwen-Plus, Qwen-Flash, e Qwen-Coder- Reduz os custos e aumenta a velocidade de resposta.
O recurso de cache de contexto é ativado automaticamente. Não é necessário mudar o código.
Códigos de erro.
Se uma ligação falhar, veja [Mensagens de erro] (/api-reference/preparation/error-messages).