محادثة متوافقة مع OpenAI
استخدم POST /v1/chat/completions وGET /v1/models مع OpenAI Python أو JavaScript SDK عن طريق تغيير عنوان URL الأساسي ومفتاح واجهة برمجة التطبيقات. هذا هو التوافق مع إكمالات الدردشة النصية، وليس دعمًا لكل نقطة نهاية أو قدرة OpenAI.
المصادقة والنماذج
استخدم نفس مفتاح API لوحدة التحكم: Authorization: Bearer sk-your-key. تحتوي قائمة النماذج على نماذج نصية متاحة حاليًا ومعرفاتها العامة. استخدم id الذي تم إرجاعه؛ لا تستخدم اسم العرض. تظل الأسعار والمعرفات الصوتية متاحة في /v1/chat/catalog.
curl https://api.coldstart.win/v1/models -H "Authorization: Bearer sk-your-key"{"object":"list","data":[{"id":"chat-standard","object":"model","created":0,"owned_by":"girllab"}]}الطلبات وسجل المحادثات
يوفر كل طلب مصفوفة messages الكاملة بالترتيب. الأدوار المدعومة: system، developer، user، assistant، tool. قد يكون المحتوى عبارة عن سلسلة أو مجموعة من أجزاء { "type": "text", "text": "..." }. لا تتم إضافة أي سجل للخادم أو شخصية افتراضية. يجب أن يتضمن كل دور تعليمات النظام المطلوبة والتاريخ ذي الصلة.
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}'{
"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. تستخدم القيم الخالية الاختيارية الإعدادات الافتراضية. الحد الأقصى لنص HTTP JSON هو 15 MiB؛ تعتمد حدود سياق الرمز المميز على النموذج.
البث والاستخدام
يستخدم البث SSE للبيانات فقط، بدون event: delta أو event: completed المخصص. اقرأ choices[0].delta.content، ثم finish_reason النهائي (stop أو length أو content_filter, tool_calls) وdata: [DONE]. مع include_usage: true، هناك قطعة إضافية مع choices: [] وusage النهائي يسبق [DONE]؛ القطع الأخرى لها usage: null. وبدون ذلك، فإن أجزاء البث تتجاهل الاستخدام. تشترك جميع القطع في معرف الإكمال المحلي ووقت الإنشاء ومعرف النموذج العام.
{"model":"chat-standard","messages":[{"role":"user","content":"Hello!"}],"stream":true,"stream_options":{"include_usage":true}}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
يتم تطبيق نفس الرصيد وأسعار النماذج العامة وفواتير الرمز المميز للإدخال/الإخراج. يتم حجز الاعتمادات قبل الإنشاء وتسويتها باستخدام الاستخدام المبلغ عنه؛ يتم تحرير الحجوزات غير المستخدمة. فشل الإنشاء أو الاستخدام غير الصالح أو قطع الاتصال قبل أن تقوم التسوية بتحرير الحجز. الإلغاء بعد تسوية ناجحة لا يؤدي إلى التراجع عن الرسوم. تظهر المكالمات في سجل الاستخدام ولوحة تحكم المسؤول؛ تحتوي استجابة JSON القياسية على usage، وليس على حقل billing مخصص. قد يؤدي تكرار الطلب إلى فرض رسوم أخرى؛ لم يتم توفير العجز.
pip install openai
npm install openaiimport 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)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);
}أدوات الوكيل والمخرجات المنظمة
تحقق من models[].capabilities في /v1/chat/catalog: tool_calling وparallel_tool_calls وjson_mode وstructured_outputs. يختلف الدعم حسب النموذج؛ تعيد القدرات غير المدعومة HTTP 400 قبل التوليد. ينفذ تطبيقك الأدوات. لا تنفذ الواجهة الدوال ولا تخزن ذاكرة الوكيل.
تتوفر tools بحد أقصى 128 دالة، وtool_choice بالقيم auto أو none أو required أو دالة محددة، وparallel_tool_calls كقيمة منطقية تتطلب tools. تقبل الدالة name وdescription وparameters وفق JSON Schema وstrict اختياريًا. اقرأ message.tool_calls؛ قد تكون content بقيمة null. أضف رسالة assistant كما هي ثم رسالة role: "tool" لكل استدعاء مع tool_call_id المطابق. أعد جميع النتائج بما فيها الأخطاء قبل استدعاء النموذج التالي، وحافظ على ترتيب الرسائل ومعرّفات فريدة.
عند البث، اجمع choices[0].delta.tool_calls حسب index ووصل أجزاء 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 صراحة في التعليمات. يتطلب المخطط الصارم إدراج جميع الخصائص في required وضبط additionalProperties: false؛ يمكن تمثيل القيم الاختيارية بالسماح بـ null. لا تجمع JSON Schema مع parallel_tool_calls: true. تحقق من refusal وlength والأخطاء قبل التحليل. لا يضمن المخطط صحة الحقائق. تدخل تعريفات الأدوات ومعاملاتها ونتائجها ضمن حساب الرموز، وتُحاسب كل جولة نموذج على حدة.
حلقة أدوات كاملة
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")مثال للمخرجات المنظمة
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)