8341TokenFactory
LLM APIAPI GatewayIntegration

مصنع Token8341: تفكيك طبقة ترجمة البروتوكول في بوابة النماذج، تقسيم SSE وأكواد الأخطاء وتوحيد الاستخدام

SiCore TokenWorks Team·2026-10-27

إذا كنت تعمل على الواجهة الخلفية لتكامل نماذج متعددة، فمن المحتمل جدًا أنك مررت بهذا الانهيار: كود الأعمال مليء بـ if (vendor === 'openai') ... else if (vendor === 'claude') ...، وواجهة محادثة متدفقة واحدة كُتب فيها ثمانمائة سطر من منطق التكيّف، وكل إضافة مزوّد جديد تتطلب تعديل المسار الأساسي بأكمله. المشكلة ليست فيك، بل في أن بروتوكولات واجهات برمجة النماذج الكبيرة لدى مختلف الشركات لم تُصمم أصلًا لتكون موحّدة.

جوهر بوابة النماذج هو طبقة ترجمة بروتوكول: تحويل الطلبات/الاستجابات غير المتجانسة من N مزوّد إلى مجموعة واحدة من البروتوكول الداخلي المعياري. هذه المقالة تتبع تدرجًا من ثلاثة أجزاء: المبدأ، والتطبيق العملي، والمقارنة، لتوضيح كيفية بناء طبقة الترجمة فعليًا.

أولًا: أربعة أنواع من نقاط التباين: لماذا يفقد التوجيه المباشر لعدة مزوّدين السيطرة حتمًا

لنبدأ بالاختلافات الفعلية، وكل منها مع أرقام.

طريقة المصادقة: تعتمد OpenAI على Authorization: Bearer sk-xxx، بطول حقل رأس يبلغ نحو 51 حرفًا؛ وتعتمد Claude على x-api-key؛ وتضع Gemini المفتاح في معامل الاستعلام ?key= داخل URL؛ وتستخدم Qwen وERNIE ترويسة Authorization لكن بخوارزمية توقيع مختلفة، إذ يبلغ العمر الافتراضي لـ access_token في ERNIE 30 يومًا، وعند انتهاء صلاحيته يعيد رمز الخطأ 110. أربع شركات وأربع طرق كتابة.

تنسيق تقسيم SSE المتدفق: قطعة chunk في OpenAI هي data: {"choices":[{"delta":{"content":"x"}}]}، وعلامة النهاية هي data: [DONE]؛ أما نوع الحدث في Claude فهو event: content_block_delta مع data: {"delta":{"text":"x"}}، واسم الحقل يتغير من content إلى text؛ وتضع Gemini الزيادة في candidates[0].content.parts[0].text، بعمق تداخل يبلغ 3 طبقات. لكي تحلل طبقة الأعمال الجملة نفسها، عليك كتابة أربع مجموعات من المحللات (parsers).

منظومة أكواد الأخطاء: هذا هو الجزء الأكثر إزعاجًا. تستخدم OpenAI رمز حالة HTTP مع error.type، وتحديد المعدل هو 429؛ ويعيد Claude 429 عند تحديد المعدل لكن type في الـ body هو rate_limit_error؛ وقد يعيد Qwen رمز الحالة 200 عند تحديد المعدل لكن مع code: "Throttling" في الـ body؛ ويستخدم ERNIE error_code: 17 للإشارة إلى تجاوز الحصة. الشيء نفسه، بأربعة تعبيرات.

معيار إحصاء Token: في OpenAI، usage.total_tokens = prompt + completion، ويُقسَّم الصينية والإنجليزية وفق BPE؛ ويعيد Claude input_tokens وoutput_tokens منفصلين، كما أن تفصيل تقسيم الأحرف الصينية أدق، فالنص الصيني نفسه المكوّن من 500 حرف قد يختلف عدد التوكنات المحسوب بين الشركتين بنسبة 20% إلى 35%. عند الفوترة حسب الاستخدام يتحول هذا الاختلاف مباشرة إلى خطأ في الفاتورة.

مع التوجيه المباشر لأربع شركات، يتضخم حجم كود طبقة الأعمال إلى 3 أو 4 أضعاف ما هو عليه مع مزوّد واحد، وتزداد تكلفة الصيانة خطيًا مع عدد المزوّدين.

ثانيًا: تصميم طبقة الترجمة: تنسيق موحّد، توحيد التدفق، تعيين أكواد الأخطاء، تجميع الاستخدام

على طبقة الترجمة القيام بأربعة أمور، ولا يمكن الاستغناء عن أي منها.

تنسيق الطلب/الاستجابة الموحّد: تعريف مجموعة Schema معيارية داخليًا، بحقول تحاكي أسلوب OpenAI (لأن نظامه البيئي هو الأوسع). يُحوَّل الطلب الخارجي أولًا إلى التنسيق الداخلي، ثم يحوّله المحوّل (adapter) إلى تنسيق كل مزوّد. نمط المحوّل، صنف واحد لكل مزوّد، ينفّذ طريقتين buildRequest() وparseResponse().

توحيد تقسيم التدفق: الجوهر هو تحويل chunk الـ SSE من كل الشركات إلى {delta: string, finish_reason: string|null} موحّد. الطريقة هي كتابة آلة حالة، توزّع حسب نوع المزوّد إلى محللات مختلفة، وتُخرج بنية موحّدة. النقطة الأساسية هي معالجة الحدود: فاصل \n\n في SSE، وبادئة data:، ودمج data متعدد الأسطر، كل هذه يجب استهلاكها داخل المحلل. من الأخطاء التي وقعت فيها حدثا ping وmessage_stop في Claude، فإذا لم يتم تجاهلهما صراحةً، سيُدفع delta فارغ إلى الواجهة الأمامية causing اهتزازًا في واجهة المستخدم.

جدول تعيين أكواد الأخطاء: الحفاظ على تعيين vendorCode -> unifiedCode، موحّدًا في 6 فئات: AUTH_FAILED، RATE_LIMITED، QUOTA_EXCEEDED، INVALID_REQUEST، UPSTREAM_ERROR، TIMEOUT. أيًا كان ما يعيده المزوّد الأعلى، تبحث طبقة الترجمة في الجدول وتحوّله إلى الكود الموحّد، ولا تتعرف طبقة الأعمال إلا على هذه الستة.

تجميع الاستخدام: بعد كل استدعاء يُحوَّل معيار token لكل شركة إلى token داخلي معياري، ويُخزَّن في قاعدة البيانات مع vendor وmodel وrequest_id، للاستخدام لاحقًا في التسوية وتحليل التكلفة. هنا يجب الانتباه إلى فروق المعايير، فلا يمكن جمع output_tokens في Claude وcompletion_tokens في OpenAI مباشرةً، بل يجب توحيدهما إلى مرجع واحد وفق معامل تحويل.

في البنية الطبقية، أقسم عادةً إلى أربع طبقات: طبقة الوصول (المصادقة + تحديد المعدل)، طبقة التوجيه (اختيار النموذج)، طبقة الترجمة (تحويل البروتوكول)، طبقة التكيّف (استدعاء SDK المزوّد). طبقة الترجمة دالة نقية، لا تلمس الإدخال/الإخراج، ما يسهّل اختبار الوحدة.

ثالثًا: كود عملي: تعديل سطر واحد في base_url للاتصال ببوابة تجميع

إذا كنت لا تريد كتابة طبقة الترجمة من الصفر، فإن استخدام منصة تجميع AI API جاهزة هو الخيار الأكثر عملية. استخدمنا في مشروعنا token8341، وهي متوافقة مع OpenAI SDK، ويكفي تعديل سطر واحد من base_url للتبديل، فهي تقوم بعمل طبقة الترجمة نيابةً عنك.

from openai import OpenAI

client = OpenAI(
    api_key="your-key",
    base_url="https://api.token8341.com/v1"  # عدّل هذا السطر فقط
)

resp = client.chat.completions.create(
    model="deepseek-v3",  # يمكن أيضًا التبديل إلى gpt-4o / qwen-max / claude-4-sonnet
    messages=[{"role": "user", "content": "اشرح SSE"}],
    stream=True
)

for chunk in resp:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="")

في هذا الكود، يتم توحيد تقسيم SSE وتعيين أكواد الأخطاء وتجميع الاستخدام على جانب البوابة، وما تحصل عليه طبقة الأعمال هو تنسيق OpenAI المعياري. كما يتم توفير توجيه النماذج المتعددة، إذ يمكن للبوابة اختيار النموذج الأمثل تلقائيًا حسب المهمة، مثل توجيه النصوص الصينية الطويلة إلى Qwen، ومهام الاستدلال إلى DeepSeek، والسيناريوهات الحساسة للتكلفة إلى Doubao.

تنبيه من الأخطاء: بعد تبديل base_url، لا تمرر معاملات المزوّد الخاصة مباشرةً. مثل logit_bias في OpenAI وtop_k في Claude، فقد لا تدعمها البوابة بالكامل، وقد يُتجاهل تمريرها بصمت، فتظن أنها فعّالة بينما هي ليست كذلك. قبل الإطلاق، شغّل سكربت اختبار الضغط لفحص توافق المعاملات.

رابعًا: المقارنة: توجيه النماذج المتعددة مقابل الربط بنموذج واحد

إليك مجموعة من الأرقام المقاسة فعليًا. الربط بنموذج واحد (التوجيه المباشر إلى OpenAI): وقت التكامل نحو شخصين/يوم، والتبديل عند الأعطال يتطلب تعديل الكود وإعادة النشر، ومتوسط زمن الاستعادة 15 دقيقة، ولا مجال لتحسين التكلفة. توجيه النماذج المتعددة (عبر البوابة): وقت التكامل نحو 0.5 شخص/يوم، والتبديل عند الأعطال يتم تلقائيًا، وزمن الاستعادة أقل من 3 ثوانٍ، ويمكن خفض التكلفة بنحو 30% إلى 40% عبر توزيع الحمل حسب المهمة.

من حيث تعقيد الصيانة، يبلغ كود التكيّف للتوجيه المباشر إلى 4 مزوّدين نحو 2000 سطر، وبعد استخدام البوابة ينخفض كود التكيّف في طبقة الأعمال إلى أقل من 200 سطر، بانخفاض 90%. أما من حيث زمن الاستجابة، فتضيف البوابة قفزة واحدة، بزيادة نحو 20 إلى 40ms في P99، وهي تكلفة مقبولة مقارنةً بما توفره من تكلفة صيانة ومرونة تبديل.

بالطبع، البوابة ليست حلًا سحريًا. إذا كان عملك يستخدم نموذجًا واحدًا فقط ولن يتغير أبدًا، فالتوجيه المباشر أبسط. لكن بمجرد أن يتعلق الأمر بنماذج متعددة ومزوّدين متعددين وتحسين التكلفة، تصبح طبقة الترجمة بنية أساسية لا غنى عنها. بوابة النماذج، وواجهات النماذج الكبيرة، وتجميع AI API، هي في الجوهر ثلاث تسميات للمشكلة نفسها على المستوى نفسه.

تذكير أخير: يجب رفع تغطية اختبار الوحدة لطبقة الترجمة إلى أقصاها، خاصةً حالات الحدود في تقسيم التدفق، فهي منطقة عالية الخطورة للحوادث في بيئة الإنتاج.

المؤلف: ليو تشييوان

تاريخ النشر: 28 أكتوبر 2026