انتقل إلى المحتوى
كل الملاحظات

3 د للقراءة

ما الذي يحتاجه الوكيل فعلًا من الأداة

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

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

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

#1. الوصف هو العقد

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

json
{
  "name": "orders_search",
  "description": "Find orders by customer email, order number or date range. Use this before orders_update to get the order id. Returns at most 50 orders, newest first, with a cursor for more. Does not return line items — call orders_get for one order's details.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": { "type": "string", "description": "Email, order number, or free text." },
      "since": { "type": "string", "format": "date" },
      "cursor": { "type": "string" }
    },
    "required": ["query"]
  }
}

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

#2. مدخلات صغيرة، مخطّطات صارمة

كل حقل اختياري قرار على النموذج اتخاذه. التعدادات تتفوّق على النص الحر. التواريخ بصيغة واحدة. وlimit بسقف صلب في الخادم أيًا كان ما تقوله المدخلات. أولّد المخطّطات من Zod حتى لا يفترق التحقق عن الوصف.

typescript
const SearchInput = z.object({
  query: z.string().min(2).describe('Email, order number, or free text.'),
  status: z.enum(['open', 'paid', 'shipped', 'cancelled']).optional(),
  since: z.string().date().optional(),
  cursor: z.string().optional(),
})

#3. أعِد أخطاءً يستطيع النموذج التصرّف بناءً عليها

الاستثناء طريق مسدود. أما الخطأ المُهيكل مع تلميح فهو الخطوة التالية.

typescript
return {
  ok: false,
  error: 'ORDER_NOT_FOUND',
  hint: 'No order matches "KF-1042". Order numbers look like KF-<digits>; try orders_search with the customer email instead.',
}

غيّر حقل hint السلوك أكثر من أي موجّه (prompt) كتبته. يحوّل حلقة إعادة المحاولة إلى نداء واحد مُصحَّح.

#4. كل ما يكتب يأخذ مفتاح تكرارية

الوكلاء يعيدون المحاولة. والشبكات تتعثّر. أداة orders_refund بلا مفتاح تكرارية (idempotency key) ستردّ المال مرتين، عاجلًا أم آجلًا. اشترط المفتاح، وخزّن النتيجة تحته، وأعِد النتيجة المخزّنة حين يعود المفتاح نفسه.

#5. صفّح بالمؤشرات، وضع سقفًا

الإزاحات (offsets) تنكسر حين تتحرّك البيانات تحت الوكيل، وهي تتحرّك دائمًا. أعِد cursor، واقبل cursor، ولا تُعِد أبدًا أكثر من السقف حتى لو طُلب منك. وينبغي للوصف أن يذكر السقف ليخطّط النموذج له.

#6. قدرة واحدة لكل أداة، والقراءات لا تكتب أبدًا

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

#7. قيّمها كما تقيّم البرمجيات

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

#الأعراض، إن كنت تصحّح واحدة الآن

القاعدة المخالَفةما تراه في المحادثة
وصف مبهمالنموذج ينادي الأداة الخطأ، أو الأداة الصحيحة للسبب الخطأ
مخطّط متراخٍتواريخ بثلاث صيغ، وحدود من 10 000
أخطاء مُلقاةالنداء نفسه يتكرّر بإعادات صياغة صغيرة
لا مفتاح تكراريةكتابات مكرّرة بعد انتهاء المهلة
تصفيح بالإزاحةسجلّات مُتجاوَزة أو مكرّرة في منتصف التشغيل
خلط القراءة والكتابة«بحث» غيّر شيئًا
لا تقييمكان يعمل البارحة

لا شيء من هذا غريب. إنه تصميم واجهات برمجية، مطبَّق على عميل لا يستطيع القراءة بين السطور. النموذج ليس الجزء الصعب؛ الصعب هو السطح الذي تناوله إياه.

هل أفادك هذا؟

النقاش

تبني شيئًا من هذا القبيل؟

أخبرني بما تعمل عليه. أردّ في غضون يوم.

راسلني