أضف مزوّداً مخصصاً متوافقاً مع OpenAI إلى OpenCode.
Updated 2026-07-29
يقرأ OpenCode المزوّدين المخصصين مباشرة من opencode.json. عرِّف كتلة provider بحزمة @ai-sdk/openai-compatible، ووجّه options.baseURL إلى https://api.apisrouter.com/v1، وكل نموذج تُدرجه يصبح قابلاً للاختيار في منتقي /models تحت مفتاح واحد.
إجابة سريعة: كتلة provider واحدة في opencode.json.
يدعم OpenCode مزوّدين مخصصين متوافقين مع OpenAI بشكل أصيل. أضف مدخل provider إلى opencode.json مع ضبط npm على "@ai-sdk/openai-compatible"، واضبط options.baseURL على https://api.apisrouter.com/v1، واقرأ المفتاح من متغيّر بيئة عبر قالب {env:...}، وأدرج معرّفات النماذج التي تريدها تحت models. ثم اضبط حقل model على المستوى الأعلى على "apisrouter/<model-id>" ويوجّه OpenCode حلقة الوكيل بأكملها عبر البوابة. هذا هو مسار المزوّد المخصص الموثّق في وثائق OpenCode، وليس غلافاً (wrapper) أو نسخة معدَّلة (fork). ملف الإعداد يعيش إما في جذر مشروعك (opencode.json) أو عالمياً في ~/.config/opencode/opencode.json، ويُدمَج الاثنان، لذا يمكن تعريف كتلة provider مرة واحدة وإعادة استخدامها عبر كل مستودع.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"apisrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "APIsRouter",
"options": {
"baseURL": "https://api.apisrouter.com/v1",
"apiKey": "{env:APISROUTER_API_KEY}"
},
"models": {
"claude-sonnet-4-6": { "name": "Claude Sonnet 4.6" }
}
}
},
"model": "apisrouter/claude-sonnet-4-6"
}كيف يحلّ OpenCode المزوّدين والنماذج.
يبني OpenCode (anomalyco على GitHub، أحد أكثر وكلاء البرمجة في الطرفية حصولاً على نجوم بنحو 186 ألف نجمة) طبقة المزوّد الخاصة به على Vercel AI SDK. حقل npm في كتلة provider يسمّي حزمة SDK التي يحمّلها OpenCode للتحدث مع ذلك المزوّد: "@ai-sdk/openai-compatible" تتحدث بروتوكول /v1/chat/completions القياسي، بينما "@ai-sdk/openai" تتحدث بروتوكول /v1/responses الخاص بـ OpenAI. البوابة متعددة البائعين تخدم chat completions، لذا openai-compatible هي الحزمة الصحيحة؛ اختيار "@ai-sdk/openai" مقابل نقطة نهاية chat-completions هو الطريقة الأكثر شيوعاً لتعطّل هذا الإعداد. يُعنوَن النماذج كأزواج provider/model. معرّف المزوّد هو أياً كان المفتاح الذي اخترته في كتلة provider ("apisrouter" أعلاه)، ومعرّف النموذج هو المفتاح داخل خريطة models، لذا يصبح النموذج الافتراضي "apisrouter/claude-sonnet-4-6". كل ما تعرّفه يظهر في منتقي /models داخل TUI، قابلاً للتبديل في منتصف الجلسة. سلوك واحد يستحق الاستيعاب: بالنسبة للمزوّدين المخصصين، خريطة models هي قائمة سماح (allowlist). المزوّدون المدمجون يأتون مع كتالوج معروف، لكن OpenCode لا يستطيع تعداد نماذج نقطة نهاية مخصصة بنفسه، لذا فقط المعرّفات التي تعرّفها صراحة قابلة للعنونة. عندما تخدم نقطة النهاية خلف baseURL معرّفات Claude وGPT وDeepSeek وKimi جنباً إلى جنب، فإن تعريف مدخل واحد لكل نموذج يحوّل المنتقي إلى لوحة تحويل عبر البائعين خلف مفتاح واحد.
الإعداد الكامل: إعداد عالمي، إعداد مشروع، وحدود لكل نموذج.
التخطيط النظيف هو تعريف المزوّد مرة واحدة في الإعداد العالمي في ~/.config/opencode/opencode.json والاحتفاظ فقط بخيارات لكل مستودع (أي نموذج، أي وكلاء) في opencode.json الخاص بكل مشروع. يدمج OpenCode ملفات الإعداد بدلاً من استبدالها، لذا يبقى ملف المشروع صغيراً ولا تتكرر كتلة provider أبداً. قالب {env:APISROUTER_API_KEY} يُحلّ عند وقت التحميل من البيئة، مما يُبقي المفتاح خارج أي ملف قد يُثبَّت (commit). صدّره من ملف تعريف shell الخاص بك حتى تراه كل جلسة طرفية تُطلق OpenCode. كل مدخل نموذج يقبل أيضاً كائن limit بحدود قصوى لسياق ومخرج tokens. تعريفها يهم أكثر مما يبدو: يستخدم OpenCode رقم السياق لتحديد متى تحتاج الجلسة إلى تلخيص، لذا نموذج بسياق طويل مُعرَّف بدون حدود يُعامَل بتحفّظ أكثر مما ينبغي. اضبط limit.context على ما يدعمه النموذج فعلياً وستتم عملية ضغط الجلسات الطويلة لاحقاً بدلاً من مبكراً.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"apisrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "APIsRouter",
"options": {
"baseURL": "https://api.apisrouter.com/v1",
"apiKey": "{env:APISROUTER_API_KEY}"
},
"models": {
"claude-opus-4-7": { "name": "Claude Opus 4.7", "limit": { "context": 200000, "output": 32000 } },
"claude-sonnet-4-6": { "name": "Claude Sonnet 4.6", "limit": { "context": 200000, "output": 64000 } },
"gpt-5.5": { "name": "GPT-5.5" },
"gpt-5.6-sol": { "name": "GPT-5.6 Sol" },
"kimi-k2.7-code": { "name": "Kimi K2.7 Code" }
}
}
},
"model": "apisrouter/claude-sonnet-4-6",
"small_model": "apisrouter/kimi-k2.7-code"
}اختيار model وsmall_model.
سير العمل العملي هو الإبقاء على الفتحة الرئيسية على النموذج الذي تثق به للتعديلات وتدوير المرشحين عبر جلسات حقيقية بدلاً من معايير قياسية: بعد ظهيرة من diffs فعلية مقابل قاعدة الكود الخاصة بك يخبرك أكثر من لوحة صدارة. التوجيه عبر نقطة نهاية واحدة يجعل كل مرشّح مجرد تغيير سطر واحد، وعرض الاستخدام لكل مفتاح يُظهر ما كلّفته كل تجربة فعلياً.
- model يقود حلقة الوكيل الرئيسية: قراءة الملفات، تخطيط التعديلات، كتابة diffs، تشغيل الأدوات. هذه الفتحة ترى أطول السياقات وتقوم بالهندسة الفعلية، لذا مكان نموذج برمجة حديث (claude-sonnet-4-6، claude-opus-4-7، gpt-5.5) هنا.
- small_model يتعامل مع مهام خفيفة مثل توليد عنوان الجلسة. يعمل كثيراً لكنه لا يحمل عمل البرمجة أبداً، لذا معرّف سريع ورخيص هو الشكل الصحيح؛ لا سبب لحرق tokens حديثة على العناوين.
- معرّفات مضبوطة للبرمجة مثل gpt-5.6-sol وkimi-k2.7-code تستحق التعريف حتى لو لم تكن افتراضك: التبديل إليها لجلسة ثقيلة بإعادة الهيكلة هو مجرد اختيار واحد من /models، لا تعديل إعداد.
- بما أن كلا الفتحتين تأخذان سلاسل provider/model مقابل نفس كتلة provider، يمكن أن تأتي الفتحتان الرئيسية والصغيرة من بائعين مختلفين في نفس الجلسة، وهو ما لا يسمح به أي مفتاح بائع واحد.
ادفع حسب الاستخدام · أقل من السعر الرسمي
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| النموذج | السعر الرسمي | سعرنا |
|---|---|---|
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| Claude Opus 4.7 | $5.00 / $25.00 per M | $4.00 / $20.00 per M |
| GPT-5.5 | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| GPT-5.6 Sol | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| Kimi K2.7 Code | $0.95 / $4.00 per M | $1.00 / $4.00 per M |
أنماط الفشل الخاصة بمزوّدي OpenCode المخصصين.
حزمة SDK خاطئة. "@ai-sdk/openai" يُرسل إلى /v1/responses؛ بوابة chat-completions تجيب على ذلك المسار بخطأ. إذا فشل طلبك الأول بخطأ على شكل بروتوكول أو مسار بدلاً من خطأ مصادقة، تحقق من أن حقل npm يقول "@ai-sdk/openai-compatible" بالضبط. نموذج غائب عن المنتقي. نماذج المزوّد المخصص موجودة فقط إذا عُرِّفت؛ خطأ إملائي في مفتاح models، أو معرّف افترضته لكن لم تضفه أبداً، ببساطة لا يظهر في /models. المعرّفات سلاسل دقيقة تشمل لواحق الإصدار، وقائمة /v1/models الخاصة بالبوابة هي مصدر الحقيقة للنسخ منه. {env:...} غير محلول. يُحلّ القالب من بيئة العملية التي أطلقت OpenCode. مفتاح صُدِّر في طرفية واحدة لا يصل إلى نسخة OpenCode أُطلقت من طرفية أخرى أو من مُطلِق سطح مكتب لم يستورد ملف تعريفك أبداً. ضع الـ export في ملف تعريف shell، لا في جلسة لمرة واحدة. مفاجآت دمج الإعداد. بما أن الإعدادات العالمية والمشروع تُدمَج، فإن opencode.json مشروع يضبط model على مزوّد مختلف يتجاوز افتراضك العالمي بصمت، وكتلة provider متبقية في مشروع قديم يمكن أن تُظلّل التوقعات. عندما يبدو التوجيه خاطئاً، اقرأ كلا الملفين قبل افتراض أن البوابة أساءت التصرف. baseURL بدون /v1. يُلحق SDK مسارات مثل /chat/completions بأياً كان الـ base الذي تعطيه، لذا https://api.apisrouter.com/v1 صحيح والمضيف العاري ليس كذلك. فشل اتصال أو على شكل 404 في إعداد صحيح لولا ذلك هو هذا في الغالب.
من يوجّه OpenCode عبر بوابة.
- المطورون الذين يعيشون في TUI طوال اليوم ويريدون Claude وGPT وKimi في منتقي /models واحد بدلاً من الحفاظ على بيانات اعتماد مزوّد منفصلة لكل بائع.
- المهندسون الذين يقارنون نماذج البرمجة على عمل حقيقي. كل مرشّح هو مدخل واحد مُعرَّف واختيار واحد من المنتقي؛ المقارنة جلسة بجلسة لا تحتاج حسابات جديدة.
- الفرق التي توحّد سرّاً واحداً. APISROUTER_API_KEY واحد في وثائق التهيئة يستبدل قائمة تحقق من مفاتيح لكل بائع، والاستخدام لكل مفتاح يُظهر من ينفق كم.
- المستخدمون الذين يقرنون نموذجاً رئيسياً حديثاً بـ small_model منخفض السعر من بائع مختلف، وهو ما لا تستطيع إعدادات البائع الواحد التعبير عنه.
- المطورون الذين لا يملكون وصولاً إلى فوترة بائع معيّن. الوصول القائم على تعبئة الرصيد بدون شرط بطاقة يزيل الاعتماد على التسجيل لكل مزوّد.
تحقق من نقطة النهاية وصحّح أخطاء الجلسة الأولى.
قبل بدء جلسة، اسرد ما تخدمه البوابة. المعرّفات التي تُعيدها /v1/models هي بالضبط السلاسل التي يجب أن تطابقها مفاتيح خريطة models الخاصة بك. أخطاء الجلسة الأولى متسقة. 401 يعني أن APISROUTER_API_KEY لم يكن مرئياً لعملية OpenCode؛ استخدم echo للمتغيّر في نفس الطرفية التي تُطلق منها. خطأ نموذج غير موجود من البوابة يعني أن المفتاح المُعرَّف لا يطابق معرّفاً مخدوماً، بما في ذلك لواحق الإصدار. إذا لم يظهر المزوّد إطلاقاً، تحقق من صحة JSON، لأن فاصلة زائدة أو قوساً في مكان خاطئ يجعل الملف بأكمله غير قابل للقراءة ويعود OpenCode إلى الافتراضات. بمجرد تدفّق الطلبات، تعرض لوحة APIsRouter النموذج لكل طلب، وعدد tokens، والإنفاق. وكلاء البرمجة هم أحمال عمل ذات سياق طويل وأدوار كثيرة، ورؤية أي الجلسات وأي النماذج تستهلك الـ tokens هو كيف تقرر ما إذا كانت الفتحة الرئيسية تستحق سعرها.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50الأسئلة الشائعة
هل يمكن لـ OpenCode استخدام نماذج Claude وGPT وKimi عبر مزوّد مخصص واحد؟
نعم. المزوّد المخصص هو مجرد baseURL بالإضافة إلى قائمة سماح models. عندما تخدم نقطة النهاية عدة بائعين، عرِّف مدخلاً واحداً لكل معرّف، ويظهر كل نموذج مُعرَّف في منتقي /models تحت نفس المزوّد والمفتاح، قابلاً للتبديل في منتصف الجلسة.
أين يذهب مفتاح API في opencode.json؟
في options.apiKey باستخدام قالب البيئة، مثل "{env:APISROUTER_API_KEY}". يُحلّ القالب عند وقت التحميل حتى لا يجلس المفتاح الحرفي أبداً في ملف الإعداد. صدّر المتغيّر من ملف تعريف shell الخاص بك حتى ترثه كل طرفية تُطلق OpenCode.
هل يجب أن تعيش كتلة provider في الإعداد العالمي أم إعداد المشروع؟
عالمياً، في ~/.config/opencode/opencode.json. يدمج OpenCode ملفات الإعداد، لذا تعريف المزوّد مرة واحدة عالمياً وضبط اختيار النموذج فقط لكل مشروع يُبقي المستودعات خالية من تمديدات بيانات الاعتماد ويتجنب تباعد الكتل المكرَّرة.
لماذا لا يظهر نموذجي في منتقي /models؟
يجب تعريف نماذج المزوّد المخصص صراحة؛ لا يستطيع OpenCode تعداد نقطة نهاية مخصصة. تحقق من أن خريطة models تحتوي على سلسلة المعرّف الدقيقة، بما في ذلك لواحق الإصدار، وانسخ المعرّفات من استجابة /v1/models الخاصة بالبوابة بدلاً من كتابتها من الذاكرة.
ما الفرق بين @ai-sdk/openai-compatible و@ai-sdk/openai هنا؟
@ai-sdk/openai-compatible تتحدث /v1/chat/completions، البروتوكول الذي تخدمه البوابات متعددة البائعين. @ai-sdk/openai تتحدث بروتوكول /v1/responses الخاص بـ OpenAI. بالنسبة لـ APIsRouter، استخدم @ai-sdk/openai-compatible؛ الحزمة الأخرى سترسل إلى مسار لا تخدمه البوابة لهذا الغرض.
هل حدود السياق المُعرَّفة تهم فعلاً؟
نعم. يستخدم OpenCode limit.context لتحديد متى تحتاج الجلسة إلى ضغط. ترك الحدود غير مُعرَّفة على نموذج بسياق طويل يعني أن الجلسات تُلخَّص أبكر من اللازم، لذا اضبط limit.context وlimit.output على ما يدعمه النموذج فعلياً.