Alejandro Rioja.
AI Agents

لماذا يستمر وكيل الذكاء الاصطناعي في الفشل في بيئة الإنتاج (وكيفية إصلاحه)

Alejandro Rioja
Alejandro Rioja
5 د قراءة
TL;DR

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

نشرة بريدية مجانية

كل أربعاء. أكثر من 28,400 مشترك. بدون حشو.

جدول المحتويات

محدّث يونيو 2026.

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

[قراءة المشغّل] أدير أكثر من 30 وكيلاً في بيئة الإنتاج. لقد عانيت من جميع هذه الإخفاقات. تلك التي أهدرت أكثر وقت لم تكن الغريبة منها — بل كانت إخفاقات البنية التحتية المملة التي ظننت أنني تعاملت معها.

الإخفاق الأول: موجّهات هشّة تنهار عند مدخلات الحالات الحدية

الموجّه الذي يعمل في حالات الاختبار الخاصة بك سيفشل عند مدخلات لم تتوقعها. هذه ليست قيوداً في النموذج — إنها مشكلة كتابة التعليمات.

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

السبب الجذري: يصف موجّه النظام مسار السعادة فحسب. لا يخبر النموذج بما يجب فعله عندما تكون البيانات مفقودة أو مشوهة أو غامضة.

الإصلاح: أضف معالجة صريحة للحالات الحدية في موجّه نظامك:

code
If the input data is missing a required field, return:
{ "status": "error", "reason": "missing_field", "field": "<fieldname>" }
Do NOT attempt to infer or hallucinate missing values.

If you are uncertain which tool to call, call no tool and return:
{ "status": "clarification_needed", "question": "..." }

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

الإخفاق الثاني: لا منطق لإعادة المحاولة لأخطاء API العابرة

كل API خارجي يستدعيه وكيلك سيفشل في مرحلة ما. واجهة Claude البرمجية، وMeta Graph API، وقاعدة بياناتك — جميعها ترجع أخطاء 5xx، أو تنتهي مهلتها، أو تحد من المعدل. إذا لم يكن لدى وكيلك منطق لإعادة المحاولة، فإن خطأً عابراً واحداً يقتل التشغيل كله.

الأعراض: تفشل تشغيلات الوكيل بشكل عشوائي في خطوات مختلفة. تُظهر السجلات 503 أو 429 بدون محاولة متابعة.

الإصلاح: قم بتغليف كل استدعاء خارجي في إعادة محاولة مع تراجع أسي:

typescript
async function withRetry<T>(fn: () => Promise<T>, retries = 3, baseDelayMs = 500): Promise<T> {
  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      const isTransient = err.status === 429 || err.status >= 500 || err.code === "ECONNRESET";
      if (!isTransient || attempt === retries) throw err;
      const delay = baseDelayMs * Math.pow(2, attempt) + Math.random() * 100;
      await new Promise((r) => setTimeout(r, delay));
    }
  }
  throw new Error("unreachable");
}

// Usage
const result = await withRetry(() => client.messages.create({ ... }));

تعالج ثلاث محاولات إعادة مع تراجع أسي ~99% من الإخفاقات العابرة. أضف هذا لكل استدعاء خارجي ونصف إخفاقاتك العشوائية ستختفي.

الإخفاق الثالث: لا رؤية تشغيلية — لا يمكنك رؤية ما يتعطل

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

الأعراض: تعرف أن ثمة خللاً لكن لا تستطيع تحديد الخطوة. تضيف عبارات console.log وتعيد التشغيل يدوياً محاولاً إعادة الإنتاج.

الإصلاح: تسجيل منظم في كل خطوة، مع معرّف تشغيل يتتبع التنفيذ بأكمله:

typescript
function createLogger(runId: string, agentName: string) {
  return {
    step: (step: string, data: object) =>
      console.log(JSON.stringify({ runId, agent: agentName, step, ts: new Date().toISOString(), ...data })),
    error: (step: string, err: unknown) =>
      console.error(JSON.stringify({ runId, agent: agentName, step, error: String(err), ts: new Date().toISOString() })),
  };
}

const log = createLogger(crypto.randomUUID(), "newsletter-agent");
log.step("fetch_topic", { topicId: topic.id, topic: topic.name });
// ... do work ...
log.step("draft_complete", { subject: draft.subject, wordCount: draft.body.split(" ").length });

إذا كنت على Cloudflare Workers، تذهب هذه السجلات إلى Logpush أو Workers Tail. إذا كنت تعمل محلياً أو على VPS، أرسلها إلى مجمّع سجلات. JSON المنظم يعني أنك تستطيع التصفية بـ runId لرؤية ما حدث بالضبط في تشغيل واحد.

الإخفاق الرابع: حلقات جامحة بلا شرط خروج

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

الأعراض: ينفق الوكيل مئات الدولارات في تكاليف API قبل انتهاء المهلة. أو يُشغّل نفس استدعاء الأداة مراراً وتكراراً دون إحراز تقدم.

الإصلاح: احرص دائماً على وجود حد صارم للتكرارات وفحص للتقدم:

typescript
const MAX_ITERATIONS = 10;
let iterations = 0;
let lastToolCallName = "";
let sameToolCallCount = 0;

while (true) {
  iterations++;
  if (iterations > MAX_ITERATIONS) {
    log.error("loop", { reason: "exceeded_max_iterations" });
    break;
  }

  const response = await client.messages.create({ ... });

  // Detect stuck loops: same tool called 3x in a row
  const toolCall = response.content.find(b => b.type === "tool_use");
  if (toolCall?.name === lastToolCallName) {
    sameToolCallCount++;
    if (sameToolCallCount >= 3) {
      log.error("loop", { reason: "stuck_loop", tool: toolCall.name });
      break;
    }
  } else {
    sameToolCallCount = 0;
    lastToolCallName = toolCall?.name ?? "";
  }

  if (response.stop_reason === "end_turn") break;
}

يلتقط هذا كلا وضعي الإخفاق: “عمل وقتاً طويلاً جداً” و”دار في المكان”. يجب أن يكون الحد سخياً بما يكفي لمسار السعادة لكن ضيقاً بما يكفي للحدّ من نطاق الضرر.

الإخفاق الخامس: تعريفات أدوات غامضة يحلها النموذج خطأ

إذا أعطيت النموذج أداتين بأوصاف متداخلة، فسيستدعي أحياناً الخاطئة. هذا شائع بشكل خاص مع أدوات مثل search_database مقابل get_record أو send_email مقابل create_draft.

الأعراض: يستدعي النموذج الفئة الصحيحة من الأدوات لكن يختار الأداة المحددة الخاطئة. أو يستدعي أداة في سياق خاطئ (استخدام أداة كتابة عندما كانت القراءة فقط مناسبة).

الإصلاح: اجعل أوصاف الأدوات متنافية تبادلياً وأضف صراحةً “متى لا تستخدم هذا”:

typescript
const tools = [
  {
    name: "get_subscriber",
    description: "Fetch a single subscriber record by email. Use ONLY when you have a specific email address. Do NOT use for searching or listing subscribers.",
    input_schema: { ... }
  },
  {
    name: "search_subscribers",
    description: "Search subscribers by tag, segment, or status. Use when you need to find subscribers matching a criteria — NOT when you have a specific email address.",
    input_schema: { ... }
  }
];

بند “لا تستخدم عندما X” هو الجزء الذي يتخطاه معظم الناس. إنه أهم جزء. النماذج أفضل في اتباع القيود السلبية الصريحة من استنتاجها من الأوصاف الإيجابية.

شيء أخير: اختبر وكلاءك على مدخلات سيئة

تُختبر معظم الوكلاء فقط على مدخلات نظيفة ومسار سعادة. بيئة الإنتاج لديها مدخلات متسخة: سلاسل فارغة، وحقول null، وحالات حدية لـ Unicode، واستجابات API التي ترجع 200 لكن بمخطط غير متوقع.

أضف مجموعة اختبار تمرّن بشكل صريح على:

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

خلاصة المشغّل

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

تابع القراءة

احصل على دليل الذكاء الاصطناعي في صندوق بريدك

كل أربعاء. أكثر من 28,400 مشترك. بدون حشو.

↵ لعرض كل النتائج esc esc للإغلاق