تخطّى إلى المحتوى الرئيسي
لماذا تكلّف ميزات النماذج اللغوية أكثر مما ينبغي: ملاحظاتنا الميدانية حول التخزين المؤقت للموجّهات ونقاط القطع والطابع الزمني الذي يُفسد كل إصابة

لماذا تكلّف ميزات النماذج اللغوية أكثر مما ينبغي: ملاحظاتنا الميدانية حول التخزين المؤقت للموجّهات ونقاط القطع والطابع الزمني الذي يُفسد كل إصابة

September 8, 2026
هندسة الذكاء الاصطناعي
7 دقيقة قراءة

أبرز النقاط

• التخزين المؤقت للموجّهات هو تخزين لدى المزوّد للبادئة المعالَجة من الطلب، بحيث يتخطى أي طلب لاحق يحمل البادئة نفسها إعادة معالجتها. في واجهة Anthropic Messages يكون التفعيل اختياريًا لكل كتلة محتوى: إضافة cache_control من النوع ephemeral إلى كتلة تجعل كل ما يسبقها وما فيها بادئةً مخزَّنة، ولا يتجاوز الطلب الواحد أربع نقاط قطع.

• تُحتسب القراءة من الذاكرة المؤقتة بنسبة 0.1 من سعر وحدة الإدخال الأساسية، وتُحتسب الكتابة لمدة خمس دقائق بنسبة 1.25، والكتابة لمدة ساعة بنسبة 2. الفارق البالغ 0.25 في كتابة الخمس دقائق تسترده الإصابة الأولى داخل النافذة، لأن كل إصابة توفّر 0.9.

• مفتاح الذاكرة المؤقتة هو البادئة المسلسلة تمامًا بالترتيب الثابت: الأدوات ثم موجّه النظام ثم الرسائل. أي طابع زمني داخل موجّه النظام، أو مصفوفة أدوات مبنية بالمرور على Map، أو تغيير معرّف النموذج، يُبطل الذاكرة المؤقتة من نقطة التغيير فصاعدًا.

• كل استجابة من واجهة Messages تُبلغ عن input_tokens وcache_creation_input_tokens وcache_read_input_tokens. معدل الإصابة يساوي القراءة مقسومة على مجموع القراءة والكتابة والإدخال الجديد، وهو الطريقة الوحيدة الصادقة لمعرفة ما إذا كان التخزين المؤقت يعمل.

• التخزين المؤقت للموجّهات لا يخفض تكلفة وحدات الإخراج ولا يصلح موجّهًا متضخمًا. حذف أربعة آلاف وحدة من سياق لا يقرأه أحد أفضل من تخزينها مؤقتًا بنسبة 0.1 إلى الأبد.

كانت الميزة وكيل دعم يحمل مخطط أدوات كبيرًا ومرجع واجهة برمجية طويلًا مثبتًا داخل موجّه النظام، وهي بالضبط الحالة التي بُني لها التخزين المؤقت. أضفنا نقطة قطع ونشرنا، ولم تتحرك تكلفة المحادثة. كان حقل الاستخدام صريحًا: cache_creation_input_tokens ممتلئ في كل طلب وcache_read_input_tokens صفر في كل طلب. كنا ندفع 1.25 لكتابة مدخل لا يقرأه شيء.

ما هو التخزين المؤقت للموجّهات وعلامَ ندفع فعليًا؟

يتيح التخزين المؤقت للموجّهات للمزوّد إعادة استخدام العمل الذي أنجزه على بادئة الموجّه، فتُحتسب الوحدات الأولى المتطابقة بخصم كبير بدل إعادة معالجتها. وهو يقسّم فاتورة الإدخال إلى ثلاثة بنود بدل بند واحد: إدخال جديد غير مخزَّن، وكتابات للذاكرة المؤقتة، وقراءات منها. قراءة هذه الأرقام الثلاثة هي جوهر الانضباط كله.

هناك قيدان يحددان ما إذا كانت نقطة القطع تفعل شيئًا أصلًا. الأول هو الحد الأدنى للبادئة القابلة للتخزين، وهو 1024 وحدة في نماذج Claude الأكبر و2048 في أصغرها؛ وتحت هذا الحد يُتجاهل مؤشر cache_control دون أي خطأ، وهو ما يبدو تمامًا كأن التخزين معطّل. الثاني هو مدة البقاء: المدخل الافتراضي يعيش خمس دقائق وكل قراءة تجدد النافذة، فتُبقي حركة الطلبات المستمرة البادئة دافئة إلى ما لا نهاية دون دفع ثمن كتابة جديدة. وتمديد المدة إلى ساعة يوسّع النافذة بسعر كتابة أعلى.

أين يجب أن تقع نقطة القطع؟

ضع نقطة القطع على الحد الفاصل بين ما لا يتغير أبدًا في كل طلب وما يتغير دائمًا. يسلسل المزوّد الأدوات أولًا ثم موجّه النظام ثم الرسائل، لذا يجب أن يقع كل ما نريد تخزينه قبل أي محتوى متقلب. ومخطط الأدوات الكبير عادةً هو أضخم كتلة ثابتة في طلب الوكيل، وهو أول ما يستحق أن يوضع خلف نقطة القطع.

عمليًا نضع cache_control من النوع ephemeral على آخر كتلة ثابتة في موجّه النظام، ونُبقي تعريفات الأدوات فوقها، ونترك دور المستخدم تحتها. عندها يُبلغ الطلب البارد عن cache_creation_input_tokens غير صفري، ويُبلغ كل طلب دافئ عن cache_read_input_tokens غير صفري.

في المحادثات متعددة الأدوار نستخدم نقطتي قطع بدل واحدة. الأولى في نهاية منطقة الأدوات وموجّه النظام التي لا تتغير طوال عمر النشر. والثانية في نهاية آخر دور مكتمل، فيُخزَّن النص المتنامي تدريجيًا ولا يدفع الدور الجديد السعر الكامل إلا للوحدات التي أضافها المستخدم للتو.

لماذا يهبط معدل الإصابة إلى الصفر؟

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

القيم المتقلبة المُدرجة هي السبب الأشيع: طابع زمني أو معرّف طلب أو اسم مستخدم أو معرّف جلسة داخل موجّه النظام يغيّر البادئة في كل استدعاء. والترتيب غير الحتمي هو السبب الثاني: مصفوفة أدوات مبنية بالمرور على كائن أو Set، أو جسم طلب مسلسل بترتيب مفاتيح غير ثابت، ينتج بادئة مختلفة من البيانات نفسها.

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

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

متى تستحق مدة الساعة ضعف سعر الكتابة؟

نقطة التعادل حساب بسيط على المضاعفات المنشورة، وليست قياس أداء. كتابة الخمس دقائق تكلف 0.25 زيادة عن الطلب غير المخزَّن، وكل إصابة توفّر 0.9، فالإصابة الأولى داخل النافذة تسدد ثمن الكتابة. أما كتابة الساعة فتكلف 1 زيادة، وتحتاج إلى نحو إصابتين لتتفوق.

• بلا تخزين مؤقت: التكلفة 1 من سعر الإدخال، ويناسب البادئات دون الحد الأدنى للنموذج أو الاستدعاءات الفردية فعلًا.

• ذاكرة الخمس دقائق: كتابة بنسبة 1.25 وقراءة بنسبة 0.1، تتعادل بعد إصابة واحدة، وتناسب أدوار المحادثة وحلقات الوكيل حيث يُبقي مستخدم حيّ الطلبات متدفقة.

• ذاكرة الساعة: كتابة بنسبة 2 وقراءة بنسبة 0.1، تتعادل بعد إصابتين، وتناسب مستندًا طويلًا يُعاد استخدامه عبر جلسة عمل أو دفعة موزّعة على ساعة.

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

كيف نقيس الإصابات بدل التخمين؟

نسجّل عدادات الإدخال الثلاثة في كل استجابة ونحسب معدل الإصابة، لأن التخزين المؤقت يفشل بصمت ويبدو مطابقًا تمامًا لحالة عدم تفعيله أصلًا. تُرسَل النسبة كمقياس، ويُعامَل هبوطها مباشرة بعد النشر كأمر متوقع لا مقلق، لأن تعديل الموجّه هو بحكم التعريف إبطال للذاكرة المؤقتة.

عبر Vercel AI SDK تصل الأرقام نفسها ضمن بيانات المزوّد بدل حقل الاستخدام العلوي. تحديد رسالة عبر providerOptions.anthropic.cacheControl يضع نقطة القطع، ويحمل providerMetadata.anthropic في النتيجة الحقلين cacheCreationInputTokens وcacheReadInputTokens. وغياب هذين الحقلين يعني أن الطلب لم يصل إلى المزوّد بصيغة قابلة للتخزين.

ما الذي لا يصلحه التخزين المؤقت وكيف يتعامل المزوّدون الآخرون معه؟

التخزين المؤقت تحسين على جانب الإدخال فقط. لا يغيّر مخرجات النموذج، ولا يخفض سعر وحدات الإخراج، ولا يجعل موجّهًا سيئ التحديد رخيصًا. وأكبر توفير حققناه لم يكن من الذاكرة المؤقتة أصلًا، بل من حذف قسم قديم في مستند مرجعي لم تستشهد به أي إجابة قط.

• OpenAI تطبّق التخزين المؤقت تلقائيًا على الموجّهات التي تتجاوز نحو 1024 وحدة، دون نقطة قطع صريحة، وتُبلغ عن الوحدات المخزَّنة في حقل الاستخدام.

• Google Gemini توفّر تخزينًا ضمنيًا وواجهة تخزين سياق صريحة يُنشأ فيها مقبض محتوى مخزَّن بمدة بقاء خاصة به ويُشار إليه بالاسم.

• Anthropic هي الصريحة: المستدعي يختار نقاط القطع، وهو ما يكلّف قرار تصميم ويشتري تحكمًا دقيقًا فيما يُخزَّن.

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

الأسئلة الشائعة

س: هل يغيّر التخزين المؤقت للموجّهات مخرجات النموذج؟

ج: لا. يعيد التخزين المؤقت استخدام البادئة المعالَجة ولا يغيّر آلية العيّنات، فالموجّه نفسه بالمعاملات نفسها يتصرف بالطريقة نفسها سواء قُرئت البادئة من الذاكرة المؤقتة أو عولجت من جديد.

س: هل تستطيع مؤسسة أخرى قراءة موجّه مخزَّن؟

ج: لا. مدخلات الذاكرة المؤقتة محصورة داخل مؤسسة واحدة ومفهرسة على البادئة تمامًا، فلا توجد مشاركة للمحتوى المخزَّن بين المؤسسات.

س: هل تُعاد مدة الخمس دقائق مع كل إصابة؟

ج: نعم. كل قراءة تجدد نافذة الخمس دقائق، فتُبقي الحركة المستمرة البادئة حية دون دفع ثمن الكتابة مرة أخرى.

س: لماذا تظهر وحدات كتابة في كل طلب رغم أن شيئًا لم يتغير؟

ج: هناك شيء في البادئة يتغير، غالبًا قيمة مُدرجة أو ترتيب مفاتيح غير حتمي. جرّب حساب بصمة البادئة المسلسلة لطلبين متتاليين وقارن النصين؛ الفارق يظهر دائمًا عند النظر إلى البايتات.

س: هل نخزّن تعريفات الأدوات أم موجّه النظام أولًا؟

ج: الأدوات، لأنها تُسلسل قبل موجّه النظام وهي عادةً أكبر كتلة ثابتة في طلب الوكيل. ووضع نقطة القطع بعد موجّه النظام يغطي الأدوات أيضًا، لأن البادئة المخزَّنة هي كل ما يسبق نقطة القطع.

قراءات إضافية

بناء خادم MCP بعيد في Next.js باستخدام mcp-handler 2: الأدوات وOAuth ومواصفة 2026-07-28 عديمة الحالة
اقرأ المقال

هندسة الذكاء الاصطناعي

بناء خادم MCP بعيد في Next.js باستخدام mcp-handler 2: الأدوات وOAuth ومواصفة 2026-07-28 عديمة الحالة

أصبحنا نبني خوادم MCP البعيدة كـ Route Handler واحد في Next.js باستخدام mcp-handler 2 ومواصفة MCP عديمة الحالة بإصدار 2026-07-28. نشرح هنا كيف نركّبها، وكيف نصمّم أدوات يستدعيها النموذج بشكل صحيح، وكيف نؤمّنها بـ OAuth وبيانات RFC 9728، وكيف نختبرها قبل اتصال أي عميل حقيقي.

لماذا لا يوقف موجّه نظام أفضل حقنَ الأوامر: ملاحظاتنا الميدانية حول الثلاثية القاتلة والأدوات محددة الصلاحيات والمخرجات غير الموثوقة
اقرأ المقال

هندسة الذكاء الاصطناعي

لماذا لا يوقف موجّه نظام أفضل حقنَ الأوامر: ملاحظاتنا الميدانية حول الثلاثية القاتلة والأدوات محددة الصلاحيات والمخرجات غير الموثوقة

أثناء بناء مساعد لصندوق الدعم يملك صلاحية استدعاء الأدوات، أدخل فريقنا تذكرة اختبار تحتوي على تعليمات مخفية، فنفّذ النموذج بعضها. هذه ملاحظاتنا الميدانية حول سبب كون حقن الأوامر مشكلة معمارية لا مشكلة صياغة، وكيف تكشف الثلاثية القاتلة ميزات الذكاء الاصطناعي الخطرة، وكيف نقيّد الأدوات بصلاحيات المستخدم المسجّل، ولماذا تحتاج الآثار الجانبية إلى تأكيد بشري، وكيف يتحول عرض Markdown إلى قناة لتسريب البيانات.