跳至內容

OpenAI 相容聊天 ​

使用 POST /v1/chat/completions 和 GET /v1/models,更換 base URL 與 API Key 即可通過 OpenAI Python 或 JavaScript SDK 呼叫。這是文本 Chat Completions 格式相容,不代表支援 OpenAI 的所有介面和能力。

鑒權與模型 ​

使用控制臺現有金鑰:Authorization: Bearer sk-your-key。模型列表僅包含當前可用的文本模型和公開 ID。請求應使用返回的 id,不能使用顯示名稱。價格與音色仍通過 /v1/chat/catalog 獲取。

bash
curl https://api.coldstart.win/v1/models -H "Authorization: Bearer sk-your-key"
json
{"object":"list","data":[{"id":"chat-standard","object":"model","created":0,"owned_by":"girllab"}]}

請求與多輪歷史 ​

每次請求按順序傳入完整 messages 數組,支援 system、developer、user、assistant、tool 角色。內容可為字元串或 { "type": "text", "text": "..." } 數組。服務端不會額外疊加歷史或預設人設。 每輪都應攜帶所需系統指令和相關歷史。

bash
curl https://api.coldstart.win/v1/chat/completions \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{"model":"chat-standard","messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"Hello!"}],"max_tokens":256}'
json
{
  "id": "chatcmpl_example",
  "object": "chat.completion",
  "created": 1792540800,
  "model": "chat-standard",
  "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello!", "refusal": null}, "logprobs": null, "finish_reason": "stop"}],
  "usage": {"prompt_tokens": 12, "completion_tokens": 3, "total_tokens": 15}
}

支援的參數 ​

必填 model、非空 messages 數組。可選:stream(預設 false)、temperature(0–2)、top_p(0–1)、max_tokens 或 max_completion_tokens(整數 1–8192,二選一)、stop(一個字元串或 1–4 個字元串)、presence_penalty 和 frequency_penalty(−2–2)、seed(安全整數)、n(僅 1)。未傳生成參數時采用服務預設值;采樣參數效果取決於所選模型。stream_options: {"include_usage": true} 只能配合 stream: true。可選字段傳 null 時使用預設值。HTTP JSON 請求體上限為 15 MiB,模型上下文仍受其 token 容量限制。

串流與用量 ​

串流采用僅含 data: 的 SSE,不使用自定義 event: delta 或 event: completed。讀取 choices[0].delta.content,結束時讀取 finish_reason(stop、length 或 content_filter, tool_calls)及 data: [DONE]。啟用 include_usage: true 後,在 [DONE] 前追加 choices: []、包含最終 usage 的資料塊,其他塊的 usage 為 null;未啟用時不輸出串流 usage 字段。同一請求的所有塊使用相同的本地生成 ID、建立時間與公開模型 ID。

json
{"model":"chat-standard","messages":[{"role":"user","content":"Hello!"}],"stream":true,"stream_options":{"include_usage":true}}
text
data: {"id":"chatcmpl_example","object":"chat.completion.chunk","created":1792540800,"model":"chat-standard","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"usage":null}

data: {"id":"chatcmpl_example","object":"chat.completion.chunk","created":1792540800,"model":"chat-standard","choices":[{"index":0,"delta":{"content":"Hello!"},"logprobs":null,"finish_reason":null}],"usage":null}

data: {"id":"chatcmpl_example","object":"chat.completion.chunk","created":1792540800,"model":"chat-standard","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null}

data: {"id":"chatcmpl_example","object":"chat.completion.chunk","created":1792540800,"model":"chat-standard","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":3,"total_tokens":15}}

data: [DONE]

錯誤與支援范圍 ​

錯誤格式為 { "error": { "message": "...", "type": "invalid_request_error", "param": null, "code": "invalid_request" } }。HTTP 400 表示無效或暫不支援的參數;401 為金鑰無效,402 為點數不足,429 為限流,503 為服務暫不可用,504 為超時。報錯統一脫敏。開始串流前返回 HTTP JSON 錯誤;開始後以 data: {"error": ...} 結束,不發送成功結束標記。不能把部分文本當作完整成功。首段文本等待上限 90 秒,文本增量空閑上限 60 秒,每次增量重置;非串流請求超時為 60 秒。

不支援圖片/音訊輸入、託管搜尋與程式執行、舊版 functions / function_call、自訂工具類型、logprobs、多個候選、store、Responses API 及未列出的參數;會明確拒絕。語音使用 /v1/chat/speech。

計費與 SDK 示例 ​

沿用相同餘額、公開模型價格和輸入/輸出 token 計費。呼叫前預留點數,成功後按實際用量結算並釋放剩余預留;生成失敗、用量無效或結算前斷連釋放預留。結算成功後取消連接不會撤銷扣費。呼叫進入 Usage history 和後臺儀表盤;標準 JSON 包含 usage,不額外返回自定義 billing。重復發送可能再次計費,本介面不提供冪等保證。

bash
pip install openai
npm install openai
python
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["KARMAN_API_KEY"], base_url="https://api.coldstart.win/v1", max_retries=0)
print([model.id for model in client.models.list().data])
model = os.environ["KARMAN_MODEL"]
messages = [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"}]
reply = client.chat.completions.create(model=model, messages=messages, max_tokens=256)
print(reply.choices[0].message.content)

stream = client.chat.completions.create(model=model, messages=messages, max_tokens=256,
    stream=True, stream_options={"include_usage": True})
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="", flush=True)
    if chunk.usage:
        print("\n", chunk.usage)
javascript
import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.KARMAN_API_KEY, baseURL: "https://api.coldstart.win/v1", maxRetries: 0 });
const models = await client.models.list();
console.log(models.data.map(model => model.id));
const stream = await client.chat.completions.create({
  model: process.env.KARMAN_MODEL,
  messages: [{ role: "user", content: "Hello!" }],
  stream: true,
  stream_options: { include_usage: true }
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta.content ?? "");
  if (chunk.usage) console.log("\n", chunk.usage);
}

؀

智慧體工具與結構化輸出 ​

透過 /v1/chat/catalog 的 models[].capabilities 查詢模型能力:tool_calling、parallel_tool_calls、json_mode、structured_outputs。能力依模型而異,不支援時在生成前回傳 HTTP 400。工具由你的應用程式執行;API 不執行函式,也不儲存智慧體記憶。

支援 tools(最多 128 個函式定義)、tool_choice(auto、none、required 或指定函式)、parallel_tool_calls(布林值,需要 tools)。函式包含 name、description、JSON Schema parameters 和可選 strict。工具呼叫回傳 message.tool_calls,content 可為 null。將 assistant 訊息原樣加入歷史,再為每個呼叫加入一則 role: "tool" 訊息,填入對應 tool_call_id。下一次模型呼叫前必須回傳全部結果,工具失敗也應以工具結果說明。呼叫 ID 應唯一,並保留訊息順序。

串流時依 index 合併 choices[0].delta.tool_calls,串接 function.arguments 片段,並保存出現的 id、type、function.name。只在 finish_reason: "tool_calls" 且串流成功結束後執行,不可執行截斷(length)或失敗的輸出。工具增量也會重設 60 秒閒置逾時;首段輸出上限為 90 秒。應驗證函式名稱、參數與權限,並限制循環次數。

response_format 支援 text、json_object、json_schema;後者使用 json_schema: {name, schema, strict, description?}。JSON 模式需在提示詞中明確要求 JSON。嚴格 schema 應將所有屬性列為 required,並設定 additionalProperties: false;可空型別可表達可選值。JSON Schema 不可搭配 parallel_tool_calls: true。解析前檢查 refusal、length 與錯誤;schema 不保證事實正確。工具定義、參數和結果皆計入 token,每輪模型呼叫獨立計費。

完整工具循環 ​

python
import os, json
from openai import OpenAI

client = OpenAI(api_key=os.environ["KARMAN_API_KEY"],
                base_url="https://api.coldstart.win/v1", max_retries=0)
model = os.environ["KARMAN_MODEL"]
tools = [{"type": "function", "function": {
    "name": "lookup_memory", "description": "Read a saved preference.",
    "parameters": {"type": "object", "properties": {"topic": {"type": "string"}},
                   "required": ["topic"], "additionalProperties": False},
    "strict": True
}}]
messages = [{"role": "user", "content": "What food do I like? Use my saved memory."}]

for _ in range(4):
    reply = client.chat.completions.create(
        model=model, messages=messages, tools=tools,
        tool_choice="auto", parallel_tool_calls=False, max_tokens=512)
    choice = reply.choices[0]
    message = choice.message
    if message.refusal or choice.finish_reason not in ("stop", "tool_calls"):
        raise RuntimeError("Incomplete or refused response")
    messages.append(message.model_dump(exclude_none=True))
    if not message.tool_calls:
        print(message.content)
        break
    for call in message.tool_calls:
        try:
            if call.function.name != "lookup_memory":
                raise ValueError("Unknown function")
            args = json.loads(call.function.arguments)
            if not isinstance(args, dict) or set(args) != {"topic"} or not isinstance(args["topic"], str):
                raise ValueError("Invalid arguments")
            result = {"topic": args["topic"], "preference": "apples"}
        except (ValueError, TypeError):
            result = {"error": "Invalid tool request"}
        messages.append({"role": "tool", "tool_call_id": call.id,
                         "content": json.dumps(result)})
else:
    raise RuntimeError("Agent round limit reached")

結構化輸出範例 ​

python
reply = client.chat.completions.create(
    model=model,
    messages=[{"role": "user", "content": "I like apples. Extract this preference as JSON."}],
    response_format={"type": "json_schema", "json_schema": {
        "name": "memory", "strict": True,
        "schema": {"type": "object", "properties": {"preference": {"type": "string"}},
                   "required": ["preference"], "additionalProperties": False}
    }}, max_tokens=256)
choice = reply.choices[0]
if choice.finish_reason != "stop" or choice.message.refusal:
    raise RuntimeError("Incomplete or refused response")
memory = json.loads(choice.message.content)
print(memory)