الـ Agents· الدرس 3 من 6
- 1إيه هو الـ Agent؟8 دقيقة
- 2حلقة الـ Agent9 دقيقة
- 11نمط ReAct — الـ Agent اللي بيفكر قبل ما يتحرك8 دقيقة
- 20الـ Reflection — الـ Agent اللي بيراجع شغله9 دقيقة
- 21نمط الـ Evaluator–Optimizer — واحد يبني وواحد يحكم9 دقيقة
- 22تبني الـ Agents بإيه؟ — من غير Framework ولا LangGraph ولا CrewAI ولا AutoGen؟10 دقيقة
نمط ReAct — الـ Agent اللي بيفكر قبل ما يتحرك
في سطر واحد · **الـ ReAct بيخلّي الـ Agent يكتب خطوة تفكير قصيرة قبل كل Tool Call، ويقرا نتيجتها قبل ما يقرر الخطوة الجاية — فبدل ما يتحرك على العمياني، بيصحح مساره أول بأول.** <!-- Field 3: TL;DR -->
- Agent بينفذ Tools من غير تفكير بيغلط في تلاتة: Tool غلط، ترتيب غلط، وتجاهل كامل للنتايج اللي راجعة.
- ReAct = Reasoning + Acting: فكّر (أنا محتاج إيه دلوقتي؟) ← نفّذ Tool Call ← اقرا النتيجة (Observation) وعدّل ← فكّر تاني... لحد الإجابة.
- خطوة التفكير مش رفاهية: لما الموديل يكتب احتياجه قبل القرار، اختياره للـ Tool التالي بيبقى مبني على معلومات — مش تخمين.
- ReAct مش اختراع جديد فوق حلقة الـ Agent — ده وصفة على مستوى الـ Prompt لنفس الحلقة اللي تعرفها، بس بصوت عالي.
- التمن حقيقي: كل Thought بيتحاسب Tokens. في المهام المتعددة الخطوات بيستاهل؛ في سؤال بـ Tool واحد واضح — وفّر فلوسك.
<!-- Field 4: Why does this matter? -->
خد المشهد ده: Agent واصله سؤال من جزئين، وقدامه 6 Tools. من غير خطوة تفكير، بيعمل واحدة من تلاتة — وكلهم شفناهم في مراجعات مشاريع حقيقية: ينده Tool محتاج Parameter لسه ماجابوش فياخد Error، أو يجاوب نص السؤال ويتجاهل النص التاني، أو الأظرف: ياخد الـ Error ويعيد نفس النداء بنفس المدخلات — لأن مفيش لحظة بيسأل فيها نفسه «طيب النتيجة دي غيرت إيه؟».
المهام المتعددة الخطوات هي بالظبط الفرق بين Agent حقيقي و Chatbot عليه شوية زينة. و ReAct هو أشهر وأبسط نمط بيخلي الخطوات دي تشتغل — وعشان كده «اشرحلي ReAct» بقى سؤال شبه ثابت في انترفيوهات وظايف الـ Agents.
<!-- Field 5: Explain it simply (Layer 1) -->
قبل كل خطوة، الـ Agent بيكتب لنفسه سطر: «أنا محتاج إيه دلوقتي؟ وليه؟». بعد كل Tool، بيقرا النتيجة ويسأل: «طيب ده بيغير خطتي إزاي؟».
التفكير ده بيحصل جوه المحادثة نفسها — نص عادي الموديل بيولّده — مش مكوّن خارجي ولا سحر. مجرد إنك تجبر الموديل يفكر مكتوب، القرارات بتتحسن.
<!-- Field 6: Real-world analogy (Layer 2) -->
فني صيانة مستعجل بيفتح الجهاز ويبدل قطع «على الأمل»: يمكن المروحة، يمكن الباور. كل قطعة غلط بتكلف وقت وفلوس.
الفني الشاطر بيشتغل مختلف: «الصوت جاي من ناحية المروحة — هقيس الحرارة الأول» ← يقيس ← «الحرارة طبيعية؟ يبقى المشكلة مش تبريد، هجرب البلي» ← كل خطوة مبنية على نتيجة اللي قبلها.
الاتنين معاهم نفس العدّة. الفرق إن الأول بينفذ وخلاص، والتاني بيفكر ← ينفذ ← يلاحظ ← يعدّل. الـ ReAct بيحوّل الـ Agent بتاعك من الأول للتاني.
<!-- Field 7: Simple example — the concrete trace -->
مثال حقيقي
السؤال: «إيه سعر منتج X عندنا؟ وهل في مخزون في فرع الرياض؟»
من غير ReAct، شكل الفشل المعتاد:
Action: get_inventory(product_id=???, branch="Riyadh")
Observation: Error: product_id is required
Action: get_inventory(product_id=???, branch="Riyadh") ← نفس الغلط تانيبـ ReAct، نفس الموديل ونفس الـ Tools:
Thought: السؤال فيه جزئين: السعر، والمخزون في فرع الرياض.
الاتنين محتاجين الـ product ID الأول — هدوّر على المنتج.
Action: search_products(query="X")
Observation: [{id: "P-1042", name: "X", price: 249 SAR}]
Thought: جبت الاتنين في ضربة واحدة تقريبًا: السعر 249 ريال،
والـ ID معايا. فاضل المخزون في الرياض.
Action: get_inventory(product_id="P-1042", branch="Riyadh")
Observation: {branch: "Riyadh", in_stock: true, quantity: 7}
Thought: عندي إجابة الجزئين. أقدر أرد.
Answer: سعر المنتج X هو 249 ريال، ومتوفر حاليًا في فرع الرياض (7 قطع).لاحظ الـ Thought التاني: الموديل لاحظ إن السعر جه مع نتيجة البحث، فما نداش Tool تاني للسعر. دي بالظبط الفلوس اللي التفكير بيوفرها.
<!-- Field 8: How it works (Layer 3) -->
الدورة تلات ضربات، بتتكرر لحد ما الموديل يقرر إنه جاهز يجاوب:
1. Thought — فكّر: الموديل بيكتب سطر أو سطرين: إيه المطلوب، إيه اللي معايا، وإيه الناقص. 2. Action — نفّذ: بناءً على التفكير، بيطلب Tool Call محدد — وكودك أنت اللي بينفذه فعليًا. 3. Observation — لاحظ: نتيجة الـ Tool بترجع للمحادثة، وبتدخل خام في الـ Thought الجاي.
طيب ليه الحركة دي بتشتغل أصلًا؟ سببين:
- التفكير بيحسّن اختيار الـ Tool. لما الموديل يكتب «أنا ناقصني الـ product ID» قبل ما يختار، الاختيار بييجي مشروط بالجملة دي — فبيختار
search_productsمشget_inventory. من غيرها، بيختار أقرب Tool شبه السؤال. - الـ Observation بتصحح المسار. نتيجة فاضية، Error، رقم مفاجئ — كل دي معلومات. في ReAct ليها مكان رسمي في الدورة، فالخطة بتتعدل بدل ما الـ Agent يكمل في السكة الغلط.
<!-- Field 10: Visual explanation -->
بالرسم
┌──────────────────────────────────────────────┐
│ │
▼ │
┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ Thought │ ───► │ Action │ ───► │ Observation │ ──┘
│ "what │ │ (tool │ │ (read the │
│ next?" │ │ call) │ │ result) │
└─────────┘ └─────────┘ └─────────────┘
│
│ "I have everything I need"
▼
┌─────────┐
│ Answer │
└─────────┘السهم الراجع من الـ Observation للـ Thought هو النمط كله: النتيجة بتتقري قبل القرار الجاي. لو السهم ده مقطوع عندك، أنت عندك Agent بينفذ — مش Agent بيفكر.
<!-- Field 11: Technical explanation (Layer 4) -->
أول حاجة تثبتها: الـ ReAct هو حلقة الـ Agent اللي تعرفها — perceive ← decide ← act ← observe — بفرق واحد: خطوة الـ decide بقت نص صريح الموديل بيكتبه بدل ما تحصل ضمنيًا جوه الموديل. يعني ReAct مش معمارية جديدة تبنيها — ده أسلوب Prompting لنفس الحلقة.
تاني حاجة، للسياق التاريخي: الورقة الأصلية (2022) كانت قبل ما الـ Tool Calling يبقى Native في الـ APIs — كانوا بيكتبوا Action: search[...] كنص وبيعملوا Parsing. النهارده الـ Action بتطلع Structured من الـ API نفسه، والـ Thought بقت نص بيسبق النداء. الصيغة اتغيرت — الفكرة زي ما هي.
تالت حاجة: الـ Thoughts دي قناة داخلية. مكانها الطبيعي الـ Trace والـ Logs — وهي أصلًا أحلى هدية للـ Debugging: لما الـ Agent يغلط، بتقرا تفكيره وبتعرف ليه غلط، مش بس إنه غلط.
<!-- Field 13: Code example (CR-4: English code, Arabic surround) -->
الكود
الحلقة كلها بأي Provider وأي SDK — اقراها كسودوكود قابل للتشغيل:
SYSTEM = """You are a store assistant. Solve the task step by step.
Before every tool call, write ONE short "Thought:" line stating
what you need next and why. After each tool result, reconsider
your plan before acting again. Thoughts are internal — never
show them to the user. Answer only when you have everything."""
steps = 0
while steps < MAX_STEPS: # always cap the loop!
response = llm.generate(messages, tools=TOOLS)
messages.append(response) # keep the Thought in context
if not response.tool_calls:
break # model produced the Answer
for call in response.tool_calls:
result = execute(call) # your code does the acting
messages.append(tool_result(call, result)) # the Observation
steps += 1تلات حاجات خد بالك منهم:
- `MAX_STEPS` مش تفصيلة — ده الـ Guardrail اللي بيمنع تحدي «The agent that never stops» يحصل عندك في الإنتاج.
- الـ Thought بيتحفظ في الـ Context (
messages.append(response)) — عشان التفكير القديم يفضل قدام الموديل ويبني عليه. - الـ Observation بترجع كاملة، بما فيها رسايل الـ Errors — الموديل مش هيصلح غلطة مش شايفها.
<!-- Field 14: Common mistakes -->
تمرين (20 دقيقة): خد Agent بسيط عندك — أو الـ Agent بتاع مشروع Research Agent لو بدأته — وشغّله على سؤال مركب من جزئين، مرتين: مرة من غير أي تعليمات تفكير، ومرة بعد ما تضيف سطر «Before every tool call, write one short Thought line» للـ System Prompt. قارن الـ Traces: عدد النداءات، النداءات الغلط، وإجمالي الـ Tokens. الفرق اللي هتشوفه بعينك أبلغ من أي شرح.
<!-- Field 28: Knowledge check (scenario-based per F5) -->
| # | ❌ الغلط | ✅ الصح |
|---|---|---|
| 1 | الـ Thoughts بتتسرب للمستخدم: «Thought: المستخدم غالبًا قصده...» ظاهرة في الشات | افصل القنوات: التفكير في الـ Trace، والمستخدم يشوف Status مختصر («بدوّر في المخزون...») |
| 2 | Loop من غير سقف: الـ Agent بيلف وبيلف والفاتورة بتعد | MAX_STEPS + سقف تكلفة للمهمة الواحدة — من أول يوم، مش بعد أول حادثة |
| 3 | تفكير روائي: الموديل بيكتب مقال قبل كل نداء وأنت بتدفع تمنه | حدد في الـ System Prompt: «ONE short Thought line» — سطر بيوجه القرار، مش خاطرة |
| 4 | قص الـ Observations: بتبعت للموديل «Error» من غير التفاصيل | مرّر رسالة الخطأ كاملة — هي المادة الخام لتصحيح المسار |
| 5 | ReAct على كل حاجة: حتى «إيه حالة الطقس؟» واخدة Thought و Observation | Tool واحد واضح = نداء مباشر. المراسم للمهام اللي مستاهلاها (شوف «إمتى لأ») |
<!-- Field 15: Common misconceptions -->
مفاهيم غلط منتشرة
1) «ReAct هو نفسه موديلات الـ Reasoning» — ❌ موديلات الـ Reasoning بتفكر جوه نفسها قبل ما ترد. الـ ReAct نمط على مستوى تطبيقك أنت: بينظم التفكير بين الـ Tool Calls وبيخليه جزء من الـ Trace. بيكملوا بعض — ولو شغال بموديل Reasoning قوي، ممكن تخفف صيغة الـ Thought الصريحة وتسيب له التفكير الداخلي. جرّب وقيس.
2) «طالما بيفكر، يبقى الإجابة صح» — ❌ الـ Thought ممكن يكون مكتوب بمنطق جميل — وغلط. التفكير المكتوب بيحسّن الاحتمالات، مش بيضمن النتيجة. عشان كده الـ Evaluation لسه واجب، و Trace فيه تفكير مقنع محتاج مراجعة زي أي Trace تاني.
<!-- Field 21: Cost considerations -->
💸 التكلفة
كل Thought بيتحاسب مرتين: Output وقت كتابته، و Input في كل نداء بعده — لأن السياق بيتبعت كامل كل مرة. خلينا نحسبها على سؤال المخزون بتاعنا (3 دورات + إجابة):
> 💸 أرقام قابلة للتغير *(Volatile fragment — أسعار نموذجية للتوضيح؛ راجع أسعار مزوّدك الحالية)*: $3/مليون Input Token و $15/مليون Output Token.
| البند | الحساب | التكلفة |
|---|---|---|
| نداء مباشر واحد (لو المهمة كانت بسيطة) | Input 900 + Output 150 | ~$0.005 |
| ReAct بأربع نداءات | Input تراكمي: 900 + 1,150 + 1,400 + 1,650 ≈ 5,100 → $0.015؛ Output: 3 دورات × ~80 + إجابة ~150 ≈ 390 → $0.006 | ~$0.021 |
يعني ReAct هنا ≈ 4× تكلفة النداء الواحد. على 20,000 سؤال في الشهر: ~$420 بدل ~$105.
بس خد بالك من المقارنة الصح: المهمة المتعددة الخطوات مش بتتحل أصلًا بنداء واحد — يعني الـ 4× دي تمن إن الشغلانة تخلص، مش ترف. السؤال الهندسي الصحيح مش «ReAct غالي؟» — السؤال: «المهمة دي فعلًا محتاجة خطوات متعددة؟». لو لأ، ارجع للغلطة رقم 5 فوق.
<!-- Field 16: When to use it (Layer 7a) -->
- سؤال مركب من أجزاء: كل جزء محتاج Tool مختلف، والترتيب بيفرق.
- Tools بتعتمد على نتايج بعضها: ناتج البحث هو مدخل الاستعلام اللي بعده.
- بيئة نتايجها مش متوقعة: بحث ويب، APIs خارجية، بيانات ممكن تكون ناقصة — لازم حد «يقرا ويعدّل».
- عايز Traces مفهومة: تفكير مكتوب = Debugging أسهل بمراحل — بتشوف ليه الـ Agent اختار اللي اختاره.
<!-- Field 17: When NOT to use it (Layer 7b) -->
- Tool واحد واضح: «كام رصيد أجازاتي؟» = نداء واحد معروف. الـ Thought هنا Tokens على الفاضي — سيبك من المراسم.
- خطوات معروفة مسبقًا وثابتة: لو تقدر ترسم الـ Flow على ورقة قبل التشغيل، اعمل Workflow عادي — أرخص وأضمن وأسهل في الاختبار.
- زمن استجابة حرج: كل دورة ReAct = نداء LLM كامل. في مسار المستخدم الساخن، كل Thought بيتحس.
- مفيش Tools أصلًا: محادثة عادية أو توليد نص مباشر — مفيش Actions يبقى مفيش ReAct.
💡 نصيحة: القاعدة العملية: الخطوات بتتقرر حسب النتايج؟ ReAct. الخطوات معروفة قبل التشغيل؟ Workflow. مش عارف؟ ابدأ Workflow — وارجع للمفهوم «Agents vs. workflows vs. chains» لو اتلخبطت.
<!-- Field 23: Related concepts -->
- جوه BuildAI (بالترتيب): Planning intro ← Agent reliability ← Agent cost management.
- الورقة الأصلية: *"ReAct: Synergizing Reasoning and Acting in Language Models"* — Yao et al., 2022. اقراها كتاريخ الفكرة مش كدليل تنفيذ — كانت قبل الـ Tool Calling الـ Native، وهتلاحظ قد إيه الـ APIs الحالية بلعت النمط جواها.
<!-- Reading→building exit — single primary CTA per Phase 1 §6 -->