إن الاختيار بين Responses API و Chat Completions هو في الأساس مسألة تتعلق بمن يمتلك حالة المحادثة، وليس أي نقطة نهاية تبدو أحدث. تجعل Chat Completions المنسق الخاص بك يعيد إرسال مصفوفة messages بالكامل في كل دور. بينما يمكن لـ Responses المتابعة من معرف استجابة (response ID) مخزن بدلاً من ذلك. لقد قرأنا وثائق API المنشورة لـ TokenLab وواجهة برمجة تطبيقات النموذج المباشرة في 2026-10-03، وتعتمد الإجابة أيضاً على التنسيقات التي يقبلها نموذجك. لذا نبدأ بجدول اتخاذ القرار.
| متطلبات الوكيل | الخيار | السبب |
|---|---|---|
| عميل محادثة متوافق مع OpenAI، قابل للنقل عبر نماذج متعددة | Chat Completions (/v1/chat/completions) |
أوسع توافق للنماذج، وفقاً لـ دليل تنسيقات API (تمت ملاحظته في 2026-10-03) |
| متابعة محادثة من استجابة مخزنة على الخادم | Responses (/v1/responses) |
previous_response_id و store هما حقول خاصة بـ Responses |
| تعديلات عشوائية على السجل، أو التقليم، أو إخفاء الرسائل بين الأدوار | Chat Completions | أنت تمتلك مصفوفة messages بالكامل |
| استجابات الخلفية أو أحداث Responses | Responses | موثقة للنماذج التي تدعمها |
| اتصال WebSocket دائم مع المتابعة | Responses | wss://api.tokenlab.sh/v1/responses |
| مخرجات كائن JSON قابلة للنقل | Chat Completions | response_format: {"type": "json_object"} |
النموذج لا يدرج openai_responses |
Chat Completions، أو التنسيق الأصلي للنموذج | Responses مخصص فقط للنماذج التي تدرجه |
| كتل تفكير Claude، استخدام أدوات Claude، حقول ذاكرة التخزين المؤقت للمطالبات | Anthropic Messages (/v1/messages) |
Chat Completions لا تضمن تلك الحقول |
| محتويات Gemini، الملفات، المحتوى المخزن مؤقتاً، أدوات Gemini | Gemini (/v1beta/models/:model:generateContent) |
احتفظ بالحقول الأصلية لـ Gemini على مسار Gemini |
أبرز النقاط
- Chat Completions هي حالة يديرها العميل. يمكن الإشارة إلى Responses من خلال الخادم عبر
previous_response_id. - تنتقل استدعاءات الأدوات من رسائل
tool_callsالمتداخلة بالإضافة إلىrole: "tool"إلى عناصرfunction_callوfunction_call_outputذات النوع المحدد. - تتغير عملية البث من أجزاء
choices[0].deltaإلى أحداث مسماة، ويجب على عميل Responses أيضاً مراقبةresponse.failedوresponse.incomplete. - دعم التنسيق يعتمد على النموذج. في 2026-10-03، قبل نموذج
gpt-5.6-terraفقط من بين نماذجنا الثلاثة المثالopenai_responses. - لا تخلط أبداً بين التنسيقات داخل محادثة واحدة. قم بتحويل والتحقق من صحة السجل المخزن قبل الطلب التالي.
Responses API مقابل Chat Completions: نفس المهمة، طلبان
خذ مهمة ذات دور واحد: اشرح لماذا السماء زرقاء في جملتين. إليك هذا كطلب Chat Completions، باستخدام إعداد العميل من دليل تنسيقات API (تمت ملاحظته في 2026-10-03):
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["TOKENLAB_API_KEY"],
base_url="https://api.tokenlab.sh/v1",
)
response = client.chat.completions.create(
model="gpt-5.6-terra",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain why the sky is blue in two sentences."},
],
max_tokens=1000,
)
print(response.choices[0].message.content)
وهنا نفس المهمة كطلب Responses:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["TOKENLAB_API_KEY"],
base_url="https://api.tokenlab.sh/v1",
)
response = client.responses.create(
model="gpt-5.6-terra",
instructions="You are a helpful assistant.",
input="Explain why the sky is blue in two sentences.",
max_output_tokens=1000,
)
print(response.output_text)
تتوافق الحقول واحداً لواحد في هذه الحالة البسيطة. تصبح رسالة النظام instructions على المستوى الأعلى. تصبح messages هي input، والتي تقبل سلسلة نصية أو مصفوفة من العناصر. تصبح max_tokens هي max_output_tokens.
تختلف أجسام الاستجابة بشكل أكبر. تُرجع Chat Completions كلاً من choices[0].message و finish_reason. بينما تُرجع Responses مصفوفة output من العناصر المكتوبة وحقل status. يسرد مرجع إنشاء الاستجابة (تمت ملاحظته في 2026-10-03) حالات queued و in_progress و completed و incomplete و failed و cancelled، ويخبرك بالتحقق من status حتى عند نجاح طلب HTTP. تختلف مفاتيح الاستخدام أيضاً: prompt_tokens و completion_tokens على جانب، و input_tokens و output_tokens على الجانب الآخر. تُظهر أمثلة المرجع 20/9/29 و 10/12/22 على التوالي. هذه حمولات نموذجية، وليست قياسات.
متابعة محادثة
تخيل وكيلاً للدعم أجاب للتو على سؤال واحد والآن يتلقى "ماذا عن الطلب #4472؟". مع Chat Completions، تقوم بإلحاق رسالة المستخدم الجديدة بالمصفوفة المخزنة وإعادة إرسال كل شيء. مع Responses، تقوم بتمرير id الاستجابة السابقة وإرسال الدور الجديد فقط:
{
"model": "gpt-5.6-terra",
"previous_response_id": "resp_abc123",
"input": "What about order #4472?"
}
يتم ضبط store افتراضياً على true، لذا يتم الاحتفاظ بالاستجابة السابقة لاسترجاعها لاحقاً ما لم تقم بإيقاف تشغيلها. لا يزال يتعين على تطبيقك الاحتفاظ بـ id المرجعة بشكل دائم بين القفزات. إذا كنت بحاجة إلى تقليم مخصص أو إخفاء الرسائل، فإن التنسيق عديم الحالة هو الأكثر ملاءمة.
يُظهر تقدير تقريبي سبب أهمية إعادة الإرسال عديم الحالة على مستوى الوكيل. افترض وجود سجل من 10,000 رمز (token) يتم إعادة إرساله في كل من 20 استدعاء. هذا يعني 200,000 رمز إدخال. بسعر إدخال gpt-5.6-terra البالغ 0.60 دولار لكل مليون رمز، يصل ذلك إلى 200,000 × 0.60 / 1,000,000 = 0.12 دولار (تقدير؛ بافتراض عدد الرموز، بدون تخزين مؤقت). يأتي السعر من واجهة برمجة تطبيقات النموذج المباشرة، التي تمت ملاحظتها في 2026-10-03، مع تحديث الأسعار في 2026-10-02T16:53:30.068Z.
هناك تحذيران. الوثائق التي قرأناها لا تذكر ما إذا كان السياق المحتفظ به في الخادم يُحاسب كرموز إدخال، لذا قارن usage على حركة المرور الخاصة بك. والطلبات التي تزيد عن 272 ألف رمز إدخال يتم تسعيرها بضعف سعر الإدخال و1.5 ضعف سعر الإخراج للطلب الكامل: 1.20 دولار و5.40 دولار لكل مليون بدلاً من 0.60 دولار و3.60 دولار. يمكن للسجلات الطويلة عديمة الحالة تجاوز هذا الخط.
استدعاء الأدوات: شكل الطلب والاستجابة
يتبع كلا التنسيقين الحلقة الموجودة في دليل المخرجات المهيكلة واستدعاء الأدوات (تمت ملاحظته في 2026-10-03). أرسل الأدوات، واقرأ الاستدعاء، وقم بتشغيله في خلفيتك الخاصة، وأعد النتيجة بنفس التنسيق، وكرر ذلك حتى تصل إجابة نهائية. تختلف الأشكال.
Chat Completions. يتم الإعلان عن الأدوات كـ {"type": "function", "function": {...}}. يجيب النموذج بـ tool_calls على choices[0].message، ويكون finish_reason هو tool_calls. للمتابعة، تقوم بإعادة إرسال المصفوفة بأكملها، بما في ذلك رسالة المساعد مع tool_calls الخاصة بها ورسالة role: "tool" التي تحمل tool_call_id. القيم أدناه توضيحية؛ lookup_customer هو اسم الأداة المستخدم في الدليل:
{
"model": "gpt-5.6-terra",
"messages": [
{"role": "user", "content": "Look up [email protected]"},
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_xyz789",
"type": "function",
"function": {"name": "lookup_customer", "arguments": "{\"email\": \"[email protected]\"}"}
}
]
},
{"role": "tool", "tool_call_id": "call_xyz789", "content": "{\"status\": \"active\"}"}
]
}
Responses. يجيب النموذج بعناصر function_call داخل output، يحمل كل منها call_id و name و arguments. تعيد النتيجة كعنصر إدخال function_call_output وتشير إلى الاستجابة السابقة:
{
"model": "gpt-5.6-terra",
"previous_response_id": "resp_abc123",
"input": [
{
"type": "function_call_output",
"call_id": "call_xyz789",
"output": "{\"status\": \"shipped\", \"tracking_number\": \"1Z999\"}"
}
]
}
أنت لا تعيد بناء رسالة أداة المساعد الوسيطة أبداً. يوجد parallel_tool_calls في كلا التنسيقين. في مرجع إنشاء الاستجابة، يتم ضبطه افتراضياً على true. يسرد مرجع Chat ذلك بدون قيمة افتراضية ويقول إنه ينطبق "عندما يدعمه النموذج المحدد".
وجدنا فجوة واحدة. تصف الصفحات التي قرأناها أدوات Responses و tool_choice بمصطلحات عامة فقط. قبل نقل مخططات الأدوات، اقرأ شكل تعريف الأداة في مرجع إنشاء الاستجابة واختبره على نموذجك المستهدف. التزم أيضاً بهذه القواعد من الدليل:
- لا تقوم TokenLab بتحويل الأدوات المدمجة بين التنسيقات.
- تحقق من صحة وسيطات الأداة قبل أي تأثير جانبي.
- اجعل تنفيذ الأداة متماثلاً (idempotent)، لأن إعادة محاولة العميل يمكن أن تكرر نفس الاستدعاء.
- طبق فحوصات الأذونات الخاصة بك.
البث: الأحداث التي يجب على العميل التعامل معها
تقوم Chat Completions ببث أجزاء SSE. يقرأ عميلك choices[0].delta.content، ويسجل finish_reason، ويتخطى الأجزاء التي لا تحتوي على choices. مع stream_options={"include_usage": True}، يصل الاستخدام في مثل هذا الجزء. يتعامل دليل البث (تمت ملاحظته في 2026-10-03) مع stop كاكتمال، و length كحد للرموز، و tool_calls كطلب لتشغيل الأدوات.
تقوم Responses ببث أحداث مسماة. يتعامل مستهلك الدليل مع هذه:
response.output_text.deltaللنص المراد إلحاقهresponse.completedلعلامة النجاحresponse.failedوresponse.incompleteوerrorكمشاكل نهائية
import os
from openai import OpenAI
with OpenAI(
api_key=os.environ["TOKENLAB_API_KEY"],
base_url="https://api.tokenlab.sh/v1",
timeout=30.0,
max_retries=0,
) as client:
completed = False
with client.responses.create(
model="gpt-5.6-terra",
input="Write a short poem.",
stream=True,
) as stream:
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.completed":
completed = True
elif event.type in {"response.failed", "response.incomplete", "error"}:
raise RuntimeError(f"Stream ended with {event.type}")
if not completed:
raise RuntimeError("Stream closed before response.completed")
تتبع ثلاث قواعد للعميل من الدليل:
- بعد وصول الحدث الأول، يكون البث المتقطع غير مكتمل ولا يتم إعادة تشغيله تلقائياً. احتفظ بالمخرجات الجزئية إذا كان ذلك مفيداً، ولكن لا تضع علامة "مكتمل". قد يختلف الطلب المكرر ويكلف مرة أخرى.
- استخدم SDK لتحليل SSE، لأن جزء الشبكة الواحد ليس بالضرورة حدثاً كاملاً واحداً.
- قم بإلغاء البث الصاعد عندما يتوقف المستخدم أو ينقطع الاتصال، واحتفظ بالمفتاح على خادمك.
توفر Responses أيضاً WebSocket على wss://api.tokenlab.sh/v1/responses. الاستجابات هناك يتم بثها دائماً، background و response.cancel غير مدعومتين، كل اتصال يشغل استجابة نشطة واحدة في كل مرة، ويستمر الاتصال لمدة تصل إلى 60 دقيقة. تحمل الأحداث sequence_number خاصاً بالاستجابة. أحداث البث المسماة error هي كائنات مسطحة، بينما تستخدم إخفاقات الاتصال والبروتوكول كائن error متداخلاً، لذا تعامل مع كلا الشكلين.
تحقق من التنسيقات التي يقبلها النموذج قبل الإرسال
اقرأ tokenlab.accepted_request_formats من صفحة النموذج أو من GET /v1/models/{model}، كما هو موضح في مرجع الحصول على نموذج (تمت ملاحظته في 2026-10-03):
curl "https://api.tokenlab.sh/v1/models/gpt-5.6-terra"
تتضمن الاستجابة كائن tokenlab مع accepted_request_formats و pricing والحدود و lifecycle. تتوافق القيم مع نقاط النهاية كما يصف دليل الأخطاء: openai_chat_completions إلى /v1/chat/completions، و openai_responses إلى /v1/responses، و anthropic_messages إلى /v1/messages، و gemini_generate_content إلى /v1beta/models/{model}:generateContent. يؤكد التنسيق المقبول نقطة النهاية فقط. لا تزال الأدوات والحقول الفردية قد تختلف حسب النموذج.
لقد تحققنا من النماذج الثلاثة التي يشير إليها هذا المقال مقابل واجهة برمجة تطبيقات النموذج المباشرة في 2026-10-03:
| النموذج | التنسيقات المقبولة | الحد الأقصى لرموز الإدخال / الإخراج | السعر لكل مليون إدخال / إخراج (دولار أمريكي) | المصدر |
|---|---|---|---|---|
gpt-5.6-terra |
openai_chat_completions, openai_responses |
1,050,000 / 128,000 | 0.60 / 3.60 (إدخالات تصل إلى 272 ألف) | واجهة برمجة التطبيقات المباشرة |
claude-sonnet-5 |
anthropic_messages, openai_chat_completions |
1,000,000 / 128,000 | 0.90 / 4.50 | واجهة برمجة التطبيقات المباشرة |
gemini-3.5-flash |
gemini_generate_content, openai_chat_completions |
1,048,576 / 65,536 | 0.75 / 4.50 | واجهة برمجة التطبيقات المباشرة |
كانت النماذج الثلاثة في مرحلة دورة الحياة النشطة بدون نموذج بديل، وتم تحديث الأسعار في 2026-10-02T16:53:30.068Z. لذا، gpt-5.6-terra فقط هو الذي يقبل طلب Responses اليوم. يعمل الاثنان الآخران من خلال Chat Completions أو مساراتهما الأصلية. أعد التحقق قبل الشحن، حيث يمكن أن تتغير دورة الحياة والأسعار.
التعامل مع الأخطاء مهم أيضاً هنا. إرجاع نموذج مكتوب بشكل خاطئ في استدعاء إنشاء يعطي 400 model_not_found وقد يتضمن did_you_mean. السؤال عن GET /v1/models/{model} حول معرف غير معروف يُرجع 404 model_not_found. يعني 503 all_channels_failed مع retryable: false أن تكرار الطلب لن يساعد. لا تقم بتبديل النماذج تلقائياً ما لم يكن لدى منتجك إذن للقيام بذلك.
قائمة مراجعة الترحيل: Responses API مقابل Chat Completions
استخدم هذا الترتيب عند نقل وكيل من Chat Completions إلى Responses.
- تأكد من أن النموذج يدرج
openai_responses. إذا لم يفعل ذلك، توقف هنا. البقاء على Chat Completions هو المسار المدعوم. - اختر حدوداً للتحويل. ابدأ محادثات جديدة على Responses. لا تقم بتبديل سلسلة محادثات مباشرة في منتصف الطريق، لأن التنسيقات تمثل الحالة واستدعاءات الأدوات بشكل مختلف.
- قم بتحويل السجل المخزن بعناية. إذا كان يجب عليك ترحيل سلاسل المحادثات القديمة، فقم بتحويلها والتحقق من صحتها في تطبيقك قبل الطلب التالي.
- أعد تسمية الحقول الأساسية. تصبح
messagesهيinput، وتصبح رسائل النظام أو المطورinstructions، وتصبحmax_tokensأوmax_completion_tokensهيmax_output_tokens. - أعد كتابة حلقة الأدوات. استبدل تحليل
choices[0].message.tool_callsبعناصرfunction_call، واستبدل رسائلrole: "tool"بعناصرfunction_call_outputالتي يتم تحديدها بواسطةcall_id. - احتفظ بمعرفات الاستجابة. قم بتخزين كل
idحتى تتمكن من تمريرprevious_response_id. قرر بشأنstoreوالاحتفاظ بالبيانات مسبقاً، وتحقق من المدة التي تحتفظ فيها TokenLab بالاستجابات المخزنة، لأن الصفحات التي قرأناها لا تذكر ذلك. - أعد كتابة مستهلك البث. تعامل مع
response.output_text.deltaوresponse.completedوresponse.failedوresponse.incompleteوerror. تعامل مع البث المغلق بدونresponse.completedكإخفاق. - تحقق من
status. يمكن أن يحمل نجاح HTTP حالاتincompleteأوfailed. - راجع المعلمات التي قد لا تنتقل. تسرد صفحة إنشاء الاستجابة
temperatureوtop_pوtoolsوparallel_tool_callsوreasoningوtext. لا تسردnأوlogprobsأوlogit_biasأوfrequency_penaltyأوpresence_penaltyأوseedأوtop_kأوstopأوuserأوstream_options. تحقق من كل واحدة على نموذجك قبل الاعتماد عليها. قد تمرر TokenLab حقولاً غير معروفة، لكن هذا لا يعني أن النموذج يقبلها. - تعيين مخرجات JSON. يستخدم Chat التنسيق
response_format. تستخدم Responses كائنtext، ويعتمد دعمtext.formatعلى النموذج. - خطط حول نقاط النهاية المفقودة. نقاط النهاية للإلغاء، وعناصر الإدخال، ورموز الإدخال غير متوفرة حالياً. حذف استجابة مخزنة لا يلغي الإنشاء.
- اختبار إعادة التشغيل مع إيقاف المحاولات. احتفظ بـ
max_retries=0وقرر في الكود الخاص بك متى تكون إعادة المحاولة آمنة. لا ينبغي إعادة تشغيل عمليات الإنشاء التي انتهت مهلتها تلقائياً.
أسئلة شائعة
هل يمكنني إرسال طلب Responses إلى Claude Sonnet 5 أو Gemini 3.5 Flash؟
ليس وفقاً لواجهة برمجة تطبيقات النموذج المباشرة في 2026-10-03. يدرج claude-sonnet-5 كلاً من anthropic_messages و openai_chat_completions. ويدرج gemini-3.5-flash كلاً من gemini_generate_content و openai_chat_completions. استخدم Chat Completions أو المسار الأصلي، وتحقق من accepted_request_formats مرة أخرى قبل الشحن.
هل أتوقف عن الدفع مقابل الأدوار السابقة عند استخدام previous_response_id؟
الصفحات التي قرأناها لا تذكر ذلك. إنها توثق أن الخادم يمكنه المتابعة من استجابة مخزنة، ولكن ليس كيفية محاسبة السياق المستعاد. قم بتشغيل بضع استدعاءات متعددة الأدوار وقارن حقول usage مقابل خط الأساس عديم الحالة الخاص بك قبل التخطيط للتوفير.
هل يمكنني تبديل التنسيقات في منتصف المحادثة؟
لا. تقول أدلة TokenLab بالحفاظ على تنسيق واحد لكل محادثة، لأن كل تنسيق يمثل الحالة واستدعاءات الأدوات بشكل مختلف. إذا كان يجب عليك ترحيل السجل المخزن، فقم بتحويله والتحقق من صحته في تطبيقك قبل إرسال الطلب التالي.
كيف يمكنني إلغاء طلب Responses قيد التشغيل؟
نقطة نهاية الإلغاء غير متوفرة حالياً. حذف استجابة مخزنة لا يلغي الإنشاء، ولا تدعم استجابات WebSocket response.cancel. بالنسبة للبث، أغلق البث الصاعد من خادمك عندما يتوقف المستخدم أو ينقطع الاتصال.
قبل تغيير نقاط النهاية، افتح كتالوج نماذج TokenLab وتأكد من accepted_request_formats للنموذج الدقيق الذي يستدعيه وكيلك.
المصادر
تم رصد السعر في 2026-10-03
- TokenLab Docs: API formatsتمت المراجعة في 2026-10-03
- TokenLab Docs: Create Responseتمت المراجعة في 2026-10-03
- TokenLab Docs: Create Chat Completionتمت المراجعة في 2026-10-03
- TokenLab Docs: Structured Outputs & Tool Callingتمت المراجعة في 2026-10-03
- TokenLab Docs: Streamingتمت المراجعة في 2026-10-03
- TokenLab Docs: Errors agents can act onتمت المراجعة في 2026-10-03
- TokenLab Docs: Migration Guidesتمت المراجعة في 2026-10-03
- TokenLab Docs: Get a Modelتمت المراجعة في 2026-10-03



