Getting started with Assistant API (Deprecated)

更新时间:
复制 MD 格式

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.

Important

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):

  1. 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.

  2. Create a Thread: When a user starts a conversation, create a session thread to track the conversation history.

  3. Send a Message to the Thread: Add the user's message to the conversation.

  4. 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.

image

Step 1: Prepare the development environment

  • Request permission to use plugins: You must first request permission to use the Image Generation plugin and the Quark Search plugin. Go to the Plug-ins page in the Model Studio console and click Apply for Plug-in on the corresponding card.

  • Python interpreter: The Assistant API requires Python 3.8 or later. You can check your Python version. To install a specific version of Python, see Download Python.

  • DashScope SDK: We recommend that you use the latest version of the DashScope SDK. You can use the command on the right to check your version. To install a specific version of the DashScope SDK, use pip.

  • API key: The Assistant API requires an Alibaba Cloud Model Studio API key. You can get an API key here. When you use the DashScope SDK for the first time, we recommend that you configure the API key as an environment variable to avoid exposing sensitive information.

# Check the Python interpreter version
python --version 
# Check the DashScope SDK
pip list | grep dashscope 
# Install DashScope SDK version 1.17.0
pip install dashscope==1.17.0

Step 2: Create an Assistant

After 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:

  • model: the name of the large language model, used to configure the LLM for the agent

  • name: the name of the agent, used to distinguish it

  • description: a description of the agent's function

  • instructions: instructions in natural language that define the agent's role and task

  • tools: a list of tools configured for the agent

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:

  • Quark Search, which helps the agent retrieve extensive text information about pet cats.

  • Image Generation, which ensures the agent can automatically generate corresponding image content based on the received text descriptions.

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.

import dashscope

# Create a new painting assistant using Qwen-Max
painting_assistant = dashscope.Assistants.create(
    model='qwen-max',  # Use the Qwen-Max model for enhanced understanding. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
    name='Art Maestro',  # The assistant's name is "Art Maestro"
    description='An AI assistant specializing in painting and art knowledge.',
    instructions='''You are an expert painting assistant. Provide detailed information about painting techniques, art history, and creative guidance.
    Use Quark Search to find accurate information about art topics, and use the image generation tool to create visual examples when needed.''',
    tools=[
        {
            'type': 'quark_search',  # A tool for searching extensive information
            'description': 'Use this tool to find detailed information about painting techniques, art history, and artists.'
        },
        {
            'type': 'text_to_image',  # A tool for generating images based on descriptions
            'description': 'Use this tool to create visual examples of a painting style, technique, or art concept.'
        }
    ]
)

# Print the assistant's ID to confirm successful creation
print(f"Painting assistant 'Art Maestro' created successfully, ID: {painting_assistant.id}")

Step 3: Create a Thread

A 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:

  • Create a new Thread for each new user or new conversation topic.

  • Continue to use the same Thread when you need to maintain context.

  • Consider creating a new Thread when the conversation topic changes significantly to avoid context confusion.

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.

from http import HTTPStatus
import dashscope

# Create a new empty thread
thread = dashscope.Threads.create()

# Check if the thread was created successfully
if thread.status_code == HTTPStatus.OK:
    print(f"Thread created successfully. Thread ID: {thread.id}")
    print("You can now start a painting conversation with the AI assistant.")
else:
    print(f"Thread creation failed. Status code: {thread.status_code}")
    print(f"Error code: {thread.code}")
    print(f"Error message: {thread.message}")

# Note: This empty thread can now be used to maintain the context of your painting project discussion,
# including any future messages about ragdoll cats or other painting subjects.

Step 4: Add a Message to a Thread

Your 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:

  • The unique ID of the Thread: thread_id

  • The content of the message: content

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.

from http import HTTPStatus
import dashscope


# Create a message to tell the assistant what to do.
message = dashscope.Messages.create(thread.id, content='Please help me draw a picture of a ragdoll cat.')

# Check if the message was created successfully
if message.status_code == HTTPStatus.OK:
    print('Message created successfully! Message ID: %s' % message.id)
else:
    print('Message creation failed. Status code: %s, Error code: %s, Error message: %s' % (message.status_code, message.code, message.message))

Step 5: Create and execute a Run

After 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:

  1. Initialize a run object to drive the painting assistant, passing the thread ID (thread.id) and assistant ID (assistant.id).

  2. Use the run object's wait method (Run.wait) until the execution is complete.

  3. Use the message list method (Messages.list) to retrieve the pet cat picture drawn by the assistant.

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.

from http import HTTPStatus
import json
import dashscope


# Create a new run to execute the message
run = dashscope.Runs.create(thread.id, assistant_id=painting_assistant.id)
if run.status_code != HTTPStatus.OK:
    print('Failed to create assistant, Status code: %s, Error code: %s, Error message: %s' % (run.status_code, run.code, run.message))
else:
    print('Assistant created successfully, ID: %s' % run.id)

# Wait for the run to complete or require action
run = dashscope.Runs.wait(run.id, thread_id=thread.id)
if run.status_code != HTTPStatus.OK:
    print('Failed to get run status, Status code: %s, Error code: %s, Error message: %s' % (run.status_code, run.code, run.message))
else:
    print(run)

# Get the thread messages to get the run output
msgs = dashscope.Messages.list(thread.id)
if msgs.status_code != HTTPStatus.OK:
    print('Failed to get messages, Status code: %s, Error code: %s, Error message: %s' % (msgs.status_code, msgs.code, msgs.message))
else:
    print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4))

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.