الوكلاء طويلو المدى
معمارية الوكيلين
4 دقيقة للقراءة
عندما تتجاوز المهام ما يمكن لجلسة واحدة التعامل معه، قسّم المسؤوليات. نمط المُهيِّئ + العامل، الموثق من Anthropic لأنظمة Claude، يحل مشكلة الجلسات طويلة المدى بأناقة.
النمط
وكيلان متخصصان بأدوار مميزة:
┌─────────────────┐ ┌─────────────────┐
│ المُهيِّئ │────▶│ العامل │
│ │ │ │
│ • يحلل المهمة │ │ • ينفذ العمل │
│ • ينشئ خطة │ │ • يستخدم الأدوات │
│ • يعد الحالة │ │ • ينشئ نقاط حفظ │
│ • سياق نظيف │ │ • يمكن إعادة تشغيله │
└─────────────────┘ └─────────────────┘
وكيل المُهيِّئ
يعمل مرة واحدة في البداية. سياق نظيف، انتباه كامل.
class InitializerAgent:
"""يحلل المهمة وينشئ خطة التنفيذ."""
def __init__(self, llm_client):
self.llm = llm_client
def initialize(self, task: str, codebase_path: str) -> dict:
# الخطوة 1: تحليل قاعدة الكود
structure = self.analyze_codebase(codebase_path)
# الخطوة 2: تقسيم المهمة
plan = self.llm.generate(f"""
المهمة: {task}
هيكل قاعدة الكود: {structure}
أنشئ خطة تنفيذ مفصلة:
1. اذكر جميع المهام الفرعية بالترتيب
2. حدد التبعيات بين المهام الفرعية
3. لاحظ أي ملفات تؤثر عليها كل مهمة فرعية
4. قدّر تعقيد كل مهمة فرعية
""")
# الخطوة 3: حفظ الحالة الأولية
state = {
"task": task,
"plan": plan,
"subtasks": self.parse_subtasks(plan),
"completed": [],
"current_index": 0,
"created_at": datetime.now().isoformat()
}
return state
وكيل العامل
يعمل في حلقة، يكمل من حيث توقف.
class WorkerAgent:
"""ينفذ المهام الفرعية مع نقاط الحفظ."""
def __init__(self, llm_client, state_file: str):
self.llm = llm_client
self.state = self.load_state(state_file)
def run(self):
while self.state["current_index"] < len(self.state["subtasks"]):
subtask = self.state["subtasks"][self.state["current_index"]]
# بناء سياق مركز لهذه المهمة الفرعية
context = self.build_context(subtask)
# تنفيذ بسياق أدنى
result = self.execute_subtask(subtask, context)
# نقطة حفظ فوراً
self.checkpoint(subtask, result)
# الانتقال للتالي
self.state["current_index"] += 1
self.save_state()
def build_context(self, subtask: dict) -> str:
"""تحميل ما هو مطلوب فقط لهذه المهمة الفرعية."""
relevant_files = subtask.get("files", [])
recent_changes = self.state["completed"][-3:] # آخر 3 فقط
return f"""
المهمة الفرعية الحالية: {subtask['description']}
الملفات ذات الصلة: {self.read_files(relevant_files)}
التغييرات الأخيرة: {json.dumps(recent_changes, indent=2)}
"""
لماذا يعمل هذا
| الفائدة | التفسير |
|---|---|
| بدايات نظيفة | العامل يمكنه إعادة التشغيل بسياق نظيف |
| سياق مركز | كل مهمة فرعية تحصل على معلومات ذات صلة فقط |
| قابل للاستئناف | الأعطال لا تفقد التقدم |
| قابل للتنقيح | مسار نقاط حفظ واضح |
| كفاءة التكلفة | لا تضخم السياق من الأدوار القديمة |
التسليم
def run_long_task(task: str, codebase: str):
state_file = f"state_{hash(task)}.json"
# التحقق من وجود حالة
if os.path.exists(state_file):
print("استئناف من نقطة الحفظ...")
worker = WorkerAgent(llm, state_file)
else:
print("تهيئة مهمة جديدة...")
initializer = InitializerAgent(llm)
state = initializer.initialize(task, codebase)
save_state(state_file, state)
worker = WorkerAgent(llm, state_file)
# تشغيل العامل (يمكن مقاطعته واستئنافه)
worker.run()
الاستخدام العملي
هذا النمط يشغّل أدوات مثل:
- Claude Code: يستخدم المُهيِّئ للتخطيط، العامل للتنفيذ
- Cursor: وكلاء خلفية تنجو من إعادة تشغيل IDE
- Devin: جلسات برمجة متعددة الساعات مع نقاط حفظ
ملاحظة نيردية: المُهيِّئ يجب أن يكون قوياً في تقسيم المهام. أفضل أن يكون لديك 20 مهمة فرعية صغيرة من 5 كبيرة—أسهل لنقاط الحفظ والاستئناف.
التالي: تتبع التقدم عبر الجلسات. :::