All Products
Search
Document Center

Alibaba Cloud Model Studio:Runs

Last Updated:Mar 12, 2026

Run mengeksekusi assistant pada sebuah thread. Saat Anda membuat run, assistant memproses semua pesan dalam thread tersebut dan menambahkan responsnya sebagai pesan baru.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Cara kerja runs

Run melewati siklus hidup berikut ini:

queued --> in_progress --> completed
                      \-> requires_action --> (submit tool outputs) --> queued ...
                      \-> failed
                      \-> cancelled
                      \-> expired
                      \-> incomplete
  1. queued: Run sedang dalam antrean untuk diproses.

  2. in_progress: Assistant sedang memproses pesan-pesan dalam thread.

  3. requires_action: Assistant memanggil tool fungsi dan menunggu output dari tool tersebut. Kirimkan output melalui titik akhir Submit tool outputs untuk melanjutkan run.

  4. completed: Run berhasil selesai. Ambil respons assistant dari pesan-pesan dalam thread.

  5. failed: Run mengalami error. Periksa last_error untuk detailnya.

  6. cancelled: Run dibatalkan.

  7. expired: Run melebihi batas waktu sebelum selesai.

  8. incomplete: Run berakhir tanpa menyelesaikan seluruh proses.

  9. cancelling: Proses pembatalan sedang berlangsung.

Catatan

Assistants API tidak menyediakan titik akhir khusus untuk pembatalan. Implementasikan logika pembatalan di aplikasi Anda jika diperlukan.

Operasi API

OperationMethodEndpoint
Create a runPOST/api/v1/threads/{thread_id}/runs
List runsGET/api/v1/threads/{thread_id}/runs
Retrieve a runGET/api/v1/threads/{thread_id}/runs/{run_id}
Modify a runPOST/api/v1/threads/{thread_id}/runs/{run_id}
Submit tool outputsPOST/api/v1/threads/{thread_id}/runs/{run_id}/submit_tool_outputs
Wait for a runSDK onlyN/A

Base URL: https://dashscope-intl.aliyuncs.com/api/v1

Create a run

POST /api/v1/threads/{thread_id}/runs

Memulai assistant pada sebuah thread. Mendukung respons streaming maupun non-streaming.

Parameter permintaan

ParameterTypeRequiredDescription
thread_idstringYesID thread. Ditentukan dalam path URL.
assistant_idstringYesAsisten yang akan dijalankan.
modelstringNoMengganti model yang ditentukan dalam assistant. Contoh: qwen-max, qwen-plus.
instructionsstringNoMengganti instruksi yang ditentukan dalam assistant.
toolsarrayNoMengganti daftar tool yang ditentukan dalam assistant. Lihat Tool authentication untuk detail autentikasi plug-in.
metadataobjectNoPasangan kunci-nilai yang akan disambungkan ke run.
streambooleanNoAtur ke true untuk respons streaming melalui server-sent events (SSE). Default: false.
temperaturefloatNoMengontrol tingkat keacakan. Nilai yang lebih tinggi menghasilkan output yang lebih bervariasi.
top_pfloatNoAmbang batas probabilitas untuk pengambilan sampel inti.
top_kintegerNoUkuran kumpulan token kandidat selama pengambilan sampel.
truncation_strategyobjectNoStrategi pemotongan pesan. Hanya last_messages yang didukung. Default: {"type": "last_messages", "last_messages": 10}
workspacestringNoID ruang kerja. Diperlukan hanya jika kunci API milik sub-ruang kerja.

Tool authentication

Untuk meneruskan autentikasi kustom untuk tool plug-in, sertakan bidang auth dalam definisi tool:

{
  "type": "plugin_type",
  "auth": {
    "type": "user_http",
    "user_token": "<your-bearer-token>"
  }
}

Saat assistant memanggil plug-in, token bearer tersebut akan ditambahkan ke header permintaan plug-in.

Contoh permintaan

cURL (non-streaming)

curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{
    "assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
    "metadata": {}
  }'

cURL (streaming)

curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{
    "assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
    "metadata": {},
    "stream": true
  }'

Python (streaming)

import dashscope
import os

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

stream_iterator = dashscope.Runs.create(
    '<your-thread-id>',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    assistant_id='<your-assistant-id>',
    stream=True
)

for event, msg in stream_iterator:
    print(event)
    print(msg)

Java (streaming)

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.runs.Run;
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 main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Runs runs = new Runs();
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        Run run = runs.retrieve("<your-thread-id>", "<your-run-id>", apiKey);
    }
}

Respons non-streaming

Mengembalikan objek run.

{
    "id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
    "object": "thread.run",
    "created_at": 1711517598169,
    "thread_id": "thread_cc2a3e9d-436b-482b-91c5-377e0f376506",
    "assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
    "status": "in_progress",
    "model": "qwen-max",
    "instructions": "You are an intelligent assistant. You can call different tools based on user needs to provide answers. Use tools as appropriate.",
    "tools": [
        {"type": "search"},
        {"type": "text_to_image"}
    ],
    "metadata": {},
    "request_id": "225292ff-9843-95d4-8591-b1377c33e2be"
}

Respons streaming

Mengembalikan aliran server-sent events (SSE). Setiap event memiliki bidang event dan bidang data yang berisi objek JSON.

Jenis event streaming

EventDescription
thread.createdThread baru dibuat (ketika run membuatnya).
thread.run.createdRun dibuat.
thread.run.queuedRun masuk ke antrean.
thread.run.in_progressRun mulai diproses.
thread.run.step.createdLangkah run baru dibuat.
thread.run.step.in_progressLangkah run mulai diproses.
thread.run.step.deltaPembaruan inkremental pada langkah run (misalnya, argumen pemanggilan tool).
thread.run.step.completedLangkah run selesai.
thread.message.createdPesan baru dibuat.
thread.message.in_progressPembuatan pesan dimulai.
thread.message.deltaKonten inkremental ditambahkan ke pesan.
thread.message.completedPembuatan pesan selesai.
thread.run.completedRun selesai. Berisi token usage dalam bidang usage.
doneAliran berakhir. Nilai data: [DONE].

Contoh aliran SSE (singkat)

event:thread.run.created
data:{"id":"run_04fba6a3-...","object":"thread.run","status":"queued",...}

event:thread.run.in_progress
data:{"id":"run_04fba6a3-...","object":"thread.run","status":"in_progress",...}

event:thread.message.delta
data:{"id":"message_f4f68f6b-...","object":"thread.message.delta","delta":{"content":[{"type":"text","text":{"value":"999 multiplied"}}]}}

event:thread.message.completed
data:{"id":"message_f4f68f6b-...","object":"thread.message","content":[{"type":"text","text":{"value":"999 multiplied by 998 equals 997002."}}],...}

event:thread.run.completed
data:{"id":"run_04fba6a3-...","status":"completed","usage":{"input_tokens":419,"output_tokens":16,"total_tokens":435},...}

event:done
data:[DONE]

Parameter respons SDK

SDK mengembalikan bidang tambahan di luar objek run standar:

ParameterTypeDescription
status_codeintegerKode status HTTP. 200 menunjukkan keberhasilan.
codestringKode error jika permintaan gagal. Hanya untuk Python SDK.
messagestringDetail error jika permintaan gagal. Hanya untuk Python SDK.

List runs

GET /api/v1/threads/{thread_id}/runs

Mengembalikan daftar run untuk sebuah thread.

Parameter permintaan

ParameterTypeRequiredDescription
thread_idstringYesID thread. Ditentukan dalam path URL.
limitintegerNoJumlah maksimum run yang dikembalikan. Default: 20.
orderstringNoUrutan pengurutan berdasarkan waktu pembuatan. desc (default) atau asc.

Contoh permintaan

cURL

curl 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs?limit=20&order=asc' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY"

Python

import dashscope
from dashscope import Runs
import os

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

run = Runs.retrieve(
    '<id-run-Anda>',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    thread_id='<id-thread-Anda>'
)

Java

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.runs.Run;
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 main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Runs runs = new Runs();
        GeneralListParam listRuns = GeneralListParam.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .build();
        ListResult<Run> run = runs.list("<your-thread-id>", listRuns);
    }
}

Respons

{
    "object": "list",
    "data": [
        {
            "id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
            "object": "thread.run",
            "created_at": 1711517598169,
            "thread_id": "thread_cc2a3e9d-436b-482b-91c5-377e0f376506",
            "assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
            "status": "completed",
            "model": "qwen-max",
            "tools": [
                {"type": "search"},
                {"type": "text_to_image"}
            ],
            "metadata": {},
            "usage": {
                "prompt_tokens": 66,
                "completion_tokens": 9,
                "total_tokens": 75
            }
        }
    ],
    "first_id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
    "last_id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
    "has_more": false,
    "request_id": "ff3d2aea-555c-9825-80ca-24029a636641"
}

Parameter respons

ParameterTypeDescription
dataarrayDaftar objek run.
first_idstringID run pertama dalam hasil.
last_idstringID run terakhir dalam hasil.
has_morebooleanApakah masih ada run lain yang tersedia di luar halaman ini.

Retrieve a run

GET /api/v1/threads/{thread_id}/runs/{run_id}

Mengembalikan satu run berdasarkan ID.

Parameter permintaan

ParameterTypeRequiredDescription
thread_idstringYesID thread. Ditentukan dalam path URL.
run_idstringYesID run. Ditentukan dalam path URL.

Contoh permintaan

cURL

curl 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs/run_3de634fa-75d4-4370-adcf-92ba2a60c396' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY"

Python

import dashscope
from dashscope import Runs
import os

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

run = Runs.retrieve(
    '<your-run-id>',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    thread_id='<your-thread-id>'
)

Java

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.runs.Run;
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 main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Runs runs = new Runs();
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        Run run = runs.retrieve("<your-thread-id>", "<your-run-id>", apiKey);
    }
}

Respons

Mengembalikan objek run yang sesuai dengan ID yang ditentukan.

Modify a run

POST /api/v1/threads/{thread_id}/runs/{run_id}

Memperbarui metadata run.

Parameter permintaan

ParameterTypeRequiredDescription
thread_idstringYesID thread. Ditentukan dalam path URL.
run_idstringYesID run. Ditentukan dalam path URL.
metadataobjectNoPasangan kunci-nilai yang akan diperbarui pada run.

Contoh permintaan

cURL

curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs/run_3de634fa-75d4-4370-adcf-92ba2a60c396' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{
    "metadata": {
      "user": "abc123"
    }
  }'

Python

import dashscope
from dashscope import Runs
import os

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

run = Runs.update(
    '<your-run-id>',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    thread_id='<your-thread-id>',
    metadata={'newkey': 'newvalue'}
)

Java

import java.util.HashMap;
import java.util.Map;
import com.alibaba.dashscope.common.UpdateMetadataParam;
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.runs.Run;
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 main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Runs runs = new Runs();
        Map<String, String> metadata = new HashMap<>();
        metadata.put("key", "value");
        UpdateMetadataParam updateParam = UpdateMetadataParam.builder()
                .metadata(metadata)
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .build();
        Run run = runs.update("<your-thread-id>", "<your-run-id>", updateParam);
    }
}

Respons

Mengembalikan objek run yang telah diperbarui.

Submit tool outputs and continue a run

POST /api/v1/threads/{thread_id}/runs/{run_id}/submit_tool_outputs

Ketika run memiliki status requires_action dan required_action.type bernilai submit_tool_outputs, kirimkan hasil eksekusi tool melalui titik akhir ini untuk melanjutkan run.

Penting

Kirimkan output untuk semua pemanggilan tool yang tertunda dalam satu permintaan. Pengiriman parsial tidak didukung.

Cara kerja pengiriman output tool

  1. Buat run. Assistant memproses thread dan menentukan apakah akan memanggil tool.

  2. Jika assistant memanggil tool fungsi, status run berubah menjadi requires_action.

  3. Baca array required_action.submit_tool_outputs.tool_calls dari objek run untuk mendapatkan nama fungsi, argumen, dan ID pemanggilan tool.

  4. Eksekusi fungsi dalam aplikasi Anda dan kumpulkan hasilnya.

  5. Kirimkan output tool melalui titik akhir ini.

  6. Run melanjutkan pemrosesan dan akhirnya mencapai status terminal (completed, failed, atau expired).

Parameter permintaan

ParameterTypeRequiredDescription
thread_idstringYesID thread. Ditentukan dalam path URL.
run_idstringYesID run. Harus memiliki status requires_action. Ditentukan dalam path URL.
tool_outputsarrayYesHasil pemanggilan tool yang akan dikembalikan ke assistant.
tool_outputs[].tool_call_idstringNoID pemanggilan tool dari respons required_action.
tool_outputs[].outputstringYesHasil dari eksekusi tool.
streambooleanNoAtur ke true untuk respons streaming. Default: false.

Contoh permintaan

cURL (non-streaming)

curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_9157dfad-71fd-4add-b7a9-1afa452d2d67/runs/run_99935dbd-e731-4bad-b450-60d9d6bf9a44/submit_tool_outputs' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "",
        "output": "rain"
      }
    ]
  }'

cURL (streaming)

curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_9157dfad-71fd-4add-b7a9-1afa452d2d67/runs/run_99935dbd-e731-4bad-b450-60d9d6bf9a44/submit_tool_outputs' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "",
        "output": "rain"
      }
    ],
    "stream": true
  }'

Contoh end-to-end: pemanggilan fungsi dengan output tool

Contoh berikut menunjukkan alur kerja lengkap: membuat assistant dengan fungsi kustom, menjalankannya, menangani status requires_action, mengirimkan output tool, dan mengambil respons akhir.

Python

import json
import sys
from http import HTTPStatus
import dashscope
from dashscope import Assistants, Messages, Runs, Steps, Threads

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

def create_assistant():
    # Create an assistant with a custom "big_add" function tool
    assistant = Assistants.create(
        model='qwen-max',
        name='smart helper',
        description='A tool helper.',
        instructions='You are a helpful assistant. When asked a question, use tools wherever possible.',
        tools=[{
            'type': 'tools',
            'tools': {
                '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:
        sys.exit(res.status_code)

if __name__ == '__main__':
    # Step 1: Create the assistant
    assistant = create_assistant()
    verify_status_code(assistant)

    # Step 2: Create a thread
    thread = Threads.create()
    verify_status_code(thread)

    # Step 3: Add a message to the thread
    message = Messages.create(thread.id, content='bigAdd 87787 to 788988737.')
    verify_status_code(message)

    # Step 4: Create a run
    message_run = Runs.create(thread.id, assistant_id=assistant.id)
    verify_status_code(message_run)

    # Step 5: Wait for the run to reach a terminal state
    run_status = Runs.wait(message_run.id, thread_id=thread.id)

    # Step 6: If the run requires tool output, submit it
    if run_status.required_action:
        tool_outputs = [{
            'tool_call_id':
            run_status.required_action.submit_tool_outputs.tool_calls[0].id,
            'output':
            '789076524'
        }]
        run = Runs.submit_tool_outputs(
            message_run.id,
            thread_id=thread.id,
            tool_outputs=tool_outputs
        )
        verify_status_code(run)

        # Step 7: Wait for the run to complete after submitting tool output
        run_status = Runs.wait(message_run.id, thread_id=thread.id)
        verify_status_code(run_status)

    # Step 8: Retrieve the thread messages
    msgs = Messages.list(thread.id)
    print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4))

Java

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 AssistantFunctionCall {
    static {
        Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
    }

    // Custom function tool: adds two numbers
    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);

        ObjectNode jsonSchema = generator.generateSchema(AddFunctionTool.class);

        FunctionDefinition fd = FunctionDefinition.builder()
                .name("add")
                .description("add two numbers")
                .parameters(JsonUtils.parseString(jsonSchema.toString()).getAsJsonObject())
                .build();
        return ToolFunction.builder().function(fd).build();
    }

    // Step 1: Create an assistant with a custom function tool
    static public Assistant createAssistant() throws ApiException, NoApiKeyException {
        AssistantParam assistantParam = AssistantParam.builder()
                .model("qwen-max")
                .description("a helper assistant")
                .name("system")
                .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 {
        // Step 2: Create a thread
        Threads threads = new Threads();
        AssistantThread assistantThread = threads.create(ThreadParam.builder().build());

        // Step 3: Add a message and create a run
        Messages messages = new Messages();
        TextMessageParam textMessageParam = TextMessageParam.builder()
                .role("user")
                .content("Add 87787 to 788988737.")
                .build();
        ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);

        Runs runs = new Runs();
        RunParam runParam = RunParam.builder().assistantId(assistantId).build();
        Run run = runs.create(assistantThread.getId(), runParam);

        // Step 4: Poll until the run reaches a terminal state
        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());
        }

        // Step 5: Handle requires_action by submitting tool output
        if (run.getStatus().equals(Run.Status.REQUIRES_ACTION)) {
            RequiredAction requiredAction = run.getRequiredAction();
            if (requiredAction.getType().equals("submit_tool_outputs")) {
                ToolCallBase toolCall = requiredAction.getSubmitToolOutputs()
                        .getToolCalls().get(0);
                if (toolCall.getType().equals("function")) {
                    String functionName = ((ToolCallFunction) toolCall).getFunction().getName();
                    String functionId = ((ToolCallFunction) toolCall).getId();
                    String functionArgument = ((ToolCallFunction) toolCall)
                            .getFunction().getArguments();
                    if (functionName.equals("add")) {
                        AddFunctionTool addFunction =
                                JsonUtils.fromJson(functionArgument, AddFunctionTool.class);
                        int sum = addFunction.call();
                        SubmitToolOutputsParam submitToolOutputsParam =
                                SubmitToolOutputsParam.builder()
                                        .toolOutput(ToolOutput.builder()
                                                .toolCallId(functionId)
                                                .content(String.valueOf(sum))
                                                .build())
                                        .build();
                        run = runs.submitToolOutputs(
                                assistantThread.getId(), run.getId(), submitToolOutputsParam);
                    }
                }
            }
        }

        // Step 6: Poll again until the run completes
        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());
        }

        // Step 7: Retrieve the final messages
        GeneralListParam listParam = GeneralListParam.builder().limit(100L).build();
        ListResult<ThreadMessage> threadMessages =
                messages.list(assistantThread.getId(), listParam);
        for (ThreadMessage msg : threadMessages.getData()) {
            System.out.println(msg);
        }
    }

    public static void main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Assistant assistant = createAssistant();
        run(assistant.getId());
    }
}

Respons

Mengembalikan objek run yang telah diperbarui. Saat run dilanjutkan, statusnya berubah dari requires_action menjadi queued.

Wait for a run to complete

Hanya SDK — Memblokir hingga run mencapai status terminal: cancelled, failed, completed, expired, atau requires_action.

Kode contoh

Python

import dashscope
from dashscope import Runs
import os

dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

run = Runs.wait(
    '<your-run-id>',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    thread_id='<your-thread-id>'
)

Java

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.runs.Run;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.utils.Constants;

public class AssistantFunctionCall {
    static {
        Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
    }

    public static void main(String[] args) throws ApiException, NoApiKeyException,
            InputRequiredException, InvalidateParameter, InterruptedException {
        Runs runs = new Runs();
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        Run run = runs.retrieve("<your-thread-id>", "<your-run-id>", apiKey);

        // Poll until the run reaches a terminal state
        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("<your-thread-id>", run.getId());
        }
    }
}

Parameter permintaan

ParameterTypeRequiredDescription
run_idstringYesRun ID.
thread_idstringYesID thread.
workspacestringNoID ruang kerja. Diperlukan hanya jika kunci API milik sub-ruang kerja.
api_keystringNoKunci API. Default menggunakan variabel lingkungan DASHSCOPE_API_KEY.

Respons

Mengembalikan objek run dalam status terminalnya.

Objek run

Mewakili run yang dieksekusi pada sebuah thread.

Contoh

{
    "assistant_id": "asst_xxxx",
    "cancelled_at": null,
    "completed_at": null,
    "created_at": 1735026246751,
    "expires_at": null,
    "failed_at": null,
    "file_ids": [],
    "id": "run_xxxx",
    "instructions": "you are a helpful assistant",
    "last_error": null,
    "max_tokens": null,
    "metadata": {},
    "model": "qwen-plus",
    "object": "thread.run",
    "request_id": "req_xxxx",
    "required_action": null,
    "started_at": null,
    "status": "in_progress",
    "temperature": null,
    "thread_id": "thread_xxxx",
    "tool_choice": "auto",
    "tools": [],
    "top_k": null,
    "top_p": null,
    "truncation_strategy": null,
    "usage": null
}

Atribut

AttributeTypeDescription
idstringIdentifier unik untuk run. Format: run_*.
objectstringTipe objek. Selalu thread.run.
assistant_idstringAssistant yang terkait dengan run ini.
thread_idstringThread tempat run ini berada.
statusstringStatus saat ini: queued, in_progress, requires_action, cancelling, cancelled, failed, completed, incomplete, atau expired.
modelstringModel yang digunakan untuk run ini.
instructionsstringInstruksi yang diikuti oleh assistant selama run ini.
toolsarrayTool yang tersedia bagi assistant selama run ini.
metadatamapHingga 16 pasangan kunci-nilai. Kunci: maksimal 64 karakter. Nilai: maksimal 512 karakter.
required_actionobjectAksi yang diperlukan agar run dapat dilanjutkan, seperti mengirimkan output tool. null kecuali statusnya requires_action.
last_errorobjectError terakhir yang terjadi selama run. null jika tidak ada error.
usageobjectPenggunaan token untuk run ini. Berisi input_tokens dan output_tokens.
created_atintegerTimestamp Unix (milidetik) saat run dibuat.
started_atintegerTimestamp Unix (milidetik) saat run mulai diproses.
completed_atintegerTimestamp Unix (milidetik) saat run selesai.
cancelled_atintegerTimestamp Unix (milidetik) saat run dibatalkan.
failed_atintegerTimestamp Unix (milidetik) saat run gagal.
expired_atintegerTimestamp Unix (milidetik) saat run kedaluwarsa.

FAQ

Q: Bagaimana cara membatalkan run yang sedang berjalan?

Assistants API tidak menyediakan titik akhir khusus untuk membatalkan run. Implementasikan logika pembatalan di aplikasi Anda sebagai gantinya.

Kode error

Jika panggilan API gagal, lihat Pesan error untuk troubleshooting.