The Assistant API provides a set of development tools to help you easily manage conversation messages and call tools. This topic uses the example of building a painting assistant from scratch to help you quickly learn the basic encoding methods of the Assistant API.
The Assistant API is being deprecated. Migrate to the Responses API as an alternative. The Responses API includes multiple built-in tools and supports multi-turn context management.
Typical process
The following is a typical process for building an agent application (Assistant):
-
Create an Assistant: When you create an assistant, select a model, provide instructions, and add tools, such as a code interpreter, Quark Search, and function calling.
-
Create a Thread: When a user starts a conversation, create a session thread to track the conversation history.
-
Send a Message to the Thread: Add the user's message to the conversation.
-
Start a Run: Run the assistant on the session thread. The assistant parses the message, calls the appropriate tools or services, generates a response, and returns it to you.
Example scenario
Text generation models cannot generate images on their own. A specific text-to-image model is typically required to convert text into images. An agent application created with the Assistant API can automatically optimize the descriptive words provided by the user, enrich the details using an internet search tool, and call a text-to-image tool to generate high-quality images. For example, to generate a lifelike image of a pet cat, you only need to provide a basic description. The drawing assistant automatically refines the prompt and passes it directly to the text-to-image tool to efficiently complete the image creation task.
Procedure
The following steps guide you through the process in Python for the non-streaming output mode. For the complete Python and Java SDK code for both streaming and non-streaming output, see Complete code at the end of this topic.

Step 1: Prepare the development environment
|
|
Step 2: Create an AssistantAfter you import the Dashscope SDK, use the create method of the Assistant class to create an Assistant agent. This process involves setting the following key parameters:
In our example, the goal is to build an Assistant that focuses on painting. Because the text-to-image tool has high requirements for language understanding, we select Qwen-Max as the reasoning model to enhance the Assistant's semantic understanding and text generation capabilities. The configuration details of the agent, including its name, function description, and instructions, are clearly shown in the accompanying code snippet. To enrich the agent's functionality and practicality, we integrate two official pre-built plugins:
You can create an unlimited number of Assistants. However, frequent calls to a single model may trigger rate limiting. We recommend that you configure different models for your Assistants based on their use cases. For more information about how to use the API, see Assistants API. |
|
Step 3: Create a ThreadA Thread is a key concept in the Assistant API that represents a continuous conversation context. A Thread lets you create a session management thread when a user starts a new conversation. The Assistant can use the Thread to understand the entire conversation context and provide more coherent and relevant responses. We recommend that you:
In the painting assistant scenario, the Thread can track the user's initial request, the Assistant's preliminary suggestions, the user's feedback, and the final painting result, forming a complete creation process. This ensures the coherence and traceability of the entire creation process. For more information about how to use the API, see Threads API. |
|
Step 4: Add a Message to a ThreadYour input is passed through a Message object. The Assistant API supports sending one or more messages to a single Thread. When you create a Message, consider the following parameters:
Although there is no hard limit on the number of tokens a Thread can receive, the actual number of tokens passed to the LLM must comply with the model's maximum input length limit. For more information, see the official documentation for each Qwen series model regarding context length. In our scenario, you will send the first message in the Thread through a Message: "Please help me draw a picture of a ragdoll cat." You need to create a Message class. The detailed parameter settings are provided in the accompanying code snippet. For more information about how to use the API, see Messages. Note
After the Messages.create() method is executed, it automatically adds the message to the thread and triggers spooling. This is equivalent to completing both the message creation and sending operations at the same time, which is the default behavior of the API. |
|
Step 5: Create and execute a RunAfter a user assigns a message to a specific Thread, you can start a Run to activate the pre-set Assistant. The assistant uses all messages in the thread as context, utilizes the specified model and available plugins to intelligently respond to the user's questions, and inserts the generated answers into the thread's message sequence. In this scenario, perform the following steps:
This series of operations ensures an automated processing flow for the assistant, from receiving a question to outputting a result. For more information about how to use the API, see Runs API. Note
Many users may be using the model at the same time, which can extend the processing time. We recommend that you wait until the status shows "complete" before you perform the next operation to ensure a smooth process. |
|
Complete code
Non-streaming output
import dashscope
from http import HTTPStatus
import json
def check_status(component, operation):
if component.status_code == HTTPStatus.OK:
print(f"{operation} successful.")
return True
else:
print(f"{operation} failed. Status code: {component.status_code}, Error code: {component.code}, Error message: {component.message}")
return False
# 1. Create a painting assistant
painting_assistant = dashscope.Assistants.create(
model='qwen-max', # Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
name='Art Maestro',
description='AI assistant for painting and art knowledge',
instructions='''Provide information on painting techniques, art history, and creative guidance.
Use tools for research and image generation.''',
tools=[
{'type': 'quark_search', 'description': 'For researching art topics'},
{'type': 'text_to_image', 'description': 'For creating visual examples'}
]
)
if not check_status(painting_assistant, "Assistant creation"):
exit()
# 2. Create a new thread
thread = dashscope.Threads.create()
if not check_status(thread, "Thread creation"):
exit()
# 3. Send a message to the thread
message = dashscope.Messages.create(thread.id, content='Please help me draw a picture of a ragdoll cat.')
if not check_status(message, "Message creation"):
exit()
# 4. Run the assistant on the thread
run = dashscope.Runs.create(thread.id, assistant_id=painting_assistant.id)
if not check_status(run, "Run creation"):
exit()
# 5. Wait for the run to complete
print("Waiting for the assistant to process the request...")
run = dashscope.Runs.wait(run.id, thread_id=thread.id)
if check_status(run, "Run completion"):
print(f"Run completed, status: {run.status}")
else:
print("Run not completed.")
exit()
# 6. Retrieve and display the assistant's response
messages = dashscope.Messages.list(thread.id)
if check_status(messages, "Message retrieval"):
if messages.data:
# Display the content of the last message (the assistant's response)
last_message = messages.data[0]
print("\nAssistant's response:")
print(json.dumps(last_message, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))
else:
print("No messages found in the thread.")
else:
print("Failed to retrieve the assistant's response.")
# Tip: This code creates a painting assistant, starts a conversation about how to draw a ragdoll cat,
# and displays the assistant's answer.package com.example;
import java.util.Arrays;
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.assistants.Assistants;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ListResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.AssistantThread;
import com.alibaba.dashscope.threads.ThreadParam;
import com.alibaba.dashscope.threads.Threads;
import com.alibaba.dashscope.threads.messages.Messages;
import com.alibaba.dashscope.threads.messages.TextMessageParam;
import com.alibaba.dashscope.threads.messages.ThreadMessage;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.RunParam;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.tools.T2Image.Text2Image;
import com.alibaba.dashscope.tools.search.ToolQuarkSearch;
public class PaintingAssistant {
private static boolean checkStatus(Object response, String operation) {
if (response != null) {
System.out.println(operation + " successful.");
return true;
} else {
System.out.println(operation + " failed.");
return false;
}
}
public static void main(String[] args) {
try {
// 1. Create a painting assistant
Assistants assistants = new Assistants();
AssistantParam assistantParam = AssistantParam.builder()
// Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max")
.name("Art Maestro")
.description("AI assistant for painting and art knowledge")
.instructions("Provide information on painting techniques, art history, and creative guidance. Use tools for research and image generation.")
.tools(Arrays.asList(ToolQuarkSearch.builder().build(),Text2Image.builder().build()))
.build();
Assistant paintingAssistant = assistants.create(assistantParam);
if (!checkStatus(paintingAssistant, "Assistant creation")) {
System.exit(1);
}
// 2. Create a new thread
Threads threads = new Threads();
AssistantThread thread = threads.create(ThreadParam.builder().build());
if (!checkStatus(thread, "Thread creation")) {
System.exit(1);
}
// 3. Create and automatically send a message to the specified thread
Messages messages = new Messages();
ThreadMessage message = messages.create(thread.getId(),
TextMessageParam.builder()
.role("user")
.content("Please help me draw a picture of a ragdoll cat.")
.build());
if (!checkStatus(message, "Message creation")) {
System.exit(1);
}
// 4. Run the assistant on the thread
Runs runs = new Runs();
RunParam runParam = RunParam.builder().assistantId(paintingAssistant.getId()).build();
Run run = runs.create(thread.getId(), runParam);
if (!checkStatus(run, "Run creation")) {
System.exit(1);
}
// 5. Wait for the run to complete
System.out.println("Waiting for the assistant to process the request...");
while (true) {
if (run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
}
Thread.sleep(1000);
run = runs.retrieve(thread.getId(), run.getId());
}
if (checkStatus(run, "Run completion")) {
System.out.println("Run completed, status: " + run.getStatus());
} else {
System.out.println("Run not completed.");
System.exit(1);
}
// 6. Retrieve and display the assistant's response
ListResult<ThreadMessage> messagesList = messages.list(thread.getId(), GeneralListParam.builder().build());
if (checkStatus(messagesList, "Message retrieval")) {
if (!messagesList.getData().isEmpty()) {
// Display the last message (the assistant's response)
ThreadMessage lastMessage = messagesList.getData().get(0);
System.out.println("\nAssistant's response:");
System.out.println(lastMessage.getContent());
} else {
System.out.println("No messages found in the thread.");
}
} else {
System.out.println("Failed to retrieve the assistant's response.");
}
} catch (ApiException | NoApiKeyException | InputRequiredException | InvalidateParameter | InterruptedException e) {
e.printStackTrace();
}
}
}
Streaming output
The Java SDK does not currently support streaming calls for the image generation tool.
import dashscope
from http import HTTPStatus
import json
import sys
def check_status(response, operation):
if response.status_code == HTTPStatus.OK:
print(f"{operation} successful.")
return True
else:
print(f"{operation} failed. Status code: {response.status_code}, Error code: {response.code}, Error message: {response.message}")
sys.exit(response.status_code)
# 1. Create a painting assistant
def create_painting_assistant():
return dashscope.Assistants.create(
model='qwen-max', # Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
name='Art Maestro',
description='AI assistant for painting and art knowledge',
instructions='''Provide information on painting techniques, art history, and creative guidance.
Use tools for research and image generation.''',
tools=[
{'type': 'quark_search', 'description': 'For researching art topics'},
{'type': 'text_to_image', 'description': 'For creating visual examples'}
]
)
if __name__ == '__main__':
# Create a painting assistant
painting_assistant = create_painting_assistant()
print(painting_assistant)
check_status(painting_assistant, "Assistant creation")
# Create a new thread with an initial message
thread = dashscope.Threads.create(
messages=[{
'role': 'user',
'content': 'Please help me draw a picture of a ragdoll cat.'
}]
)
print(thread)
check_status(thread, "Thread creation")
# Create a run with streaming output
run_iterator = dashscope.Runs.create(
thread.id,
assistant_id=painting_assistant.id,
stream=True
)
# Iterate over events and messages
print("Processing request...")
for event, msg in run_iterator:
print(event)
print(msg)
# Retrieve and display the assistant's response
messages = dashscope.Messages.list(thread.id)
check_status(messages, "Message retrieval")
print("\nAssistant's response:")
print(json.dumps(messages, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))
# Tip: This script creates a painting assistant with streaming output, starts a conversation about drawing a ragdoll cat,
# and displays the assistant's responses in real time.
import java.util.Arrays;
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.assistants.Assistants;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ListResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.AssistantThread;
import com.alibaba.dashscope.threads.ThreadParam;
import com.alibaba.dashscope.threads.Threads;
import com.alibaba.dashscope.threads.messages.Messages;
import com.alibaba.dashscope.threads.messages.TextMessageParam;
import com.alibaba.dashscope.threads.messages.ThreadMessage;
import com.alibaba.dashscope.threads.runs.AssistantStreamMessage;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.RunParam;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.tools.T2Image.Text2Image;
import com.alibaba.dashscope.tools.search.ToolQuarkSearch;
import io.reactivex.Flowable;
public class PaintingAssistant {
private static boolean checkStatus(Object response, String operation) {
if (response != null) {
System.out.println(operation + " successful.");
return true;
} else {
System.out.println(operation + " failed.");
return false;
}
}
private static Assistant createPaintingAssistant() throws ApiException, NoApiKeyException {
Assistants assistants = new Assistants();
AssistantParam assistantParam = AssistantParam.builder()
// Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max")
.name("Art Maestro")
.description("AI assistant for painting and art knowledge")
.instructions("Provide information on painting techniques, art history, and creative guidance. Use tools for research and image generation.")
.tools(Arrays.asList(ToolQuarkSearch.builder().build(), Text2Image.builder().build()))
.build();
return assistants.create(assistantParam);
}
private static void runPaintingAssistant(String assistantId) throws ApiException, NoApiKeyException, InvalidateParameter, InputRequiredException, InterruptedException {
Threads threads = new Threads();
AssistantThread thread = threads.create(ThreadParam.builder().build());
if (!checkStatus(thread, "Thread creation")) {
System.exit(1);
}
// Create and automatically send a message to the specified thread
Messages messages = new Messages();
ThreadMessage message = messages.create(thread.getId(),
TextMessageParam.builder()
.role("user")
.content("Please help me draw a picture of a ragdoll cat.")
.build());
if (!checkStatus(message, "Message creation")) {
System.exit(1);
}
Runs runs = new Runs();
RunParam runParam = RunParam.builder().assistantId(assistantId).stream(true).build();
try {
System.out.println("Attempting to stream the assistant's response...");
Flowable<AssistantStreamMessage> runFlowable = runs.createStream(thread.getId(), runParam);
runFlowable.blockingForEach(assistantStreamMessage -> {
System.out.println("Event: " + assistantStreamMessage.getEvent());
System.out.println("Data: " + assistantStreamMessage.getData());
});
} catch (Exception e) {
System.out.println("Streaming failed, switching to non-streaming method.");
e.printStackTrace();
// Switch to non-streaming method
Run run = runs.create(thread.getId(), RunParam.builder().assistantId(assistantId).build());
while (true) {
if (run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
}
Thread.sleep(1000);
run = runs.retrieve(thread.getId(), run.getId());
}
System.out.println("Run completed, status: " + run.getStatus());
}
// Retrieve and display the assistant's response
GeneralListParam listParam = GeneralListParam.builder().limit(100L).build();
ListResult<ThreadMessage> messagesList = messages.list(thread.getId(), listParam);
if (checkStatus(messagesList, "Message retrieval")) {
if (!messagesList.getData().isEmpty()) {
System.out.println("\nAssistant's response:");
for (ThreadMessage threadMessage : messagesList.getData()) {
System.out.println(threadMessage.getContent());
}
} else {
System.out.println("No messages found in the thread.");
}
} else {
System.out.println("Failed to retrieve the assistant's response.");
}
}
public static void main(String[] args) {
try {
Assistant paintingAssistant = createPaintingAssistant();
if (!checkStatus(paintingAssistant, "Assistant creation")) {
System.exit(1);
}
runPaintingAssistant(paintingAssistant.getId());
} catch (ApiException | NoApiKeyException | InputRequiredException | InvalidateParameter | InterruptedException e) {
System.out.println("An error occurred while running the painting assistant:");
e.printStackTrace();
}
}
}
What to do next
To learn more about the basic operations, lifecycle, data management, and production environment practices for Assistant API components, see Manage Assistant API components.
For detailed parameter explanations for Assistant API components, see Assistant API development reference.