من الدردشة إلى القرار: بناء وكيل ذكاء اصطناعي محلي (AI Agent) ودمجه في CI/CD مع n8n

بدأت القصة بحوار شيق على LinkedIn مع المهندس محمد عبد الله، وهو مطور Back-end مصري موهوب. تحول نقاشنا التقني حول Laravel سريعاً إلى عالم الذكاء الاصطناعي والنماذج اللغوية الكبيرة (LLMs) التي أصبحت حديث الساعة. أثار محمد نقطة جوهرية حول استخدام “وكيل محلي” لاتخاذ القرارات، وهي الفكرة التي أشعلت حماسي لتوثيق هذه التجربة العملية في مقال تطبيقي.

التحول الحقيقي الذي نتحدث عنه ليس مجرد استخدام نموذج لغوي للدردشة، بل هو ترقية دوره ليصبح جزءاً فاعلاً في عملياتنا الهندسية. يحدث هذا التحول عندما يصبح النموذج:

قادراً على اتخاذ قرار ضمن سياق محدد.
يعمل داخل حلقة تحكم (Control Loop) مستمرة.
متصلاً بالأنظمة الفعلية التي نستخدمها يومياً.
مدمجاً في دورة حياة تطوير التطبيقات (CI/CD) كجزء لا يتجزأ منها.

في هذا المقال، سنبني معاً نظاماً حقيقياً (PoC) خطوة بخطوة، معتمدين على بيئة محلية معزولة. سنقوم ببناء:

  • وكيل ذكاء اصطناعي محلي (Local AI Agent) يعتمد على نموذج مثل LLaMA 3.
  • تصميم بسيط وفعال بدون استخدام أطر عمل معقدة مثل LangChain أو AutoGen.
  • وكيل يقتصر دوره على اتخاذ القرار فقط (Decision-only)، وليس التنفيذ.
  • ربط هذا الوكيل بمنصة الأتمتة الرائعة n8n ليعمل داخل CI/CD Pipeline حقيقي.

هيا بنا نبدأ رحلتنا لجعل عمليات الـ CI/CD أكثر ذكاءً وفعالية.

ما هو وكيل الذكاء الاصطناعي؟ (تعريف هندسي عملي)

بعيداً عن التعريفات التسويقية، يمكننا تعريف وكيل الذكاء الاصطناعي من منظور هندسي بمعادلة بسيطة وواضحة:

AI Agent = LLM + Memory + Decision Logic + Tools + Control Loop

لنفصل هذه المكونات:

  • LLM (النموذج اللغوي الكبير): هو العقل المفكر، مثل نماذج LLaMA, GPT, Claude، الذي يمتلك القدرة على فهم اللغة، التحليل، والاستنتاج.
  • Memory (الذاكرة): ذاكرة قصيرة أو طويلة الأمد لتذكر التفاعلات السابقة والنتائج. في مثالنا، ستكون الذاكرة هي سياق الأحداث الواردة من الـ CI، ولكن في أنظمة متقدمة يمكن أن تكون قاعدة بيانات Vector DB لتخزين التجارب السابقة.
  • Decision Logic (منطق القرار): القواعد والقيود التي يتبعها الوكيل لاتخاذ قراره. نحن نحدد هذا المنطق بدقة من خلال ما يعرف بـ “System Prompt”.
  • Tools (الأدوات): مجموعة الإجراءات التي يمكن للوكيل استخدامها (أو في حالتنا، اقتراح استخدامها). هذه الأدوات هي الأوامر والسكربتات الموجودة في بيئة الـ CI.
  • Control Loop (حلقة التحكم): الحلقة المستمرة التي يعمل ضمنها الوكيل: يستقبل حدثاً، يحلله، يقرر، ينتظر نتيجة القرار، ثم يستقبل الحدث التالي.

الفرق الجوهري: Chatbot مقابل Agent

الفكرة بسيطة لكنها أساسية لفهم تصميمنا. يمكن تلخيص الفرق في الجدول التالي:

المعيار Chatbot (المجيب) AI Agent (المقرِّر)
الوظيفة الأساسية الإجابة على أسئلة المستخدم. تحديد الخطوة التالية التي يجب أن يتخذها النظام.
طبيعة التفاعل تفاعلي (سؤال وجواب). استباقي (يحلل السياق ويقرر).
الناتج النهائي نص أو معلومات للمستخدم. قرار منظم (مثل JSON) لتوجيه النظام.
الهدف توفير المعرفة. تحقيق هدف أو إنجاز مهمة.

في تصميمنا، سنلتزم بمبدأ صارم: الوكيل لا يملك أي صلاحيات تنفيذية. التنفيذ يتم دائماً عبر طبقة منفصلة وموثوقة، وهي n8n و CI/CD Pipeline.

لماذا وكيل محلي (Local Agent) داخل الـ CI/CD؟

قد يسأل سائل: “لماذا كل هذه التعقيدات؟ لماذا لا أستخدم API جاهز من OpenAI أو Google؟” الجواب يكمن في مجموعة من الدوافع التقنية والمعمارية الحاسمة في بيئات الإنتاج.

دوافع تقنية واستراتيجية

  • تحكم كامل بالبيانات والخصوصية: عندما يعمل النموذج على خوادمك، لا يخرج أي كود مصدري أو بيانات حساسة من بيئتك. هذا الأمر غير قابل للتفاوض في الشركات التي تتعامل مع بيانات العملاء أو الملكية الفكرية.
  • زمن استجابة منخفض جدًا (Low Latency): لا يوجد اتصال عبر الإنترنت ولا انتظار في طوابير الـ API. القرار يصدر في أجزاء من الثانية، وهو أمر ضروري لـ CI/CD سريع وفعال.
  • تكلفة يمكن التنبؤ بها: أنت لا تدفع لكل طلب (Token). التكلفة ثابتة ومتمثلة في تشغيل الخادم، مما يمنع الفواتير المفاجئة ويجعل الميزانية واضحة.
  • لا تبعية لمزود خدمة (No Vendor Lock-in): أنت حر في تغيير النموذج، تحديثه، أو حتى تدريبه (Fine-tuning) دون أن تكون مقيدًا بسياسات وأسعار شركة معينة.

دوافع معمارية وهندسية

  • فصل القرار عن التنفيذ (Separation of Concerns): هذا هو المبدأ الذهبي في هندسة البرمجيات. الوكيل يقرر، والـ CI ينفذ. هذا الفصل يجعل النظام أكثر أمانًا، استقرارًا، وسهولة في الصيانة.
  • سهولة التدقيق والمراجعة (Auditing): كل قرار يصدر عن الوكيل هو كائن JSON واضح ومسجل. يمكنك بسهولة تتبع سلسلة القرارات وفهم “لماذا” تم اتخاذ إجراء معين، وهو أمر حيوي للمساءلة.
  • قابلية التوسع مستقبلًا (Scalability): هذا التصميم هو حجر الأساس لأنظمة أكثر تعقيدًا مثل أنظمة الوكلاء المتعددين (Multi-Agent Systems)، حيث يمكن لوكيل الـ CI/CD أن يتواصل مع وكلاء آخرين (وكيل اختبارات، وكيل أمان، إلخ).

المتطلبات الأساسية للبدء

قبل أن نبدأ في كتابة الكود، تأكد من وجود هذه الأدوات على جهازك:

  • نظام تشغيل Linux أو macOS (أو Windows مع WSL2).
  • Python 3.10 أو أحدث.
  • Docker و Docker Compose مثبتان ويعملان بشكل صحيح.
  • نموذج لغوي كبير يعمل محليًا. أوصي بشدة باستخدام Ollama لسهولة إعداده.

تشغيل النموذج محليًا (مثال مع Ollama)

Ollama هو أسهل طريقة لتشغيل نماذج مثل LLaMA على جهازك. بعد تثبيته، افتح الطرفية (Terminal) واكتب الأمر التالي لتحميل وتشغيل نموذج Llama 3 بحجم 8 مليار مُعامل (Quantized):

ollama run llama3:8b

بمجرد تشغيله، سيصبح النموذج متاحًا عبر واجهة برمجية (API) محلية على العنوان http://localhost:11434. هذا هو كل ما نحتاجه للتواصل معه.

المعمارية العامة للنظام

قبل الغوص في التفاصيل، من المهم أن نفهم الصورة الكبيرة. تدفق العمليات في نظامنا سيكون كالتالي:

  1. Git / CI Event: يبدأ التدفق عند وقوع حدث في نظام التحكم بالمصادر (مثل git push).
  2. n8n Webhook: يستقبل n8n الحدث عبر Webhook ويحصل على السياق الكامل (اسم المستودع، الفرع، نتائج الاختبارات، إلخ).
  3. Agent Gateway: يقوم n8n بإرسال هذا السياق إلى واجهة برمجية بسيطة (Gateway) مكتوبة بلغة Python.
  4. Local AI Agent: يقوم الـ Gateway بصياغة الطلب وإرساله إلى نموذج LLaMA المحلي الذي يعمل عبر Ollama.
  5. Decision (JSON): يعيد النموذج قراره على شكل كائن JSON منظم.
  6. n8n Logic: يستقبل n8n القرار، يفسره، ويوجه التدفق بناءً على قيمة القرار (e.g., deploy, block).
  7. Execution: يقوم n8n بتنفيذ الإجراء المناسب (نشر، التراجع، إرسال إشعار).

مبدأ التصميم الأساسي: جوهر الأمان

النموذج يقرر — ولا ينفذ.
The model decides — it does not execute.

هذا المبدأ ليس مجرد توصية، بل هو حجر الزاوية الذي يجعل هذا النظام آمنًا وقابلاً للاستخدام في بيئة الإنتاج. عندما تمنع النموذج من الوصول المباشر إلى Shell أو أي صلاحيات تنفيذية، فأنت تقضي على فئة كاملة من المخاطر الأمنية، وأشهرها هجمات حقن الأوامر (Prompt Injection) التي قد تؤدي إلى تنفيذ أوامر ضارة.

تصميم بروتوكول القرار (Communication Protocol)

لكي يفهم الوكيل ما نريده منه، ولكي نفهم نحن قراره، يجب أن نتفق على لغة مشتركة. هذه اللغة تتكون من جزأين: System Prompt و JSON Schema.

1. الـ System Prompt: دستور الوكيل

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

You are a CI decision agent. You act as a senior DevOps engineer reviewing a CI pipeline event.

Your rules are:
1. You DO NOT execute code or shell commands.
2. You NEVER suggest commands to run.
3. You analyze the context provided and make a single decision.
4. You respond ONLY in a strict JSON format, with no additional text, markdown, or explanations.

2. الـ JSON Schema: هيكل القرار

يجب أن نجبر النموذج على الرد بهيكل محدد وثابت. هذا يسهل على n8n تفسير القرار آليًا. في حالتنا، سنستخدم Schema بسيط وفعال:

{
  "action": "deploy | block | rollback | notify",
  "target": "staging | production | none",
  "reason": "A brief, human-readable explanation for the decision."
}
  • action: الإجراء الذي يوصي به الوكيل.
  • target: البيئة المستهدفة للإجراء.
  • reason: سبب اتخاذ هذا القرار، وهو مفيد جدًا للتدقيق والمراجعة البشرية.

بناء واجهة الوكيل (Agent Gateway): الكود الفعلي

الـ Gateway هو خادم ويب بسيط، وظيفته أن يكون الوسيط بين n8n والنموذج المحلي. سنبنيه باستخدام FastAPI في Python لسهولته وسرعته.

تثبيت المكتبات اللازمة

pip install fastapi "uvicorn[standard]" requests

كود الـ Gateway (ملف `agent_gateway.py`)

from fastapi import FastAPI, HTTPException
import requests
import json

# --- Configuration ---
OLLAMA_URL = "http://localhost:11434/api/generate"
MODEL_NAME = "llama3:8b"
SYSTEM_PROMPT = """
You are a CI decision agent. You act as a senior DevOps engineer reviewing a CI pipeline event.
Your rules are:
1. You DO NOT execute code or shell commands.
2. You NEVER suggest commands to run.
3. You analyze the context provided and make a single decision.
4. Your response MUST be ONLY a single, strict JSON object. Do not add any text before or after the JSON.
The JSON schema is: {"action": "deploy | block | rollback | notify", "target": "staging | production | none", "reason": "string"}
"""

# --- FastAPI App ---
app = FastAPI(
    title="CI Decision Agent Gateway",
    description="A gateway to a local LLM for CI/CD decision making."
)

@app.post("/decide")
def decide(payload: dict):
    """
    Receives CI context, asks the local LLM for a decision, and returns it.
    """
    try:
        # 1. Construct the full prompt
        full_prompt = f"{SYSTEM_PROMPT}\n\nContext:\n{json.dumps(payload, indent=2)}"

        # 2. Call the local Ollama model
        response = requests.post(
            OLLAMA_URL,
            json={
                "model": MODEL_NAME,
                "prompt": full_prompt,
                "stream": False,
                "format": "json"  # Important for models that support it (like Llama 3)
            },
            timeout=60  # Add a timeout for robustness
        )
        response.raise_for_status()

        # 3. Parse and clean the response
        raw_response_str = response.json()["response"]
        
        # The model sometimes wraps the JSON in markdown, let's be defensive
        if "```json" in raw_response_str:
            raw_response_str = raw_response_str.split("```json\n")[1].split("\n```")[0]
        
        decision = json.loads(raw_response_str.strip())

        # 4. Validate the decision structure (basic validation)
        if not all(k in decision for k in ["action", "target", "reason"]):
            raise ValueError("Invalid JSON structure in model response")

        return decision

    except requests.exceptions.RequestException as e:
        raise HTTPException(status_code=503, detail=f"Error communicating with Ollama: {e}")
    except (json.JSONDecodeError, ValueError) as e:
        raise HTTPException(status_code=500, detail=f"Error parsing or validating model response: {e}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {e}")

نصيحة احترافية: في بيئة الإنتاج، استخدم Pydantic في FastAPI لتعريف موديل للـ Payload الوارد والـ Response الخارج. هذا يوفر تحققًا تلقائيًا من صحة البيانات ويجعل الكود أكثر قوة وموثوقية.

تشغيل الـ Gateway

في الطرفية، ومن نفس المجلد الذي يحتوي على الملف، نفذ الأمر التالي:

uvicorn agent_gateway:app --host 0.0.0.0 --port 8000 --reload

الآن، أصبحت واجهة الوكيل جاهزة لاستقبال الطلبات على المنفذ 8000.

تشغيل n8n محليًا باستخدام Docker

n8n هي منصة أتمتة مفتوحة المصدر وقوية جدًا. سنستخدمها لتصميم تدفق العمل (Workflow). أسهل طريقة لتشغيلها هي عبر Docker:

docker run -it --rm --name n8n-ci-agent -p 5678:5678 -v ~/.n8n:/home/node/.n8n n8nio/n8n

بعد تنفيذ الأمر، افتح المتصفح على العنوان http://localhost:5678 وستجد واجهة n8n جاهزة للاستخدام.

إعداد تدفق العمل (Workflow) داخل n8n

الآن تبدأ المتعة الحقيقية. سنقوم ببناء الـ Workflow خطوة بخطوة.

  1. الخطوة 1: نقطة البداية (Webhook Trigger)

    أنشئ Workflow جديدًا وأضف عقدة (Node) من نوع Webhook. سيقوم n8n بإنشاء عنوان URL فريد لك. هذا هو العنوان الذي سيستدعيه نظام الـ CI/CD (مثل Jenkins, GitLab CI, GitHub Actions) عند وقوع حدث معين. لأغراض الاختبار، يمكنك استخدام `curl` لإرسال بيانات وهمية إلى هذا العنوان.

    مثال على Payload يمكن أن يرسله نظام الـ CI:

    curl -X POST http://localhost:5678/webhook/your-unique-path \
    -H "Content-Type: application/json" \
    -d '{
      "repo": "backend-api",
      "branch": "feature/new-login",
      "commit_hash": "a1b2c3d4",
      "tests_result": {
        "status": "passed",
        "coverage": "92.5"
      },
      "security_scan": {
        "vulnerabilities": 0
      },
      "deployment_target": "staging"
    }'
  2. الخطوة 2: إرسال السياق إلى الوكيل

    أضف عقدة جديدة من نوع HTTP Request وقم بإعدادها كالتالي:

    • URL: أدخل عنوان الـ Gateway: http://host.docker.internal:8000/decide. (نستخدم host.docker.internal للسماح لحاوية n8n بالوصول إلى خدمة تعمل على جهازك المضيف).
    • Method: POST.
    • Body Content Type: JSON.
    • JSON/RAW Parameters: في حقل الـ Body، استخدم تعبير n8n التالي لتمرير كل البيانات القادمة من الـ Webhook: {{ $json }}.
  3. الخطوة 3: تفسير وتوجيه القرار

    بعد أن ترجع عقدة الـ HTTP Request بقرار الوكيل، نحتاج للتصرف بناءً عليه. أضف عقدة Switch (أو IF إذا كانت الخيارات محدودة). قم بإعداد مسارات (Outputs) مختلفة بناءً على قيمة الحقل action في استجابة الوكيل.

    • المسار 1 (Deploy): الشرط {{ $json.action }} يساوي deploy.
    • المسار 2 (Block): الشرط {{ $json.action }} يساوي block.
    • المسار 3 (Rollback): الشرط {{ $json.action }} يساوي rollback.
    • وهكذا لبقية الإجراءات المحتملة.
  4. الخطوة 4: تنفيذ الأوامر

    من كل مخرج في عقدة الـ Switch، أضف العقدة التي تنفذ الإجراء الفعلي.

    • في مسار `deploy`: أضف عقدة Execute Command التي تنفذ سكربت النشر الخاص بك. مثال: ./deploy.sh {{ $json.target }}. لاحظ كيف نستخدم البيئة المستهدفة من قرار الوكيل.
    • في مسار `block`: أضف عقدة Slack أو Discord أو Email لإرسال إشعار فوري للفريق المسؤول، مع تضمين سبب الرفض {{ $json.reason }} في نص الرسالة.
    • في مسار `rollback`: أضف عقدة Execute Command أخرى لتشغيل سكربت التراجع.

لمسة احترافية: حلقة التغذية الراجعة (Feedback Loop)

لجعل نظامك يتعلم ويتحسن، لا تتوقف عند تنفيذ القرار. يجب أن تخبر الوكيل بنتيجة قراره. بعد تنفيذ أمر النشر (Deploy)، يمكنك إضافة خطوة أخرى في n8n:

  1. أضف عقدة HTTP Request أخرى لاستدعاء نقطة نهاية جديدة في الـ Gateway (مثلاً /feedback).
  2. أرسل payload يحتوي على القرار الأصلي ونتيجة التنفيذ الفعلية.
  3. في الـ Gateway، يمكنك تخزين هذه المعلومات في قاعدة بيانات بسيطة (مثل SQLite) أو حتى ملفات logs.

هذه البيانات الذهبية يمكن استخدامها لاحقًا لتحسين أداء الوكيل. على سبيل المثال، يمكن تعديل الـ System Prompt ليشمل أمثلة من القرارات الناجحة والفاشلة السابقة (Few-shot learning)، أو استخدام تقنية RAG (Retrieval-Augmented Generation) للبحث في تاريخ القرارات قبل اتخاذ قرار جديد.

لماذا لم نستخدم LangChain أو AutoGen؟

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

  • تعقيد غير ضروري (Over-engineering): هذه المكتبات مصممة لسيناريوهات معقدة ومتعددة الخطوات. لاستدعاء API بسيط، هي أشبه باستخدام “مدفع لقتل بعوضة”.
  • صعوبة التتبع والتصحيح (Debugging): عندما يحدث خطأ، قد يكون من الصعب جدًا تتبع مصدره داخل الطبقات العديدة التي تضيفها هذه الأطر (“Abstraction Hell”).
  • غير مناسبة لبيئة إنتاج حرجة مثل CI/CD: في الـ CI، أنت تريد تحكمًا كاملاً، وضوحًا مطلقًا، وأقل عدد ممكن من نقاط الفشل.

قناعتي الشخصية: وكيل حقيقي وجاهز للإنتاج يتطلب منطقًا واضحًا وتحكمًا كاملاً. بناء المكونات الأساسية بنفسك (مثل الـ Gateway) يمنحك هذا التحكم ويجعل النظام أكثر شفافية وموثوقية.

نتائج التجربة (PoC)

بعد بناء هذا النظام وتشغيله في بيئة محلية، كانت النتائج مشجعة جدًا:

  • قرارات منطقية: كان الوكيل قادرًا على اتخاذ قرارات منطقية بناءً على السياق (مثلاً، حظر النشر إذا فشلت الاختبارات، والسماح به إذا كانت الشروط مستوفاة).
  • استقرار عالي: بفضل فصل القرار عن التنفيذ، كان النظام مستقرًا. حتى لو فشل النموذج في توليد JSON صحيح، فإن الـ Gateway يعترض الخطأ، ويقوم n8n بإرسال إشعار بدلاً من تعطل الـ Pipeline.
  • زمن استجابة منخفض: كانت القرارات تصدر في غضون 1-3 ثوانٍ على جهاز MacBook Pro M1، وهو أداء ممتاز لبيئة CI/CD.
  • تكامل ممتاز: مرونة n8n سمحت بربط كل الأجزاء معًا بسهولة فائقة، مما يثبت أنها أداة مثالية لهذا النوع من الأتمتة.

الخلاصة: من الأتمتة إلى الذكاء

إن ربط وكيل ذكاء اصطناعي محلي بـ n8n داخل CI/CD ليس فكرة مستقبلية أو خيالًا علميًا، بل هو نمط معماري عملي وجاهز للتطبيق اليوم. هذا التحول ينقل الـ CI/CD من كونه مجرد سلسلة من الأوامر العمياء إلى نظام ذكي يساعد في اتخاذ القرارات بناءً على سياق غني.

عندما تقوم بالفصل الصارم بين:

  • القرار (مسؤولية الوكيل)
  • التنفيذ (مسؤولية n8n والـ CI)

فأنت تحصل على نظام يجمع أفضل ما في العالمين: نظام CI/CD أذكى وأكثر وعياً بالسياق، مع الحفاظ على أعلى درجات الأمان والموثوقية بفضل عزل الصلاحيات ووضوح المسؤوليات.

أتمنى أن يكون هذا المقال قد فتح شهيتكم لتجربة هذا النمط المعماري. ابدأ صغيرًا، ابنِ نموذجك الأولي (PoC)، وشاهد بنفسك كيف يمكن للذكاء الاصطناعي أن يحسن من عمليات التطوير في فريقك.

رسم بياني يوضح المعمارية العامة للنظام، يظهر تدفق البيانات من حدث Git إلى n8n ثم إلى Agent Gateway ومنه إلى النموذج المحلي، وعودة القرار إلى n8n لتنفيذ الإجراء. يجب أن يوضح الرسم مبدأ فصل القرار عن التنفيذ.
رسم بياني يوضح المعمارية العامة للنظام، يظهر تدفق البيانات من حدث Git إلى n8n ثم إلى Agent Gateway ومنه إلى النموذج المحلي، وعودة القرار إلى n8n لتنفيذ الإجراء. يجب أن يوضح الرسم مبدأ فصل القرار عن التنفيذ.
لقطة شاشة لواجهة n8n تظهر تدفق العمل (Workflow) الكامل، مع عقدة Webhook، وعقدة HTTP Request، وعقدة Switch، والعقد النهائية لتنفيذ الأوامر (مثل Execute Command و Slack).
لقطة شاشة لواجهة n8n تظهر تدفق العمل (Workflow) الكامل، مع عقدة Webhook، وعقدة HTTP Request، وعقدة Switch، والعقد النهائية لتنفيذ الأوامر (مثل Execute Command و Slack).
أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

أتمتة العمليات

قهوتك الصباحية مع ملخص الإنجازات: كيف تبني داشبورد يومي يصلك على الموبايل باستخدام n8n والذكاء الاصطناعي

كف عن تشتيت نفسك كل صباح بين Jira وGitHub والإيميلات. تعلم معي، أبو عمر، كيف تبني ورك فلو أتمتة يرسل لك ملخصاً ذكياً ومنسقاً بإنجازات...

12 فبراير، 2026 قراءة المزيد
البودكاست