Sam Huang Logo
DaVinci Assistant API Playground
端點整合規範 查看手冊 → 下載外掛 JSON 20260919-plugin.json ⤓ 返回個人首頁 sam-huang.info ↗

Assistant API 測試控台

相容 OpenAI Assistants API v2 規範之執行除錯與外掛整合工具

下載 Plugin 定義
已就緒外掛 內建 SummarizeUrlContent2 外掛,支援自動讀取 DOCX、PDF 與圖片並執行結構化內容摘要。
查看流程手冊 →
連線與執行參數
API v2
即時執行狀態
閒置中 (Ready)
1
建立 Thread
2
寫入訊息
3
觸發 Run
4
輪詢/外掛
5
取得結果
Console Output
0.0s
[Ready]系統就緒,點擊「開始呼叫 API 測試」即可啟動測試流程。
分析回覆內容 Completed
DaVinci Assistant API 呼叫流程與整合指南
API Specification

DaVinci Assistant 架構完全相容於 OpenAI Assistants API v2 規範。所有請求需附帶 Authorization: Bearer <API_KEY> 與 OpenAI-Beta: assistants=v2 HTTP 標頭。

左右滑動可檢視完整端點規格與參數
步驟 方法 端點路徑 (Endpoint) 用途說明 關鍵參數
步驟 1 POST /threads 建立獨立對話空間 (Thread) 回傳 { "id": "thread_..." }
步驟 2 POST /threads/{thread_id}/messages 寫入使用者訊息或文件連結 { "role": "user", "content": "..." }
步驟 3 POST /threads/{thread_id}/runs 發起 Run 觸發 AI 與外掛處理 { "assistant_id": "asst_..." }
步驟 4 GET /threads/{thread_id}/runs/{run_id} 輪詢狀態 (Polling) 檢查是否為 completed 或 requires_action
步驟 4-B POST /pluginapi 執行外部外掛 (若狀態為 requires_action) ?tid={thread_id}&aid={assistant_id}&pid={func_name}
步驟 4-C POST /threads/{thread_id}/runs/{run_id}/submit_tool_outputs 提交外掛結果給 Run 繼續執行 { "tool_outputs": [{ "tool_call_id": "...", "output": "..." }] }
步驟 5 GET /threads/{thread_id}/messages 取得最終 AI 回覆文字內容 讀取 res.data[0].content[0].text.value

直接可在伺服器或本機執行的 Node.js 完整腳本:

davinci-ai-test.js (Node.js)
const axios = require('axios');

const API_KEY = '您的_DAVINCI_API_KEY';
const ASSISTANT_ID = 'asst_dvc_FnejbpNgNNXVqnsKUhzBMGfa';
const ASSISTANT_API = 'https://sandbox.davinci.tw/api/assts/v1';
const TARGET_URL = 'https://www.sam-huang.info/files/system_v0.2_draft.docx';

const headers = {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
    'OpenAI-Beta': 'assistants=v2'
};

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

async function analyzeDocument() {
    console.log("=== DaVinci Assistant 自動分析腳本 ===");

    // 1. 建立 Thread
    let res = await axios.post(`${ASSISTANT_API}/threads`, {}, { headers });
    const THREAD_ID = res.data.id;
    console.log(`Thread ID: ${THREAD_ID}`);

    // 2. 寫入 Message (直接帶入目標檔案網址)
    await axios.post(`${ASSISTANT_API}/threads/${THREAD_ID}/messages`, {
        role: 'user',
        content: TARGET_URL
    }, { headers });

    // 3. 發起 Run
    res = await axios.post(`${ASSISTANT_API}/threads/${THREAD_ID}/runs`, {
        assistant_id: ASSISTANT_ID,
        additional_instructions: `\nThe current time is: ${new Date().toLocaleString()}`
    }, { headers });
    const RUN_ID = res.data.id;

    // 4. Polling 輪詢與外掛調用
    while (true) {
        await sleep(1500);
        res = await axios.get(`${ASSISTANT_API}/threads/${THREAD_ID}/runs/${RUN_ID}`, { headers });
        let run = res.data;

        if (['queued', 'in_progress', 'cancelling'].includes(run.status)) {
            continue;
        }

        if (run.status === 'requires_action') {
            const toolCalls = run.required_action.submit_tool_outputs.tool_calls;
            const toolOutputs = await Promise.all(toolCalls.map(async (call) => {
                const args = call.function.arguments ? JSON.parse(call.function.arguments) : {};
                const pluginRes = await axios.post(`${ASSISTANT_API}/pluginapi`, args, {
                    params: { tid: THREAD_ID, aid: ASSISTANT_ID, pid: call.function.name },
                    headers: headers,
                    timeout: 30000
                });
                return {
                    tool_call_id: call.id,
                    output: typeof pluginRes.data === 'string' ? pluginRes.data : JSON.stringify(pluginRes.data)
                };
            }));

            await axios.post(`${ASSISTANT_API}/threads/${THREAD_ID}/runs/${RUN_ID}/submit_tool_outputs`, {
                tool_outputs: toolOutputs
            }, { headers });
            continue;
        }

        if (run.status === 'completed') break;
        throw new Error(`任務未預期終止: ${run.status}`);
    }

    // 5. 取得最終對話結果
    res = await axios.get(`${ASSISTANT_API}/threads/${THREAD_ID}/messages`, { headers });
    console.log("分析結果:", res.data.data[0].content[0].text.value);
}

analyzeDocument();

逐步呼叫 API 的 cURL 指令流程:

cURL 指令範例
# 1. 建立 Thread
curl -X POST https://sandbox.davinci.tw/api/assts/v1/threads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v2"

# 2. 建立 Message (直接帶入目標檔案網址)
curl -X POST https://sandbox.davinci.tw/api/assts/v1/threads/THREAD_ID/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v2" \
  -d '{"role": "user", "content": "https://www.sam-huang.info/files/system_v0.2_draft.docx"}'

# 3. 建立 Run
curl -X POST https://sandbox.davinci.tw/api/assts/v1/threads/THREAD_ID/runs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v2" \
  -d '{"assistant_id": "asst_dvc_FnejbpNgNNXVqnsKUhzBMGfa"}'

# 4. 檢查 Run 狀態
curl -X GET https://sandbox.davinci.tw/api/assts/v1/threads/THREAD_ID/runs/RUN_ID \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "OpenAI-Beta: assistants=v2"

# 5. 取得訊息回覆
curl -X GET https://sandbox.davinci.tw/api/assts/v1/threads/THREAD_ID/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "OpenAI-Beta: assistants=v2"

跨網域 CORS 與檔案讀取注意事項

當分析工具在外部環境或瀏覽器下載文件時,若目標檔案伺服器未設定 CORS 標頭,或網址有 HTTP 308 重定向,會導致檔案抓取中斷。

  1. 使用標準完整網址:請使用完整主機名稱 https://www.sam-huang.info/files/...,避免被重定向截斷。
  2. 檔案伺服器開放 CORS:回傳標頭需包含 Access-Control-Allow-Origin: * 與 Access-Control-Allow-Methods: GET, HEAD, OPTIONS。
  3. 支援 OPTIONS 預檢:預檢請求需回傳 HTTP 200 或 204,防止瀏覽器阻擋後續下載。