Zum Inhalt springen

OpenAI-kompatibler Chat ​

Mit angepasster Basis-URL und API-Schlüssel lassen sich POST /v1/chat/completions und GET /v1/models über das OpenAI Python- oder JavaScript-SDK nutzen. Unterstützt wird das Textformat von Chat Completions, nicht jede OpenAI-Funktion.

Authentifizierung und Modelle ​

Verwenden Sie den vorhandenen Konsolenschlüssel: Authorization: Bearer sk-your-key. Die Liste enthält verfügbare Textmodelle und öffentliche IDs. Verwenden Sie die zurückgegebene id, nicht den Anzeigenamen. Preise und Stimmen stehen weiterhin unter /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"}]}

Anfragen und Gesprächsverlauf ​

Senden Sie bei jeder Anfrage das vollständige, geordnete Array messages. Rollen: system, developer, user, assistant, tool. Inhalte sind Zeichenketten oder Arrays aus { "type": "text", "text": "..." }. Es werden weder Serververlauf noch Standardpersona ergänzt. Senden Sie die benötigten Systemanweisungen und den relevanten Verlauf bei jeder Runde mit.

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}
}

Unterstützte Parameter ​

Pflichtfelder: model und ein nicht leeres messages-Array. Optional: stream (Standard false), temperature (0–2), top_p (0–1), max_tokens oder max_completion_tokens (Ganzzahl 1–8192, nicht gleichzeitig), stop (eine Zeichenkette oder 1–4 Zeichenketten), presence_penalty und frequency_penalty (−2–2), seed (sichere Ganzzahl), n (nur 1). Ohne Angabe gelten Dienststandardwerte; die Wirkung der Sampling-Parameter hängt vom Modell ab. stream_options: {"include_usage": true} setzt stream: true voraus. Optionale null-Werte verwenden den Standard. Das JSON-Limit beträgt 15 MiB; die Kontextgrenze richtet sich nach dem Modell.

Streaming und Verbrauch ​

SSE verwendet nur data:, keine eigenen Ereignisse wie event: delta oder event: completed. Lesen Sie choices[0].delta.content, anschließend finish_reason (stop, length, content_filter, tool_calls) und data: [DONE]. Bei include_usage: true folgt vor dem Ende ein zusätzlicher Block mit choices: [] und endgültigem usage; andere Blöcke haben usage: null. Sonst wird usage weggelassen. Alle Blöcke teilen dieselbe lokale ID, Erstellungszeit und öffentliche Modell-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]

Fehler und Funktionsumfang ​

Fehlerformat: { "error": { "message": "...", "type": "invalid_request_error", "param": null, "code": "invalid_request" } }. HTTP 400 bedeutet ungültige oder nicht unterstützte Eingabe, 401 ungültiger Schlüssel, 402 unzureichendes Guthaben, 429 Ratenlimit, 503 vorübergehender Fehler und 504 Zeitüberschreitung. Fehlerdetails werden bereinigt. Vor Streambeginn wird ein HTTP-JSON-Fehler gesendet, danach ein Block data: {"error": ...} ohne Erfolgsmarker. Teilantworten gelten nicht als abgeschlossen. Zeitlimits: 90 Sekunden bis zum ersten Text, 60 Sekunden ohne Textzuwachs (bei jedem Delta zurückgesetzt), 60 Sekunden für Anfragen ohne Streaming.

Nicht unterstützt: Bild-/Audioeingaben, gehostete Suche und Codeausführung, ältere functions / function_call, benutzerdefinierte Tool-Typen, logprobs, mehrere Kandidaten, store, Responses API und nicht aufgeführte Parameter. Diese werden abgelehnt. Sprache verwendet /v1/chat/speech.

Abrechnung und SDK-Beispiele ​

Guthaben, öffentliche Modellpreise und Abrechnung der Ein-/Ausgabetokens bleiben gleich. Vor der Generierung wird Guthaben reserviert, nach Erfolg nach tatsächlichem Verbrauch abgerechnet und der Rest freigegeben. Bei Fehlern, ungültigem Verbrauch oder Verbindungsabbruch vor der Abrechnung wird die Reservierung freigegeben. Ein Abbruch nach erfolgreicher Abrechnung storniert diese nicht. Aufrufe erscheinen im Nutzungsverlauf und Admin-Dashboard. Standard-JSON enthält usage, kein eigenes billing. Wiederholte Anfragen können erneut berechnet werden; Idempotenz wird nicht garantiert.

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);
}

Agent-Werkzeuge und strukturierte Ausgaben ​

Prüfen Sie models[].capabilities unter /v1/chat/catalog: tool_calling, parallel_tool_calls, json_mode, structured_outputs. Die Fähigkeiten hängen vom Modell ab; nicht unterstützte Funktionen liefern vor der Generierung HTTP 400. Werkzeuge laufen in Ihrer Anwendung. Die API führt keine Funktionen aus und speichert kein Agent-Gedächtnis.

Unterstützt werden tools (bis zu 128 Funktionen), tool_choice (auto, none, required oder eine benannte Funktion) und parallel_tool_calls (boolesch, tools erforderlich). Funktionen enthalten name, description, JSON-Schema-parameters und optional strict. Lesen Sie message.tool_calls; content darf null sein. Übernehmen Sie die assistant-Nachricht unverändert und ergänzen Sie pro Aufruf eine Nachricht mit role: "tool" und passender tool_call_id. Senden Sie vor dem nächsten Modellaufruf alle Ergebnisse, auch Fehler. Behalten Sie eindeutige IDs und die Reihenfolge bei.

Beim Streaming sammeln Sie choices[0].delta.tool_calls nach index und verketten function.arguments. Bewahren Sie id, type und function.name auf. Führen Sie Werkzeuge erst nach finish_reason: "tool_calls" und erfolgreichem Stream-Ende aus, niemals bei length oder Fehlern. Tool-Deltas setzen das Leerlauflimit von 60 Sekunden zurück; für die erste Ausgabe gelten 90 Sekunden. Validieren Sie Namen, Argumente und Berechtigungen und begrenzen Sie die Anzahl der Runden.

response_format unterstützt text, json_object und json_schema mit json_schema: {name, schema, strict, description?}. Fordern Sie im JSON-Modus ausdrücklich JSON an. Strikte Schemas benötigen alle Eigenschaften in required sowie additionalProperties: false; optionale Werte können null erlauben. JSON Schema ist nicht mit parallel_tool_calls: true kombinierbar. Prüfen Sie refusal, length und Fehler vor dem Parsen. Strukturvorgaben garantieren keine sachliche Richtigkeit. Tool-Definitionen, Argumente und Ergebnisse zählen zur Token-Abrechnung; jede Modellrunde wird separat berechnet.

Vollständige Werkzeugschleife ​

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")

Beispiel für strukturierte Ausgaben ​

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)