全部產品
Search
文件中心

Alibaba Cloud Model Studio:OpenAI相容-Batch

更新時間:Jan 30, 2026

阿里雲百鍊提供與 OpenAI 相容的 Batch API,支援以檔案方式批量提交任務,系統將非同步執行,任務完成或達到最長等待時間時返回結果,費用僅為即時調用的 50%。適用於資料分析、模型評測等對時效性要求不高但需要大批量處理的業務。

如需在控制台操作,請參見批量推理

工作流程

image

前提條件

支援通過OpenAI SDK(Python、Node.js)或HTTP API調用 Batch 介面。

  • 擷取 API Key擷取並配置 API Key 到環境變數

  • 安裝SDK(可選):若使用 SDK 調用,請安裝 OpenAI SDK

  • 服務端點

    • 中國內地:https://dashscope.aliyuncs.com/compatible-mode/v1

    • 國際:https://dashscope-intl.aliyuncs.com/compatible-mode/v1

適用範圍

中國內地

中國內地部署模式下,存取點與資料存放區均位於北京地區,模型推理計算資源僅限於中國內地。

支援的模型

  • 文本產生模型:通義千問 Max、Plus、Flash、Long 的穩定版本及其部分 latest 版本,以及 QwQ 系列(qwq-plus)和部分第三方模型(deepseek-r1、deepseek-v3)。

  • 多模態模型:通義千問 VL Max、Plus、Flash的穩定版本及其部分 latest 版本,以及通義千問 OCR 模型。

  • 文本向量模型: text-embedding-v4 模型。

支援的模型名稱清單

國際

國際部署模式下,存取點與資料存放區均位於新加坡地區,模型推理計算資源在全球範圍內動態調度(不含中國內地)。

支援的模型:qwen-max、qwen-plus、qwen-flash、qwen-turbo。

快速開始

在處理正式任務前,可使用測試模型batch-test-model進行全鏈路閉環測試。測試模型會跳過推理過程,直接返回一個固定的成功響應,用於驗證 API 呼叫鏈路和資料格式是否正確。

說明

測試模型(batch-test-model)的限制:

  • 測試檔案需滿足輸入檔案要求,且檔案大小不超過 1 MB,行數不超過100行

  • 並發限制:最大並行任務數 2 個

  • 費用:測試模型不產生模型推理費用。

第 1 步:準備輸入檔案

準備一個名為test_model.jsonl的檔案,內容如下:

{"custom_id":"1","method":"POST","url":"/v1/chat/ds-test","body":{"model":"batch-test-model","messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"你好!有什麼可以協助你的嗎?"}]}}
{"custom_id":"2","method":"POST","url":"/v1/chat/ds-test","body":{"model":"batch-test-model","messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"What is 2+2?"}]}}

第 2 步:運行代碼

根據使用的程式設計語言,選擇以下範例程式碼並將其儲存在輸入檔案的同一目錄下,然後運行。代碼將完成檔案上傳、建立任務、輪詢狀態和下載結果的完整流程。

如需調整檔案路徑或其他參數,請根據實際情況修改代碼。

範例程式碼

OpenAI Python SDK

import os
from pathlib import Path
from openai import OpenAI
import time

# 初始化用戶端
client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx",但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區的base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"  # 阿里雲百鍊服務的base_url
)

def upload_file(file_path):
    print(f"正在上傳包含請求資訊的JSONL檔案...")
    file_object = client.files.create(file=Path(file_path), purpose="batch")
    print(f"檔案上傳成功。得到檔案ID: {file_object.id}\n")
    return file_object.id

def create_batch_job(input_file_id):
    print(f"正在基於檔案ID,建立Batch任務...")
    # 請注意:此處endpoint參數值需和輸入檔案中的url欄位保持一致.測試模型(batch-test-model)填寫/v1/chat/ds-test,Embedding文本向量模型填寫/v1/embeddings,其他模型填寫/v1/chat/completions
    batch = client.batches.create(input_file_id=input_file_id, endpoint="/v1/chat/ds-test", completion_window="24h")
    print(f"Batch任務建立完成。 得到Batch任務ID: {batch.id}\n")
    return batch.id

def check_job_status(batch_id):
    print(f"正在檢查Batch任務狀態...")
    batch = client.batches.retrieve(batch_id=batch_id)
    print(f"Batch任務狀態: {batch.status}\n")
    return batch.status

def get_output_id(batch_id):
    print(f"正在擷取Batch任務中執行成功請求的輸出檔案ID...")
    batch = client.batches.retrieve(batch_id=batch_id)
    print(f"輸出檔案ID: {batch.output_file_id}\n")
    return batch.output_file_id

def get_error_id(batch_id):
    print(f"正在擷取Batch任務中執行錯誤請求的輸出檔案ID...")
    batch = client.batches.retrieve(batch_id=batch_id)
    print(f"錯誤檔案ID: {batch.error_file_id}\n")
    return batch.error_file_id

def download_results(output_file_id, output_file_path):
    print(f"正在列印並下載Batch任務的請求成功結果...")
    content = client.files.content(output_file_id)
    # 列印部分內容以供測試
    print(f"列印請求成功結果的前1000個字元內容: {content.text[:1000]}...\n")
    # 儲存結果檔案至本地
    content.write_to_file(output_file_path)
    print(f"完整的輸出結果已儲存至本地輸出檔案result.jsonl\n")

def download_errors(error_file_id, error_file_path):
    print(f"正在列印並下載Batch任務的請求失敗資訊...")
    content = client.files.content(error_file_id)
    # 列印部分內容以供測試
    print(f"列印請求失敗資訊的前1000個字元內容: {content.text[:1000]}...\n")
    # 儲存錯誤資訊檔至本地
    content.write_to_file(error_file_path)
    print(f"完整的請求失敗資訊已儲存至本地錯誤檔案error.jsonl\n")

def main():
    # 檔案路徑
    input_file_path = "test_model.jsonl"  # 可替換為您的輸入檔案路徑
    output_file_path = "result.jsonl"  # 可替換為您的輸出檔案路徑
    error_file_path = "error.jsonl"  # 可替換為您的錯誤檔案路徑
    try:
        # Step 1: 上傳包含請求資訊的JSONL檔案,得到輸入檔案ID
        input_file_id = upload_file(input_file_path)
        # Step 2: 基於輸入檔案ID,建立Batch任務
        batch_id = create_batch_job(input_file_id)
        # Step 3: 檢查Batch任務狀態直到結束
        status = ""
        while status not in ["completed", "failed", "expired", "cancelled"]:
            status = check_job_status(batch_id)
            print(f"等待任務完成...")
            time.sleep(10)  # 等待10秒後重新查詢狀態
        # 如果任務失敗,則列印錯誤資訊並退出
        if status == "failed":
            batch = client.batches.retrieve(batch_id)
            print(f"Batch任務失敗。錯誤資訊為:{batch.errors}\n")
            print(f"參見錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code")
            return
        # Step 4: 下載結果:如果輸出檔案ID不為空白,則列印請求成功結果的前1000個字元內容,並下載完整的請求成功結果到本地輸出檔案;
        # 如果錯誤檔案ID不為空白,則列印請求失敗資訊的前1000個字元內容,並下載完整的請求失敗資訊到本地錯誤檔案.
        output_file_id = get_output_id(batch_id)
        if output_file_id:
            download_results(output_file_id, output_file_path)
        error_file_id = get_error_id(batch_id)
        if error_file_id:
            download_errors(error_file_id, error_file_path)
            print(f"參見錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code")
    except Exception as e:
        print(f"An error occurred: {e}")
        print(f"參見錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code")

if __name__ == "__main__":
    main()

OpenAI Node.js SDK

/**
 * 阿里雲百鍊 Batch API 測試 - 使用 OpenAI Node.js SDK
 *
 * 安裝依賴:npm install openai
 * 運行:node test-nodejs.js
 */

const OpenAI = require('openai');
const fs = require('fs');

// 新加坡地區的 Base URL
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,使用以下 URL:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    process.exit(1);
}

// 初始化用戶端
const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

async function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {
    try {
        console.log('=== 開始 Batch API 測試 ===\n');

        // Step 1: 上傳檔案
        console.log('步驟 1: 上傳包含請求資訊的 JSONL 檔案...');
        const fileStream = fs.createReadStream('test_model.jsonl');
        const fileObject = await client.files.create({
            file: fileStream,
            purpose: 'batch'
        });
        const fileId = fileObject.id;
        console.log(`✓ 檔案上傳成功,檔案ID: ${fileId}\n`);

        // Step 2: 建立 Batch 任務
        console.log('步驟 2: 建立 Batch 任務...');
        const batch = await client.batches.create({
            input_file_id: fileId,
            endpoint: '/v1/chat/ds-test',  // 測試模型使用 /v1/chat/ds-test
            completion_window: '24h'
        });
        const batchId = batch.id;
        console.log(`✓ Batch 任務建立成功,任務ID: ${batchId}\n`);

        // Step 3: 輪詢任務狀態
        console.log('步驟 3: 等待任務完成...');
        let status = batch.status;
        let pollCount = 0;
        let latestBatch = batch;

        while (!['completed', 'failed', 'expired', 'cancelled'].includes(status)) {
            await sleep(10000); // 等待 10 秒
            latestBatch = await client.batches.retrieve(batchId);
            status = latestBatch.status;
            pollCount++;
            console.log(`  [${pollCount}] 任務狀態: ${status}`);
        }

        console.log(`\n✓ 任務已完成,最終狀態: ${status}\n`);

        // Step 4: 處理結果
        if (status === 'completed') {
            console.log('步驟 4: 下載結果檔案...');

            // 下載成功結果
            const outputFileId = latestBatch.output_file_id;
            if (outputFileId) {
                console.log(`  輸出檔案ID: ${outputFileId}`);
                const content = await client.files.content(outputFileId);
                const text = await content.text();
                console.log('\n--- 成功結果(前 500 字元)---');
                console.log(text.substring(0, Math.min(500, text.length)));
                console.log('...\n');
            }

            // 下載錯誤檔案(如有)
            const errorFileId = latestBatch.error_file_id;
            if (errorFileId) {
                console.log(`  錯誤檔案ID: ${errorFileId}`);
                const errorContent = await client.files.content(errorFileId);
                const errorText = await errorContent.text();
                console.log('\n--- 錯誤資訊 ---');
                console.log(errorText);
            }

            console.log('\n=== 測試成功完成 ===');
        } else if (status === 'failed') {
            console.error('\n✗ Batch 任務失敗');
            if (latestBatch.errors) {
                console.error('錯誤資訊:', latestBatch.errors);
            }
            console.error('\n請參考錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code');
        } else {
            console.log(`\n任務狀態: ${status}`);
        }

    } catch (error) {
        console.error('發生錯誤:', error.message);
        console.error(error);
    }
}

main();

Java(HTTP)

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;

/**
 * 阿里雲百鍊 Batch API 測試 - 使用 HTTP API 呼叫
 *
 * 前置條件:
 * 1. 確保已經設定環境變數 DASHSCOPE_API_KEY
 * 2. 準備好測試檔案 test_model.jsonl(在專案根目錄)
 *
 * 地區配置說明:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 */
public class BatchAPITest {

    // 新加坡地區的 Base URL
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";

    private static String API_KEY;

    public static void main(String[] args) throws Exception {
        // 從環境變數擷取 API Key
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.exit(1);
        }

        System.out.println("=== 開始 Batch API 測試 ===\n");

        try {
            // Step 1: 上傳檔案
            System.out.println("步驟 1: 上傳包含請求資訊的 JSONL 檔案...");
            String fileId = uploadFile("test_model.jsonl");
            System.out.println("✓ 檔案上傳成功,檔案ID: " + fileId + "\n");

            // Step 2: 建立 Batch 任務
            System.out.println("步驟 2: 建立 Batch 任務...");
            String batchId = createBatch(fileId);
            System.out.println("✓ Batch 任務建立成功,任務ID: " + batchId + "\n");

            // Step 3: 輪詢任務狀態
            System.out.println("步驟 3: 等待任務完成...");
            String status = "";
            int pollCount = 0;

            while (!isTerminalStatus(status)) {
                Thread.sleep(10000); // 等待 10 秒
                String batchInfo = getBatch(batchId);
                status = parseStatus(batchInfo);
                pollCount++;
                System.out.println("  [" + pollCount + "] 任務狀態: " + status);

                // Step 4: 如果完成,下載結果
                if ("completed".equals(status)) {
                    System.out.println("\n✓ 任務已完成!\n");
                    System.out.println("步驟 4: 下載結果檔案...");

                    String outputFileId = parseOutputFileId(batchInfo);
                    if (outputFileId != null && !outputFileId.isEmpty()) {
                        System.out.println("  輸出檔案ID: " + outputFileId);
                        String content = getFileContent(outputFileId);
                        System.out.println("\n--- 成功結果(前 500 字元)---");
                        System.out.println(content.substring(0, Math.min(500, content.length())));
                        System.out.println("...\n");
                    }

                    String errorFileId = parseErrorFileId(batchInfo);
                    if (errorFileId != null && !errorFileId.isEmpty() && !"null".equals(errorFileId)) {
                        System.out.println("  錯誤檔案ID: " + errorFileId);
                        String errorContent = getFileContent(errorFileId);
                        System.out.println("\n--- 錯誤資訊 ---");
                        System.out.println(errorContent);
                    }

                    System.out.println("\n=== 測試成功完成 ===");
                    break;
                } else if ("failed".equals(status)) {
                    System.err.println("\n✗ Batch 任務失敗");
                    System.err.println("任務資訊: " + batchInfo);
                    System.err.println("\n請參考錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code");
                    break;
                } else if ("expired".equals(status) || "cancelled".equals(status)) {
                    System.out.println("\n任務狀態: " + status);
                    break;
                }
            }

        } catch (Exception e) {
            System.err.println("發生錯誤: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 上傳檔案
     */
    private static String uploadFile(String filePath) throws Exception {
        String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
        URL url = new URL(BASE_URL + "/files");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

        try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
            // 添加 purpose 欄位
            out.writeBytes("--" + boundary + "\r\n");
            out.writeBytes("Content-Disposition: form-data; name=\"purpose\"\r\n\r\n");
            out.writeBytes("batch\r\n");

            // 添加檔案
            out.writeBytes("--" + boundary + "\r\n");
            out.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + filePath + "\"\r\n");
            out.writeBytes("Content-Type: application/octet-stream\r\n\r\n");

            byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
            out.write(fileBytes);
            out.writeBytes("\r\n");
            out.writeBytes("--" + boundary + "--\r\n");
        }

        String response = readResponse(conn);
        return parseField(response, "\"id\":\s*\"([^\"]+)\"");
    }

    /**
     * 建立 Batch 任務
     */
    private static String createBatch(String fileId) throws Exception {
        String jsonBody = String.format(
            "{\"input_file_id\":\"%s\",\"endpoint\":\"/v1/chat/ds-test\",\"completion_window\":\"24h\"}",
            fileId
        );

        String response = sendRequest("POST", "/batches", jsonBody);
        return parseField(response, "\"id\":\s*\"([^\"]+)\"");
    }

    /**
     * 擷取 Batch 任務資訊
     */
    private static String getBatch(String batchId) throws Exception {
        return sendRequest("GET", "/batches/" + batchId, null);
    }

    /**
     * 擷取檔案內容
     */
    private static String getFileContent(String fileId) throws Exception {
        return sendRequest("GET", "/files/" + fileId + "/content", null);
    }

    /**
     * 發送 HTTP 要求
     */
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);

        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }

        return readResponse(conn);
    }

    /**
     * 讀取響應
     */
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();

        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }

    /**
     * 解析 JSON 欄位(簡單實現)
     */
    private static String parseField(String json, String regex) {
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(regex);
        java.util.regex.Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }

    private static String parseStatus(String json) {
        return parseField(json, "\"status\":\s*\"([^\"]+)\"");
    }

    private static String parseOutputFileId(String json) {
        return parseField(json, "\"output_file_id\":\s*\"([^\"]+)\"");
    }

    private static String parseErrorFileId(String json) {
        return parseField(json, "\"error_file_id\":\s*\"([^\"]+)\"");
    }

    /**
     * 判斷是否為終止狀態
     */
    private static boolean isTerminalStatus(String status) {
        return "completed".equals(status)
            || "failed".equals(status)
            || "expired".equals(status)
            || "cancelled".equals(status);
    }
}

curl (HTTP)

#!/bin/bash
# 阿里雲百鍊 Batch API 測試 - 使用 curl
#
# 前置條件:
# 1. 確保已經設定環境變數 DASHSCOPE_API_KEY
# 2. 準備好測試檔案 test_model.jsonl(在目前的目錄)
#
# 地區配置說明:
# - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
# - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1

API_KEY="${DASHSCOPE_API_KEY}"
BASE_URL="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"

# 如果使用北京地區,請將 BASE_URL 替換為:
# BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"

# 檢查 API Key
if [ -z "$API_KEY" ]; then
    echo "錯誤: 請設定環境變數 DASHSCOPE_API_KEY"
    exit 1
fi

echo "=== 開始 Batch API 測試 ==="
echo ""

# Step 1: 上傳檔案
echo "步驟 1: 上傳包含請求資訊的 JSONL 檔案..."
UPLOAD_RESPONSE=$(curl -s -X POST "${BASE_URL}/files" \
  -H "Authorization: Bearer ${API_KEY}" \
  -F 'file=@test_model.jsonl' \
  -F 'purpose=batch')

FILE_ID=$(echo $UPLOAD_RESPONSE | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "✓ 檔案上傳成功,檔案ID: ${FILE_ID}"
echo ""

# Step 2: 建立 Batch 任務
echo "步驟 2: 建立 Batch 任務..."
BATCH_RESPONSE=$(curl -s -X POST "${BASE_URL}/batches" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{\"input_file_id\":\"${FILE_ID}\",\"endpoint\":\"/v1/chat/ds-test\",\"completion_window\":\"24h\"}")

BATCH_ID=$(echo $BATCH_RESPONSE | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "✓ Batch 任務建立成功,任務ID: ${BATCH_ID}"
echo ""

# Step 3: 輪詢任務狀態
echo "步驟 3: 等待任務完成..."
STATUS=""
POLL_COUNT=0

while [[ "$STATUS" != "completed" && "$STATUS" != "failed" && "$STATUS" != "expired" && "$STATUS" != "cancelled" ]]; do
    sleep 10
    BATCH_INFO=$(curl -s -X GET "${BASE_URL}/batches/${BATCH_ID}" \
      -H "Authorization: Bearer ${API_KEY}")
    STATUS=$(echo $BATCH_INFO | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
    POLL_COUNT=$((POLL_COUNT + 1))
    echo "  [${POLL_COUNT}] 任務狀態: ${STATUS}"
done

echo ""
echo "✓ 任務已完成,最終狀態: ${STATUS}"
echo ""

# Step 4: 下載結果
if [[ "$STATUS" == "completed" ]]; then
    echo "步驟 4: 下載結果檔案..."

    OUTPUT_FILE_ID=$(echo $BATCH_INFO | grep -o '"output_file_id":"[^"]*"' | cut -d'"' -f4)
    if [[ -n "$OUTPUT_FILE_ID" && "$OUTPUT_FILE_ID" != "null" ]]; then
        echo "  輸出檔案ID: ${OUTPUT_FILE_ID}"

        RESULT_CONTENT=$(curl -s -X GET "${BASE_URL}/files/${OUTPUT_FILE_ID}/content" \
          -H "Authorization: Bearer ${API_KEY}")

        echo ""
        echo "--- 成功結果(前 500 字元)---"
        echo "${RESULT_CONTENT:0:500}"
        echo "..."
        echo ""
    fi

    ERROR_FILE_ID=$(echo $BATCH_INFO | grep -o '"error_file_id":"[^"]*"' | cut -d'"' -f4)
    if [[ -n "$ERROR_FILE_ID" && "$ERROR_FILE_ID" != "null" ]]; then
        echo "  錯誤檔案ID: ${ERROR_FILE_ID}"

        ERROR_CONTENT=$(curl -s -X GET "${BASE_URL}/files/${ERROR_FILE_ID}/content" \
          -H "Authorization: Bearer ${API_KEY}")

        echo ""
        echo "--- 錯誤資訊 ---"
        echo "${ERROR_CONTENT}"
    fi

    echo ""
    echo "=== 測試成功完成 ==="
elif [[ "$STATUS" == "failed" ]]; then
    echo ""
    echo "✗ Batch 任務失敗"
    echo "任務資訊: ${BATCH_INFO}"
    echo ""
    echo "請參考錯誤碼文檔: https://www.alibabacloud.com/help/zh/model-studio/developer-reference/error-code"
else
    echo ""
    echo "任務狀態: ${STATUS}"
fi

第 3 步: 驗證測試結果

任務成功完成後,結果檔案result.jsonl會包含固定響應{"content":"This is a test result."}

{"id":"a2b1ae25-21f4-4d9a-8634-99a29926486c","custom_id":"1","response":{"status_code":200,"request_id":"a2b1ae25-21f4-4d9a-8634-99a29926486c","body":{"created":1743562621,"usage":{"completion_tokens":6,"prompt_tokens":20,"total_tokens":26},"model":"batch-test-model","id":"chatcmpl-bca7295b-67c3-4b1f-8239-d78323bb669f","choices":[{"finish_reason":"stop","index":0,"message":{"content":"This is a test result."}}],"object":"chat.completion"}},"error":null}
{"id":"39b74f09-a902-434f-b9ea-2aaaeebc59e0","custom_id":"2","response":{"status_code":200,"request_id":"39b74f09-a902-434f-b9ea-2aaaeebc59e0","body":{"created":1743562621,"usage":{"completion_tokens":6,"prompt_tokens":20,"total_tokens":26},"model":"batch-test-model","id":"chatcmpl-1e32a8ba-2b69-4dc4-be42-e2897eac9e84","choices":[{"finish_reason":"stop","index":0,"message":{"content":"This is a test result."}}],"object":"chat.completion"}},"error":null}

執行正式任務

輸入檔案要求

  • 格式:UTF-8 編碼的 JSONL(每行一個獨立 JSON 對象)

  • 規模限制:單檔案 ≤ 50,000 個請求,且 ≤ 500 MB

  • 單行限制:每個 JSON 對象 ≤ 6 MB,且不超過模型上下文長度

  • 一致性要求:同一檔案內所有請求須使用相同模型及思考模式(如適用)

  • 唯一標識:每個請求必須包含檔案內唯一的 custom_id 欄位,用於結果匹配

樣本檔案內容:

{"custom_id":"1","method":"POST","url":"/v1/chat/completions","body":{"model":"qwen-plus","messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"Hello!"}]}}
{"custom_id":"2","method":"POST","url":"/v1/chat/completions","body":{"model":"qwen-plus","messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"What is 2+2?"}]}}

JSONL 批量產生工具

使用以下工具可快速產生 JSONL 檔案。

JSONL 批量產生工具
請選擇模式:

1. 修改輸入檔案

  • 可直接修改用於測試的 test_model.jsonl 檔案,將 model 參數設定為需要使用的正式模型,並設定 url 欄位:

    模型類型

    url

    文本產生/多模態模型

    /v1/chat/completions

    文本向量模型

    /v1/embeddings

  • 或使用上方的“JSONL 批量產生工具”為正式任務產生一個新的檔案。關鍵是確保 model 和 url 欄位正確。

2. 修改快速開始的代碼

  1. 輸入檔案路徑更改為您的檔案名稱

  2. 將 endpoint 參數值修改為與輸入檔案中 url 欄位一致的值

3. 運行代碼並等待結果

任務成功後,成功的請求結果將儲存在本地的 result.jsonl 檔案中。如果部分請求失敗,錯誤詳情將儲存在 error.jsonl 檔案中。

  • 成功結果(output_file_id):每一行對應一個成功的原始請求,包含 custom_id 和 response

    {"id":"3a5c39d5-3981-4e4c-97f2-e0e821893f03","custom_id":"req-001","response":{"status_code":200,"request_id":"3a5c39d5-3981-4e4c-97f2-e0e821893f03","body":{"created":1768306034,"usage":{"completion_tokens":654,"prompt_tokens":14,"total_tokens":668},"model":"qwen-plus","id":"chatcmpl-3a5c39d5-3981-4e4c-97f2-e0e821893f03","choices":[{"finish_reason":"stop","index":0,"message":{"role":"assistant","content":"你好!杭州西湖是中國著名的風景名勝區,位於浙江省杭州市西部,因此得名“西湖”。它是中國十大風景名勝之一,也是世界文化遺產(2011年被聯合國教科文組織列入《世界遺產名錄》),以其秀麗的自然風光與深厚的人文底蘊聞名於世。\n\n### 一、自然景觀\n西湖三面環山,一面鄰城,湖面面積約6.39平方公裡,形似如意,碧波蕩漾。湖中被孤山、白堤、蘇堤、楊公堤等自然或人工分隔成多個水域,形成“一山二塔三島三堤”的格局。\n\n主要景點包括:\n- **蘇堤春曉**:北宋大文豪蘇東坡任杭州知州時主持疏浚西湖,用挖出的淤泥堆築成堤,後人稱為“蘇堤”。春天桃紅柳綠,景色如畫。\n- **斷橋殘雪**:位於白堤東端,是白蛇傳中“斷橋相會”的發生地,冬日雪後銀裝素裹,尤為著名。\n- **雷峰夕照**:雷峰塔在夕陽映照下金光熠熠,曾是“西湖十景”之一。\n- **三潭印月**:湖中小瀛洲上的三座石塔,中秋夜可在塔內點燈,月影、燈光、湖光交相輝映。\n- **平湖秋月**:位於白堤西端,是觀賞湖上明月的絕佳地點。\n- **花港觀魚**:以賞花和觀魚著稱,園內牡丹、錦鯉相映成趣。\n\n### 二、人文歷史\n西湖不僅風景優美,還承載著豐富的歷史文化:\n- 自唐宋以來,眾多文人墨客如白居易、蘇東坡、林逋、楊萬裡等在此留下詩篇。\n- 白居易曾主持修建“白堤”,疏浚西湖,造福百姓。\n- 西湖周邊有眾多古迹,如嶽王廟(紀念民族英雄嶽飛)、靈隱寺(千年古刹)、六和塔、龍井村(中國十大名茶龍井茶的產地)等。\n\n### 三、文化象徵\n西湖被譽為“人間天堂”的代表,是中國傳統山水美學的典範。它融合了自然美與人文美,體現了“天人合一”的哲學思想。許多詩詞、繪畫、戲曲都以西湖為題材,成為中國文化的重要符號。\n\n### 四、旅遊建議\n- 最佳遊覽季節:春季(3-5月)桃紅柳綠,秋季(9-11月)天高氣爽。\n- 推薦方式:步行、騎行(環湖綠道)、乘船遊湖。\n- 周邊美食:西湖醋魚、龍井蝦仁、東坡肉、片兒川等。\n\n總之,杭州西湖不僅是一處自然美景,更是一座活著的文化博物館,值得細細品味。如果你有機會到杭州,一定不要錯過這個“淡妝濃抹總相宜”的人間仙境。"}}],"object":"chat.completion"}},"error":null}
    {"id":"628312ba-172c-457d-ba7f-3e5462cc6899","custom_id":"req-002","response":{"status_code":200,"request_id":"628312ba-172c-457d-ba7f-3e5462cc6899","body":{"created":1768306035,"usage":{"completion_tokens":25,"prompt_tokens":18,"total_tokens":43},"model":"qwen-plus","id":"chatcmpl-628312ba-172c-457d-ba7f-3e5462cc6899","choices":[{"finish_reason":"stop","index":0,"message":{"role":"assistant","content":"春風拂柳綠,  \n夜雨潤花紅。  \n鳥語林間鬧,  \n山川處處同。"}}],"object":"chat.completion"}},"error":null}
  • 失敗詳情(error_file_id):包含處理失敗的請求行資訊和錯誤原因,可參考錯誤碼進行排查。

具體流程

Batch API 的使用流程分為四個步驟:上傳檔案、建立任務、查詢任務狀態、下載結果。

1. 上傳檔案

建立Batch任務前,將符合輸入檔案格式要求的JSONL檔案通過檔案上傳介面上傳,擷取file_id

上傳檔案,purpose必須是batch

OpenAI Python SDK

請求樣本

import os
from pathlib import Path
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

# test.jsonl 是一個本地樣本檔案,purpose必須是batch
file_object = client.files.create(file=Path("test.jsonl"), purpose="batch")

print(file_object.model_dump_json())

OpenAI Node.js SDK

請求樣本

/**
 * 阿里雲百鍊 Batch API - 上傳檔案
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');
const fs = require('fs');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

const fileStream = fs.createReadStream('test.jsonl');
const fileObject = await client.files.create({
    file: fileStream,
    purpose: 'batch'
});
console.log(fileObject.id);

Java(HTTP)

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 上傳檔案
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPIUploadFile {
    
    // 新加坡地區配置
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }
        
String fileId = uploadFile("test.jsonl");
        System.out.println("檔案ID: " + fileId);
    }
    
    // === 工具方法 ===
    
    private static String uploadFile(String filePath) throws Exception {
        String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
        URL url = new URL(BASE_URL + "/files");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

        try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
            // 添加 purpose 欄位
            out.writeBytes("--" + boundary + "\r\n");
            out.writeBytes("Content-Disposition: form-data; name=\"purpose\"\r\n\r\n");
            out.writeBytes("batch\r\n");

            // 添加檔案
            out.writeBytes("--" + boundary + "\r\n");
            out.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + filePath + "\"\r\n");
            out.writeBytes("Content-Type: application/octet-stream\r\n\r\n");

            byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
            out.write(fileBytes);
            out.writeBytes("\r\n");
            out.writeBytes("--" + boundary + "--\r\n");
        }

        String response = readResponse(conn);
        return parseField(response, "\"id\":\\s*\"([^\"]+)\"");
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/files
# === 執行時請刪除該注釋 ===
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/files \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
--form 'file=@"test.jsonl"' \
--form 'purpose="batch"'

返回樣本

{
    "id": "file-batch-xxx",
    "bytes": 437,
    "created_at": 1742304153,
    "filename": "test.jsonl",
    "object": "file",
    "purpose": "batch",
    "status": "processed",
    "status_details": null
}

2. 建立 Batch 任務

使用上傳檔案返回的檔案 id建立 Batch 任務。

OpenAI Python SDK

請求樣本

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

batch = client.batches.create(
    input_file_id="file-batch-xxx",  # 上傳檔案返回的id
    endpoint="/v1/chat/completions",  # # 測試模型batch-test-model填寫/v1/chat/ds-test,文本向量模型填寫/v1/embeddings,文本產生/多模態模型填寫/v1/chat/completions
    completion_window="24h",
    metadata={'ds_name':"任務名稱",'ds_description':'任務描述'} # metadata資料,非必要欄位,用於建立任務名稱、描述
)
print(batch)

OpenAI Node.js SDK

請求樣本

/**
 * 阿里雲百鍊 Batch API - 建立Batch任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

const batch = await client.batches.create({
    input_file_id: 'file-batch-xxx',
    endpoint: '/v1/chat/completions',
    completion_window: '24h',
    metadata: {'ds_name': '任務名稱', 'ds_description': '任務描述'}
});
console.log(batch.id);

Java(HTTP)

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 建立Batch任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPICreateBatch {
    
    // 新加坡地區配置(預設)
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }
        
        String jsonBody = "{\"input_file_id\":\"file-batch-xxx\",\"endpoint\":\"/v1/chat/completions\",\"completion_window\":\"24h\",\"metadata\":{\"ds_name\":\"任務名稱\",\"ds_description\":\"任務描述\"}}";
String response = sendRequest("POST", "/batches", jsonBody);
        String batchId = parseField(response, "\"id\":\\s*\"([^\"]+)\"");
        System.out.println("Batch任務ID: " + batchId);
    }
    
    // === 工具方法 ===
    
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        
        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }
        
        return readResponse(conn);
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/batches
# === 執行時請刪除該注釋 ===
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/batches \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_file_id": "file-batch-xxx",
    "endpoint": "/v1/chat/completions",
    "completion_window": "24h",
    "metadata":{"ds_name":"任務名稱","ds_description":"任務描述"}
  }'

輸入參數

欄位

類型

傳參

方式

必選

描述

input_file_id

String

Body

用於指定檔案ID,作為Batch任務的輸入檔案。

使用準備與上傳檔案介面返回的檔案ID,如file-batch-xxx

endpoint

String

Body

訪問路徑,需和輸入檔案中的url欄位保持一致。

  • 測試模型batch-test-model填寫/v1/chat/ds-test

  • 其他模型填寫/v1/chat/completions

completion_window

String

Body

等待時間,支援最短等待時間24h,最長等待時間336h,僅支援整數。

支援"h"和"d"兩個單位,如"24h"或"14d"。

metadata

Map

Body

任務擴充中繼資料,以索引值對形式附加資訊。

metadata.ds_name

String

Body

任務名稱。

樣本:"ds_name":"Batch任務"

限制:長度不超過100個字元。

若重複定義該欄位,以最後一次傳入的值為準。

metadata.ds_description

String

Body

任務描述。

樣本:"ds_description":"Batch推理任務測試"

限制:長度不超過200個字元。

若重複定義該欄位,以最後一次傳入的值為準。

返回樣本

{
    "id": "batch_xxx",
    "object": "batch",
    "endpoint": "/v1/chat/completions",
    "errors": null,
    "input_file_id": "file-batch-xxx",
    "completion_window": "24h",
    "status": "validating",
    "output_file_id": null,
    "error_file_id": null,
    "created_at": 1742367779,
    "in_progress_at": null,
    "expires_at": null,
    "finalizing_at": null,
    "completed_at": null,
    "failed_at": null,
    "expired_at": null,
    "cancelling_at": null,
    "cancelled_at": null,
    "request_counts": {
        "total": 0,
        "completed": 0,
        "failed": 0
    },
    "metadata": {
        "ds_name": "任務名稱",
        "ds_description": "任務描述"
    }
}

返回參數

欄位

類型

描述

id

String

本次建立的Batch任務 ID。

object

String

物件類型,固定值batch

endpoint

String

訪問路徑。

errors

Map

錯誤資訊。

input_file_id

String

檔案ID。

completion_window

String

等待時間,支援最短等待時間24h,最長等待時間336h,僅支援整數。

支援"h"和"d"兩個單位,如"24h"或"14d"。

status

String

任務狀態,包括validating、failed、in_progress、finalizing、completed、expired、cancelling、cancelled。

output_file_id

String

執行成功請求的輸出檔案id。

error_file_id

String

執行錯誤請求的輸出檔案id。

created_at

Integer

任務建立的Unix 時間戳記(秒)。

in_progress_at

Integer

任務開始啟動並執行Unix時間戳記(秒)。

expires_at

Integer

任務開始逾時的時間戳記(秒)。

finalizing_at

Integer

任務最後開始時間戳(秒)。

completed_at

Integer

任務完成的時間戳記(秒)。

failed_at

Integer

任務失敗的時間戳記(秒)。

expired_at

Integer

任務逾時的時間戳記(秒)。

cancelling_at

Integer

任務設定為取消中的時間戳記(秒)。

cancelled_at

Integer

任務取消的時間戳記(秒)。

request_counts

Map

不同狀態的請求數量。

metadata

Map

附加資訊,索引值對。

metadata.ds_name

String

當前任務的任務名稱。

metadata.ds_description

String

當前任務的任務描述。

3. 查詢與管理 Batch 任務

任務建立後,您可以通過以下介面查詢其狀態、列出歷史任務或取消進行中的任務。

查詢指定任務狀態

通過傳入 Batch 任務 ID,來查詢指定 Batch 任務的資訊。當前僅支援查詢 30 天之內建立的 Batch 任務。

OpenAI Python SDK

請求樣本

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
batch = client.batches.retrieve("batch_id")  # 將batch_id替換為Batch任務的id
print(batch)

OpenAI Node.js SDK

請求樣本

/**
 * 阿里雲百鍊 Batch API - 查詢單個任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

const batch = await client.batches.retrieve('batch_id');
console.log(batch.status);

Java(HTTP)

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 查詢單個任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPIRetrieveBatch {
    
    // 新加坡地區配置
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }
        
        String batchInfo = sendRequest("GET", "/batches/batch_id", null);
        String status = parseField(batchInfo, "\"status\":\\s*\"([^\"]+)\"");
        System.out.println("任務狀態: " + status);
    }
    
    // === 工具方法 ===
    
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        
        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }
        
        return readResponse(conn);
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/batches/batch_id
# === 執行時請刪除該注釋 ===
curl --request GET 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/batches/batch_id' \
 -H "Authorization: Bearer $DASHSCOPE_API_KEY"

返回樣本

查詢成功後返回 Batch 任務的詳細資料。以下是一個 completed 狀態的返回樣本:

{
  "id": "batch_abc123",
  "object": "batch",
  "endpoint": "/v1/chat/completions",
  "errors": null,
  "input_file_id": "file-abc123",
  "completion_window": "24h",
  "status": "completed",
  "output_file_id": "file-batch_output-xyz789",
  "error_file_id": "file-batch_error-xyz789",
  "created_at": 1711402400,
  "in_progress_at": 1711402450,
  "expires_at": 1711488800,
  "finalizing_at": 1711405000,
  "completed_at": 1711406000,
  "failed_at": null,
  "expired_at": null,
  "cancelling_at": null,
  "cancelled_at": null,
  "request_counts": {
    "total": 100,
    "completed": 95,
    "failed": 5
  },
  "metadata": {
    "customer_id": "user_123456789",
    "batch_description": "Nightly eval job"
  }
}

返回的 JSON 對象包含 Batch 任務的完整資訊,包括任務狀態、結果檔案 ID、請求統計等。欄位詳細說明見下表。

欄位

類型

描述

id

String

Batch任務ID。

status

String

任務狀態,可能的值包括:

  • validating:正在驗證輸入檔案。

  • in_progress:任務正在處理中。

  • finalizing:任務已完成處理,正在產生輸出檔案。

  • completed:任務成功完成。

  • failed:任務因嚴重錯誤失敗。

  • expired:任務在 completion_window 內未能完成而到期。

  • cancelling:正在取消任務。

  • cancelled:任務已被取消。

output_file_id

String

成功結果檔案的ID,任務完成後產生。

error_file_id

String

失敗結果檔案的ID,任務完成後且有失敗請求時產生。

request_counts

Object

包含total, completed, failed 數量的統計對象。

查詢工作清單

可使用 batches.list() 方法查詢 Batch 工作清單,通過分頁機制逐步擷取完整的工作清單。

OpenAI Python SDK

請求樣本

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
batches = client.batches.list(after="batch_xxx", limit=2,extra_query={'ds_name':'任務名稱','input_file_ids':'file-batch-xxx,file-batch-xxx','status':'completed,expired','create_after':'20250304000000','create_before':'20250306123000'})
print(batches)

OpenAI Node.js SDK

請求樣本

/**
 * 阿里雲百鍊 Batch API - 查詢工作清單
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

const batches = await client.batches.list({
    after: 'batch_xxx',
    limit: 2,
    extra_query: {
        'ds_name': '任務名稱',
        'input_file_ids': 'file-batch-xxx,file-batch-xxx',
        'status': 'completed,expired',
        'create_after': '20250304000000',
        'create_before': '20250306123000'
    }
});

for (const batch of batches.data) {
    console.log(batch.id, batch.status);
}

Java(HTTP)

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 查詢工作清單
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPIListBatches {
    
    // 新加坡地區配置
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }
        
        String response = sendRequest("GET", "/batches?after=batch_xxx&limit=2&ds_name=Batch&input_file_ids=file-batch-xxx,file-batch-xxx&status=completed,failed&create_after=20250303000000&create_before=20250320000000", null);
// 解析 JSON 擷取工作清單
        System.out.println(response);
    }
    
    // === 工具方法 ===
    
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        
        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }
        
        return readResponse(conn);
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/batches?xxx同下方內容xxx
# === 執行時請刪除該注釋 ===
curl --request GET  'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/batches?after=batch_xxx&limit=2&ds_name=Batch&input_file_ids=file-batch-xxx,file-batch-xxx&status=completed,failed&create_after=20250303000000&create_before=20250320000000' \
 -H "Authorization: Bearer $DASHSCOPE_API_KEY"
after=batch_id中的batch_id替換為實際值,limit參數設定為返回任務的數量,ds_name填寫為任務名稱片段,input_file_ids的值可填寫多個檔案ID,status填寫Batch任務的多個狀態,create_aftercreate_before的值填寫為時間點。

輸入參數

欄位

類型

傳參方式

必選

描述

after

String

Query

用於分頁的遊標,值為上一頁最後一個任務的ID。

limit

Integer

Query

每頁返回的任務數量,範圍[1, 100],預設20。

ds_name

String

Query

按任務名稱進行模糊比對。

input_file_ids

String

Query

按檔案 ID 篩選,多個 ID 用逗號分隔,最多20個。

status

String

Query

按任務狀態篩選,多個狀態用逗號分隔。

create_after

String

Query

篩選在此時間點之後建立的任務,格式:yyyyMMddHHmmss

create_before

String

Query

篩選在此時間點之前建立的任務,格式:yyyyMMddHHmmss

返回樣本

{
  "object": "list",
  "data": [
    {
      "id": "batch_xxx",
      "object": "batch",
      "endpoint": "/v1/chat/completions",
      "errors": null,
      "input_file_id": "file-batch-xxx",
      "completion_window": "24h",
      "status": "completed",
      "output_file_id": "file-batch_output-xxx",
      "error_file_id": null,
      "created_at": 1722234109,
      "in_progress_at": 1722234109,
      "expires_at": null,
      "finalizing_at": 1722234165,
      "completed_at": 1722234165,
      "failed_at": null,
      "expired_at": null,
      "cancelling_at": null,
      "cancelled_at": null,
      "request_counts": {
        "total": 100,
        "completed": 95,
        "failed": 5
      },
      "metadata": {}
    },
    { ... }
  ],
  "first_id": "batch_xxx",
  "last_id": "batch_xxx",
  "has_more": true
}

返回參數

欄位

類型

描述

object

String

類型,固定值list。

data

Array

Batch任務對象,參見建立Batch任務的返回參數。

first_id

String

當前頁第一個 Batch任務 ID。

last_id

String

當前頁最後一個Batch任務 ID。

has_more

Boolean

是否有下一頁。

取消Batch任務

取消一個進行中或排隊中的任務。成功調用後,任務狀態將變為 cancelling,最終變為 cancelled。在任務被完全取消前,已完成的部分仍會計費。

OpenAI Python SDK

請求樣本

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
batch = client.batches.cancel("batch_id")  # 將batch_id替換為Batch任務的id
print(batch)

OpenAI Node.js SDK

請求樣本

/**
 * 阿里雲百鍊 Batch API - 取消任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

const batch = await client.batches.cancel('batch_id');
console.log(batch.status); // cancelled

Java(HTTP)

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 取消任務
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPICancelBatch {
    
    // 新加坡地區配置
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }
        
        String response = sendRequest("POST", "/batches/batch_id/cancel", null);
        System.out.println(response);
    }
    
    // === 工具方法 ===
    
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        
        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }
        
        return readResponse(conn);
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/batches/batch_id/cancel
# === 執行時請刪除該注釋 ===
curl --request POST 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/batches/batch_id/cancel' \
 -H "Authorization: Bearer $DASHSCOPE_API_KEY"
batch_id替換為實際值。

返回樣本

取消任務成功後返回 Batch 任務的詳細資料。以下是一個 cancelling 狀態的返回樣本:

{
  "id": "batch_abc123",
  "object": "batch",
  "endpoint": "/v1/chat/completions",
  "errors": null,
  "input_file_id": "file-abc123",
  "completion_window": "24h",
  "status": "cancelling",
  "output_file_id": null,
  "error_file_id": null,
  "created_at": 1711402400,
  "in_progress_at": 1711402450,
  "expires_at": 1711488800,
  "finalizing_at": null,
  "completed_at": null,
  "failed_at": null,
  "expired_at": null,
  "cancelling_at": 1711403000,
  "cancelled_at": null,
  "request_counts": {
    "total": 100,
    "completed": 23,
    "failed": 1
  },
  "metadata": null
}
取消任務後,狀態會先變為 cancelling,等待正在執行的請求完成;最終會變為 cancelled。已完成的請求結果仍會儲存在輸出檔案中。

4. 下載Batch結果檔案

任務結束後會產生結果檔案(output_file_id)和可能的錯誤檔案(error_file_id),兩者均通過相同的檔案下載介面擷取。

僅支援下載以file-batch_output開頭的file_id對應的檔案。

OpenAI Python SDK

您可以通過content方法擷取Batch任務結果檔案內容,並通過write_to_file方法將其儲存至本地。

請求樣本

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
content = client.files.content(file_id="file-batch_output-xxx")
# 列印結果檔案內容
print(content.text)
# 儲存結果檔案至本地
content.write_to_file("result.jsonl")

返回樣本

{"id":"c308ef7f-xxx","custom_id":"1","response":{"status_code":200,"request_id":"c308ef7f-0824-9c46-96eb-73566f062426","body":{"created":1742303743,"usage":{"completion_tokens":35,"prompt_tokens":26,"total_tokens":61},"model":"qwen-plus","id":"chatcmpl-c308ef7f-0824-9c46-96eb-73566f062426","choices":[{"finish_reason":"stop","index":0,"message":{"content":"你好!當然可以。無論是需要資訊查詢、學習資料、解決問題的方法,還是其他任何協助,我都在這裡為你提供支援。請告訴我你需要什麼方面的協助?"}}],"object":"chat.completion"}},"error":null}
{"id":"73291560-xxx","custom_id":"2","response":{"status_code":200,"request_id":"73291560-7616-97bf-87f2-7d747bbe84fd","body":{"created":1742303743,"usage":{"completion_tokens":7,"prompt_tokens":26,"total_tokens":33},"model":"qwen-plus","id":"chatcmpl-73291560-7616-97bf-87f2-7d747bbe84fd","choices":[{"finish_reason":"stop","index":0,"message":{"content":"2+2 equals 4."}}],"object":"chat.completion"}},"error":null}

OpenAI Node.js SDK

您可以通過content方法擷取Batch任務結果檔案內容。

請求樣本

/**
 * 阿里雲百鍊 Batch API - 下載結果檔案
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:apiKey: 'sk-xxx'
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 安裝依賴:npm install openai
 */
const OpenAI = require('openai');
const fs = require('fs');

// 新加坡地區配置(預設)
const BASE_URL = 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
// 如果使用北京地區,請將上面的 BASE_URL 替換為:
// const BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// 注意:切換地區時,API Key也需要對應更換

const apiKey = process.env.DASHSCOPE_API_KEY;
if (!apiKey) {
    console.error('錯誤: 請設定環境變數 DASHSCOPE_API_KEY');
    console.error('或在代碼中設定: const apiKey = "sk-xxx";');
    process.exit(1);
}

const client = new OpenAI({
    apiKey: apiKey,
    baseURL: BASE_URL
});

// 下載結果檔案
const content = await client.files.content('file-batch_output-xxx');
const text = await content.text();
console.log(text);

// 儲存到本地檔案
fs.writeFileSync('result.jsonl', text);
console.log('結果已儲存到 result.jsonl');

Java(HTTP)

您可以通過GET請求到/files/{file_id}/content端點擷取檔案內容。

請求樣本

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 阿里雲百鍊 Batch API - 下載結果檔案
 * 
 * 若沒有配置環境變數,可在代碼中寫入程式碼API Key:API_KEY = "sk-xxx"
 * 但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
 * 新加坡和北京地區的API Key不同。
 * 
 * 地區配置:
 * - 北京地區:https://dashscope.aliyuncs.com/compatible-mode/v1
 * - 新加坡地區:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
 * 注意:切換地區時,API Key也需要對應更換
 */
public class BatchAPIDownloadFile {
    
    // 新加坡地區配置
    private static final String BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
    // 如果使用北京地區,請將上面的 BASE_URL 替換為:
    // private static final String BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
    // 注意:切換地區時,API Key也需要對應更換
    
    private static String API_KEY;
    
    public static void main(String[] args) throws Exception {
        API_KEY = System.getenv("DASHSCOPE_API_KEY");
        if (API_KEY == null || API_KEY.isEmpty()) {
            System.err.println("錯誤: 請設定環境變數 DASHSCOPE_API_KEY");
            System.err.println("或在代碼中設定: API_KEY = \"sk-xxx\";");
            System.exit(1);
        }

// 下載結果檔案
String content = sendRequest("GET", "/files/file-batch_output-xxx/content", null);
System.out.println(content);

// 儲存到本地檔案
        Files.write(Paths.get("result.jsonl"), content.getBytes());
        System.out.println("結果已儲存到 result.jsonl");
    }
    
    // === 工具方法 ===
    
    private static String sendRequest(String method, String path, String jsonBody) throws Exception {
        URL url = new URL(BASE_URL + path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        
        if (jsonBody != null) {
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes("UTF-8"));
            }
        }
        
        return readResponse(conn);
    }
    
    private static String readResponse(HttpURLConnection conn) throws Exception {
        int responseCode = conn.getResponseCode();
        InputStream is = (responseCode < 400) ? conn.getInputStream() : conn.getErrorStream();
        try (Scanner scanner = new Scanner(is, "UTF-8").useDelimiter("\\A")) {
            return scanner.hasNext() ? scanner.next() : "";
        }
    }
    
    private static String parseField(String json, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        return matcher.find() ? matcher.group(1) : null;
    }
}

curl(HTTP)

您可以通過GET方法,在URL中指定file_id來下載Batch任務結果檔案。

請求樣本

# ======= 重要提示 =======
# 新加坡和北京地區的API Key不同。
# 以下是新加坡地區base_url,如果使用北京地區的模型,需要將base_url替換為:https://dashscope.aliyuncs.com/compatible-mode/v1/files/file-batch_output-xxx/content
# === 執行時請刪除該注釋 ===
curl -X GET https://dashscope-intl.aliyuncs.com/compatible-mode/v1/files/file-batch_output-xxx/content \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" > result.jsonl

返回樣本

單條響應結果:

{
    "id": "c308ef7f-xxx",
    "custom_id": "1",
    "response": {
        "status_code": 200,
        "request_id": "c308ef7f-0824-9c46-96eb-73566f062426",
        "body": {
            "created": 1742303743,
            "usage": {
                "completion_tokens": 35,
                "prompt_tokens": 26,
                "total_tokens": 61
            },
            "model": "qwen-plus",
            "id": "chatcmpl-c308ef7f-0824-9c46-96eb-73566f062426",
            "choices": [
                {
                    "finish_reason": "stop",
                    "index": 0,
                    "message": {
                        "content": "你好!當然可以。無論是需要資訊查詢、學習資料、解決問題的方法,還是其他任何協助,我都在這裡為你提供支援。請告訴我你需要什麼方面的協助?"
                    }
                }
            ],
            "object": "chat.completion"
        }
    },
    "error": null
}

返回參數

欄位

類型

描述

id

String

請求 ID。

custom_id

String

使用者自訂的 ID。

response

Object

請求結果。

status_code

Integer

狀態代碼。200表示請求成功。

request_id

String

服務端為這次請求產生的唯一ID。

completion_tokens

Integer

模型產生的回複內容(completion)所消耗的Token數量。

prompt_tokens

Integer

發送給模型的輸入內容(prompt)所消耗的Token數量。

total_tokens

Integer

本次調用總共消耗的Token數量。

model

String

本次調用所使用的模型名稱。

error

Object

錯誤資訊對象。如果API調用成功,該值為null。如果發生錯誤,這裡會包含錯誤碼和詳細的錯誤資訊。

error.code

String

錯誤行資訊和錯誤原因,可參考錯誤碼進行排查。

error.message

String

錯誤資訊。

進階功能

配置任務完成通知

對於長時間啟動並執行任務,輪詢會消耗不必要的資源。建議使用非同步通知機制,系統會在任務完成後主動通知。

  • Callback 回調:在建立任務時指定一個公網可訪問的 URL

  • EventBridge 訊息佇列:與阿里雲生態深度整合,無需公網 IP

方式一:Callback 回調

在建立任務時通過 metadata 指定一個公網可訪問的 URL。任務完成後,系統會向指定 URL 發送包含任務狀態的 POST 請求:

OpenAI Python SDK

import os
from openai import OpenAI

client = OpenAI(
    # 若沒有配置環境變數,可用阿里雲百鍊API Key將下行替換為:api_key="sk-xxx"。但不建議在生產環境中直接將API Key寫入程式碼到代碼中,以減少API Key泄露風險。
    # 新加坡和北京地區的API Key不同。
    api_key=os.getenv("DASHSCOPE_API_KEY"), 
    # 以下是北京地區base_url,如果使用新加坡地區的模型,需要將base_url替換為:https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    # 注意:切換地區時,API Key也需要對應更換
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

batch = client.batches.create(
    input_file_id="file-batch-xxx",  # 上傳檔案返回的 id
    endpoint="/v1/chat/completions",  # Embedding文本向量模型填寫"/v1/embeddings",測試模型batch-test-model填寫/v1/chat/ds-test,其他模型填寫/v1/chat/completions
    completion_window="24h", 
    metadata={
            "ds_batch_finish_callback": "https://xxx/xxx"
          }
)
print(batch)

curl(HTTP)

請求樣本

curl -X POST --location "https://dashscope.aliyuncs.com/compatible-mode/v1/batches" \
    -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
          "input_file_id": "file-batch-xxxxx",
          "endpoint": "/v1/chat/completions",
          "completion_window": "24h",
          "metadata": {
            "ds_batch_finish_callback": "https://xxx/xxx"
          }
        }'

方式二:EventBridge 訊息佇列

此方式無需公網 IP,適用於需要與阿里雲其他服務(如Function Compute、RocketMQ)整合的複雜情境。

當 Batch 任務完成時,系統會向阿里雲事件匯流排 EventBridge 發送一個事件。您可以配置 EventBridge 規則來監聽此事件,並將其路由到指定目標。

  • 事件來源 (Source): acs.dashscope

  • 事件類型 (Type): dashscope:System:BatchTaskFinish

相關文檔:路由到訊息佇列RocketMQ版

應用於生產環境

  • 檔案管理

    • 定期調用 OpenAI-File刪除檔案介面刪除不需要的檔案,避免達到檔案儲存體上限(10000個檔案或100GB)

    • 對於大型檔案,推薦將其儲存在阿里雲 OSS 中

  • 任務監控

    • 優先使用 Callback 或 EventBridge 非同步通知

    • 輪詢間隔 > 1分鐘,使用指數退避策略

  • 錯誤處理

    • 實現完整的異常處理機制,包括網路錯誤、API錯誤等

    • 下載並分析 error_file_id 的錯誤詳情

    • 對於常見錯誤碼,參考錯誤資訊進行解決

  • 成本最佳化

    • 合并小任務到一個批次

    • 合理設定 completion_window 提供更多調度靈活性

工具 + 生產力

CSV 轉 JSONL

如果未經處理資料儲存在 CSV 檔案中(第一列為 ID,第二列為內容),可使用以下指令碼快速產生 Batch 任務所需的 JSONL 檔案。

如需調整檔案路徑或其他參數,請根據實際情況修改代碼。
import csv
import json
def messages_builder_example(content):
    messages = [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": content}]
    return messages

with open("input_demo.csv", "r") as fin:
    with open("input_demo.jsonl", 'w', encoding='utf-8') as fout:
        csvreader = csv.reader(fin)
        for row in csvreader:
            body = {"model": "qwen-turbo", "messages": messages_builder_example(row[1])}
            # 選擇Embedding文本向量模型進行調用時,url的值需填寫"/v1/embeddings",其他模型填寫/v1/chat/completions
            request = {"custom_id": row[0], "method": "POST", "url": "/v1/chat/completions", "body": body}
            fout.write(json.dumps(request, separators=(',', ':'), ensure_ascii=False) + "\n")

JSONL 結果轉 CSV

使用以下指令碼可將 result.jsonl 檔案解析為易於在 Excel 中分析的 result.csv 檔案。

如需調整檔案路徑或其他參數,請根據實際情況修改代碼。
import json
import csv
columns = ["custom_id",
           "model",
           "request_id",
           "status_code",
           "error_code",
           "error_message",
           "created",
           "content",
           "usage"]

def dict_get_string(dict_obj, path):
    obj = dict_obj
    try:
        for element in path:
            obj = obj[element]
        return obj
    except:
        return None

with open("result.jsonl", "r") as fin:
    with open("result.csv", 'w', encoding='utf-8') as fout:
        rows = [columns]
        for line in fin:
            request_result = json.loads(line)
            row = [dict_get_string(request_result, ["custom_id"]),
                   dict_get_string(request_result, ["response", "body", "model"]),
                   dict_get_string(request_result, ["response", "request_id"]),
                   dict_get_string(request_result, ["response", "status_code"]),
                   dict_get_string(request_result, ["error", "error_code"]),
                   dict_get_string(request_result, ["error", "error_message"]),
                   dict_get_string(request_result, ["response", "body", "created"]),
                   dict_get_string(request_result, ["response", "body", "choices", 0, "message", "content"]),
                   dict_get_string(request_result, ["response", "body", "usage"])]
            rows.append(row)
        writer = csv.writer(fout)
        writer.writerows(rows)

Excel 亂碼解決

  • 可使用文字編輯器(如Sublime)將 CSV 檔案的編碼轉換為GBK,然後再用Excel開啟。

  • 或在 Excel 中建立一個 Excel 檔案,並在匯入資料時指定正確的編碼格式 UTF-8。

介面限流

介面

限流(主帳號層級)

建立任務

1000 次/分鐘,最大並發 1000 個

查詢任務

1000 次/分鐘

查詢工作清單

100 次/分鐘

取消任務

1000 次/分鐘

計費說明

  • 計費單價:所有成功請求的輸入和輸出Token,單價均為對應模型即時推理價格的50%,具體請參見模型列表

  • 計費範圍:

    • 僅對任務中成功執行的請求進行計費。

    • 檔案解析失敗、任務執行失敗、或行級錯誤請求均不產生費用

    • 對於被取消的任務,在取消操作前已成功完成的請求仍會正常計費。

重要

批量推理為獨立計費項目,不支援預付費(節省計劃)、新人免費額度等優惠,以及上下文緩衝等功能。

錯誤碼

如果調用失敗並返回報錯資訊,請參見錯誤資訊進行解決。

常見問題

  1. Batch調用如何計費?需要單獨購買嗎?

    答:Batch是一種調用方式,採用後付費模式,根據任務中成功請求的Token使用量計費,無需額外購買套餐。

  2. 提交的Batch任務是按順序執行的嗎?

    答:不是。後台採用動態調度機制,系統會根據當前整體的計算資源負載來安排任務執行,不保證嚴格遵循提交順序。在資源緊張時,任務啟動和執行可能會有延遲。

  3. 提交的Batch任務需要多長時間完成?

    答:執行時間取決於系統資源分派情況和您的任務規模。若任務在您設定的 completion_window內未能完成,其狀態將變為expired,此時未處理的請求將不會再執行,也不會產生費用。

    情境建議:對模型推理時效性有嚴格要求的情境,建議使用即時調用;對於處理大規模資料且對時效性有一定容忍度的情境,推薦使用Batch調用。