تخطَّ إلى المحتوى
16/30الفصل 16 من 30

Context Window وtokens والفاتورة، بالأرقام

محادثة من 40 دورًا تكلف 22 ضعف طولها في input tokens. يخفض caching ذلك 68%، وtimestamp في الموضع الخطأ يضيف 20%.

في هذه الصفحة

هذه محادثة دعم من أربعين دورًا، محسوبة التكلفة دورًا بدور. لا شيء فيها غير مألوف: مطوّر يسأل عن API، ومساعد يجيب في فقرة أو فقرتين. التبادل كاملًا يبلغ 5,090 tokens من النص — نحو ثماني صفحات.

الدورprompt tokensنص جديدoutputتكلفة هذا الدورالإجمالي التراكمي
121318183$0.002622$0.002622
589214123$0.003260$0.014354
101,65619114$0.004680$0.035530
202,86818103$0.006972$0.094426
303,9412099$0.009070$0.174170
404,94717142$0.011598$0.274386

اقرأ العمودين الثاني والثالث معًا. في الدور 40 كتب المستخدم سبعة عشر tokens، وحوسب على 4,947. لم يكن السؤال أصعب من السؤال الأول؛ بل كان أقصر. ما تغيّر هو أن الطلب حمل معه المحادثة كلها، مرة أخرى، للمرة الأربعين.

إجمالي input tokens المحتسبة عبر تلك الاستدعاءات الأربعين: 112,617. طول المحادثة 5,090 tokens. لقد دفعت ثمنها اثنتين وعشرين مرة.

هذا الفصل يشرح لماذا يحدث ذلك، وما الاسم الذي يظهر به في فاتورة كل مزوّد، وأي من الأشياء الخمسة التي تُحاسَب عليها يمكنك فعل شيء حياله.

عرض التفاصيل

ما يحتاجه هذا الفصل من الجزء الثاني.

  • الفصل 7 بنى tokenizer. الـ token هي الوحدة هنا أيضًا — الوحدة نفسها، لكنها الآن مسعّرة.
  • الفصل 9 اشتق self-attention وتكلفتها O(n2)O(n^2)، في صندوق الترميز التقاربي. تلك التكلفة هي سبب وجود حد أصلًا، ولذلك يُحال إليها هنا بدل إعادة شرحها.
  • الفصل 13 قاس prefill مقابل decode وحسب ما تشغله KV cache. هاتان المرحلتان هما ما تشتريه فعليًا أعمدة input وoutput أعلاه.

كل ما عدا ذلك TypeScript، لأن الأمر هنا محاسبة لاستدعاء بعيد وليس رياضيات عن model.

أغلى سوء فهم في هذا المجال هو أن model يتذكر المحادثة.

هو لا يفعل، وآلية الفصل 13 تشرح السبب بدقة. حالة transformer أثناء التوليد هي KV cache: المفاتيح والقيم المحسوبة لكل token في التسلسل. تعيش تلك cache لمدة طلب واحد. عندما ينتهي الطلب، تصبح العملية التي احتفظت بها حرة لخدمة شخص آخر، وتختفي cache. لا يوجد مخزن لكل مستخدم في الجهة الأخرى، ولا session.

لذلك يجب أن يصل الطلب التالي حاملًا كل ما يُفترض أن يعرفه model، ويعيد model بناء تلك الحالة بتشغيل forward pass على prompt كاملًا قبل أن يطلق token جديدة واحدة. سمّى الفصل 15 الـ prompt «الحالة كلها». هذا هو السبب الفيزيائي: الـ prompt هو الحالة الكاملة لأن لا شيء آخر ينجو بعد الاستدعاء.

الـ context window هي الطول الأقصى لذلك الـ prompt مع إجابته. إنها سقف لمقدار الحالة التي يمكنك إعادة بنائها، لا وعاء يحتفظ بأي شيء بين الطلبات. تسميتها «ذاكرة model» تقلب اتجاه السببية — أنت لا تملأ ذاكرة، بل تدفع لإعادة إنشائها.

من هنا يأتي رقم الاثنتين والعشرين. الدور nn يحمل كل الأدوار السابقة n1n-1، لذلك يكون إجمالي input عبر محادثة من nn أدوار هو مجموع سلسلة متنامية، أي تربيعي:

total input  =  i=1n(s+hi)  =  Θ(n2)\text{total input} \;=\; \sum_{i=1}^{n} \big(s + h_i\big) \;=\; \Theta(n^2)

حيث ss هو system prompt وhih_i هو السجل عند الدور ii. عند ملاءمة input التراكمي المقاس مع an2+bnan^2 + bn عبر الأربعين دورًا نحصل على 60.22n2+432.25n60.22\,n^2 + 432.25\,n، وهو ما يتنبأ بـ 113,645 tokens عند الدور 40 مقابل 112,617 مقاسة. الحد التربيعي هو المسيطر، والحد الخطي هو ما كتبه المستخدم فعليًا.

الخلاصة التي يجب أن تخرج بها من هذا الفصل: فاتورتك تنمو مع مربع المحادثة، لا مع السؤال الأخير. الأسئلة الأربعون نفسها إذا طُرحت بلا أي سجل تكلف $0.066036. الاحتفاظ بالسجل كلف $0.274386. السجل ضاعف الفاتورة 4.2 مرة، وسيواصل المضاعفة، لأن المضاعِف هو طول المحادثة.

النافذة محدودة لسببين يدفعان في الاتجاه نفسه. الأول هو سبب الفصل 9: attention تقارن كل token بكل token أخرى، لذلك ينمو عمل تلك الطبقة مع مربع طول التسلسل. والثاني هو الذاكرة: تنمو KV cache خطيًا مع طول التسلسل، وقد أجرى الفصل 13 ذلك الحساب — وعند التسلسلات الطويلة تصبح أكبر من الأوزان.

تمت مهاجمة كلا الحدين، ولم يُزل أي منهما. FlashAttention1 يعيد تنظيم الحساب بحيث يقرأ ويكتب أقل بكثير إلى الذاكرة عالية النطاق، ما يجعل التسلسلات الطويلة عملية دون تغيير التكلفة التقاربية. Position Interpolation2 وYaRN3 يوسّعان نافذة model المدرّب القابلة للاستخدام عبر إعادة تحجيم positional encodings من الفصل 9 بدل إعادة التدريب. معًا، هما سبب انتقال النوافذ من 2K إلى 1M خلال خمس سنوات.

ما لم يفعلاه هو جعل السياقات الطويلة مجانية. لقد رفعا السقف وجعلا الميل ألطف. لكن الميل ما زال موجودًا، وهو ما تقيسه شرائح الأسعار لاحقًا في هذا الفصل.

تقريبًا كل حاسبة تكلفة على الإنترنت تصوغ استدعاء API على أنه input tokens مضروبة في سعر input زائد output tokens مضروبة في سعر output. كان ذلك صحيحًا في 2023. أما الآن فهو خطأ بطريقة تجعل الفواتير تنحرف بمقدار ضعفين أو أكثر في كلا الاتجاهين.

هناك خمس فئات token قابلة للفوترة:

السلةما هيالسعر النموذجي، نسبةً إلى input
uncached inputprompt tokens اضطر model إلى معالجتها من جديد
cache readprompt tokens خُدمت من بادئة مخزنة0.1×
cache writeprompt tokens خُزنت في cache في هذا الاستدعاء1.25× إلى 2×
outputtokens ولّدها model وأرسلها إليك5× إلى 6×
reasoningtokens ولّدها model ولم يرسلها إليكبسعر output

ثلاث من هذه الخمس لم تكن موجودة كبنود منفصلة قبل عامين، وبندا cache هما ما يخطئ فيه الناس، لأن cache write تكلف أكثر من input العادي، لا أقل. تدفع علاوة لتخزين شيء كي تدفع خصمًا عند قراءته لاحقًا، وما إذا كانت هذه الصفقة جيدة يعتمد كليًا على عدد مرات قراءته.

سلة reasoning هي سلة الفصل 12، لكنها الآن ذات سعر، وتحمل تفصيلًا يستحق التصريح به: تقول وثائق Google إن التسعير «يعتمد على كامل thought tokens التي يحتاج model إلى توليدها، رغم أن الملخص وحده هو ما يخرج من API.»4 تُحاسَب على tokens لا تُنقل إليك أبدًا. إنها السلة الوحيدة التي لا يمكنك عد محتواها أو فحصه أو التحقق منه.

والآن الجزء الذي يجعل هذه مشكلة تطبيع لا مشكلة ضرب. كل مزوّد يبلّغ عن هذه السلال بأسماء مختلفة، و—وهذا هو الفخ—اثنان منهم يستخدمان الكلمة نفسها لكمّيتين مختلفتين.

خذ استدعاءً واحدًا: 4,837 tokens مقروءة من cache، و110 جديدة، و142 output tokens مرئية، و300 reasoning tokens.

three usage payloads, one callJSON
// OpenAI-compatible
{ "usage": { "prompt_tokens": 4947,
             "prompt_tokens_details": { "cached_tokens": 4837 },
             "completion_tokens": 442,
             "completion_tokens_details": { "reasoning_tokens": 300 } } }

// Anthropic
{ "usage": { "input_tokens": 110,
             "cache_read_input_tokens": 4837,
             "cache_creation_input_tokens": 0,
             "output_tokens": 442 } }

// Gemini
{ "usageMetadata": { "promptTokenCount": 4947,
                     "cachedContentTokenCount": 4837,
                     "candidatesTokenCount": 142,
                     "thoughtsTokenCount": 300 } }

انظر إلى prompt_tokens: 4947 وinput_tokens: 110. كلا الحقلين هو عدد input tokens للـ prompt نفسه. حقل OpenAI يتضمن tokens المخزنة في cache؛ أما حقل Anthropic فيستثنيها — وتذكر وثائقه الهوية صراحة، total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens.5 يعني input_tokens لدى Anthropic «tokens بعد آخر cache breakpoint لديك».

وانظر إلى output. يبلغ OpenAI وAnthropic كلاهما عن 442، وهذا يتضمن بالفعل 300 reasoning tokens. يبلغ Gemini عن 142 ويضع الـ 300 في حقل مستقل. أشار الفصل 12 إلى هذا كتعارض بين طريقتين لعد العمل نفسه؛ وها هي تكلفته.

طبقة التطبيع ثلاثون سطرًا وليست اختيارية:

normalise.tsTS
export interface Usage {
  promptTokens?: number;        // input, NOT cached
  cachedInputTokens?: number;   // read from cache
  cacheWriteTokens?: number;    // written to cache on this call
  completionTokens?: number;    // output
  reasoningTokens?: number;     // billed apart from output (Gemini only)
}

const num = (v: unknown) => (typeof v === "number" && isFinite(v) ? v : 0);

export const fromOpenAI = (raw: any): Usage => {
  const u = raw.usage ?? {}, d = u.prompt_tokens_details ?? {};
  const cached = num(d.cached_tokens), write = num(d.cache_write_tokens);
  return {
    promptTokens: Math.max(0, num(u.prompt_tokens) - cached - write), 
    cachedInputTokens: cached,
    cacheWriteTokens: write,
    completionTokens: num(u.completion_tokens),   // reasoning already inside
    reasoningTokens: 0,
  };
};

export const fromAnthropic = (raw: any): Usage => {
  const u = raw.usage ?? {};
  return {
    promptTokens: num(u.input_tokens),            // already excludes cache
    cachedInputTokens: num(u.cache_read_input_tokens),
    cacheWriteTokens: num(u.cache_creation_input_tokens),
    completionTokens: num(u.output_tokens),
    reasoningTokens: 0,
  };
};

export const fromGemini = (raw: any): Usage => {
  const m = raw.usageMetadata ?? {}, cached = num(m.cachedContentTokenCount);
  return {
    promptTokens: Math.max(0, num(m.promptTokenCount) - cached),
    cachedInputTokens: cached,
    cacheWriteTokens: 0,
    completionTokens: num(m.candidatesTokenCount), // EXCLUDES thinking
    reasoningTokens: num(m.thoughtsTokenCount),    // billed at output rate
  };
};

مرّر payloads الثلاثة أعلاه عبر القراء الثلاثة، وستنتج الثلاثة Usage نفسه، وبالتالي الرقم نفسه: $0.006491. هذا التوافق هو الهدف كله من كتابة الطبقة.

وإذا أخطأت، فهذه هي التكلفة على الاستدعاء نفسه:

الخطأالمحتسبالخطأ
التعامل مع cached_tokens كأنه إضافي إلى prompt_tokens$0.0161652.49× — تحتسب prompt مرتين
التعامل مع cache reads كأنها مجانية بدل 0.1×$0.0055240.85× — تتحمل أنت 15%
قراءة candidatesTokenCount وتجاهل thoughtsTokenCount$0.00289155% من الاستدعاء يختفي

الثالث هو الأخطر، لأنه يفشل بصمت في اتجاه الأخبار الجيدة. تعرض لوحة التحكم لديك model للاستدلال يكلف أقل من نصف تكلفته الفعلية، ولا يرفع أي شيء في أي مكان خطأ.

بعد تطبيع السلال، تكون دالة التكلفة قصيرة. الجزء الوحيد غير البديهي هو البحث عن الشريحة، وهو ما يشرحه القسم التالي:

cost.tsTS
export interface Tier { maxPromptTokens: number | null; price: number }
export interface Pricing {
  input: Tier[]; output: Tier[];
  cachedInput?: Tier[]; cacheWrite?: Tier[]; reasoning?: Tier[];
}

const tierPrice = (tiers: Tier[] | undefined, contextSize: number, fallback?: Tier[]) => {
  const table = tiers ?? fallback;
  if (!table?.length) return 0;
  const sorted = [...table].sort(
    (a, b) => (a.maxPromptTokens ?? Infinity) - (b.maxPromptTokens ?? Infinity));
  for (const t of sorted)
    if (t.maxPromptTokens === null || contextSize <= t.maxPromptTokens) return t.price;
  return sorted[sorted.length - 1].price;
};

export function computeCost(pricing: Pricing, usage: Usage): number {
  const fresh = usage.promptTokens ?? 0;
  const read  = usage.cachedInputTokens ?? 0;
  const write = usage.cacheWriteTokens ?? 0;
  const out   = usage.completionTokens ?? 0;
  const think = usage.reasoningTokens ?? 0;
  const contextSize = fresh + read + write;   // the tier depends on the WHOLE prompt
  return fresh * tierPrice(pricing.input, contextSize)
       + read  * tierPrice(pricing.cachedInput, contextSize, pricing.input)
       + write * tierPrice(pricing.cacheWrite,  contextSize, pricing.input)
       + out   * tierPrice(pricing.output, contextSize)
       + think * tierPrice(pricing.reasoning, contextSize, pricing.output);
}

هناك قراران تصميميان يستحقان الدفاع عنهما. القيم الاحتياطية — أسعار cache تعود إلى input، وreasoning إلى output — ترمز إلى معنى غياب الجدول: reasoning tokens على Gemini تُحاسَب بسعر output، لذلك غياب سعر reasoning لا يعني صفرًا، بل يعني سعر output. وcontextSize يجمع سلال input الثلاث كلها بدل الجديدة فقط، لأن الشريحة تُختار بحسب طول prompt، لا بحسب مقدار ما حوسبت عليه بالسعر الكامل.

Prompt caching، وما تكلفه الكتابة إليه

رابط إلى القسم: Prompt caching، وما تكلفه الكتابة إليه

تخزن prompt cache الحالة المحسوبة لدى model لبادئة prefix من prompt، بحيث يتخطى طلب لاحق له البادئة نفسها إعادة حسابها. من كلمة «prefix» تتبع أربع خصائص، وكل الأربع تفاجئ الناس.

تطابق cache من بداية prompt المولّد إلى الأمام، وتتوقف عند أول byte يختلف. لا يوجد رصيد جزئي لمحتوى يظهر لاحقًا بترتيب مختلف. تقول OpenAI ذلك بوضوح: «إعادة استخدام cache تتطلب تطابق كامل البادئة المولّدة.»6

دونه، لا يُخزّن شيء في cache ولا يُعاد أي خطأ. لدى OpenAI الحد الأدنى هو 1,024 tokens لـ GPT-5.6 وما بعده، و2,048 للنماذج الأقدم. ولدى Anthropic يتراوح من 512 إلى 4,096 بحسب model — 1,024 لـ Claude Sonnet 4.5، و4,096 لـ Claude Haiku 4.5. إذا عاد حقلا cache كلاهما صفرًا، فغالبًا هذا هو السبب.

الكتابة تكلف أكثر من القراءة، وأكثر من عدم استخدام caching

رابط إلى القسم: الكتابة تكلف أكثر من القراءة، وأكثر من عدم استخدام caching

على OpenAI وAnthropic، تبلغ cache write 1.25× من سعر uncached input للـ cache قصيرة العمر، وتبلغ cache ذات الساعة الواحدة لدى Anthropic 2×. أما القراءة فهي 0.1×. لا تفرض Google تكلفة على الكتابة، لكنها تؤجر التخزين: $4.50 لكل مليون tokens في الساعة على Gemini 2.5 Pro.

تنتهي صلاحيتها، وتعيش على آلة واحدة

رابط إلى القسم: تنتهي صلاحيتها، وتعيش على آلة واحدة

تعيش entry الافتراضية لدى Anthropic خمس دقائق، وتُجدّد مجانًا عند كل hit. أما لدى OpenAI فهي ثلاثون دقيقة على الأقل بعد أحدث كتابة أو إعادة استخدام. وتشير OpenAI إلى أن الحالات المخزنة تعيش على آلات منفردة، لذلك لا يصيب الطلب إلا إذا وُجّه إلى الآلة التي تحتفظ بالـ entry — وهذا ما يؤثر فيه prompt_cache_key، من دون ضمان.

نقطة التعادل صغيرة بما يكفي لتبقيها في رأسك، ووثائق OpenAI تجري الحساب: كتابة prefix مرة وإعادة استخدامها مرة تكلف 1.35× من تكلفة input العادية لها، مقابل 2× لمعالجتها مرتين بلا cache؛ وعبر عشرة طلبات، تكلف كتابة واحدة وتسع قراءات 2.15× مقابل 10×. إعادة استخدام واحدة تدفع ثمن الكتابة. تصل Anthropic إلى النتيجة نفسها: قراءة واحدة للـ cache ذات الخمس دقائق، وقراءتان للـ cache ذات الساعة الواحدة.

والآن محادثة الأربعين دورًا مرة أخرى، مع تفعيل caching وثبات prefix:

uncached inputcache readscache writesالإجمالي
بلا cache112,617$0.274386
caching2,887104,7834,947$0.088250

أرخص بنسبة ثمانية وستين في المئة، وهناك ثلاثة أرقام في ذلك الجدول تستحق الانتباه.

لا تبدأ cache بالعمل حتى الدور 6. لا يصل prompt إلى 1,024 tokens حتى ذلك الحين، لذلك تُحاسَب الأدوار الخمسة الأولى كما كانت تمامًا — ويُحاسَب الدور السادس أسوأ، بعلاوة كتابة 1.25\u00d7، لأنه الدور الذي يملأ cache. أول قراءة تصل في الدور 7. الـ 2,887 uncached tokens في الجدول هي الحساب: ما يعادل خمسة أدوار، لا ستة. caching خصم على prompts الطويلة، والمحادثة القصيرة لا تستفيد منه شيئًا.

علاوة الكتابة هي $0.002474، أي 2.8% من الفاتورة مع cache. كل دور يكتب ذيله الجديد، أربعين مرة، وعلاوة الكتابة كلها خطأ تقريب مقابل ما وفّرته القراءات. يجدر فهم رسم الكتابة بدقة كي تتوقف عن القلق بشأنه.

لم تُحاسَب سوى 2,887 tokens بسعر input الكامل من أصل 112,617. هذا هو شكل cache تعمل: كل شيء تقريبًا قراءة.

هذا هو الفشل الذي يكلف مالًا حقيقيًا، وهو bug من سطر واحد.

ضع شيئًا يتغير في كل استدعاء قرب مقدمة prompt — timestamp، أو request id، أو اسم المستخدم، أو سطر «اليوم هو»، أو مستندًا مسترجعًا حديثًا — وستختلف prefix من أول byte. لا شيء يطابق. كل استدعاء miss. ولأن كل استدعاء يقدم prefix جديدة، فإن كل استدعاء أيضًا يكتب.

المحادثة نفسها، الأربعون دورًا نفسها، caching مفعل، مع timestamp لكل استدعاء في أعلى system prompt:

الإجماليمقارنةً بـ
بلا caching إطلاقًا$0.274386
caching، prefix ثابتة$0.088250−67.8%
caching، prefix متقلبة$0.329251+20.0%

تفعيل prompt caching جعل المحادثة أغلى بنسبة عشرين في المئة من عدم تفعيله. دفعت علاوة كتابة 1.25× على 109,730 tokens وقرأت صفرًا. لا خطأ، ولا تحذير، والميزة مفعلة.

إذًا القاعدة، وهي كل prompt caching في سطر واحد: المحتوى الثابت في الأمام، والمحتوى المتغير في الخلف. تعليمات النظام، وتعريفات الأدوات، والمواد المرجعية أولًا؛ timestamps، وهوية المستخدم، والسؤال الحالي آخرًا. تجعل Anthropic الهرمية صريحة — تتبع cache ‏toolssystemmessages، وأي تغيير على أي مستوى يبطل ذلك المستوى وكل ما بعده، لذلك تعديل وصف أداة واحد يبطل cache كلها.5

هناك نتيجتان يتعثر فيهما الناس. تغيير الأدوات المفعلة يغيّر تعريفات الأدوات، لذلك feature flag يضيف أداة لبعض المستخدمين يقسم cache لديك إلى اثنتين. وعلى Anthropic، تبديل web search أو citations يعدل system prompt، ما يبطل system وmessage caches من دون أن تلمس سطرًا واحدًا من نصك.

الاستجابة البديهية لفاتورة تربيعية هي التوقف عن إرسال السجل كله: احتفظ بآخر اثنتي عشرة رسالة وأسقط الباقي. هذا يخفض الفاتورة، وغالبًا ما يكون القرار الخاطئ، والقياس يشرح السبب.

الاستراتيجيةالإجماليمقارنةً بالسجل الكامل + cache
سجل كامل، بلا cache$0.274386+211%
سجل كامل، مع caching$0.088250
آخر 12 رسالة، بلا cache$0.118712+35%
آخر 12 رسالة، مع caching$0.122546+39%

الاقتطاع إلى نافذة من اثنتي عشرة رسالة أرخص بنسبة 57% من إرسال كل شيء بلا cache — وهي المقارنة التي يجريها الجميع، وسبب شعبية التقنية. لكنه أغلى بنسبة 39% من إرسال كل شيء مع cache تعمل، وتشغيل caching إلى جانب الاقتطاع يجعله أسوأ قليلًا لا أفضل.

الآلية هي prefix مرة أخرى. sliding window تسقط أقدم رسالة في كل دور، لذلك لا يعود prompt يبدأ من حيث بدأ في المرة السابقة، وكل دور يقدم prefix جديدة. تقول إرشادات OpenAI ذلك نصًا: «summarisation أو compaction أو context truncation يمكن أن يغيّر prefix ويعيد ضبط cache reuse.»6 بحلول الدور 40 تصبح windowed prompt بطول 813 tokens، دون الحد الأدنى 1,024-token، لذلك لا يمكن تخزينها في cache إطلاقًا.

والمال هو النصف الرخيص من التكلفة. ما أسقطته هو التعليمة التي أعطاها المستخدم في الدور 2 وكان model يحتاجها في الدور 40. الاقتطاع يبادل فاتورة تراها بفشل لا تراه، وتنفيذه كما ينبغي — compaction، وملاحظات مهيكلة محفوظة خارج النافذة، واسترجاع السجل عند الطلب — هو موضوع الفصل 24.

السياقات الطويلة ليست أغلى لمجرد أنها أطول. بعد عتبة معينة تصبح أغلى لكل token، وتنطبق العتبة بأثر رجعي على prompt كله.

تقول صفحة model لدى OpenAI لـ gpt-5.6-terra ذلك في جملة واحدة: «Prompts with >272K input tokens are priced at 2x input and 1.5x output for the full request.»7 ليس على الزائد. على الشيء كله.

the most expensive token you will ever sendTEXT
prompt 271,999 + 500 output  ->  $0.5500
prompt 272,000 + 500 output  ->  $0.5500
prompt 272,001 + 500 output  ->  $1.0970

token واحدة، وخمسة وخمسون سنتًا. إذا كانت خدمتك تبني prompts من مستندات مسترجعة لا تتحكم في حجمها، فلديك هاوية في نموذج التكلفة عند حد لم يدوّنه أحد في فريقك.

يعمل تسعير Google بالطريقة نفسها مع عتبة 200,000-token: Gemini 2.5 Pro بسعر $1.25 لكل مليون input tokens للـ prompts حتى 200K و$2.50 فوقها، مع انتقال output من $10.00 إلى $15.00.8 سلكت Anthropic الاتجاه المعاكس — في 6 سبتمبر 2026 تنص وثائقها على أن Claude 4.6 وما بعده يتضمن context window كاملة بطول مليون token بالسعر القياسي، لذلك «طلب 900k-token يُحاسَب بالسعر نفسه لكل token مثل طلب 9k-token.»9 النماذج الأقدم احتفظت بالزيادة.

لهذا فإن السعر ليس رقمًا. السعر جدول شرائح مفتاحه طول prompt، وهذا هو سبب وجود Tier[] في دالة التكلفة، وسبب أن computeCost يختار الشريحة باستخدام prompt كله لا كل سلة على حدة.

Prefill وdecode، ولماذا يكلف output ستة أضعاف input

رابط إلى القسم: Prefill وdecode، ولماذا يكلف output ستة أضعاف input

تتطابق السلال الخمس مع مرحلتي الفصل 13، وما إن ترى المطابقة حتى تتوقف نسب الأسعار عن الظهور كأنها عشوائية.

Input tokens هي prefill. يمر prompt كله عبر model في مرة واحدة، ويُعالَج بالتوازي — ضرب مصفوفات كبير، محدود بالحوسبة. تكلفة كل token منخفضة، وهذه هي المرحلة التي تحدد time to first token: prompt بطول 4,947 tokens يحتاج إلى 4,947 tokens من prefill قبل أن تظهر الكلمة الأولى.

Output tokens هي decode. تُنتج واحدة تلو الأخرى، كل منها forward pass كامل يقرأ KV cache كلها، بينما ينتظر GPU الذاكرة في الغالب بدل الحساب. هذه هي المرحلة التي تحدد tokens per second، ولا يمكن موازاتها داخل استجابة واحدة، وهي سبب أن output يكلف نحو ستة أضعاف input في model المسعّر هنا: $12.00 مقابل $2.00 لكل مليون tokens.

تتبع ثلاث نتائج مباشرة. cache read تستبدل عمل prefill، لذلك تشتري زمنًا ومالًا في الوقت نفسه — يظهر الخصم نفسه كفاتورة أقل وانتظار أقصر لأول token. Reasoning tokens هي decode لا تراها، ولذلك لا يبث reasoning model شيئًا لعدة ثوان ثم يجيب بسرعة: حذّر الفصل 12 من نتيجة الواجهة، وهذه هي نتيجة الفاتورة. وإيقاف stream لا يوقف التوليد — بنى الفصل 14 الإلغاء وترك السعر لهذا الفصل، والسعر هو عدد output كاملًا، لأن tokens تُنتج وتُحاسَب سواء كان هناك من يستمع أم لا. وينطبق الأمر نفسه على الإجابة التي لا يحتفظ بها أحد: إعادة توليد إجابة الدور 40 خمس مرات تكلف $0.057990 للإجابة الواحدة المتروكة على الشاشة.

كان tokenizer في الفصل 7 مكتوبًا بـ Python وبقي هناك. أما إعداد الميزانية فيحدث في الخادم الذي يبني الطلب، لذلك يجب أن يحدث هنا، ولا توجد إلا ثلاثة مستويات للدقة.

المستوى الأول: العد محليًا. يشحن js-tiktoken جداول دمج BPE نفسها مثل tiktoken في Python، لذلك تحصل على عدد مطابق byte-for-byte لترميزات OpenAI، بلا استدعاء شبكة:

count.tsTS
import { getEncoding } from "js-tiktoken";

const enc = getEncoding("o200k_base");
const PER_MESSAGE = 4;   // role and delimiters added by the chat template
const PER_REPLY = 3;     // priming for the assistant turn

export function promptTokens(messages: { role: string; content: string }[]) {
  return messages.reduce(
    (sum, m) => sum + enc.encode(m.content).length + PER_MESSAGE, PER_REPLY);
}

الثابتان مهمان، وهما موضع انحراف العد المحلي. نصك ليس ما يجري tokenized — chat template في الفصل 11 يلف كل رسالة بعلامات دور أولًا، وهذه tokens تدفع ثمنها. أربع لكل رسالة وثلاث لتهيئة الرد هو التقريب التقليدي لنماذج OpenAI chat؛ وعبر الرسائل الإحدى والثمانين في المحادثة أعلاه تضيف 324 tokens، أي 6.4% من طولها. تمت مطابقة الأعداد هنا مع tiktoken في Python من الفصل 7 على السلاسل الإحدى والثمانين كلها، وهي متطابقة.

المستوى الثاني: اسأل المزوّد. تعرض Anthropic ‏/v1/messages/count_tokens وتعرض Google ‏count_tokens، وكلاهما يقبل شكل الطلب نفسه لاستدعاء حقيقي ويعيد عدد input tokens مجانًا. استخدمهما عندما لا يمكنك العد محليًا — ولا يمكنك العد محليًا لـ Anthropic، التي لا تنشر tokenizer الخاص بها. وثائق Anthropic دقيقة فيما تعطيك: العدد «تقدير»، وقد «يتضمن tokens تضيفها Anthropic تلقائيًا لتحسينات النظام»، وهي «لا تُحاسَب عليك».10

المستوى الثالث: اقرأ usage في الاستجابة. تلك هي الحقيقة، وتصل بعد إنفاق المال. ولهذا بالضبط يوجد المستويان الأولان — لاتخاذ قرار إرسال الطلب، لا لإصدار الفاتورة عليه.

الأشياء التي تدفع ثمنها ولا يعرضها أحد

رابط إلى القسم: الأشياء التي تدفع ثمنها ولا يعرضها أحد

أربعة بنود لا تظهر كبنود.

system prompt، مدفوع في كل استدعاء. المذكور أعلاه يبلغ 192 tokens مع overhead القالب. عبر أربعين استدعاءً يصبح ذلك 7,680 tokens — 5.6% من فاتورة هذه المحادثة كلها، لثمانية أسطر كُتبت مرة واحدة. وهو أيضًا أفضل مرشح ممكن للـ cache، لأنه ثابت وأولًا.

تعريفات الأدوات. اسم كل أداة ووصفها وJSON schema الخاصة بها تخرج في كل طلب، ويضيف المزوّدون scaffolding فوق ذلك. تنشر Anthropic الرقم: تفعيل الأدوات أصلًا يضيف system prompt مخفيًا من 496 tokens على Claude Sonnet 4.5 مع ضبط tool_choice على auto، أو 588 مع any أو أداة مسماة.9 هذا قبل schemas الخاصة بك. يبني الفصل 18 الكتالوج؛ ويقيس الفصل 24 ما يلتهمه.

كل توليد، بما في ذلك ما تتخلص منه. خمس عمليات إعادة توليد تكلف خمسة أضعاف. تعرض chat واحدة.

الأفكار التي لا تُعرض عليك. تستند الفوترة إلى full thought tokens رغم أن الملخص وحده يُعاد، ولا يستطيع أي نظام محاسبة لديك تدقيق ذلك الرقم.

تحذير أخير، لأنه الخاطر الطبيعي التالي، والإجابة ليست الواضحة.

نافذة بمليون token لا تعني مليون tokens قابلة للاستخدام. تتدهور دقة الاسترجاع مع الموضع: وجد Liu وآخرون أن النماذج تحدد المعلومات بثقة في بداية input طويل ونهايته، وبثقة أقل بكثير في الوسط.11 النافذة الأكبر تشتري القدرة على إرسال المزيد، لا يقين القراءة.

قيس هذا phenomenon مرة واحدة في هذه الدورة — معدل الاسترجاع في تسعة مواضع داخل prompt نفسه بطول 853-token — ومكانه الفصل 24، حيث يغيّر ما يفعله agent. يُستشهد به هنا لأنه يغيّر ما ينبغي أن تشتريه: أرخص token هي التي لم ترسلها.

يمكنك الآن توقع تكلفة استدعاء قبل إجرائه، وقراءة ما كلفه بعد ذلك، والتمييز بين الاثنين. هذا يغطي كل شيء في الطلب باستثناء الجزء الذي لم تلمسه: knobs.

الفصل 17 هو sampling — temperature، وtop-p، وtop-k، والعقوبات، والحتمية التي لا تملكها. يبدأ بتفكيك أكثر الأخطاء انتشارًا في المجال، وهو أن temperature مقبض للإبداع. ليس كذلك: temperature تقسم logits من الفصل 4 قبل softmax، ورفعها لا يجعل model أكثر خيالًا، بل يرفع احتمال tokens التي قيّمها model نفسه كأسوأ. ومن هناك، لماذا ينتج greedy decoding نصًا أسوأ قابلًا للقياس من sampling، ولماذا يفشل top-k وtop-p على شكلين متعاكسين من التوزيع، والتجربة التي تنهي الفصل: عشرون forward passes متطابقة عند temperature 0 تعود متطابقة bit-for-bit عندما يعمل model وحده، ووضع prompt نفسه في batch إلى جانب طلبات شخص آخر يحرّك 97% من logits الخاصة به.

إنها لا تتطابق كلها. يبدأ السبب من صندوق floating-point في الفصل 2.


قُرئت كل الأسعار والعتبات والمضاعفات في هذا الفصل من صفحات المزوّدين أنفسهم في 6 سبتمبر 2026، وذُكرت بذلك التاريخ لأنها ستتغير. المنهج أهم من الأرقام: السلال، وقاعدة prefix، وحساب الشرائح كانت مستقرة لعامين بينما تحرك كل رقم داخلها.

محاضرة Stanford CS336 رقم 2، Resource accounting، هي أقرب معالجة أكاديمية لهذه المادة والقراءة التالية المناسبة: تجري الحساب نفسه على جانب التدريب الذي يجريه هذا الفصل على جانب inference. أُنتجت أعداد tokens هنا باستخدام js-tiktoken 1.0.21 مع ترميزي o200k_base وcl100k_base، على محادثة من أربعين دورًا بطول 5,090 tokens؛ overhead قالب كل رسالة هو تقريب الأربع زائد الثلاث التقليدي، ويُذكر أينما أُدرج. أرقام cache والشرائح والاقتطاع هي قواعد التسعير الموثقة مطبقة على أعداد tokens المقاسة تلك، وليست ملاحظات لاستجابات API حية — لم يُجر أي استدعاء مدفوع لإنتاج هذا الفصل، وهذا أيضًا هو السبب الصادق في أن ادعاءات latency نوعية وادعاءات التكلفة ليست كذلك.

  1. Dao, T., Fu, D. Y., Ermon, S., Rudra, A. and Ré, C. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. arXiv:2205.14135 (2022). لماذا تحرك السقف من دون تغيّر التكلفة التقاربية.

  2. Chen, S., Wong, S., Chen, L. and Tian, Y. Extending Context Window of Large Language Models via Positional Interpolation. arXiv:2306.15595 (2023).

  3. Peng, B., Quesnelle, J., Fan, H. and Shippole, E. YaRN: Efficient Context Window Extension of Large Language Models. arXiv:2309.00071 (2023).

  4. Google، Thinking، ai.google.dev/gemini-api/docs/thinking، وToken counting، ai.google.dev/gemini-api/docs/tokens، تمت زيارة كليهما 2026-09-06. «Pricing is based on the full thought tokens the model needs to generate, despite only the summary being output from the API.» يبلّغ usage object عن total_input_tokens، total_output_tokens، total_thought_tokens، total_cached_tokens، total_tool_use_tokens وtotal_tokens — ست سلال، مع الأفكار واستخدام الأدوات خارج عدد output. اسم الحقل السابق للكمية نفسها، والذي لا يزال generateContent surface يعيده، هو thoughtsTokenCount، موثق في صفحة ثالثة، ai.google.dev/gemini-api/docs/generate-content/thinking.

  5. Anthropic، Prompt caching، docs.anthropic.com/en/docs/build-with-claude/prompt-caching، تمت الزيارة 2026-09-06. مصدر هرمية الإبطال toolssystemmessages وجدولها؛ الحدود الدنيا القابلة للتخزين في cache لكل model؛ الهوية total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens؛ وعمر الخمس دقائق الافتراضي الذي يُجدّد بلا رسوم عند كل hit. 2

  6. OpenAI، Prompt caching، platform.openai.com/docs/guides/prompt-caching، تمت الزيارة 2026-09-06. مصدر: قاعدة entire-rendered-prefix؛ الحد الأدنى للـ prefix القابلة للتخزين في cache (1,024 input tokens مرئية على GPT-5.6 وما بعده، و2,048 قبل ذلك)؛ مضاعفات 1.25× للكتابة و0.1× للقراءة، وغياب أي رسم كتابة على GPT-5.5 وما قبله؛ عمر 30 دقيقة؛ حدود أربع كتابات لكل طلب وخمسين breakpoint؛ ملاحظة machine-affinity وprompt_cache_key؛ أمثلة التعادل المحسوبة 1.35× و2.15× و10×؛ والتصريح بأن summarisation أو compaction أو truncation يعيد ضبط cache reuse. 2

  7. OpenAI، Pricing (platform.openai.com/docs/pricing) وصفحة model لـ gpt-5.6-terra، تمت زيارة كليهما 2026-09-06. ‏gpt-5.6-terra، شريحة الخدمة القياسية، لكل مليون tokens: input $2.00، cached input $0.20، cache writes $2.50، output $12.00؛ long context input $4.00، cached $0.40، writes $5.00، output $18.00؛ «prompts with >272K input tokens are priced at 2x input and 1.5x output for the full request»؛ context window ‏1,050,000 tokens مع حد أقصى 922,000 input tokens. يسرد الجدول نفسه gpt-6-astra بسعر $10.00/$1.00/$12.50/$50.00 وgpt-5.6-luna بسعر $0.20/$0.02/$0.25/$1.20. تستخدم كل تكلفة محسوبة في هذا الفصل أسعار gpt-5.6-terra القياسية للسياق القصير.

  8. Google، Gemini Developer API pricing، ai.google.dev/gemini-api/docs/pricing، تمت الزيارة 2026-09-06. Gemini 2.5 Pro، لكل مليون tokens: input $1.25 للـ prompts حتى 200K و$2.50 فوقها؛ output $10.00 و$15.00، وفي كلتا الحالتين موسوم «including thinking tokens»؛ context caching ‏$0.125 و$0.25، إضافة إلى رسم تخزين $4.50 لكل مليون tokens في الساعة. يستخدم Gemini 3.1 Pro Preview عتبة 200K نفسها عند $2.00/$4.00 input و$12.00/$18.00 output.

  9. Anthropic، Pricing، docs.anthropic.com/en/docs/about-claude/pricing، تمت الزيارة 2026-09-06. لكل مليون tokens، base input / 5-minute cache write / 1-hour cache write / cache read / output: Claude Sonnet 4.5 ‏$3 / $3.75 / $6 / $0.30 / $15؛ Claude Haiku 4.5 ‏$1 / $1.25 / $2 / $0.10 / $5؛ Claude Opus 5 ‏$5 / $6.25 / $10 / $0.50 / $25. المضاعفات: 1.25× لكتابة الخمس دقائق، و2× لكتابة الساعة الواحدة، و0.1× للقراءة. وهي أيضًا مصدر تصريح long-context («Claude 4.6 and later models... include the full 1M token context window at standard pricing»)، وعدد tool-use system prompt tokens (496 tokens على Claude Sonnet 4.5 مع tool_choice بقيمة auto أو none، و588 مع any أو أداة مسماة)، وملاحظة أن Claude 4.7 وما بعده يستخدم tokenizer أحدث ينتج «approximately 30 % more tokens for the same text». 2 3

  10. Anthropic، Token counting، docs.anthropic.com/en/docs/build-with-claude/token-counting، تمت الزيارة 2026-09-06. endpoint ‏/v1/messages/count_tokens يأخذ المدخلات نفسها كرسالة ويعيد عدد input tokens؛ تنص الوثائق على أن العدد تقدير، وأنه قد يتضمن tokens تضيفها Anthropic لتحسينات النظام، وأن تلك لا تُحاسَب.

  11. Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. and Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (2023). ذُكر هنا، وقيس في الفصل 24.

هل أنت مستعد لتترك الاختيار لـ LIA؟

ابنِ بكل نماذج الذكاء الاصطناعي في مكان واحد — ابدأ مجانًا اليوم.