Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 31

حلقة الإدراك-التفكير-العمل الأساسية للوكيل

Recommended resources

أهلاً بك مجدداً! في الدرس السابق، وضعنا الأساس المعماري لوكيلنا عبر تعلم كيفية استخدام الفئات (Classes) في بايثون. لقد صممنا "مخطط" وكيلنا، وعرفنا أنه سيحتوي على سمات (بيانات) وتوابع (أفعال).

اليوم، سنقوم ببث الحياة في هذا المخطط. سنهدف إلى تحقيق مخرج التعلم التالي: تنفيذ حلقة العمل الأساسية للوكيل (Perceive-Think-Act Loop). هذه الحلقة هي المحرك الذي يجعل الوكيل كياناً مستقلاً وقادراً على العمل، وهي ما يميزه عن كونه مجرد برنامج عادي يستجيب للأوامر.

استعد، ففي نهاية هذا الدرس، سيكون لديك أول نسخة عاملة من وكيل ذكاء اصطناعي كتبته بنفسك!


1. فهم حلقة عمل الوكيل (Agent Loop)

قبل كتابة الكود، دعنا نرسخ فهمنا لهذه الحلقة. في الوحدة السابقة، تعرفنا على دورة حياة الوكيل: الإدراك، التفكير، التصرف. هذه الدورة المستمرة هي قلب كل وكيل ذكي.

The Perceive-Think-Act Loop of an AI Agent
هذه الصورة تلخص جوهر عمل الوكيل: حلقة مستمرة من الإدراك (Perceive)، ثم التفكير (Think)، ثم التصرف (Act)، ليعود ويدرك نتائج تصرفه وهكذا.

لنترجم هذه الخطوات إلى مصطلحات برمجية عملية:

  1. الإدراك أو الملاحظة (Perceive / Observe): كيف يرى الوكيل العالم؟ في البداية، ستكون "الملاحظة" هي المدخلات التي تقدمها أنت (مثل سؤال أو أمر). لاحقاً، يمكن أن تكون نتيجة عمل أداة (مثل نتيجة بحث على الإنترنت).
  2. التفكير (Think): هذه هي مرحلة اتخاذ القرار. بناءً على "الملاحظة" الحالية وهدفه العام، يقرر الوكيل ما هي الخطوة التالية. هذا هو الجزء الذي سيلعبه نموذج اللغة الكبير (LLM) لاحقاً ليكون "عقل" الوكيل.
  3. التصرف (Act): ينفذ الوكيل القرار الذي اتخذه. قد يكون التصرف هو إعطاء إجابة نهائية، أو استخدام أداة، أو طرح سؤال توضيحي.

هذه الحلقة ليست مجرد تسلسل لمرة واحدة؛ إنها عملية مستمرة تتكرر حتى يقرر الوكيل أن هدفه قد تحقق.

للحصول على رؤية أوضح لكيفية تطبيق هذه الحلقة في كود حقيقي، لنقرأ مقطعاً من دليل احترافي حول بناء الوكلاء.

How to Build AI Agents Using Python: A Step-by-Step Guide

يقدم هذا المقال من 'Ema.co' شرحاً ممتازاً وموجزاً للمكونات الأساسية للوكيل، بما في ذلك حلقة العمل. سنركز على الجزء الذي يصف هذه الحلقة وكيفية تنفيذها.

اقرأ القسمين التاليين: ابدأ من '5 Core Building Blocks of an AI Agent' واقرأ النقطة الخامسة 'Orchestration Logic'. لاحظ كيف تصف الحلقة بأنها: Observe → Decide → Act → Record → Stop or Repeat. ثم انتقل إلى 'Step 4: Implement the Core Agent Loop'. ألقِ نظرة على بنية دالة run_agent. لا تقلق بشأن فهم كل سطر من الكود بالتفصيل، فقط ركز على البنية العامة للحلقة (while not state["done"]).

كما رأيت في المقال، حلقة العمل هي "منطق التنسيق" (Orchestration Logic) الذي يحكم كل شيء. إنها الكود الذي يستمر في العمل، ويسأل العقل (LLM) "ماذا أفعل الآن؟"، ثم ينفذ الأمر، ويسجل النتيجة، ويقرر ما إذا كان سيستمر أم يتوقف.



2. بناء الحلقة في بايثون

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

سنقوم بإنشاء ملف بايثون جديد (مثلاً agent_v1.py) ونكتب الكود التالي. سأشرح كل جزء بالتفصيل.

# agent_v1.py

class Agent:
    """
    نسخة أولية وبسيطة من وكيل الذكاء الاصطناعي.
    """
    def __init__(self, goal):
        print(f"تم إنشاء وكيل جديد بهدف: '{goal}'")
        self.goal = goal
        self.memory = []      # ذاكرة لتسجيل ما حدث في كل جولة
        self.is_done = False  # علم (flag) لإيقاف الحلقة عندما تكتمل المهمة

    def think(self, observation):
        """
        خطوة التفكير: يقرر الوكيل ما يجب فعله.
        هذا مجرد تابع وهمي (placeholder) الآن.
        """
        print(f"🤔 الوكيل يفكر في الملاحظة: '{observation}'")
        # في هذا الإصدار البسيط، يقرر الوكيل دائمًا أنه يجب أن يجيب.
        # لاحقًا، سيتم استبدال هذا بمنطق أكثر تعقيدًا (LLM).
        decision = "تقديم إجابة نهائية للمستخدم."
        return decision

    def act(self, decision, observation):
        """
        خطوة التصرف: ينفذ الوكيل القرار.
        """
        print(f"🏃 الوكيل يتصرف بناءً على القرار: '{decision}'")
        # بناءً على القرار، يقوم الوكيل بصياغة إجابة.
        # في هذا المثال، الإجابة بسيطة جدًا.
        response = f"بناءً على هدفي ('{self.goal}') والملاحظة ('{observation}'), قررت أن أقول مرحبًا!"
        return response

    def run(self, initial_observation):
        """
        الحلقة الرئيسية التي تدير عمل الوكيل (Perceive-Think-Act Loop).
        """
        print("\n--- بدء حلقة عمل الوكيل ---")
        
        observation = initial_observation
        turn_count = 0

        # while: تستمر الحلقة طالما أن الوكيل لم ينتهِ من مهمته
        while not self.is_done:
            turn_count += 1
            print(f"\n--- الجولة رقم {turn_count} ---")
            
            # 1. التفكير (Think)
            decision = self.think(observation)

            # 2. التصرف (Act)
            result = self.act(decision, observation)
            print(f"💬 نتيجة التصرف: {result}")

            # 3. تسجيل ما حدث في الذاكرة (Record)
            self.memory.append({
                "turn": turn_count,
                "observation": observation,
                "decision": decision,
                "result": result
            })
            
            # 4. تقييم الحالة: هل يجب أن تتوقف الحلقة؟ (Stop or Repeat)
            # في هذا المثال البسيط، سنتوقف بعد جولة واحدة فقط.
            if turn_count >= 1:
                print("\nالوكيل قرر أن مهمته قد اكتملت.")
                self.is_done = True

        print("\n--- انتهاء حلقة عمل الوكيل ---")
        print("\nمحتويات ذاكرة الوكيل النهائية:")
        # طباعة الذاكرة بشكل منظم
        for entry in self.memory:
            print(entry)


# --- الجزء الرئيسي من البرنامج ---
if __name__ == "__main__":
    # 1. إنشاء وكيل جديد مع هدف محدد
    my_agent = Agent("الرد على تحية المستخدم بأدب")

    # 2. تشغيل الوكيل مع ملاحظة أولية (مدخلات المستخدم)
    my_agent.run("مرحباً أيها الوكيل!")

شرح الكود خطوة بخطوة:

  1. __init__(self, goal): كما تعلمنا، هذا هو المُنشئ. يقوم بإعداد الحالة الأولية للوكيل:

    • self.goal: الهدف الذي يسعى لتحقيقه.
    • self.memory: قائمة فارغة لتخزين سجل أفعاله.
    • self.is_done: متغير منطقي (Boolean) قيمته الأولية False. سيتحكم هذا المتغير في استمرار الحلقة.
  2. think(self, observation) و act(self, decision, observation): هذان هما التابعان اللذان يمثلان "التفكير" و"التصرف". في الوقت الحالي، هما بسيطان جداً ويطبعان فقط ما يفعلانه. لاحظ أن think يقرر ماذا يفعل، و act ينفذ ذلك القرار. هذا الفصل بين التفكير والتنفيذ مهم جداً وسيكون أساسياً عندما نضيف أدوات وقدرات أكثر تعقيداً.

  3. run(self, initial_observation): هذا هو قلب الدرس اليوم!

    • يبدأ التابع بحلقة while not self.is_done:. هذا يعني: "استمر في تكرار الكود الموجود بالداخل طالما أن self.is_done قيمتها False".
    • داخل الحلقة، يتم تنفيذ دورة العمل بالترتيب:
      1. decision = self.think(...): الوكيل "يفكر".
      2. result = self.act(...): الوكيل "يتصرف".
      3. self.memory.append(...): الوكيل "يسجل" ما حدث للتو في ذاكرته. هذا مهم جداً لتتبع قراراته وأفعاله.
      4. if turn_count >= 1:: هذا هو شرط الإيقاف. في هذا المثال البسيط، نجعل الوكيل يتوقف بعد جولة واحدة فقط عن طريق تعيين self.is_done = True. عندما تبدأ الحلقة دورتها التالية، ستجد أن الشرط not self.is_done لم يعد صحيحاً، فتتوقف الحلقة.
  4. الجزء الرئيسي (if __name__ == "__main__":): هنا نقوم بإنشاء نسخة (كائن) من وكيلنا ونطلق حلقة العمل الخاصة به عن طريق استدعاء my_agent.run(...) مع تمرير "ملاحظة أولية" له.

عند تشغيل هذا الكود، سترى المخرجات في الطرفية (Terminal) تتبع خطوات الوكيل بوضوح، مما يوضح لك تماماً كيف تعمل الحلقة.

اختبر فهمك!

ماذا سيحدث لو قمنا بتغيير شرط الإيقاف داخل التابع run من if turn_count >= 1: إلى if turn_count >= 3:؟

أظهر الإجابة

ستستمر الحلقة في العمل لثلاث جولات بدلاً من جولة واحدة. في كل جولة، سيقوم الوكيل بتنفيذ خطوات think و act و record مرة أخرى، وسيتم إضافة إدخال جديد إلى self.memory. ستتوقف الحلقة فقط عندما يصل turn_count إلى 3 ويتم تعيين self.is_done إلى True. هذا يوضح كيف يمكن التحكم في مدة عمل الوكيل بناءً على شروط معينة.



خلاصة الدرس

لقد أنجزت اليوم خطوة هائلة! لم تعد تتعامل مع مفاهيم نظرية فقط، بل قمت ببناء وتشغيل أول نسخة من وكيل ذكاء اصطناعي.

أهم النقاط التي تعلمناها:

  • حلقة عمل الوكيل (Agent Loop) هي المحرك الذي يدير دورة الإدراك -> التفكير -> التصرف -> التسجيل -> التكرار أو التوقف.
  • استخدمنا حلقة while في بايثون لتنفيذ هذه الدورة المستمرة.
  • استخدمنا متغيراً منطقياً (is_done) للتحكم في وقت توقف الحلقة.
  • فصلنا منطق "التفكير" (think) عن "التصرف" (act) في توابع منفصلة، مما يجعل الكود أكثر تنظيماً وقابلية للتطوير.
  • قمنا بتنفيذ ذاكرة بسيطة (memory) تسجل كل ما يفعله الوكيل في كل جولة.

ماذا بعد؟

وكيلنا الحالي يعمل، ولكنه ليس ذكياً بعد. فتابع think الخاص به لا "يفكر" حقاً؛ إنه يتبع قاعدة ثابتة.

في الدرس القادم، سنقوم بالخطوة الأكثر إثارة حتى الآن: ربط الوكيل بنموذج لغة كبير (LLM) ليكون بمثابة 'العقل'. سنستبدل التابع think الوهمي باستدعاء حقيقي لواجهة برمجة تطبيقات (API) لنموذج لغوي، مما سيمنح وكيلنا القدرة على اتخاذ قرارات ديناميكية وذكية بناءً على المدخلات. استعد لرؤية وكيلك يفهم اللغة ويقرر بنفسه