تصنيف أنماط فشل الوكلاء
أنشئ تصنيفًا لفشل الوكلاء يشمل أخطاء الأدوات، والمخرجات المشوهة، وحلقات الاستدلال، واستنفاد السياق، وعدم توفر الخدمات الخارجية، وصمّم استراتيجيات للتعافي من كل حالة.
تصنيف أنماط فشل الوكلاء درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
لماذا تفشل الوكلاء بطرق مميّزة
تفشل الوكلاء بطرق مختلفة عن استدعاءات LLM البسيطة. فإما أن يعيد الاستدعاء أحادي الدور إجابة أو يطرح خطأً. أما الوكيل الذي ينفّذ مهمة متعددة الخطوات، فقد يفشل في أي نقطة — وقد لا يكون الفشل واضحًا من المخرج النهائي. يُعد فهم تصنيف أنماط فشل الوكلاء الخطوة الأولى لبناء وكلاء يكتشفون حالات فشلهم ويشخّصونها ويتعافون منها.
نمط الفشل 1: أخطاء الأدوات
تحدث أخطاء الأدوات عندما يستدعي الوكيل أداةً بوسائط غير صالحة، أو تطرح الأداة استثناءً، أو تعيد نتيجة فارغة أو مشوّهة. ومن أمثلتها: استدعاء واجهة بحث API باستعلام مشوّه، أو الاستعلام عن قاعدة بيانات باستخدام SQL غير صالح، أو استدعاء منفّذ شيفرة يتجاوز مهلة الانتظار. وتُعد أخطاء الأدوات الأسهل اكتشافًا لأنها تنتج إشارات استثناء صريحة يمكن التقاطها ومعالجتها.
class ToolError(Exception):
def __init__(self, tool_name: str, args: dict, error: Exception):
self.tool_name = tool_name
self.args = args
self.original_error = error
super().__init__(f'Tool {tool_name} failed: {error}')
def safe_tool_call(tool_func, args: dict) -> str:
try:
result = tool_func(**args)
if not result:
return 'Tool returned empty result. Try a different approach.'
return str(result)
except Exception as e:
raise ToolError(tool_func.__name__, args, e)نمط الفشل 2: المخرجات المشوّهة
تحدث المخرجات المشوّهة عندما ينشئ الوكيل نصًا لا يطابق التنسيق المتوقع — مثل إعادة لغة طبيعية بينما تتوقع الخطوة التالية JSON، أو استدعاء أداة بوسائط ذات بنية خاطئة. يحدث ذلك غالبًا عندما يخلط الوكيل بين خطوته الحالية وخطوة سابقة. تحقّق من تنسيق كل مخرج للوكيل قبل استخدامه، وأعد توجيه المطالبة عندما يكون التنسيق خاطئًا.
import json
def validate_agent_output(raw_output: str, expected_format: str) -> dict:
if expected_format == 'json':
try:
return json.loads(raw_output)
except json.JSONDecodeError as e:
return {
'valid': False,
'error': f'Expected JSON but got invalid JSON: {e}',
'raw': raw_output[:200]
}
return {'valid': True, 'data': raw_output}نمط الفشل 3: حلقات الاستدلال
تحدث حلقات الاستدلال عندما يكرر الوكيل الإجراء أو الفكرة نفسها إلى ما لا نهاية دون إحراز تقدم. فقد يستدعي الوكيل استعلام البحث نفسه 10 مرات متتالية، ويحصل على النتيجة الفارغة نفسها دون أن يعرف ما الذي يجربه بعد ذلك. اكتشف الحلقات بتتبّع الإجراءات الأخيرة والتحقق من تكرارها. وعند اكتشاف حلقة، أدرج مطالبةً وصفية تطلب من الوكيل تجربة نهج مختلف.
from collections import Counter
class LoopDetector:
def __init__(self, window: int = 5, threshold: int = 3):
self.recent_actions = []
self.window = window
self.threshold = threshold
def record(self, action: str) -> bool:
self.recent_actions.append(action)
if len(self.recent_actions) > self.window:
self.recent_actions.pop(0)
counts = Counter(self.recent_actions)
most_common_count = counts.most_common(1)[0][1] if counts else 0
return most_common_count >= self.threshold # True = loop detectedنمط الفشل 4: استنفاد السياق
يحدث استنفاد السياق عندما يتجاوز السجل المتراكم للوكيل (استدعاءات الأدوات والملاحظات والأفكار) نافذة سياق النموذج. فإما أن يقتطع النموذج السجل بصمت، مما يؤدي إلى فقدان معلومات مهمة، أو يطرح خطأً متعلقًا بحد الرموز. امنع ذلك بتتبّع استخدام الرموز عبر الخطوات وضغط السجل (تلخيص الخطوات القديمة) قبل بلوغ الحد.
import tiktoken
CONTEXT_LIMIT = 100_000 # tokens
COMPRESS_AT = 80_000 # trigger compression with headroom
enc = tiktoken.encoding_for_model('gpt-4o')
def total_tokens(messages: list) -> int:
return sum(len(enc.encode(str(m))) for m in messages)
def check_context(messages: list) -> str:
tokens = total_tokens(messages)
if tokens > COMPRESS_AT:
return 'compress'
if tokens > CONTEXT_LIMIT:
return 'critical'
return 'ok'نمط الفشل 5: عدم توفّر الخدمة الخارجية
تحدث أعطال الخدمات الخارجية عندما تكون الخدمة الأساسية لأداة ما متوقفة أو مقيّدة بمعدل الاستخدام أو تعيد أخطاء غير متوقعة. فالوكيل الذي لا يستطيع الوصول إلى قاعدة البيانات التي يحتاج إلى الاستعلام عنها يكون عالقًا. وبخلاف حلقات الاستدلال (التي تقع على عاتق الوكيل)، تُعد الأعطال الخارجية أعطالًا بيئية. عالجها بإعادة المحاولة مع تراجع أُسّي، ووفّر أدوات بديلة يمكنها تقريب النتيجة باستخدام مصادر بيانات مختلفة.
import asyncio
async def resilient_tool_call(tool_func, args: dict, max_retries: int = 3) -> str:
for attempt in range(max_retries):
try:
return await tool_func(**args)
except (ConnectionError, TimeoutError) as e:
if attempt == max_retries - 1:
return f'Service unavailable after {max_retries} attempts. Error: {e}'
wait = 2 ** attempt # 1s, 2s, 4s
await asyncio.sleep(wait)
return 'Unexpected error in resilient_tool_call'نمط الفشل 6: سوء فهم الهدف
يحدث سوء فهم الهدف عندما يفسّر الوكيل المهمة تفسيرًا خاطئًا ويسعى إلى تحقيق هدف مختلف اختلافًا دقيقًا. وهذا أصعب حالات الفشل اكتشافًا، إذ قد يُكمل الوكيل المهمة بنجاح — لكن ليس المهمة التي قصدها المستخدم. خفّف ذلك بأن تطلب من الوكيل إعادة صياغة الهدف بكلماته الخاصة في البداية، وأن تنفّذ خطوة تحقق نهائية تفحص ما إذا كانت النتيجة تجيب فعلًا عن السؤال الأصلي.
async def confirm_goal_understanding(original_task: str) -> str:
resp = await client.chat.completions.create(
model='gpt-4o',
messages=[
{'role': 'system', 'content': 'Restate the task in your own words. Be specific about what the final deliverable should be.'},
{'role': 'user', 'content': f'Task: {original_task}'}
]
)
return resp.choices[0].message.content
# Use the restatement as the first step of the agent
# to catch misunderstandings before any tools are calledإنشاء نظام لتصنيف حالات الفشل
أنشئ مصنّفًا منظّمًا لحالات الفشل يضع تسمية لنوع كل استثناء يطرحه الوكيل. يتيح ذلك التوجيه التلقائي إلى استراتيجية التعافي المناسبة. خزّن سجلات الفشل مع تسميات الأنواع حتى تتمكن من تحليل أنماط الفشل الأكثر شيوعًا وتحديد أولويات معالجتها. تكون أخطاء الأدوات والحلقات عادةً الأكثر تكرارًا والأسهل إصلاحًا.
from enum import Enum
from dataclasses import dataclass
class FailureType(Enum):
TOOL_ERROR = 'tool_error'
MALFORMED_OUTPUT = 'malformed_output'
REASONING_LOOP = 'reasoning_loop'
CONTEXT_EXHAUSTION = 'context_exhaustion'
EXTERNAL_SERVICE = 'external_service'
GOAL_MISUNDERSTANDING = 'goal_misunderstanding'
MAX_ITERATIONS = 'max_iterations'
UNKNOWN = 'unknown'
@dataclass
class AgentFailure:
failure_type: FailureType
step: int
tool_name: str | None
error_message: str
recoverable: boolربط حالات الفشل بإجراءات التعافي
لكل نوع من حالات الفشل إجراء تعافٍ مناسب. تستدعي أخطاء الأدوات إعادة المحاولة مع تعديل الوسائط. وتستدعي الحلقات مطالبةً بالتنويع تطلب من الوكيل تجربة أمر جديد. ويستدعي استنفاد السياق ضغط السجل. وتستدعي أعطال الخدمات الخارجية أدوات بديلة. أما سوء فهم الهدف فيستدعي طلب توضيح. اربط هذه الإجراءات صراحةً في موجّه تعافٍ يستدعيه وقت تشغيل الوكيل عند حدوث حالات الفشل.
RECOVERY_ACTIONS = {
FailureType.TOOL_ERROR: 'retry_with_corrected_args',
FailureType.MALFORMED_OUTPUT: 'reformat_output',
FailureType.REASONING_LOOP: 'inject_diversity_prompt',
FailureType.CONTEXT_EXHAUSTION: 'compress_history',
FailureType.EXTERNAL_SERVICE: 'use_fallback_tool',
FailureType.GOAL_MISUNDERSTANDING:'request_clarification',
FailureType.MAX_ITERATIONS: 'escalate_to_human',
FailureType.UNKNOWN: 'escalate_to_human'
}تعيين حدود قصوى للتكرار
يجب أن يكون لكل وكيل حد أقصى للتكرار بوصفه حدًا صارمًا للسلامة. فمن دونه، سيعمل الوكيل العالق في حلقة إلى ما لا نهاية، مستهلكًا الرموز والمال. عيّن الحد بناءً على تعقيد المهمة المتوقع: فقد يقتصر وكيل بسيط للإجابة عن الأسئلة على 5 خطوات، بينما قد يُسمح لوكيل بحث معقد بـ20 خطوة. عند بلوغ الحد، سجّل الفشل، واحفظ النتائج الجزئية، وصعّد الحالة إلى شخص أو أعد إجابة جزئية.
MAX_ITERATIONS = 15
async def run_agent(task: str) -> str:
messages = [{'role': 'user', 'content': task}]
loop_detector = LoopDetector()
for iteration in range(MAX_ITERATIONS):
response = await get_agent_action(messages)
if response.is_final:
return response.answer
action_key = f'{response.tool}:{response.args}'
if loop_detector.record(action_key):
messages.append({'role': 'system', 'content': 'You are repeating yourself. Try a completely different approach.'})
continue
result = await execute_tool(response.tool, response.args)
messages.append({'role': 'tool', 'content': result})
return 'Task exceeded maximum iterations. Partial results: ' + get_partial_result(messages)تسجيل حالات الفشل لتحليل ما بعد الحادثة
سجّل كل حالة فشل للوكيل بسياق كافٍ لتشخيصها لاحقًا: وصف المهمة كاملًا، وسجل الإجراءات الكامل حتى نقطة الفشل، ونوع الفشل ورسالة الخطأ، وعدد التكرارات، واستخدام الرموز. خزّن ذلك في جدول failures مع فهرس على failure_type وtask_id. راجع سجلات الفشل بانتظام لتحديد أنواع المهام الأكثر عرضة لأنماط فشل محددة، ورتّب الإصلاحات وفقًا لذلك.
import json
from dataclasses import asdict
async def log_agent_failure(task_id: str, failure: AgentFailure, history: list, pool):
async with pool.acquire() as conn:
await conn.execute('''
INSERT INTO agent_failures
(task_id, failure_type, step, tool_name, error_message,
recoverable, action_history, failed_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
''',
task_id,
failure.failure_type.value,
failure.step,
failure.tool_name,
failure.error_message,
failure.recoverable,
json.dumps(history)
)تحقق سريع
اختبر مدى فهمك لتصنيف أنماط فشل الوكلاء.
مراجعة الدرس
تعلّمت في هذا الدرس أن أنماط فشل الوكلاء الرئيسية الستة تشمل أخطاء الأدوات، والمخرجات المشوّهة، وحلقات الاستدلال، واستنفاد السياق، وأعطال الخدمات الخارجية، وسوء فهم الهدف؛ وأن اكتشاف الحلقات عبر سجل الإجراءات يلتقط الأنماط المتكررة قبل استنفاد ميزانية التكرار؛ وأن ربط أنواع الفشل بإجراءات التعافي يتيح الإصلاح الذاتي الآلي. في الدرس التالي سننفّذ التصحيح الذاتي والمطالبات التأملية.
الأسئلة الشائعة
هل درس «تصنيف أنماط فشل الوكلاء» مجاني؟
نعم — نص درس «تصنيف أنماط فشل الوكلاء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «تصنيف أنماط فشل الوكلاء»؟
أنشئ تصنيفًا لفشل الوكلاء يشمل أخطاء الأدوات، والمخرجات المشوهة، وحلقات الاستدلال، واستنفاد السياق، وعدم توفر الخدمات الخارجية، وصمّم استراتيجيات للتعافي من كل حالة. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «تصنيف أنماط فشل الوكلاء»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تصنيف أنماط فشل الوكلاء
- التصحيح الذاتي وكتابة Prompts تأملية
- حفظ نقاط التحقق واستئناف المهام
- التصعيد إلى الإنسان ضمن الحلقة