مرونة ترجمة المحتوى
يستخدم خط أنابيب ترجمة المحتوى في Champollion (مستندات Markdown/MDX) نظام مرونة متعدد الطبقات للتعامل مع الإخفاقات بسلاسة. على عكس ترجمة المفاتيح والقيم — حيث تكون كل دفعة صغيرة وإعادة المحاولة منخفضة التكلفة — تتضمن ترجمة المحتوى مطالبات (prompts) كبيرة ومخرجات طويلة قد تفشل لأسباب بنيوية، وليس فقط لأسباب عابرة.
المشكلة
تختلف أنماط الفشل في ترجمة المحتوى اختلافًا جوهريًا عن ترجمة المفاتيح والقيم:
| نمط الفشل | المفاتيح والقيم | المحتوى |
|---|---|---|
| تجاوز حد المعدل (429) | شائع، عابر | شائع، عابر |
| انتهاء المهلة | نادر (دفعات صغيرة) | شائع (مخرجات طويلة) |
| استجابة فارغة | نادر | شائع (حدود المخرجات، المرشحات) |
| اقتطاع المخرجات | غير منطبق (JSON يتم التحقق منه) | يحدث بصمت |
| مرشح المحتوى | نادر للغاية | محتمل (وثائق CLI، وثائق الأمان) |
| قصور النموذج | إعادة المحاولة تحل المشكلة | إعادة المحاولة لن تحل المشكلة |
الفكرة الأساسية: إعادة محاولة الطلب الفاشل نفسه ليست مرونة، بل عناد. نظام المرونة السليم يحدد سبب فشل شيء ما ويغيّر نهجه وفقًا لذلك.
نظرة عامة على البنية
الطبقة 1: إعادة المحاولة المعتمدة على التشخيص أولًا
قبل تقرير كيفية إعادة المحاولة، يفحص النظام استجابة واجهة برمجة التطبيقات لفهم ما الذي فشل.
تحليل سبب الإنهاء
تُعيد كل واجهة برمجة تطبيقات لنماذج اللغة الكبيرة finish_reason إلى جانب النص المُولَّد. يستخدم Champollion هذا لاتخاذ قرارات ذكية بشأن إعادة المحاولة:
finish_reason | المعنى | الإجراء |
|---|---|---|
stop + محتوى | أكمل النموذج العمل بشكل طبيعي | ✅ قبول النتيجة |
stop + فارغ | لم يولّد النموذج شيئًا | ⚠️ إعادة محاولة الطلب نفسه (عابر) |
length | بلغت المخرجات حد الرموز (tokens) | 🔶 تقسيم المستند تلقائيًا إلى أجزاء |
content_filter | حجب مرشح الأمان المخرجات | 🔴 تسجيل وتخطٍّ (إعادة المحاولة لن تجدي) |
null / مفقود | استجابة غير سليمة البنية | ⚠️ إعادة محاولة الطلب نفسه (عابر) |
يحل هذا محل النهج الحالي الذي يتعامل مع كل فشل بشكل متطابق عبر إعادة المحاولات مع تأخير تصاعدي.
ميزانية إعادة المحاولة
ميزانية إعادة المحاولة القياسية للإخفاقات العابرة:
| الجولة | المحاولات | المهلة | التأخير التصاعدي |
|---|---|---|---|
| قياسية | 4 (0→3) | 60 ثانية | 1 ثانية → 2 ثانية → 4 ثوانٍ |
| مُصعَّدة | 4 (0→3) | 120 ثانية | 1 ثانية → 2 ثانية → 4 ثوانٍ |
| الإجمالي | 8 | — | ~3.5 دقيقة في أسوأ الحالات |
بين الجولتين، تتيح فترة تهدئة مدتها 10 ثوانٍ زوال المشكلات العابرة.
الطبقة 2: تقسيم المحتوى إلى أجزاء
عندما يتجاوز مستند ما حدًا معينًا للحجم — أو عندما تشير الطبقة 1 إلى اقتطاع المخرجات — يقسّم النظام المستند إلى أجزاء بحجم مناسب للترجمة.
راجع استمرارية السياق للاطلاع على إعدادات التقسيم التفصيلية. النقاط الأساسية:
استراتيجية التقسيم
- حدود العناوين — يُعد
##و###حدودًا طبيعية لوحدات الترجمة. كل قسم مستقل بما يكفي للترجمة المنفصلة. - الرجوع إلى الفقرات — إذا تجاوز قسم بعنوان واحد حجم الجزء، يتم التقسيم عند الأسطر الفارغة المزدوجة.
- التقسيم القسري — الملاذ الأخير للفقرات الطويلة جدًا (مثل الجداول). يتم التقسيم عند حدود الجمل.
السياق بين الأجزاء
يتلقى كل جزء آخر فقرتين أو ثلاث فقرات من ترجمة الجزء السابق كسياق. هذا يمنع:
- انحراف المصطلحات — يرى النموذج المصطلح الذي استخدمه مثل "tableau de bord" في الجزء السابق
- تحديد مرجع الضمائر — تنتقل المراجع من القسم السابق
- اتساق الأسلوب — النبرة المُرساة في الجزء 1 تستمر حتى الجزء N
مُحفِّزات التقسيم التلقائي
| المُحفِّز | السلوك |
|---|---|
تعيين contentChunkSize في الإعدادات | تقسيم المستندات التي تتجاوز ذلك الحجم دائمًا |
إرجاع finish_reason: "length" | تقسيم تلقائي كحل احتياطي (حتى بدون إعدادات) |
| المدخلات > ~12 كيلوبايت (كشف تلقائي) | تسجيل اقتراح، دون فرض التقسيم |
الطبقة 3: سلسلة النماذج الاحتياطية
عندما يفشل النموذج المُعد باستمرار — ليس بشكل عابر، بل بنيوي — يجرّب النظام نماذج بديلة. تمتلك النماذج المختلفة نوافذ سياق وحدود مخرجات ومرشحات أمان وقدرات متعددة اللغات مختلفة.
سلسلة النماذج الاحتياطية الافتراضية
{
"contentFallbackChain": [
"google/gemini-2.5-flash",
"anthropic/claude-sonnet-4"
]
}
يتم تجربة النموذج المُعد أولًا دائمًا. لا تُستخدم النماذج الاحتياطية إلا بعد استنفاد جميع جولات إعادة المحاولة (القياسية + المُصعَّدة).
لماذا بنيات متعددة
| السيناريو | فشل النموذج الأساسي | نجاح النموذج الاحتياطي |
|---|---|---|
| وثائق CLI بالفيتنامية | Gemini يُعيد استجابة فارغة | Claude يتعامل معها بنجاح |
| محتوى محجوب بمرشح الأمان | OpenAI يحجبه | لدى Gemini عتبات مرشحات مختلفة |
| جداول منظمة طويلة | النموذج A يقتطع المخرجات | النموذج B لديه نافذة مخرجات أكبر |
تكمن قيمة النماذج الاحتياطية في التنوع البنيوي — لعائلات النماذج المختلفة أنماط فشل مختلفة. الفشل البنيوي لنموذج ما قد يكون أمرًا بسيطًا لنموذج آخر.
النطاق
النماذج الاحتياطية خاصة بالمحتوى فقط. دفعات المفاتيح والقيم صغيرة ولا تكاد تفشل بنيويًا أبدًا. إضافة تعقيد النماذج الاحتياطية هناك سيكون إفراطًا في الهندسة.
الطبقة 4: محاسبة الإخفاقات
عند حدوث إخفاقات، يتتبعها النظام ويبلّغ عنها بشكل صحيح بدلًا من الاستمرار بصمت.
أثناء المزامنة
- تظهر العناصر الفاشلة بعلامة
[FAIL]في مخرجات التقدم - يُسجل كل فشل بسببه المحدد (انتهاء المهلة، استجابة فارغة، مرشح المحتوى، الاقتطاع)
- تُحفظ العناصر المكتملة في ملف البيان (manifest) فورًا (حفظ تدريجي)
بعد المزامنة
يُطبع ملخص الإخفاقات في النهاية:
┌─ Content Translation Failures ─────────────────────────────────────┐
│ │
│ 2 of 24 content translations failed: │
│ │
│ ✗ docs/reference/cli.md → vi │
│ Reason: empty response after 8 attempts + 1 fallback model │
│ Models tried: google/gemini-3.1-pro-preview, gemini-2.5-flash │
│ │
│ ✗ docs/guides/troubleshooting.md → ar │
│ Reason: content_filter (no retry — blocked by safety filter) │
│ │
│ Re-run: npx champollion@latest sync │
│ (22 completed translations are cached and won't re-run) │
└─────────────────────────────────────────────────────────────────────┘
بيان إعادة المحاولة
تُكتب الملفات الفاشلة في .champollion-retry.json:
{
"failedAt": "2026-05-27T21:45:00Z",
"files": [
{
"source": "docs/reference/cli.md",
"locale": "vi",
"reason": "empty_response",
"attempts": 8,
"modelsTried": ["google/gemini-3.1-pro-preview", "google/gemini-2.5-flash"]
}
]
}
عند تشغيل sync التالي، تُعاد معالجة هذه الملفات فقط. تُحفظ الملفات المكتملة عبر بيان تجزئة المحتوى (.champollion-content.lock).
رموز الخروج
| الرمز | المعنى |
|---|---|
| 0 | نجحت جميع الترجمات |
| 1 | خطأ في الإعدادات، مفتاح API مفقود، إلخ. |
| 2 | فشل جزئي — فشلت بعض ترجمات المحتوى |
الإعدادات
{
"contentChunkSize": 4000,
"contentOverlap": 200,
"contentFallbackChain": [
"google/gemini-2.5-flash",
"anthropic/claude-sonnet-4"
]
}
| الحقل | النوع | الافتراضي | الوصف |
|---|---|---|---|
contentChunkSize | number | null | null | الحد الأقصى للرموز (tokens) لكل جزء محتوى. null = بدون تقسيم (تقسيم تلقائي عند الاقتطاع فقط) |
contentOverlap | number | 200 | رموز التداخل بين أجزاء المحتوى لاستمرارية السياق |
contentFallbackChain | string[] | [] | النماذج الاحتياطية التي تُجرَّب عند فشل النموذج المُعد بنيويًا |
حالة التنفيذ
| الميزة | الحالة |
|---|---|
| إعادة المحاولة المعتمدة على التشخيص أولًا (تحليل finish_reason) | 🔲 مُخطط له |
| تقسيم المحتوى (التقسيم حسب العناوين/الفقرات) | 🔲 مُخطط له |
| استمرارية السياق بين الأجزاء | 🔲 مُخطط له |
| سلسلة النماذج الاحتياطية | 🔲 مُخطط له |
| تقرير ملخص الإخفاقات | 🔲 مُخطط له |
| بيان إعادة المحاولة (.champollion-retry.json) | 🔲 مُخطط له |
| رمز الخروج 2 للإخفاقات الجزئية | 🔲 مُخطط له |
| إعادة المحاولة المُصعَّدة (مهلة ممتدة) | ✅ مُنفذ (v3.3.3) |
| رسائل إعادة محاولة مُرقمة بعدد المحاولات | ✅ مُنفذ (v3.3.3) |
| فشل صريح عند أخطاء المحتوى | ✅ مُنفذ (v3.3.3) |
انظر أيضًا
- استمرارية السياق — اتساق الدفعات وإعدادات تقسيم المحتوى
- كيف تعمل المزامنة — خط أنابيب المزامنة الكامل
- طرق الترجمة — الطرق المتاحة وخصائصها