This topic provides examples of how to use assistants.
Important
To run the following examples, you must have Python SDK version 1.18.0 or later. Run pip install -U dashscope to update.
For Java SDK, version 2.14.2 or later is required.
Sample assistant
import os
import json
import sys
from http import HTTPStatus
from dashscope import Assistants, Messages, Runs, Threads
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant():
# create an assistant with the required details
assistant = Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant.', # noqa E501
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
print('Failed: ')
print(res)
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant()
print(assistant)
verify_status_code(assistant)
# create thread.
thread = Threads.create(
messages=[{
'role': 'user',
'content': 'How to make beef and potato stew?'
}])
print(thread)
verify_status_code(thread)
# create run
run = Runs.create(thread.id, assistant_id=assistant.id)
print(run)
verify_status_code(run)
# Wait for the run to complete or require action
run_status = Runs.wait(run.id, thread_id=thread.id)
print(run_status)
# get the thread messages.
msgs = Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))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.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void assistantUsage() throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Assistants assistants = new Assistants();
// build assistant parameters
AssistantParam param = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max")
.name("intelligent guide")
.description("a smart guide")
.instructions("You are a helpful assistant.")
.build();
Assistant assistant = assistants.create(param);
// create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
// create a message to thread
Messages messages = new Messages();
ThreadMessage message = messages.create(assistantThread.getId(), TextMessageParam.builder().role("user").content("How to make beef and potato stew?").build());
System.out.println(message);
// create run
Runs runs = new Runs();
RunParam runParam = RunParam.builder().assistantId(assistant.getId()).build();
Run run = runs.create(assistantThread.getId(), runParam);
System.out.println(run);
// wait for run completed
while(true){
if(run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION)||
run.getStatus().equals(Run.Status.EXPIRED)){
break;
}else{
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), GeneralListParam.builder().build());
System.out.println(threadMessages);
}
public static void main(String[] args) throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
assistantUsage();
}
}
Assistant example (streaming mode)
import os
import json
import sys
from http import HTTPStatus
from dashscope import Assistants, Messages, Runs, Threads
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant():
# create an assistant with the required details
assistant = Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant.', # noqa E501
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
print('Failed: ')
print(res)
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant()
print(assistant)
verify_status_code(assistant)
# create thread.
thread = Threads.create(
messages=[{
'role': 'user',
'content': 'How to make beef and potato stew?'
}])
print(thread)
verify_status_code(thread)
# create run with stream.
run_iterator = Runs.create(thread.id,
assistant_id=assistant.id,
stream=True)
# iterator over the event and message.
for event, msg in run_iterator:
print(event)
print(msg)
# get the thread messages.
msgs = Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))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 io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void assistantUsage() throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Assistants assistants = new Assistants();
// build assistant parameters
AssistantParam param = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max")
.name("intelligent guide")
.description("a smart guide")
.instructions("You are a helpful assistant.")
.build();
Assistant assistant = assistants.create(param);
// create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
// create a message to thread
Messages messages = new Messages();
ThreadMessage message = messages.create(assistantThread.getId(), TextMessageParam.builder().role("user").content("How to make beef and potato stew?").build());
System.out.println(message);
// create run
Runs runs = new Runs();
RunParam runParam = RunParam.builder().assistantId(assistant.getId()).stream(true).build();
Flowable<AssistantStreamMessage> runFlowable = runs.createStream(assistantThread.getId(), runParam);
runFlowable.blockingForEach(assistantStreamMessage->{
System.out.println("Event: " + assistantStreamMessage.getEvent());
System.out.println("data: ");
System.out.println(assistantStreamMessage.getData());
});
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), GeneralListParam.builder().build());
System.out.println(threadMessages);
}
public static void main(String[] args) throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
assistantUsage();
}
}
Function calling with assistant
import os
import json
import sys
from http import HTTPStatus
from dashscope import Assistants, Messages, Runs, Steps, Threads
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant_call_function():
# create an assistant with the required details
assistant = Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant. When asked a question, use tools wherever possible.', # noqa E501
tools=[{
'type': 'function',
'function': {
'name': 'big_add',
'description': 'Add to number',
'parameters': {
'type': 'object',
'properties': {
'left': {
'type': 'integer',
'description': 'The left operator'
},
'right': {
'type': 'integer',
'description': 'The right operator.'
}
},
'required': ['left', 'right']
}
}
}],
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
print('Failed: ')
print(res)
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant_call_function()
print(assistant)
verify_status_code(assistant)
# create thread.
thread = Threads.create()
print(thread)
verify_status_code(thread)
# create a message.
message = Messages.create(thread.id, content='Add 87787 to 788988737.')
print(message)
verify_status_code(message)
# create a new run to run message
message_run = Runs.create(thread.id, assistant_id=assistant.id)
print(message_run)
verify_status_code(message_run)
# Get run status
run_status = Runs.get(message_run.id, thread_id=thread.id)
print(run_status)
verify_status_code(run_status)
# wait for run completed or requires_action
run_status = Runs.wait(message_run.id, thread_id=thread.id)
print(run_status)
# if prompt input tool result, submit tool result.
# should call big_add
if run_status.required_action:
tool_outputs = [{
'output':
'789076524'
}]
run = Runs.submit_tool_outputs(message_run.id,
thread_id=thread.id,
tool_outputs=tool_outputs)
print(run)
verify_status_code(run)
# wait for run completed or requires_action
run_status = Runs.wait(message_run.id, thread_id=thread.id)
print(run_status)
verify_status_code(run_status)
run_steps = Steps.list(run.id, thread_id=thread.id)
print(run_steps)
verify_status_code(run_steps)
# get the thread messages.
msgs = Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.tools.ToolFunction;
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.RequiredAction;
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.threads.runs.SubmitToolOutputsParam;
import com.alibaba.dashscope.threads.runs.ToolOutput;
import com.alibaba.dashscope.tools.FunctionDefinition;
import com.alibaba.dashscope.tools.ToolCallBase;
import com.alibaba.dashscope.utils.JsonUtils;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import com.github.victools.jsonschema.generator.SchemaVersion;
import com.alibaba.dashscope.tools.ToolCallFunction;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
public class AddFunctionTool {
private int left;
private int right;
public AddFunctionTool(int left, int right) {
this.left = left;
this.right = right;
}
public int call() {
return left + right;
}
}
static ToolFunction buildFunction() {
SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12,
OptionPreset.PLAIN_JSON);
SchemaGeneratorConfig config = configBuilder.with(Option.EXTRA_OPEN_API_FORMAT_VALUES)
.without(Option.FLATTENED_ENUMS_FROM_TOSTRING).build();
SchemaGenerator generator = new SchemaGenerator(config);
// generate jsonSchema of function.
ObjectNode jsonSchema = generator.generateSchema(AddFunctionTool.class);
// call with tools of function call, jsonSchema.toString() is jsonschema String.
FunctionDefinition fd = FunctionDefinition.builder().name("add").description("add two number")
.parameters(JsonUtils.parseString(jsonSchema.toString()).getAsJsonObject()).build();
return ToolFunction.builder().function(fd).build();
}
static public Assistant createAssistant() throws ApiException, NoApiKeyException{
AssistantParam assistantParam = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max") // model must be set.
.description("a helper assistant")
.name("system") // name must be set.
.instructions("You are a helpful assistant. When asked a question, use tools wherever possible.")
.tool(buildFunction())
.build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
static public void run(String assistantId) throws ApiException, NoApiKeyException, InvalidateParameter, InputRequiredException, InterruptedException{
// create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
Runs runs = new Runs();
// create a new message
TextMessageParam textMessageParam = TextMessageParam.builder().role("user").content("Add 87787 to 788988737.").build();
Messages messages = new Messages();
ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);
System.out.println(threadMessage);
RunParam runParam = RunParam.builder().assistantId(assistantId).build();
Run run = runs.create(assistantThread.getId(), runParam);
while(true){
if(run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION)||
run.getStatus().equals(Run.Status.EXPIRED)){
break;
}else{
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
if(run.getStatus().equals(Run.Status.REQUIRES_ACTION)){
// submit action output.
RequiredAction requiredAction = run.getRequiredAction();
if(requiredAction.getType().equals("submit_tool_outputs")){
ToolCallBase toolCall = requiredAction.getSubmitToolOutputs().getToolCalls().get(0);
if (toolCall.getType().equals("function")) {
// get function call name and argument, both String.
String functionName = ((ToolCallFunction) toolCall).getFunction().getName();
String functionArgument = ((ToolCallFunction) toolCall).getFunction().getArguments();
if (functionName.equals("add")) {
// Create the function object.
AddFunctionTool addFunction =
JsonUtils.fromJson(functionArgument, AddFunctionTool.class);
// call function.
int sum = addFunction.call();
System.out.println(sum);
SubmitToolOutputsParam submitToolOutputsParam = SubmitToolOutputsParam.builder()
.toolOutput(ToolOutput.builder().toolCallId("").output(String.valueOf(sum)).build())
.build();
run = runs.submitToolOutputs(assistantThread.getId(), run.getId(), submitToolOutputsParam);
}
}
}
}
while(true){
if(run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION)||
run.getStatus().equals(Run.Status.EXPIRED)){
break;
}else{
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
GeneralListParam listParam = GeneralListParam.builder().limit(100l).build();
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), listParam);
for(ThreadMessage threadMessage2: threadMessages.getData()){
System.out.println(threadMessage2);
}
}
public static void main(String[] args) throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Assistant assistant = createAssistant();
run(assistant.getId());
}
}
Function calling with assistant (streaming mode)
The following Java code provides a complete example of generating a JSON schema, including description fields.
# yapf: disable
import os
import json
import sys
from http import HTTPStatus
import dashscope
from dashscope import Assistants, Messages, Runs, Steps, Threads
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant_call_function():
# create an assistant with the required details
assistant = Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant. When asked a question, use tools wherever possible.', # noqa E501
tools=[{
'type': 'function',
'function': {
'name': 'big_add',
'description': 'Add to number',
'parameters': {
'type': 'object',
'properties': {
'left': {
'type': 'integer',
'description': 'The left operator'
},
'right': {
'type': 'integer',
'description': 'The right operator.'
}
},
'required': ['left', 'right']
}
}
}],
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
print('Failed: ')
print(res)
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant_call_function()
print(assistant)
verify_status_code(assistant)
# create run
run_iterator = Runs.create_thread_and_run(thread={'messages': [{
'role': 'user',
'content': 'What is transformer? Explain it in simple terms.'
}]}, assistant_id=assistant.id, stream=True)
thread = None
for event, run in run_iterator:
print(event)
print(run)
if event == 'thread.created':
thread = run
verify_status_code(run)
run_status = Runs.get(run.id, thread_id=thread.id)
print(run_status)
verify_status_code(run_status)
# list run steps
run_steps = Steps.list(run.id, thread_id=thread.id)
print(run_steps)
verify_status_code(run_steps)
# create a message.
message = Messages.create(thread.id, content='Add 87787 to 788988737.')
print(message)
verify_status_code(message)
# create a new run to run message
responses = Runs.create(thread.id, assistant_id=assistant.id, stream=True)
for event, message_run in responses:
print(event)
print(message_run)
verify_status_code(message_run)
# Get run status
run_status = Runs.get(message_run.id, thread_id=thread.id)
print(run_status)
verify_status_code(run_status)
# if prompt input tool result, submit tool result.
# should call big_add
if run_status.required_action:
tool_outputs = [{
'output':
'789076524'
}]
# Submit tool outputs with stream.
responses = Runs.submit_tool_outputs(message_run.id,
thread_id=thread.id,
tool_outputs=tool_outputs,
stream=True)
for event, run in responses:
print(event)
print(run)
verify_status_code(run)
run_status = Runs.get(run.id, thread_id=thread.id)
print(run_status)
verify_status_code(run_status)
run_steps = Steps.list(run.id, thread_id=thread.id)
print(run_steps)
verify_status_code(run_steps)
# get the thread messages.
msgs = Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, ensure_ascii=False, default=lambda o: o.__dict__, sort_keys=True, indent=4))
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.tools.ToolFunction;
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.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.RequiredAction;
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.threads.runs.SubmitToolOutputsParam;
import com.alibaba.dashscope.threads.runs.ThreadAndRunParam;
import com.alibaba.dashscope.threads.runs.ToolOutput;
import com.alibaba.dashscope.tools.FunctionDefinition;
import com.alibaba.dashscope.tools.ToolCallBase;
import com.alibaba.dashscope.tools.wanx.ToolWanX;
import com.alibaba.dashscope.utils.JsonUtils;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import com.github.victools.jsonschema.generator.SchemaVersion;
import com.github.victools.jsonschema.generator.TypeScope;
import com.github.victools.jsonschema.generator.MemberScope;
import io.reactivex.Flowable;
import com.alibaba.dashscope.tools.ToolCallFunction;
import com.alibaba.dashscope.utils.Constants;
public class AssistantFunctionCallStream {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface JsonDescription {
String value();
}
private static String resolveJsonDescription(MemberScope<?, ?> member) {
JsonDescription jsonDescription = member.getAnnotationConsideringFieldAndGetterIfSupported(JsonDescription.class);
if (jsonDescription != null) {
return jsonDescription.value();
}
return null;
}
private static String resolveDescriptionForType(TypeScope scope) {
Class<?> rawType = scope.getType().getErasedType();
JsonDescription jsonDescription = rawType.getAnnotation(JsonDescription.class);
if (jsonDescription != null) {
return jsonDescription.value();
}
return null;
}
@JsonDescription("Add two numbers.")
public class AddFunctionTool {
@JsonDescription("The left operator")
private Integer left;
@JsonDescription("The right operator")
private Integer right;
public AddFunctionTool(int left, int right) {
this.left = left;
this.right = right;
}
public int call() {
return left + right;
}
}
static ToolFunction buildFunction() {
SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(
SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON);
configBuilder.forFields().withDescriptionResolver(AssistantFunctionCallStream::resolveJsonDescription);
configBuilder.forTypesInGeneral().withDescriptionResolver(AssistantFunctionCallStream::resolveDescriptionForType);
SchemaGeneratorConfig config = configBuilder.with(Option.EXTRA_OPEN_API_FORMAT_VALUES)
.without(Option.FLATTENED_ENUMS_FROM_TOSTRING)
.build();
SchemaGenerator generator = new SchemaGenerator(config);
// generate jsonSchema of function.
ObjectNode jsonSchema = generator.generateSchema(AddFunctionTool.class);
// call with tools of function call, jsonSchema.toString() is jsonschema String.
FunctionDefinition fd = FunctionDefinition.builder().name("add")
.description("add two number")
.parameters(JsonUtils.parseString(jsonSchema.toString()).getAsJsonObject()).build();
return ToolFunction.builder().function(fd).build();
}
static public Assistant createAssistant() throws ApiException, NoApiKeyException {
AssistantParam assistantParam = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// This uses qwen-max as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max") // model must be set.
.description("a helper assistant").name("system") // name must be set.
.instructions(
"You are a helpful assistant. When asked a question, use tools wherever possible.")
.tool(buildFunction()).tool(ToolWanX.builder().build()).build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
static public void streamRun(String assistantId)
throws ApiException, NoApiKeyException, InvalidateParameter, InputRequiredException {
Runs runs = new Runs();
ThreadParam threadParam = ThreadParam.builder()
.message(TextMessageParam.builder().role("user")
.content("What is transformer? Explain it in simple terms.").build())
.build();
ThreadAndRunParam threadAndRunParam =
ThreadAndRunParam.builder().thread(threadParam).stream(true) // set stream output
.assistantId(assistantId).build();
Flowable<AssistantStreamMessage> streamResponse =
runs.createStreamThreadAndRun(threadAndRunParam);
final List<AssistantStreamMessage> assistantStreamMessages = new ArrayList<>();
streamResponse.blockingForEach(assistantStreamMessage -> {
System.out.println("Event: " + assistantStreamMessage.getEvent());
System.out.println("data: ");
System.out.println(assistantStreamMessage.getData());
assistantStreamMessages.add(assistantStreamMessage);
});
AssistantThread thread = (AssistantThread) assistantStreamMessages.get(0).getData();
Run run = (Run) assistantStreamMessages.get(assistantStreamMessages.size() - 1).getData();
// retrieve run
run = runs.retrieve(thread.getId(), run.getId());
// list steps
runs.listSteps(thread.getId(), run.getId(), GeneralListParam.builder().build());
// create a new message
TextMessageParam textMessageParam =
TextMessageParam.builder().role("user").content("Add 87787 to 788988737.").build();
Messages messages = new Messages();
ThreadMessage threadMessage = messages.create(thread.getId(), textMessageParam);
System.out.println(threadMessage);
RunParam runParam = RunParam.builder().assistantId(assistantId).stream(true).build();
streamResponse = runs.createStream(thread.getId(), runParam);
assistantStreamMessages.clear();;
streamResponse.blockingForEach(assistantStreamMessage -> {
System.out.println("Event: " + assistantStreamMessage.getEvent());
System.out.println("data: ");
System.out.println(assistantStreamMessage.getData());
assistantStreamMessages.add(assistantStreamMessage);
});
run = (Run) assistantStreamMessages.get(assistantStreamMessages.size() - 1).getData();
if (run.getStatus().equals(Run.Status.REQUIRES_ACTION)) {
// submit action output.
RequiredAction requiredAction = run.getRequiredAction();
if (requiredAction.getType().equals("submit_tool_outputs")) {
ToolCallBase toolCall = requiredAction.getSubmitToolOutputs().getToolCalls().get(0);
if (toolCall.getType().equals("function")) {
// get function call name and argument, both String.
String functionName = ((ToolCallFunction) toolCall).getFunction().getName();
String functionArgument =
((ToolCallFunction) toolCall).getFunction().getArguments();
if (functionName.equals("add")) {
// Create the function object.
AddFunctionTool addFunction =
JsonUtils.fromJson(functionArgument, AddFunctionTool.class);
// call function.
int sum = addFunction.call();
System.out.println(sum);
SubmitToolOutputsParam submitToolOutputsParam =
SubmitToolOutputsParam.builder()
.toolOutput(ToolOutput.builder().toolCallId("")
.output(String.valueOf(sum)).build())
.stream(true).build();
streamResponse = runs.submitStreamToolOutputs(thread.getId(), run.getId(),
submitToolOutputsParam);
assistantStreamMessages.clear();
streamResponse.blockingForEach(assistantStreamMessage -> {
System.out.println("Event: " + assistantStreamMessage.getEvent());
System.out.println("data: ");
System.out.println(assistantStreamMessage.getData());
assistantStreamMessages.add(assistantStreamMessage);
});
}
}
}
}
GeneralListParam listParam = GeneralListParam.builder().limit(100l).build();
ListResult<ThreadMessage> threadMessages = messages.list(thread.getId(), listParam);
for (ThreadMessage threadMessage2 : threadMessages.getData()) {
System.out.println(threadMessage2);
}
}
public static void main(String[] args)
throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter {
Assistant assistant = createAssistant();
streamRun(assistant.getId());
}
}
Tool calling with assistant
Important
You may need to apply for some of the tools.
Supported tools list
Tool | Description |
text_to_image | Generates images from text prompts |
code_interpreter | The code interpreter plug-in. |
Text-to-image sample
import os
import json
import sys
from http import HTTPStatus
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant():
# create an assistant with the required details
assistant = dashscope.Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Here, qwen-max is used as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant. When asked a question, use tools wherever possible.', # noqa E501
tools=[{
'type': 'text_to_image'
}],
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant()
print(assistant)
verify_status_code(assistant)
# create a thread.
thread = dashscope.Threads.create()
print(thread)
verify_status_code(thread)
# create a message.
message = dashscope.Messages.create(thread.id, content='Draw a picture of a cute kitten lying on the sofa.')
print(message)
verify_status_code(message)
# create a new run to run message
message_run = dashscope.Runs.create(thread.id, assistant_id=assistant.id)
print(message_run)
verify_status_code(message_run)
# get run statue
run = dashscope.Runs.get(message_run.id, thread_id=thread.id)
print(run)
verify_status_code(run)
# print run status, to verify run is completed.
print(run.status)
# Wait for the run to complete or require action
run = dashscope.Runs.wait(run.id, thread_id=thread.id)
print(run)
run = dashscope.Runs.get(run.id, thread_id=thread.id)
print(run)
verify_status_code(run)
run_steps = dashscope.Steps.list(run.id, thread_id=thread.id)
print(run_steps)
verify_status_code(run_steps)
# get the thread messages.
msgs = dashscope.Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4, ensure_ascii=False))
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.utils.Constants;
public class AssistantCallWanx {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
static public Assistant createAssistant() throws ApiException, NoApiKeyException{
AssistantParam assistantParam = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// Here, qwen-max is used as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-plus") // model must be set.
.description("a helper assistant")
.name("system") // name must be set.
.instructions("You are a helpful assistant. When asked a question, use tools wherever possible.")
.tool(Text2Image.builder().build())
.build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
static public void run(String assistantId) throws ApiException, NoApiKeyException, InvalidateParameter, InputRequiredException, InterruptedException{
// create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
Runs runs = new Runs();
// create a new message
TextMessageParam textMessageParam = TextMessageParam.builder().role("user").content("Generate a Jiuzhaigou landscape painting").build();
Messages messages = new Messages();
ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);
System.out.println(threadMessage);
RunParam runParam = RunParam.builder().assistantId(assistantId).build();
Run run = runs.create(assistantThread.getId(), runParam);
while(true){
if(run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION)||
run.getStatus().equals(Run.Status.EXPIRED)){
break;
}else{
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
GeneralListParam listParam = GeneralListParam.builder().limit(100l).build();
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), listParam);
for(ThreadMessage threadMessage2: threadMessages.getData()){
System.out.println(threadMessage2);
}
}
public static void main(String[] args) throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Assistant assistant = createAssistant();
run(assistant.getId());
}
}Code interpreter sample
import os
import json
import sys
from http import HTTPStatus
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant():
# create an assistant with the required details
assistant = dashscope.Assistants.create(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Here, qwen-max is used as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant. When asked a question, use tools wherever possible.', # noqa E501
tools=[{
'type': 'code_interpreter'
}],
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
sys.exit(res.status_code)
if __name__ == '__main__':
# create assistant
assistant = create_assistant()
print(assistant)
verify_status_code(assistant)
# create a thread.
thread = dashscope.Threads.create()
print(thread)
verify_status_code(thread)
# create a message.
message = dashscope.Messages.create(thread.id, content='There are several chickens and rabbits in a cage. They have altogether 100 heads and 334 feet. Please use a tool to calculate how many chickens and rabbits are in the cage.')
print(message)
verify_status_code(message)
# create a new run to run message
message_run = dashscope.Runs.create(thread.id, assistant_id=assistant.id)
print(message_run)
verify_status_code(message_run)
# get run statue
run = dashscope.Runs.get(message_run.id, thread_id=thread.id)
print(run)
verify_status_code(run)
# print run status, to verify run is completed.
print(run.status)
# Wait for the run to complete or require action
run = dashscope.Runs.wait(run.id, thread_id=thread.id)
print(run)
run = dashscope.Runs.get(run.id, thread_id=thread.id)
print(run)
verify_status_code(run)
run_steps = dashscope.Steps.list(run.id, thread_id=thread.id)
print(run_steps)
verify_status_code(run_steps)
# get the thread messages.
msgs = dashscope.Messages.list(thread.id)
print(msgs)
print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4, ensure_ascii=False))
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.codeinterpretertool.ToolCodeInterpreter;
import com.alibaba.dashscope.utils.Constants;
public class AssistantCallCode {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
static public Assistant createAssistant() throws ApiException, NoApiKeyException{
AssistantParam assistantParam = AssistantParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// Here, qwen-max is used as an example. You can change the model name as needed. Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
.model("qwen-max") // model must be set.
.description("a helper assistant")
.name("system") // name must be set.
.instructions("You are a helpful assistant. When asked a question, use tools wherever possible.")
.tool(ToolCodeInterpreter.builder().build())
.build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
static public void run(String assistantId) throws ApiException, NoApiKeyException, InvalidateParameter, InputRequiredException, InterruptedException{
// create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
Runs runs = new Runs();
// create a new message
TextMessageParam textMessageParam = TextMessageParam.builder().role("user").content("There are several chickens and rabbits in a cage. They have altogether 100 heads and 334 feet. Please use a tool to calculate how many chickens and rabbits are in the cage.").build();
Messages messages = new Messages();
ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);
System.out.println(threadMessage);
RunParam runParam = RunParam.builder().assistantId(assistantId).build();
Run run = runs.create(assistantThread.getId(), runParam);
while(true){
if(run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION)||
run.getStatus().equals(Run.Status.EXPIRED)){
break;
}else{
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
GeneralListParam listParam = GeneralListParam.builder().limit(100l).build();
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), listParam);
for(ThreadMessage threadMessage2: threadMessages.getData()){
System.out.println(threadMessage2);
}
}
public static void main(String[] args) throws ApiException, NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Assistant assistant = createAssistant();
run(assistant.getId());
}
}