Tokens للمبتدئ: ازاي تحسب تكلفة Claude API قبل ما تبعت أول request
لو بتحضّر تربط أول شات بوت بـ Claude وخايف الفاتورة تيجي مفاجأة، خد رقم: سؤال عربي بـ 40 كلمة بيكلّفك أكتر من سؤال إنجليزي بنفس المعنى بحوالي 2.4 ضعف على نفس النموذج. مش لأن العربية أصعب على النموذج، لكن لأن الـ tokenizer بيقطّعها لقطع أكتر. لو فهمت ازاي الـ tokens بتتحسب، تقدر تتوقّع فاتورة الشهر بفرق ±8% قبل ما تبعت request واحد.
المشكلة باختصار
الـ APIs بتاعت LLMs (Claude, GPT, Gemini) كلها بتفوتر بالـ tokens مش بالكلمات. والـ tokens مش حروف ولا كلمات، هي وحدات وسط بين الاتنين. ده اللي بيخلّي أي محاولة تحسب التكلفة بـ "متوسط 5 حروف للكلمة" تطلع غلط بنسبة 40–300%، خصوصاً على نصوص عربية وكود برمجي.
النتيجة العملية: مطوّر بيبني MVP بميزانية $50 للشهر، بيلاقي نفسه دفع $180 في 18 يوم، فبيوقّف المشروع. والسبب الحقيقي إنه ما حسبش الـ system prompt اللي بيتبعت مع كل رسالة، ولا فرّق بين سعر input وسعر output.
أول، اتفرّج على مثال بسيط جداً (مثال محل العصير)
تخيّل إنك دخلت محل عصير، والمحل ده مالوش قائمة أسعار بالعصير الجاهز. عنده قائمة بأسعار المكونات:
- كل قطعة برتقال: 2 جنيه
- كل قطعة جزر: 1.5 جنيه
- السكر: 0.5 جنيه للملعقة
لما تطلب "كوباية برتقال متوسطة"، البائع بيقطّعها لمكوناتها: 4 برتقالات + ملعقة سكر = 8.5 جنيه. لو طلبت "كوكتيل كبير" نفس البائع بيقطّعه: 3 برتقال + 4 جزر + ملعقتين سكر = 13 جنيه. انت طلبت بالكوب، هو حسبلك بالمكون.
الـ Claude API نفس الفكرة بالظبط. انت بتبعت "جملة"، هو بيقطّعها لـ tokens (المكونات)، وبيحسب فاتورتك على عدد المكونات مش طول الجملة. الفرق إن أسعار "المكونات" بتختلف حسب اللغة وحسب نوع النص (كود، نص طبيعي، أرقام).
التعريف العلمي الدقيق: ما هو الـ Token؟
الـ Token هو أصغر وحدة معالجة بيشتغل عليها النموذج. مش حرف، ومش كلمة. هي قطعة بين الاتنين بتطلع من خوارزمية اسمها Byte-Pair Encoding (BPE) — اتنشرت في ورقة Sennrich 2016 وبتستخدمها كل النماذج التجارية حالياً مع تعديلات.
BPE بتبص على مليارات الجمل في بيانات التدريب، وبتجمع أكتر زوج حروف ظهر مع بعض، وبتحوّله لـ token واحد. تعيد العملية لحد ما توصل لحجم قاموس محدد (عادة 100k لـ 200k token). النتيجة: الكلمات الشائعة بتبقى token واحد، والكلمات النادرة بتتقسّم لقطع أصغر.
مثال محسوس على Claude tokenizer (مبني على cl100k العائلة):
"hello"→["hello"]= 1 token"unhappy"→["un", "happy"]= 2 tokens"مرحبا"→["م", "ر", "ح", "با"]≈ 4–5 tokens