→ العودة إلى المدونة
تعليم Kimi التحدث بلغة Claude Code: دليل ميداني لترجمة صيغ الأدوات

تعليم Kimi التحدث بلغة Claude Code: دليل ميداني لترجمة صيغ الأدوات

تعليم Kimi التحدث بلغة Claude Code: دليل ميداني لترجمة صيغ الأدوات

تريد تشغيل منظومة Claude Code — الوكلاء الفرعيون والمهارات والخطافات وكل السقالة التي أمضيت شهوراً في ضبطها — لكن بقيادة Kimi K2.5 أو GLM أو DeepSeek، لأن فاتورة النموذج الرائد موجعة. هناك طريقتان للوصول إلى هناك، وكلتاهما تصطدمان بالجدار نفسه:

  1. قدّم أدوات Claude Code إلى النموذج الآخر. تذهب تعريفات أدواته في الطلب الأول، وكل استدعاء أداة يجب أن يعود بالشكل الذي يتوقعه Claude Code. هذا يعني أن على أحدهم أن يترجم صيغة السلك (wire format).
  2. استخدم منظومة طرف ثالث (OpenCode أو Cline أو Goose أو Crush) تتحدث بالفعل مع كل مزود. عندها ترث منظومتهم هم، لا منظومتك أنت.

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

1. لماذا الترجمة ليست مجرد إعادة تسمية حقل

النموذج الذهني الساذج هو: Anthropic تسميه input_schema، وOpenAI تسميه parameters، اكتب مُطابِقاً، وانتهى الأمر. هذا الجزء فعلاً تافه. إليك الفرق الحقيقي.

تعريفات الأدوات:

Anthropic MessagesOpenAI Chat CompletionsOpenAI Responses
الشكلمسطح: {name, description, input_schema}متداخل: {type:"function", function:{name, description, parameters}}مسطح: {type:"function", name, parameters}
إضافات خاصة بـ Anthropic فقطcache_control، input_examples، defer_loading

لاحظ الفخ من الآن: Responses API الخاص بـ OpenAI نفسه مسطح، أقرب إلى Anthropic منه إلى OpenAI Chat Completions. المترجم الذي يفترض جامداً أن “OpenAI تعني function{} المتداخل” مخطئ في نصف حالات OpenAI.

بنية الدور (turn structure) — هذه هي الكبيرة:

  • Anthropic: استدعاءات الأدوات هي كتل محتوى tool_use داخل رسالة المساعد، متداخلة مع كتل text وthinking. تعود النتائج ككتل tool_result في رسالة بـ role: "user".
  • OpenAI CC: استدعاءات الأدوات مصفوفة tool_calls[] على رسالة المساعد. النتائج رسائل منفصلة بـ role: "tool".
  • OpenAI Responses: لا هذا ولا ذاك — عناصر function_call قائمة بذاتها مترابطة عبر call_id، وهو حقل مختلف عن id الخاص بالعنصر نفسه.

عواقب على الوكيل الوسيط (proxy) أن يتعامل معها: Anthropic تسمح بنص و استدعاء أداة في دور المساعد نفسه (المحوّلات الساذجة تقسمها إلى رسالتين وتنتج سجلاً غير صالح)؛ كل tool_use يجب أن يقابله tool_result وإلا أعادت الواجهة خطأ 400 — “استدعاءات الأدوات اليتيمة” هي مهمة التنقية الأكثر شيوعاً على الإطلاق، وLiteLLM يشحن ميزة مخصصة لها فقط.

ترميز الوسائط (Arguments encoding): tool_use.input في Anthropic هو كائن مُحلَّل. أما function.arguments في OpenAI فهو سلسلة نصية مُرمَّزة بـ JSON. الاستدعاءات بلا وسائط تنتج "" حيث يتوقع المستهلك {}، فيرمي JSON.parse استثناءً — وهو خطأ حي في Vercel AI SDK (#10295).

tool_choice: any في Anthropic هو required في OpenAI؛ وdisable_parallel_tool_use يقيم داخل tool_choice في Anthropic لكنه parallel_tool_calls على المستوى الأعلى في OpenAI. تغيير tool_choice يُبطل أيضاً كتل رسائلك المخزَّنة مؤقتاً.

قابلية نقل JSON Schema: لا مزود رئيسي يقبل $ref على المستوى الأعلى — عليك أن تُضمِّنها. Gemini يرفض items: {}. الوضع الصارم في OpenAI يقبل pattern/minimum/format لكنه لا يفرضها. وفي Responses، حذف strict يحاول الوضع الصارم على أي حال ويتدهور بصمت — فالوكيل الوسيط الذي يكتفي بتمرير تعريفات الأدوات قد غيّر الدلالات دون أن يخبرك.

كل ما سبق ميكانيكي. مزعج، لكنه قابل للحل. القسم التالي ليس كذلك.

2. الأشياء الثلاثة التي لم يحلها أحد

كل بوابة نظرت إليها تنكسر في الأماكن الثلاثة نفسها.

2.1 إعادة تجميع البث (Streaming reassembly)

الترجمة بلا بث مشكلة محلولة. Claude Code يبثّ دائماً.

  • Anthropic SSE: content_block_start (نوع tool_use، يحمل id + name) ← N مرة من content_block_delta بـ {"type":"input_json_delta","partial_json":"…"}content_block_stopmessage_delta بـ stop_reason:"tool_use".
  • OpenAI SSE: أجزاء delta.tool_calls[] مُفهرَسة بحقل index؛ يظهر id/name مرة واحدة، وتصل الوسائط كأجزاء نصية؛ ينتهي بـ finish_reason:"tool_calls".

تحويل أحدهما إلى الآخر يتطلب آلات حالة (state machines) لكل index محفوظة عبر الأجزاء، وهنا ينهار كل شيء. أصدر LiteLLM content_block_start + content_block_stop مع صفر input_json_delta بينهما — يصل كل استدعاء أداة بـ input: {} ويبلّغ Claude Code عن غياب معاملات مطلوبة (#25561، #25321، #25390). يرسل Bifrost stop_reason: "end_turn" بدلاً من "tool_use" في الأدوار المختلطة نص+أداة، فيظن العميل أن المساعد قد انتهى (#3638). ويسقط Portkey دور assistant من فروق البث (#1000). واحتفظ Roo Code بخريطتَي حالة ثابتتين عبر الأجزاء لمجرد ترقيع عدم اتساق البث بين المزودين.

2.2 حالة الاستدلال معتِمة وإلزامية

هذا هو أعمق سبب بنيوي يجعل إعداد Claude-Code-مع-نموذج-أجنبي إعداداً خاسراً (lossy).

توثيق التفكير الموسّع في Anthropic صريح: حين ترسل tool_result، يجب أن تُعاد كتل thinking في آخر رسالة مساعد كاملة وغير معدَّلة، وإلا حصلت على 400: "thinking or redacted_thinking blocks in the latest assistant message cannot be modified". والسبب الجذري المُسمّى في توثيق Anthropic نفسه هو “شِفرة التطبيق التي تُرشِّح كتل المحتوى حسب النوع” — وهو بالضبط ما يفعله مترجم الصيغ.

وsignature على كتلة التفكير هو تمثيل مشفَّر للاستدلال، يفكّه الخادم لإعادة بناء الحالة. لا يوجد حقل سلك في OpenAI لحمله. الذهاب والإياب عبر Chat Completions يدمّره. لهذا فإن LiteLLM #15601، وvercel/ai #11602، وclaude-code-router #1400/#1410 توجد جميعها كأخطاء مفتوحة منفصلة ضد قواعد شِفرة منفصلة: إنها الخطأ نفسه.

لكل مزود نسخته الخاصة ولا واحدة منها تتفاعل مع الأخرى — signature في Anthropic، وreasoning.encrypted_content في OpenAI (والذي، في البث، غائب عن output_item.added ولا يظهر إلا في output_item.done — المحوّلات التي تقرأ الحدث الأول فقط تُسقطه بصمت)، وthought_signature في Gemini على أجزاء functionCall. ومما يجدر معرفته أيضاً: tool_choice: any وtool_choice: tool خطآن قاطعان مع التفكير الموسّع — يُسمح بـ auto/none فقط — ما يكسر المخرجات المنظّمة القائمة على إجبار الأداة بالكامل.

2.3 تبخّر التخزين المؤقت للموجِّهات (Prompt caching)

cache_control خاص بـ Anthropic فقط. التخزين المؤقت في OpenAI ضمني، فلا شيء لتربطه به. كل ترجمة من Anthropic إلى OpenAI تتخلص بصمت من تخزينك المؤقت للموجِّهات — أكبر رافعة منفردة في دليل توفير التوكِنات. توفّر في سعر التوكِن الواحد وتدفعه ثمناً في إخفاقات التخزين المؤقت، ولا شيء في السجلات يخبرك.

DeepSeek هو المورّد الوحيد الذي يقول هذا صراحة: توثيق توافقهم مع Anthropic يُدرِج cache_control تحت غير مدعوم، بجوار الصور والمستندات وتكاملات MCP مباشرة. احترام على ذلك.

3. المترجمات

LiteLLM — Python، ~53k ★، وكيل وسيط + مكتبة

LiteLLM هو الجواب الافتراضي، وله سطحان لـ Anthropic يخلط الناس بينهما باستمرار. POST /anthropic/* هو تمرير مباشر (pass-through) — لا ترجمة، بل يمرّر إلى Anthropic فقط ويضيف تتبّع التكلفة. أما POST /v1/messages (anthropic_messages) فهو الترجمة الحقيقية: صيغة Anthropic داخلاً، وأي مزود خارجاً. Claude Code موثَّق كدرجة أولى — وجّه ANTHROPIC_BASE_URL إليه واضبط CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1.

إنه الأكثر اكتمالاً والأكثر خوضاً للمعارك، وهو أيضاً حيث سُجّلت معظم أخطاء البث في §2.1 — ليس لأنه أسوأ، بل لأنه ما يشغّله الجميع. إنه Python، ثقيل، وتسجيله ثرثار بما يكفي ليصبح مشكلة بحد ذاته.

Bifrost — Go، ~6.5k ★، رخصة Apache-2.0، بوابة

Bifrost هو ما سأمدّ يدي إليه لو أردت ثنائياً واحداً بدلاً من عملية Python. بادئات جاهزة للتوصيل (/openai، /anthropic، /genai)، وClaude Code هدف موثَّق من الدرجة الأولى مع تجاوزات ANTHROPIC_DEFAULT_SONNET_MODEL / ..._HAIKU_MODEL. يوثّق خطوات تحويله بصدق — استخراج رسالة النظام، وتجميع رسائل الأدوات، وتحويل كتلة التفكير، وreasoningthinking بحد أدنى للميزانية قدره 1024. وهو أيضاً بوابة MCP.

أما ادعاء “أسرع 50× من LiteLLM، بزمن معالجة إضافي 11µs” فهو منشور من المورّد بلا تكرار مستقل. تعامل معه وفقاً لذلك.

Portkey AI Gateway — TypeScript، ~12k ★، بوابة

لدى Portkey أنظف مفهوم: ثلاث صيغ دخول عالمية/v1/chat/completions، و/v1/responses، و/v1/messages — كل منها يعمل مع جميع المزودين. ثنائي الاتجاه بحكم التصميم. لكن لا يوجد دليل رسمي لـ Claude Code، والمشكلات المفتوحة هي بالضبط أصناف أعطال §2 (اقتران معرِّفات tool_use↔tool_result معطوب في الاستدعاءات المتوازية، ورفض tool_choice: none لـ Anthropic، وأدوار مفقودة في فروق البث).

claude-code-router — TypeScript، ~36k ★

يستحق تصحيح نموذج ذهني بائد هنا: CCR لم يعد الوكيل الوسيط المحوِّل الصغير الذي يتذكره الناس. إنه الآن مستودع أحادي (monorepo) عند الإصدار v3.0.11 يشحن لوحة تحكم Electron إضافةً إلى بوابة نموذج محلية، ويقود Codex وZCode أيضاً، بإعدادات مسبقة لـ OpenRouter وDeepSeek وMoonshot/Kimi وZ.AI وMiniMax وSiliconFlow. تعيش طبقة التحويل كمكتبة منفصلة أصغر بكثير، musistudio/llms، بواجهة من أربعة خطافات (transformRequestIn/Out، transformResponseIn/Out).

اقرأ متتبّع مشكلاته وسيقفز النمط من §2.2 أمامك: الأخطاء المفتوحة تتجمّع حول الاستدلال × استدعاءات الأدوات، لا حول استدعاءات الأدوات الصِّرفة. الاستدلال أثناء البث يُفسد فروق وسائط الأداة، وreasoning_content الخاص بـ Kimi لا يُحفَظ عبر سجل استدعاءات الأدوات، وthought_signature الخاص بـ Gemini مفقود، وأخطاء 400 لـ DeepSeek عند التفكير+الأدوات. استدعاء الأدوات الصِّرف يعمل. التفكير مع استدعاء الأدوات هو حيث ينزف.

Vercel AI SDK — TypeScript، ~25k ★، مكتبة، لا بوابة

الـ AI SDK يوحّد الصيغ داخل العملية عبر محوّلات لكل مزود. tool({description, inputSchema, execute})، مع Zod أو JSON Schema خام. يناسب مكدّس Bun/TS ببراعة، لكنه مكتبة — لا يمكنك وضعه أمام Claude Code دون بناء وكيل وسيط حوله أولاً.

أكثر تفصيلة كاشفة في الحزمة كلها هي experimental_refineToolInput، الموجودة — حسب التوثيق — لأن “مزودي نماذج اللغة المختلفين يولّدون مدخلات أدوات مختلفة قليلاً” (null مقابل ""). مخرج طوارئ شُحن كاعتراف رسمي بأن التوحيد خاسر.

4. فئة الوكلاء الوسطاء تحتضر، وهذا خبر سار

إليك النتيجة التي لم أتوقعها. من بين أشهر أربعة وكلاء وسطاء مجتمعيين متوافقين مع Anthropic، اثنان أُرشِفا في الأشهر الستة الماضية: y-router (أُرشِف في يناير 2026، وملف README يشير الآن إلى تكامل OpenRouter الرسمي) وanthropic-proxy (أُرشِف في أبريل 2026). ما قتلهما هو أن المزودين شحنوا نقطة النهاية بأنفسهم:

المزودعنوان URL الأساس المتوافق مع Anthropic
Moonshot / Kimihttps://api.moonshot.ai/anthropic
Z.ai / Zhipu GLMhttps://api.z.ai/api/anthropic
DeepSeekhttps://api.deepseek.com/anthropic
MiniMaxhttps://api.minimax.io/anthropic
Qwen / DashScopehttps://dashscope-intl.aliyuncs.com/apps/anthropic
OpenRouterhttps://openrouter.ai/api (واجهتهم “بطراز Anthropic”)

وهي بالضبط القائمة التي يتنقّل بينها Clother وOpenClaude بالفعل عبر متغير بيئة. لذا، للحالة الشائعة — “أريد أن يقود Kimi برنامج Claude Code” — لا تحتاج إلى مترجم صيغ إطلاقاً. المورّد يشغّل واحداً نيابةً عنك، على جانب الخادم، مجاناً. اضبط ANTHROPIC_BASE_URL وانطلق.

تحذيران. نقطة نهاية /anthropic الخاصة بـ Kimi واسعة الاستخدام لكنها غير موثَّقة من المورّد (هناك طلب مفتوح بتوثيقها). وCloudflare AI Gateway هو الأداة الخاطئة هنا — مسار /anthropic الخاص به تمرير مباشر فقط؛ يخزّن مؤقتاً ويراقب حركة المرور إلى Anthropic، لكنه لا يترجم بعيداً عنها.

تمدّ يدك إلى مترجم حقيقي حين تحتاج شيئاً لن تمنحك إياه نقطة نهاية المورّد: التوجيه (نموذج رخيص للوكلاء الفرعيين من فئة Haiku، ونموذج رائد للوكيل القائد)، والتحوّل التلقائي عند تجاوز حدود المعدل عبر المزودين، ومكان واحد لمحاسبة التكلفة عبر أسطول كامل — وهي الأشياء التي يدور حولها §2 من دليل التوكِنات.

5. المسار الآخر: منظومات توحّد الصيغ أصلاً

إن لم ترغب في الترجمة لصالح Claude Code، فاستخدم منظومة لم تحتج قط إلى صيغة Claude:

المنظومةاللغةكيف توحّد الصيغ
OpenCodeTS/Bun185kVercel AI SDK + سجل models.dev
ClineTS65kمعالِجات خاصة لكل مزود
GooseRust51kسمة Provider خاصة
CrushGo27kfantasy + سجل catwalk
AiderPython47kLiteLLM — لكن ⚠️ متوقف منذ مايو 2026
Roo CodeTS24k🔴 أُرشِف في مايو 2026

ثلاثة أشياء علّمني إياها هذا الجدول:

  1. عصر استدعاء الأدوات بـ XML انتهى. هاجر Cline v3.35 من XML-في-موجِّه-النظام إلى استدعاءات أدوات JSON أصلية؛ وأزال Roo لغة XML كلياً وصار يرفض بصرامة استدعاءات الأدوات بلا id. إن كنت تخطط للتحايل على ترجمة الصيغ بتوجيه النموذج لإصدار XML — فقد أبحرت تلك السفينة، وأبحرتها الصناعة بعيداً عن قصد.
  2. “toolshim” الخاص بـ Goose هو الدليل على وجود أن هذه كلها طبقة قابلة للترقيع (shimmable). للنماذج التي لا تملك استدعاء أدوات أصلياً، يجعل Goose النموذج الأساسي يُصدر JSON فضفاضاً، ثم يشغّل نموذجاً مفسِّراً ثانياً رخيصاً (الافتراضي mistral-nemo على Ollama) لقسره إلى استدعاء أداة صالح. إنه تجريبي ويتعلّق، لكنه مفهومياً أنقى تعبير عن الفكرة: صيغة الأداة مشكلة ترجمة، والترجمة مهمة يمكنك تسليمها لنموذج صغير.
  3. Aider ليس مرجعاً لأي من هذا — فهو يتجنب استدعاء الأدوات كلياً عن قصد، ويحرّر عبر كتل نصية SEARCH/REPLACE. نمط عطله هو “فشلت مطابقة الكتلة”، لا انحراف المخطط (schema drift). كون مختلف تماماً.

والتنفيذ المرجعي لطبقة التوحيد، حسب اللغة: TS ← Vercel AI SDK، Go ← charmbracelet/fantasy، Python ← LiteLLM، Rust ← اكتبها بنفسك.

6. المعايير لن تنقذك

MCP لا يحل هذا. هذا أكثر سوء فهم اصطدمت به. MCP طبقة اكتشاف ونقل: tools/list يسلّمك JSON Schema، ثم يبقى على المنظومة أن تحوّل كل أداة MCP إلى تعريف أداة أصلي للمزود، ويبقى النموذج يُصدر استدعاءات أدوات أصلية للمزود. كل عائق قابلية نقل في §1 ينطبق دون تغيير. MCP يركب فوق المشكلة؛ لا يمسّها.

ولدى MCP اضطرابه الخاص أيضاً: مراجعة المواصفة التالية تصل في 2026-07-28 وهي الأكبر منذ الإطلاق — مصافحة initialize مُزالة كلياً، وMcp-Session-Id اختفى، ونقل HTTP+SSE مُهمَل (deprecated). أي شيء كُتب مقابل 2025-11-25 سيحتاج إلى إعادة عمل.

أما عن مواصفة عالمية لاستدعاء الأدوات: لا شيء يفوز. UTCP حقيقي ونشِط ومتخصّص (~300★ على المواصفة) — ويشحن إضافة توافق مع MCP، ما يخبرك من الفائز. agents.json ميت (آخر دفعة في أغسطس 2025). ACP الخاص بـ IBM أُدمج في A2A. وA2A نفسه بصحة جيدة لكنه متعامد (orthogonal): إنه تفاعل وكيل↔وكيل فوق وكلاء معتِمين، لا توحيد مخطط أدوات. التوحيد الفعلي يحدث بالطريقة المملة — كل مورّد يستنسخ شكل /chat/completions، والآن شكل /v1/messages أيضاً.

7. الخلاصة التي وصلت إليها فعلاً: ابنِ فوق Claude، لا تحته

أمضيت مدة أحاول تحسين Claude Code من الأسفل — اعتراض جزء من عمله، وتبديل النموذج تحته، وتقليم سياقه، وترجمة أدواته. وأعتقد أن ذلك طريق مسدود. ليس لأنه لا يمكن جعله يعمل، بل بسبب ما يقوله §2: إعادة تجميع البث، وحالة الاستدلال المعتِمة، والتخزين المؤقت للموجِّهات المتبخّر ثلاثة أصناف أعطال لم تحلها أي طبقة ترجمة، بل خفّفتها فقط. أنت لا تبني ميزة، بل توقّع على صيانة دائمة ضد ثلاث واجهات برمجية متحرّكة. تحسين ما تحت المنظومة مشروع بحثي — تجارب لا تنتهي، بلا دليل استخدام — وينتج شيئاً ينكسر كلما شحن مزود إصداراً فرعياً.

الحركة الأفضل هي الاتجاه المعاكس: ابنِ منظومتك الخاصة التي تجلس فوق Claude Code، وعامِل Claude Code كوكيل صندوق أسود واحد من بين عدة.

الوحدة التي تنسّقها تتوقف عن كونها نموذجاً وتصبح عملية منظومة (harness process): Claude Code هنا، وجلسة OpenCode هناك، وتشغيل Codex هناك، كل منها فصيح بالفعل بلهجة أدوات مزوده، كل منها يدير سياقه الخاص، وتخزينه المؤقت الخاص، وحالة استدلاله الخاصة. تتحدث إليها عبر الواجهة التي تكشفها بالفعل للعالم الخارجي — سطر أوامر، و--format json، ومعرِّف جلسة يمكنك استئنافه — لا عبر بروتوكول سلكها الداخلي.

ما يمنحك ذلك:

  • مشكلة الصيغة تختفي. لا تترجم استدعاء أداة أبداً، لأنك لا تلمس طبقة استدعاء الأدوات أبداً. Claude Code يتحدث Anthropic أصلاً. OpenCode يتحدث ما يشاء. كل يحتفظ بتخزينه المؤقت الخاص، وكتل تفكيره الخاصة، وبثّه الخاص — الأشياء الثلاثة التي يقول §2 إنك لا تستطيع نقلها عبر السلك. أخطاء §2 هي أخطاء عن عبور حدّ. لا تعبره.
  • تتوقف عن إعادة تكييف السياق لكل نموذج. تكييف سياقك لخصوصيات Kimi، ثم لخصوصيات GLM، ثم لخصوصيات DeepSeek، هو N× من العمل ويتعفّن. فوق المنظومة، تكييف السياق هو مهمة كل منظومة بنفسها — الشيء الذي تجيده أصلاً.
  • اختيار النموذج يصبح قرار توجيه، لا قرار سباكة. منظومة رخيصة للمهمة الميكانيكية، ومنظومة رائدة للمهمة الصعبة. هذا مجدوِل (scheduler)، لا وكيل وسيط.
  • إنها أطروحة المنظومة مطبَّقة مستوى واحداً أعلى. إن كانت المنظومة — لا النموذج — هي ما يحوّل 6.7% إلى 68%، فإن الرافعة ليست في تبديل المحرّكات تحت منظومة. إنها في الطبقة التي تقرّر أي منظومة تشغّل ماذا، وترفض دفع ثمن الخطأ نفسه مرتين.

عملياً، هذا يعني لي دمج cmdop-claude داخل cmdop كخطوة أولى — ثم نقل كامل منطق تنسيق المنظومات إلى هناك، بدلاً من الاستمرار في تركيب نماذج رخيصة تحت منظومة لم تطلبها قط.

الخلاصة المستفادة

إن كان كل ما تريده هو قيادة Kimi لبرنامج Claude Code: استخدم نقطة نهاية /anthropic الخاصة بالمورّد وتخطَّ المترجمات كلياً. وإن احتجت التوجيه أو التحوّل التلقائي أو محاسبة التكلفة على مستوى الأسطول فوق ذلك: LiteLLM إن كنت على Python بالفعل، وBifrost إن أردت ثنائي Go واحداً. توقّع أخطاء استدعاء أدوات أثناء البث، وتوقّع خسارة التخزين المؤقت للموجِّهات، وتوقّع أن يكون التفكير-مع-الأدوات هو الحافة الحادة — واعلم أن تلك خصائص للحدّ نفسه، لا للأداة التي اخترتها.

والجواب الاستراتيجي هو التوقف عن الضغط على ذلك الحدّ. لا تُمضِ عمرك في تعليم كل نموذج التحدث بلهجة Claude Code من الأسفل. اكتب المنظومة التي تتحدث إلى المنظومات من الأعلى — عندها لن يهمّ أبداً بأي لهجة يتحدث أي منها.