Skip to main content
الوكيل الذي يملك أدوات كثيرة (عدة خوادم MCP، أو مجموعة أدوات داخلية كبيرة) يرسل تعريف كل أداة في كل استدعاء للنموذج. وهذا يكلّف رموز إدخال (tokens)، وبعد نحو 30 أداة يصبح النموذج أسوأ في اختيار الأداة المناسبة. مع البحث عن الأدوات، تُستبعد من الطلب الأدوات المعلَّمة بـ deferLoading. يحصل النموذج على أداة مضمَّنة واحدة هي tool_search، فيجد ما يحتاج إليه بكلمات قليلة، وتُرسل الأدوات التي وجدها ابتداءً من خطوته التالية. يجري البحث داخل SDK، فيعمل مع كل المزوّدين.

متى تستخدمه

  • الوكيل متصل بخوادم MCP كثيرة الأدوات، أو لديه مجموعة أدوات كبيرة، ومعظم التشغيلات لا تستخدم منها إلا القليل.
  • تعريفات الأدوات تشغل حصة ملحوظة من نافذة السياق.
مع عدد قليل من الأدوات لا فائدة تُرجى: افتراضيًا لا يُطبَّق التأجيل إلا حين تبلغ التعريفات المؤجَّلة 10% من نافذة السياق (انظر العتبة).

علِّم الأدوات أو الخوادم بـ deferLoading

علِّم أداة بعينها بـ defineTool({ deferLoading: true }):
أو علِّم خادم MCP بأكمله: فكل أداة يسردها تُؤجَّل.
يعمل deferLoading بالطريقة نفسها في ملفات المواصفات ومجلدات الوكيل (mcpServers.<name>.deferLoading: true)، ومع connectMcp(): فالواصفات التي يعيدها تحمل deferLoading، فيحافظ تمرير mcp.tools إلى createAgent({ tools }) على التأجيل. لا تُؤجَّل أبدًا، مهما عُلِّمت: load_skill (المهارات)، وأدوات الذاكرة، وtask وأدوات المهام الخلفية (الوكلاء الفرعيون)، وask_question، وأدوات transfer_to_<name> الخاصة بـالتسليمات، وtool_search نفسها. أما الأدوات المستضافة لدى المزوّد فتُرسل دائمًا.

ما يراه النموذج

حين ينطبق التأجيل، يحتوي أول طلب في التشغيل على الأدوات غير المؤجَّلة مع tool_search، ويضيف موجّه النظام فقرة واحدة: كم أداة لم تُحمَّل، وخوادم MCP التي جاءت منها (مع الأعداد)، وأن على النموذج استدعاء tool_search بكلمات قليلة تصف القدرة المطلوبة. تتلقى tool_search المدخل { query: string } وتعيد JSON:
يسرد loaded الأدوات التي وجدها هذا البحث (بحد أقصى maxResults)؛ ويعدّ more الأدوات المؤجَّلة التي لم تُحمَّل بعد. ابتداءً من الخطوة التالية يتضمن الطلب الأدوات المحمَّلة. وحين تُحمَّل كل الأدوات المؤجَّلة لا تعود tool_search معروضة. الأداة المؤجَّلة التي يستدعيها النموذج باسمها قبل أن تُحمَّل تعمل كأي أداة أخرى (وتنطبق الموافقات والصلاحيات وحواجز الحماية كالمعتاد). ويبلّغ stream() عن tool_search كزوج عادي من tool.start / tool.done. يقارن الترتيب الافتراضي كلمات الاستعلام باسم كل أداة مؤجَّلة (مقسَّمًا عند _ و- و__ وعند تغيّر حالة الأحرف camelCase) ووصفها، بلا حساسية لحالة الأحرف. والكلمة الموجودة في الاسم تُحتسب ثلاثة أضعاف الموجودة في الوصف؛ وتُرتَّب حالات التعادل بالاسم. وتُصدَّر الدالة نفسها باسم rankToolsByKeywords(query, tools).

خيارات toolSearch

يضبط كل من createAgent({ toolSearch }) وAgentExecutor.execute({ toolSearch }) عملية البحث. أما تفعيل التأجيل نفسه فيتم بتعليم الأدوات أو الخوادم بـ deferLoading؛ وtoolSearch: false يحمّل كل الأدوات مقدمًا.
القيمة غير الصالحة ترمي LOUSHO_CONFIG_INVALID عند إنشاء الوكيل. وأداة من عندك اسمها tool_search ترمي LOUSHO_CONFIG_INVALID حين يبدأ تشغيل والتأجيل فعّال: غيّر اسمها، أو اضبط toolSearch: false.

العتبة

عند بدء التشغيل يقدّر SDK رموز التعريفات المؤجَّلة (الاسم والوصف ومخطط JSON Schema لكل أداة، بـ estimateTokens() الخاصة بنموذج التشغيل). وتحت thresholdPercent من نافذة السياق تُرسل كل الأدوات مقدمًا ولا تُضاف أداة tool_search: فالتعريفات رخيصة، وخطوة البحث ستكلّف أكثر مما توفّر. وهذه القاعدة نفسها المتّبعة في وضع auto في Claude Agent SDK. قاس الاختبار الحي لهذه الميزة (40 أداة من سطر واحد على gpt-4o-mini) 157 رمز إدخال في الاستدعاء الأول مع التأجيل، و892 بدونه.

كيف يستمر التحميل

الأدوات المحمَّلة لا تُخزَّن في أي مكان: بل تُقرأ من السجل عند كل استدعاء للنموذج. تُعدّ الأداة محمَّلة حين تسمّيها نتيجة tool_search ناجحة في رسائل التشغيل. وعليه:
  • الاستئناف بعد تعطل من نقطة حفظ، وتوقف الموافقة واستئنافها، والتفرّع (fork)، والدورة التالية في الجلسة، كلها تُبقي الأدوات المحمَّلة.
  • لا يبلّغ الاستئناف عن انجراف الوكيل بسبب التحميل: فالبصمة تشمل كل الأدوات، المؤجَّلة وغيرها.
  • ضغط السياق الذي يقتطع نتيجة tool_search يُلغي تحميل أدواتها ابتداءً من استدعاء النموذج التالي؛ ويبحث النموذج من جديد حين يحتاج إليها.
  • هدف التسليم يبدأ دون أي أداة محمَّلة، حتى لو كانت له الأدوات المؤجَّلة نفسها: لا يُعتدّ إلا بنتائج tool_search الواقعة بعد آخر تسليم، وتنطبق أدوات الهدف الخاصة المعلَّمة بـ deferLoading وإعداد toolSearch الخاص به. أما الوكيل الفرعي فيشغّل قائمة أدواته الخاصة على سجله الخاص، فلا يرث أبدًا ما حمّله الوكيل الرئيسي.

خوادم MCP التي تتطلب تسجيل الدخول

سرد أدوات الخادم يحتاج إلى اتصال، لذا فإن خادمًا معلَّمًا بـ deferLoading ويستخدم OAuth ولم يُسجَّل الدخول إليه يُفشل التشغيل بالخطأ LOUSHO_MCP_AUTH_REQUIRED كأي خادم آخر. وحين يسجّل المشغّل الدخول تُؤجَّل أدواته كالمعتاد. وأي صلاحية تُسحب لاحقًا تحوّل استدعاء أداة محمَّلة إلى خطأ أداة LOUSHO_MCP_AUTH_REQUIRED، كما هو الحال بلا تأجيل.

التخزين المؤقت للموجّه

تتغير قائمة الأدوات حين تُحمَّل الأدوات. والمزوّدون الذين يخزّنون مؤقتًا بادئة الطلب (التخزين المؤقت للموجّه في Anthropic، والتخزين التلقائي في OpenAI) يضعون تعريفات الأدوات في أولها، فقد تخطئ الخطوة التي تحمّل أدوات التخزين المؤقت من تلك النقطة. ويحدث التحميل بضع مرات في التشغيل الواحد على الأكثر؛ وإن كانت تشغيلاتك تعيد استخدام بادئة مخزَّنة طويلة عبر استدعاءات كثيرة، فقارن التكلفة مع toolSearch: false.