const BASE_URL = "https://ark.cn-beijing.volces.com/api/coding/v3"; const API_KEY = process.env.ARK_KEY; const MODEL = "ark-code-latest"; const tools = [ { type: "function", function: { name: "read_excel", description: "读取 Excel 前5行", parameters: { type: "object", properties: { path: { type: "string" }, sheet: { type: "string" }, limit: { type: "number" } }, required: ["path"] } } }, { type: "function", function: { name: "list_directory", description: "列出目录", parameters: { type: "object", properties: { path: { type: "string" } } } } }, ]; const body = { messages: [{ role: "system", content: "请用 list_directory 查看 D:/workbench/miniai 目录,然后用 read_excel 读取其中的 data.xlsx 前3行。" }, { role: "user", content: "开始" }], tools, tool_choice: "auto", stream: true, model: MODEL, }; const resp = await fetch(BASE_URL.replace(/\/$/, "") + "/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` }, body: JSON.stringify(body), }); console.log("status:", resp.status); const reader = resp.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; let n = 0; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop() || ""; for (const line of lines) { const t = line.trim(); if (!t.startsWith("data:")) continue; const data = t.slice(5).trim(); if (data === "[DONE]") continue; let j; try { j = JSON.parse(data); } catch { continue; } const delta = j.choices?.[0]?.delta || {}; if (delta.tool_calls) { for (const tc of delta.tool_calls) { console.log(JSON.stringify({ index: tc.index, id: tc.id ?? null, name: tc.function?.name ?? "", args: tc.function?.arguments ?? "" })); } } else if (delta.content) { console.log("content:", JSON.stringify(delta.content)); } if (++n > 200) break; } if (n > 200) break; } console.log("--- end ---");