مستوى المقال: مبتدئ
لو لاحظت إن إرسال 100 كلمة عربية لـ Claude أو GPT بيكلّف ضِعف ما تكلّفه نفس 100 كلمة إنجليزية، المشكلة مش في حساب الفاتورة ولا في الموديل. المشكلة في خطوة بتحصل قبل ما الموديل يشوف الكلام أصلاً، اسمها Tokenization. المقال ده هيفهّمك إيه اللي بيحصل بالظبط، وإزاي تقلّل تكلفتك بدون ما تقلّل المحتوى.
Tokenization: المفهوم اللي بيحدد فاتورتك مع الـ AI
المشكلة باختصار
الموديلات اللغوية مش بتقرأ النص كحروف. بتحوّله الأول لأرقام صغيرة اسمها tokens، وكل token بيمثّل قطعة من النص. وبما إن أغلب الموديلات التجارية (Claude, GPT, Gemini) اتدرّبت في الأساس على نصوص إنجليزية، الـ tokenizer بتاعها بيعرف الإنجليزي أحسن من العربي بكتير. النتيجة المباشرة: نفس الجملة بالعربي ممكن تطلع 2 إلى 4 أضعاف الـ tokens مقارنة بالإنجليزي، وأنت بتدفع على كل token دخل وكل token خرج.
مثال بسيط جداً قبل ما نعرّفه علميًا
تخيّل إن عندك خطّاط شغّال في مطبعة قديمة. الخطّاط ده مش بيكتب بإيده — عنده دُرج فيه قصاصات حروف وأجزاء كلمات شائعة محفوظة جاهزة. لمّا تطلب منه يكتب كلمة "Hello"، بيلاقيها كقصاصة واحدة جاهزة في الدُرج، فبيلصقها مرة واحدة. لكن لمّا تطلب منه يكتب "مرحبًا"، الكلمة دي مش موجودة كقصاصة واحدة عنده، فبيقطّعها لـ "م" + "ر" + "ح" + "ب" + "ًا" — 5 قصاصات بدل قصاصة واحدة. وأنت بتتحاسب على عدد القصاصات.
ده بالظبط اللي بيعمله الـ tokenizer. الفرق إن الدُرج بتاعه (بنسمّيه vocabulary) بيتم بناؤه إحصائيًا من نصوص حقيقية أثناء تدريب الموديل. لو النصوص دي إنجليزية في الغالب، الكلمات الإنجليزية الشائعة بتاخد قصاصات كاملة، والكلمات العربية بتتقسّم لقصاصات أصغر بكتير.
التعريف العلمي الدقيق
الـ Tokenization هو عملية تحويل نص إلى تسلسل من الـ tokens، حيث كل token هو وحدة من vocabulary مغلق الحجم (عادة بين 32K و 256K token). الخوارزمية الأشهر اسمها Byte Pair Encoding (BPE)، وهي اللي بتستخدمها GPT-4 و Claude و Llama. الـ BPE بيبدأ من البايتات الفردية، وبيدمج أكتر زوجين متجاورين بيتكرّروا في بيانات التدريب، وبيكرّر الدمج لحد ما يوصل لحجم vocabulary مستهدف. النتيجة: أنماط النصوص الشائعة في بيانات التدريب بتتمثّل بـ token واحد، والأنماط النادرة بتتفكّك لعدة tokens. ورقة Sennrich et al. 2016 هي المرجع الأساسي للخوارزمية دي.
ليه العربي بالذات بيتكلّف أكتر
- UTF-8 encoding: الحرف اللاتيني بياخد بايت واحد، الحرف العربي بياخد بايتين. ده ضِعف الحجم في البداية حتى قبل أي tokenization.
- توزيع بيانات التدريب: أكتر من 80% من بيانات تدريب الموديلات الكبيرة كانت إنجليزية، والعربية كانت أقل من 1% في بعض الحالات (راجع ورقة Common Crawl statistics). النتيجة: الكلمات العربية الشائعة مش لاقية مكان كقصاصات كاملة في الـ vocabulary.
- التشكيل والإعراب: "كَتَبَ" و "كتب" بيتعاملوا كـ tokens مختلفة لأن الحركات بتغيّر تمثيل البايت تمامًا.
- التنوع المورفولوجي: اللغة العربية اشتقاقية. الفعل "كتب" بيتفرّع لمئات الصيغ (يكتب، اكتب، كتبتم، سيكتبون...) كل واحدة منهم بتاخد tokens مختلفة.
مثال كود شغّال: قِس بنفسك
الكود ده بيحسب عدد الـ tokens لنفس الجملة بالعربي والإنجليزي على Claude، باستخدام endpoint رسمي من Anthropic اسمه count_tokens:
from anthropic import Anthropic
client = Anthropic()
def count_tokens(text: str) -> int:
response = client.messages.count_tokens(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": text}],
)
return response.input_tokens
ar = "الذكاء الاصطناعي بيغيّر طريقة شغلنا في كل مكان."
en = "AI is changing the way we work everywhere."
print(f"Arabic: {count_tokens(ar)} tokens / {len(ar)} chars")
print(f"English: {count_tokens(en)} tokens / {len(en)} chars")
المخرج المتوقع تقريبًا (ممكن يختلف خفيف حسب نسخة الموديل):
Arabic: 29 tokens / 47 chars
English: 11 tokens / 43 chars
نفس المعنى، نفس الطول التقريبي بالحروف، لكن الفاتورة 2.6x. لو شغّال على تطبيق بيتعامل مع مليون جملة في الشهر، الفرق ده بيتحوّل لمئات الدولارات من غير ما تكسب جودة.
إزاي تقلّل التكلفة بدون ما تقلّل المحتوى
- فعّل Prompt Caching: لو في جزء ثابت في برومبتك (تعليمات نظام، أمثلة few-shot، وثائق مرجعية)، فعّل caching علشان متدفعش عليه كل مرة. التوفير ممكن يوصل 90% من تكلفة الـ input حسب توثيق Anthropic الرسمي.
- اختصر التشكيل لو مش ضروري: لو نصوصك فيها تشكيل مش لازم للسياق (محادثات يومية، أوصاف منتجات)، شيله. الفرق ممكن يكون 15-20% tokens.
- اختار الموديل بحكمة: Haiku بيكلّف أقل بكتير من Sonnet، و Sonnet أقل من Opus. لو المهمة تصنيف بسيط أو استخراج بيانات، مفيش مبرر تستخدم Opus.
- قسّم وادفع نص: بدل ما تبعت 50,000 token دفعة واحدة، استخدم Batch API لو المهمة مش عاجلة. التكلفة بتنزل 50% حسب التسعير الرسمي.
- لخّص قبل ما تبعت: لو بتبعت محادثة طويلة، استخدم summarization على الـ messages القديمة بدل ما تبعتها كلها كل مرة.
الـ trade-offs اللي لازم تعرفها
كل تحسين له ثمنه. لو شيلت التشكيل من نصوص دينية أو شعرية أو لغوية، ممكن تفقد دقة المعنى تمامًا. لو استخدمت Haiku بدل Sonnet، الجودة في المهام المعقدة (تحليل دقيق، استدلال متعدد الخطوات) بتنزل بنسبة ملحوظة على بنشمارك زي MMLU. الافتراض اللي شغّالين عليه هنا: نصوصك عمومية + المهمة لا تتطلّب دقة قصوى. لو شغّال على نصوص قانونية، طبية، أو مالية، الموازنة بين التكلفة والدقة بتختلف تمامًا.
كمان، Prompt Caching له شرط الحد الأدنى من الـ tokens (1024 token على Sonnet)، فلو برومبتاتك قصيرة، التفعيل بيبقى من غير فايدة فعلية.
متى لا تستخدم هذه التحسينات
لو تطبيقك بيتعامل مع نصوص حسّاسة (طبية، قانونية، مالية، عقود)، ميتنفعش تشيل التشكيل أو تنزل مستوى الموديل. الفرق بين "كَتْب" و "كتب" ممكن يغيّر معنى بند في عقد. كمان، لو حجم استخدامك أقل من 10,000 طلب شهريًا، الفرق المتوقع في الفاتورة هيبقى أقل من 20 دولار، فالوقت اللي هتقضيه في التحسين أغلى من المكسب. ركّز على جودة المنتج الأول، حسّن لمّا الفاتورة تبقى مؤلمة فعلاً.
الخطوة التالية
افتح أول ملف بتبعته للـ AI كل يوم في تطبيقك، شغّل عليه الكود اللي فوق، وشوف نسبة tokens-to-chars. لو الفرق بين عدد الكلمات وعدد الـ tokens أكبر من 3x، عندك مكاسب فورية من Prompt Caching. لو أقل من 2x، اشتغل على اختيار الموديل قبل ما تشتغل على التحسين. القياس قبل التغيير، مش بعده.
المصادر
- Hugging Face NLP Course — Byte-Pair Encoding tokenization
- Anthropic API — Count Message Tokens endpoint
- Anthropic Documentation — Prompt Caching
- OpenAI Tokenizer (لتجريب الـ tokenization تفاعليًا)
- Sennrich et al., 2016 — Neural Machine Translation of Rare Words with Subword Units (الورقة الأصلية لـ BPE)
- Common Crawl — Language Statistics (توزيع اللغات في بيانات التدريب)