يطلب الوكيل سجل عميل. تعيد واجهة برمجة التطبيقات (API) الخاصة بك العميل، بالإضافة إلى آخر 200 طلب له، بالإضافة إلى كل بند في تلك الطلبات، بالإضافة إلى طوابع زمنية بثلاثة تنسيقات وكتلة _links لكل منها. أربعون ألف رمز تصل إلى نافذة السياق. كان الوكيل بحاجة إلى عنوان البريد الإلكتروني.
افعل ذلك أربع مرات في جولة واحدة، ويكون الوكيل قد أنفق معظم ميزانيته في قراءة JSON لم يطلبه. ثم تبدأ الإخفاقات المثيرة للاهتمام: ينسى التعليمات الأصلية، ويلخص المهمة بدلاً من إنجازها، وترتفع التكلفة لكل جولة بينما تنخفض الجودة.
هذه مشكلة تصميم في طبقة API، وليست مشكلة موجه (prompt). تستهلك الوكلاء الاستجابات من خلال نافذة ثابتة، وكل حقل تعيده يتنافس مع التعليمات والمحادثة والخطة. يغطي هذا الدليل من أين يأتي التضخم، وأنماط اختيار الحقول وترقيم الصفحات التي تصلحه، وكيفية التقليم داخل طبقة الأدوات عندما لا تتحكم في واجهة برمجة التطبيقات، وكيفية قياس الفرق. يعالج عمودنا حول سبب تعطل وكلاء الذكاء الاصطناعي في الإنتاج استنفاد السياق كأحد أنماط الفشل الأساسية، وهذا هو النصف العملي منه.
Apidog يساعد في جانب القياس: يمكنك رؤية حجم الاستجابة الفعلي لكل نقطة نهاية قبل أن يستدعيها الوكيل على الإطلاق، ومحاكاة الشكل المقلم الذي تريده قبل أن يقوم فريق API بإطلاقه.
إلى أين تذهب الرموز (Tokens)
تحمل الاستجابات المصممة للمتصفحات ولوحات المعلومات الكثير من البيانات التي تكلف الوكيل أموالًا حقيقية.
أغلفة مطولة. يمكن لمغلف data، meta، links، included حول كائن بخمسة حقول مضاعفة حجم الحمولة. روابط الوسائط الفائقة (Hypermedia) مفيدة للعميل الذي يتبعها. الوكلاء لا يفعلون ذلك أبدًا تقريبًا، وكل عنوان URL هو رموز.
مفاتيح متكررة. يكرر JSON كل اسم حقل في كل عنصر من عناصر المصفوفة. قائمة مكونة من 200 عنصر مع 15 حقلًا لكل عنصر تدفع مقابل 3000 سلسلة مفاتيح. هذا هو السبب في أن نقاط نهاية القوائم تهيمن على استخدام السياق.
التوسيع المتداخل افتراضيًا. نقاط النهاية التي تضمن الموارد ذات الصلة تكون ملائمة حتى يصطدم بها الوكيل. عميل واحد بالإضافة إلى طلباته بالإضافة إلى العناصر هو شجرة، والأشجار تنمو بسرعة.
تنسيقات زائدة. created_at، created_at_unix، وcreated_at_human على نفس الكائن هي تكلفة ثلاثية لقيمة واحدة.
قيم فارغة وفراغات. العديد من برامج التسلسل (serializers) تصدر كل حقل حتى لو لم يتم تعيينه. عشرون قيمة null لكل سجل هي هدر محض.
طريقة مفيدة لرؤية ذلك: تكلفة الرمز تتبع حجم النص المتسلسل، وليس عدد السجلات. مائتا سجل بخمسة حقول لكل منها يمكن أن تكون أرخص من كائن واحد متداخل بعمق.
القاعدة الأولى: أعد الحقول، وليس الموارد
التغيير الوحيد ذو القيمة الأعلى هو السماح للمتصل بطلب ما يحتاجه.
GET /v1/customers/8812?fields=id,email,plan,status
{ "id": "8812", "email": "dana@example.com", "plan": "pro", "status": "active" }
هذا يمثل تخفيضًا بنسبة 90 بالمائة مقارنة بسجل كامل في معظم واجهات برمجة التطبيقات، ويستغرق إضافته فترة ما بعد الظهر. يوثق دليل تصميم واجهة برمجة التطبيقات من Google نمط قناع الحقل إذا كنت تريد إصدارًا له سابقة، ويحل GraphQL نفس المشكلة بجعل التحديد إلزاميًا.
ملاحظتان للتنفيذ. تحقق من صحة قائمة الحقول مقابل المخطط وارفض الأسماء غير المعروفة، بحيث ينتج الحقل الوهمي خطأ واضحًا بدلاً من كائن مقطوع بصمت. واحتفظ بمجموعة افتراضية صغيرة للمتصلين الذين لا يرسلون شيئًا، بدلاً من تعيين الافتراضي لكل شيء.
ثم قم بكشف المعلمة للنموذج في وصف الأداة، مع توضيح الحقول:
{
"name": "getCustomer",
"description": "جلب عميل بواسطة المعرف. مرر دائمًا `fields` بما تحتاجه فقط. المتاح: id, email, name, plan, status, created_at, billing_address, order_count.",
"input_schema": {
"type": "object",
"required": ["customerId", "fields"],
"properties": {
"customerId": { "type": "string" },
"fields": {
"type": "array",
"items": { "type": "string" },
"description": "أسماء الحقول المراد إرجاعها. حافظ على هذه القائمة في حدها الأدنى."
}
}
}
}
الأوصاف هي المكان الوحيد الذي يتعلم فيه النموذج هذه القواعد، ويولي كل من دليل استدعاء الوظائف من OpenAI و وثائق استخدام الأدوات من Anthropic نفس الأهمية لها. جعل fields إلزاميًا هو الحيلة. يتم تخطي المعلمة الاختيارية؛ أما المعلمة الإلزامية فتجبر النموذج على التفكير فيما يحتاجه بالفعل.
القاعدة الثانية: حدد القائمة دائمًا
نقاط نهاية القوائم غير المحدودة هي المصدر الكبير الثاني للانفجارات. يطلب الوكيل "الطلبات الأخيرة" ويحصل على كل شيء منذ عام 2019.
قم بتعيين حد أقصى صارم من جانب الخادم، وليس مجرد قيمة افتراضية. إذا أرسل الوكيل limit=5000، أعد 100 واذكر ذلك. تغطي أدلتنا حول ترقيم الصفحات في REST API و تصميم ترقيم الصفحات لملايين السجلات الآليات؛ والقواعد الخاصة بالوكلاء أضيق:
- حدد الصفحة عند شيء يمكن للنموذج قراءته، في نطاق 20 إلى 50 عنصرًا للسجلات النموذجية.
- أعد العدد الإجمالي حتى يتمكن الوكيل من معرفة ما إذا كان قد رأى كل شيء دون الحاجة إلى تصفح الصفحات لمعرفة ذلك.
- استخدم ترقيم الصفحات بواسطة المؤشر. تتغير الإزاحات عندما تتغير البيانات في منتصف التشغيل، والوكيل الذي يقوم بالترقيم ببطء سيواجه ذلك.
- قم بتضمين بيان واضح في الاستجابة، مثل
"truncated": true، حتى يعرف النموذج أن هناك المزيد. النماذج غالبًا ما تخطئ في الحكم على الاكتمال من طول المصفوفة وحده.
امنح الوكيل أيضًا طريقة لتجنب ترقيم الصفحات تمامًا. غالبًا ما تجيب نقطة نهاية count، أو بحث مفلتر بنافذة ضيقة، أو كائن ملخص على السؤال دون إرجاع أي سجلات. الاستجابة الأرخص هي تلك التي لا تحتوي على البيانات.
القاعدة الثالثة: قم بالتقليم في طبقة الأدوات عندما لا تكون واجهة برمجة التطبيقات ملكك
واجهات برمجة التطبيقات الخارجية لن تضيف اختيار الحقول لأنك طلبت ذلك. ضع التقليم في المنفذ الخاص بك بدلاً من ذلك، بين استجابة HTTP والنموذج.
KEEP = {
"getCustomer": ["id", "email", "plan", "status"],
"listOrders": ["id", "total", "status", "created_at"],
}
def project(tool_name, payload):
keep = KEEP.get(tool_name)
if keep is None:
return payload
if isinstance(payload, list):
return [{k: item.get(k) for k in keep if k in item} for item in payload]
return {k: payload.get(k) for k in keep if k in payload}
ثلاثة تحسينات تجعل هذا صامدًا عمليًا.
قم بتخزين الاستجابة الكاملة ومرر للنموذج الإسقاط (projection). احتفظ بالحمولة غير المقلمة في سجل التشغيل الخاص بك حتى يظل التصحيح ممكنًا. يغطي منشورنا حول تتبع استدعاءات أدوات الوكيل ما يجب تسجيله.
أخبر النموذج بما أزلته. سطر مثل "_omitted": ["billing_address", "notes", "metadata"] يسمح له بطلب السجل الكامل عندما يحتاجه حقًا، بدلاً من استنتاج أن البيانات غير موجودة.
حول القوائم إلى تنسيق مضغوط. بالنسبة للنتائج الجدولية، تكلف CSV أو جدول markdown رموزًا أقل بكثير من JSON لأن أسماء الحقول تظهر مرة واحدة بدلاً من كل صف. النماذج تقرأ كلاهما بشكل جيد.
id,total,status,created_at
ord_91,4900,paid,2026-08-21
ord_92,1200,refunded,2026-08-22
القاعدة الرابعة: لخص على الخادم للحالات الثقيلة
بعض الأسئلة لا تحتاج إلى سجلات على الإطلاق. "هل واجه هذا العميل أي مدفوعات فاشلة هذا الشهر؟" هو سؤال بنعم/لا. إرجاع 40 كائن دفع ليتمكن النموذج من حلها هو الطريقة المكلفة للإجابة.
عندما يتكرر سؤال، أضف نقطة النهاية التي تجيب عليه مباشرة. ملخص صحة الحساب، أو تجميع حالة، أو تجميع صغير. هذا يبدو كعمل تصميم API عادي لأنه كذلك، وهو النسخة الأكثر قيمة من كل ما سبق: بدلاً من تقليم استجابة كبيرة، فإنك تتجنب إنتاج واحدة.
حاجزان وقائيان. حافظ على ملخصات مستقرة في شكلها حتى يتمكن الوكلاء من الاعتماد عليها، وقم بترقيم إصداراتها، لأن موجه الوكيل مكتوب بناءً على شكل وتغيير صامت يكسره. يغطي منشورنا حول ماذا يحدث عندما تتغير واجهة برمجة التطبيقات تحت الوكيل هذا الخطر، ويغطي أفضل استراتيجية لترقيم إصدارات واجهة برمجة التطبيقات آليات ذلك.
القياس قبل وبعد
لا يستحق أي من هذا القيام به بشكل أعمى. ثلاثة أرقام تخبرك أين تكمن المشكلة.
البايتات لكل استجابة، لكل نقطة نهاية. أرسل طلبًا واقعيًا إلى كل أداة يمكن لوكيلك استدعائها وسجل حجم الحمولة. أي شيء يتجاوز بضعة كيلوبايت هو مرشح. في Apidog يمكنك تشغيل كل نقطة نهاية مرة واحدة وقراءة الحجم مباشرة من الاستجابة، ثم حفظ الطلب ليتكرر الفحص عند تغيير واجهة برمجة التطبيقات.

الرموز لكل استدعاء أداة. البايتات هي وكيل؛ الرموز هي الفاتورة. قم بتشغيل الحمولات عبر أداة تحليل الرموز الخاصة بمزودك، مثل tiktoken لنماذج OpenAI، وصنف نقاط النهاية. عادة ما يكون التصنيف غير متوازن، مع نقطة نهاية واحدة أو اثنتين مسؤولة عن معظم التكلفة.
السياق المستخدم لكل جولة. سجل الإجمالي الجاري عبر مهمة وكيل كاملة. إذا انتهت مهمة بالقرب من الحد، فإن التقليم يمنحك جولات مكتملة، وليس فقط جولات أرخص.
ثم صمم الشكل الذي تريده وقم بمحاكاته قبل أن يقوم فريق API بإنشائه. يسمح لك خادم المحاكاة الذي يعيد الاستجابة المقلمة بقياس التحسين والتحقق من أن الوكيل لا يزال ينجح ببيانات أقل، وهو السؤال المهم حقًا. يغطي منشورنا حول تشغيل الوكلاء مقابل المحاكاة بدلاً من الإنتاج سير العمل.
ماذا يبدو جيدًا
الاستجابة الصديقة للوكيل صغيرة ومسطحة وصادقة بشأن ما أغفلته:
{
"customer": { "id": "8812", "email": "dana@example.com", "plan": "pro" },
"recent_orders": [
{ "id": "ord_91", "total_cents": 4900, "status": "paid" },
{ "id": "ord_92", "total_cents": 1200, "status": "refunded" }
],
"recent_orders_total": 47,
"truncated": true,
"_omitted": ["billing_address", "metadata", "order_line_items"]
}
أقل من 200 رمز. يجيب على السؤال الشائع، ويقول إن هناك 47 طلبًا بدلاً من الإيحاء بوجود طلبين، ويخبر النموذج بما يمكنه طلبه بعد ذلك.
ابدأ بأكثر نقاط النهاية استخدامًا. قم بقياسها، أضف اختيار الحقول، حدد القائمة، وشغل الوكيل مرة أخرى. الفجوة بين الرقمين عادة ما تكون كبيرة بما يكفي لتبرير بقية العمل. قم بتنزيل Apidog إذا كنت تريد القياس والمحاكاة في نفس المشروع.
ثلاثة أماكن يظهر فيها هذا
فرز الدعم. يقرأ الوكيل تذكرة، ويستخرج العميل، ويقرر ما إذا كان يجب تصعيد المشكلة. النسخة الساذجة تجلب كائن العميل الكامل وآخر 50 تذكرة، مستهلكة 30,000 رمز قبل أن تقرأ الشكوى الفعلية. النسخة المعدلة تستدعي نقطة نهاية ملخص تعيد الخطة، الحالة، عدد التذاكر المفتوحة، وتاريخ آخر اتصال. حوالي 80 رمزًا، ويصبح قرار التصعيد أفضل لأن الحقائق ذات الصلة ليست مدفونة.
وكلاء العمليات الداخلية. وكيل نشر يتحقق من صحة الخدمة عبر 40 خدمة. كائنات الحالة الكاملة تملأ النافذة عند الخدمة 12. تلخيص يعيد سطرًا واحدًا لكل خدمة، الاسم بالإضافة إلى الحالة بالإضافة إلى معدل الخطأ، يناسب جميع الـ 40 خدمة في بضع مئات من الرموز ويسمح للوكيل بالاستدلال عبر الأسطول بدلاً من نسيان النصف الأول.
إدخال البيانات والمطابقة. وكيل يطابق الفواتير بالمدفوعات. إرجاع وثائق الفاتورة الكاملة يجعله يفشل بعد بضع عشرات من السجلات. إرجاع id، amount_cents، date، وreference بتنسيق CSV يسمح له بمعالجة عدة مئات في تمريرة واحدة، لأن المقارنة استخدمت أربعة حقول فقط.
النمط المشترك بين الثلاثة: الوكيل كان بحاجة إلى سطح قرار، وواجهة برمجة التطبيقات قدمت له وثيقة.
تحتاج إلى سجل التشغيل لرؤية النمط
تشغيل واحد يخبرك أن الاستجابة كانت كبيرة. النمط، أي نقطة نهاية تستنزف الميزانية وكم مرة، لا يظهر إلا عبر عدة تشغيلات.
هذا يعني أن الأرقام يجب أن تبقى بعد الجلسة. بالنسبة لخدمة قمت بنشرها، هذا هو قياسك عن بعد الخاص بك. بالنسبة لوكلاء البرمجة الذين ينفذون عملًا معينًا، فإنها المنصة التي تشغلهم: يحافظ Sharkly على تتبع تنفيذ كل جولة ونتيجتها في المهمة التي جاءت منها، لذا فإن المقارنة بين الجولات هي مسألة قراءة سجل المهام بدلاً من إعادة بناء جلسات المحطة الطرفية. في كلتا الحالتين، يخبرك تطبيق الميزانية بدون سجل أن شيئًا ما كبير جدًا، لكن ليس ما يجب إصلاحه أولاً.

حدد ميزانية لكل أداة، وليس فقط لكل جولة
معظم الفرق تحدد سقفًا للسياق الكلي وتتوقف عند هذا الحد. لكن ميزانية لكل أداة أكثر فائدة، لأنها تحول مشكلة غامضة إلى مشكلة محددة.
امنح كل أداة سقفًا، على سبيل المثال 1500 رمز. عندما تتجاوز الاستجابة هذا الحد، يقوم المنفذ بالتقليم إلى الإسقاط، ويضيف علامة الحقول المحذوفة، ويسجل الفائض. الآن لديك قائمة بنقاط النهاية التي تتجاوز الميزانية بانتظام، مصنفة حسب عدد مرات استدعاء الوكيل لها، وهذا هو قائمة عملك.
تحميك الميزانية أيضًا من نقطة النهاية التي تبدو صغيرة في الاختبار وتكون هائلة لعميل حقيقي واحد. التوزيعات لها ذيول، والحساب الذي يحتوي على 4000 طلب هو الذي سيتسبب في تعطل جولة في الساعة 2 صباحًا. الحد الأقصى الصارم يحول ذلك إلى استجابة مقلمة بدلاً من مهمة فاشلة.
الأسئلة المتكررة
هل تقليم الاستجابات محفوف بالمخاطر إذا كان الوكيل يحتاج إلى البيانات المفقودة؟ فقط إذا أخفيت التقليم. قم بتضمين علامة واضحة وقائمة بالحقول المحذوفة حتى يتمكن النموذج من طلبها. التقليم الصامت هو ما يسبب الإجابات الخاطئة، وليس التقليم نفسه.
هل يجب أن أستخدم GraphQL للوكلاء بدلاً من ذلك؟ يجعل GraphQL اختيار الحقول إلزاميًا، مما يحل هذه المشكلة بشكل نظيف، لكنه ينقل التعقيد إلى بناء الاستعلامات وتكتب النماذج استعلامات غير صالحة في كثير من الأحيان أكثر مما تسيء استخدام قائمة الحقول. إضافة fields إلى نقاط نهاية REST عادة ما يكون التغيير الأصغر.
ما مدى صغر استجابة الأداة؟ استهدف أقل من 1000 رمز لقراءة سجل واحد وأقل من 2000 لقائمة. بعد ذلك، اسأل ما إذا كان الوكيل يحتاج إلى سجلات أم إجابة.
هل حل التخزين المؤقت للموجه (prompt caching) يحل هذه المشكلة؟ إنه يقلل من تكلفة السياق المتكرر، وليس المساحة التي يشغلها. استجابة مخبأة بحجم 40,000 رمز لا تزال تملأ النافذة، لذا يساعد التخزين المؤقت في الفاتورة مع ترك مشكلة الموثوقية كما هي.
ماذا عن الاستجابات الثنائية والملفات؟ لا تضعها أبدًا في السياق. قم بتخزين الملف، وامنح الوكيل مرجعًا ووصفًا قصيرًا، وامنحه أداة منفصلة لاستخراج ما يحتاجه فقط.
أين يجب أن يتم التقليم، في واجهة برمجة التطبيقات (API) أم في غلاف الأداة؟ في واجهة برمجة التطبيقات عندما تكون مالكها، لأن كل متصل يستفيد والبيانات لا تعبر الشبكة أبدًا. في الغلاف عندما لا تكون مالكها. القيام بالحلين لا بأس به.
