একটি মাল্টি-এজেন্ট সিস্টেম তৈরি করা

১. ভূমিকা

সংক্ষিপ্ত বিবরণ

এই ল্যাবে, আপনি সাধারণ চ্যাটবটের গণ্ডি পেরিয়ে একটি ডিস্ট্রিবিউটেড মাল্টি-এজেন্ট সিস্টেম তৈরি করবেন।

যদিও একটিমাত্র এলএলএম ডিগ্রি দিয়ে বিভিন্ন প্রশ্নের উত্তর দেওয়া সম্ভব, বাস্তব জগতের জটিলতার জন্য প্রায়শই বিশেষায়িত ভূমিকার প্রয়োজন হয়। আপনি আপনার ব্যাকএন্ড ইঞ্জিনিয়ারকে ইউআই (UI) ডিজাইন করতে বলেন না, এবং আপনার ডিজাইনারকে ডাটাবেস কোয়েরি অপটিমাইজ করতেও বলেন না। একইভাবে, আমরা এমন বিশেষায়িত এআই এজেন্ট তৈরি করতে পারি, যারা একটি নির্দিষ্ট কাজে মনোনিবেশ করবে এবং জটিল সমস্যা সমাধানের জন্য একে অপরের সাথে সমন্বয় করবে।

আপনি একটি কোর্স তৈরির সিস্টেম তৈরি করবেন, যার মধ্যে থাকবে:

  1. গবেষক প্রতিনিধি : হালনাগাদ তথ্য খোঁজার জন্য google_search ব্যবহার করছেন।
  2. বিচারক প্রতিনিধি : গবেষণার গুণমান ও সম্পূর্ণতা যাচাই করা।
  3. কন্টেন্ট বিল্ডার এজেন্ট : গবেষণাকে একটি কাঠামোগত কোর্সে রূপান্তর করা।
  4. অর্কেস্ট্রেটর এজেন্ট : এই বিশেষজ্ঞদের মধ্যে কর্মপ্রবাহ এবং যোগাযোগ পরিচালনা করা।

পূর্বশর্ত

  • পাইথনের প্রাথমিক জ্ঞান।
  • গুগল ক্লাউড কনসোল সম্পর্কে পরিচিতি।

আপনি যা করবেন

  • এমন একটি টুল-ব্যবহারকারী এজেন্ট ( researcher ) সংজ্ঞায়িত করুন যা ওয়েব অনুসন্ধান করতে পারে।
  • judge জন্য পাইড্যান্টিক (Pydantic) ব্যবহার করে কাঠামোগত আউটপুট বাস্তবায়ন করুন।
  • এজেন্ট-টু-এজেন্ট (A2A) প্রোটোকল ব্যবহার করে রিমোট এজেন্টদের সাথে সংযোগ স্থাপন করুন।
  • গবেষক ও বিচারকের মধ্যে একটি ফিডব্যাক লুপ তৈরি করতে একটি LoopAgent নির্মাণ করুন।
  • ADK ব্যবহার করে ডিস্ট্রিবিউটেড সিস্টেমটি স্থানীয়ভাবে চালান।
  • মাল্টি-এজেন্ট সিস্টেমটি গুগল ক্লাউড রান- এ স্থাপন করুন।

স্থাপত্য ও অর্কেস্ট্রেশন নীতি

কোড লেখার আগে, চলুন বুঝে নিই এই এজেন্টগুলো কীভাবে একসাথে কাজ করে। আমরা একটি কোর্স তৈরির পাইপলাইন তৈরি করছি।

সিস্টেম ডিজাইন

স্থাপত্য ডায়াগ্রাম

এজেন্টদের সাথে সমন্বয় সাধন

সাধারণ এজেন্টরা (যেমন রিসার্চার) কাজ করে। অর্কেস্ট্রেটর এজেন্টরা (যেমন LoopAgent বা SequentialAgent ) অন্যান্য এজেন্টদের পরিচালনা করে। তাদের নিজস্ব কোনো টুল নেই; তাদের 'টুল' হলো দায়িত্ব অর্পণ।

  1. LoopAgent : এটি কোডের while লুপের মতো কাজ করে। এটি একটি শর্ত পূরণ না হওয়া পর্যন্ত (বা সর্বোচ্চ পুনরাবৃত্তি না হওয়া পর্যন্ত) ধারাবাহিকভাবে এজেন্টগুলোকে বারবার চালায়। আমরা এটি রিসার্চ লুপের জন্য ব্যবহার করি।
    • গবেষক তথ্য খুঁজে পান।
    • বিচারক এর সমালোচনা করেন।
    • Judge যদি "Fail" বলে, তাহলে EscalationChecker লুপটিকে চলতে দেয়।
    • যদি Judge "Pass" বলেন, তাহলে EscalationChecker লুপটি ভেঙে দেয়।
  2. SequentialAgent : এটি একটি সাধারণ স্ক্রিপ্ট এক্সিকিউশনের মতো কাজ করে। এটি এজেন্টগুলোকে একের পর এক চালায়। আমরা এটি হাই-লেভেল পাইপলাইনের জন্য ব্যবহার করি।
    • প্রথমে, রিসার্চ লুপটি চালান (যতক্ষণ না এটি ভালো ডেটা দিয়ে শেষ হয়)।
    • এরপর, কোর্সটি লেখার জন্য কন্টেন্ট বিল্ডারটি চালান।

এগুলোকে একত্রিত করে আমরা একটি শক্তিশালী সিস্টেম তৈরি করি যা চূড়ান্ত আউটপুট দেওয়ার আগে নিজেকে সংশোধন করতে পারে।

২. সেটআপ

পরিবেশ সেটআপ

  1. ক্লাউড শেল খুলুন : গুগল ক্লাউড কনসোলের উপরের ডানদিকে থাকা ‘অ্যাক্টিভেট ক্লাউড শেল’ আইকনটিতে ক্লিক করুন।

স্টার্টার কোডটি নিন

  1. স্টার্টার রিপোজিটরিটি আপনার হোম ডিরেক্টরিতে ক্লোন করুন:
    cd ~
    git clone --depth 1 --filter=blob:none --sparse https://github.com/GoogleCloudPlatform/devrel-demos.git temp-repo && cd temp-repo && git sparse-checkout set agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter && cd .. && mv temp-repo/agents/build-with-ai/production-ready-ai/prai-roadshow-lab-1-starter . && rm -rf temp-repo
    cd prai-roadshow-lab-1-starter
    
  2. এপিআই সক্রিয় করুন : প্রয়োজনীয় গুগল ক্লাউড পরিষেবাগুলি সক্রিয় করতে নিম্নলিখিত কমান্ডটি চালান:
    gcloud services enable \
        run.googleapis.com \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        aiplatform.googleapis.com \
        compute.googleapis.com
    
  3. আপনার এডিটরে এই ফোল্ডারটি খুলুন।

নির্ভরতা ইনস্টল করুন

দ্রুত ডিপেন্ডেন্সি ম্যানেজমেন্টের জন্য আমরা uv ব্যবহার করি।

  1. প্রজেক্টের নির্ভরতাগুলো ইনস্টল করুন:
    # Ensure you have uv installed: pip install uv
    uv sync
    
  2. এনভায়রনমেন্ট ভেরিয়েবল সেট করুন।
    • পরামর্শ : আপনি আপনার প্রজেক্ট আইডি ক্লাউড কনসোল ড্যাশবোর্ডে, অথবা gcloud config get-value project চালিয়ে খুঁজে নিতে পারেন।
    এই ভেরিয়েবলগুলো সংরক্ষণ করার জন্য আমরা একটি .env ফাইল তৈরি করব, যাতে আপনার সেশন সংযোগ বিচ্ছিন্ন হয়ে গেলে আপনি সহজেই সেগুলো পুনরায় লোড করতে পারেন।
    cat <<EOF > .env
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    EOF
    
  3. এনভায়রনমেন্ট ভেরিয়েবলগুলো সোর্স করুন:
    source .env
    
    সতর্কীকরণ: নতুন টার্মিনাল সেশনে এনভায়রনমেন্ট ভেরিয়েবলগুলো সংরক্ষিত থাকে না । আপনি যদি একটি নতুন টার্মিনাল ট্যাব খোলেন, তবে সেগুলো পুনরুদ্ধার করতে source .env চালান।

৩. 🕵️ গবেষক প্রতিনিধি

গবেষক এজেন্ট

গবেষক একজন বিশেষজ্ঞ। তার একমাত্র কাজ হলো তথ্য খুঁজে বের করা। এই কাজটি করার জন্য তার একটি টুলের প্রয়োজন: গুগল সার্চ।

গবেষককে কেন আলাদা করা হয়?

গভীর বিশ্লেষণ: কেন একজন এজেন্টকেই সবকিছু করতে দেওয়া হয় না?

ছোট ও সুনির্দিষ্ট এজেন্টগুলো মূল্যায়ন এবং ডিবাগ করা সহজ। গবেষণাটি খারাপ হলে, আপনি গবেষকের প্রম্পটটি নিয়ে কাজ করেন। কোর্সের ফরম্যাটিং খারাপ হলে, আপনি কন্টেন্ট বিল্ডারটি নিয়ে কাজ করেন। একটি একক, সবকিছু-করার প্রম্পটে, একটি জিনিস ঠিক করতে গেলে প্রায়শই অন্যটি ভেঙে যায়।

  1. আপনি যদি ক্লাউড শেলে কাজ করেন, তাহলে ক্লাউড শেল এডিটর খোলার জন্য নিম্নলিখিত কমান্ডটি চালান:
    cloudshell workspace .
    
    আপনি যদি আপনার স্থানীয় পরিবেশে কাজ করেন, তাহলে আপনার পছন্দের IDE খুলুন।
  2. agents/researcher/agent.py খুলুন।
  3. আপনি একটি করণীয় কাজসহ একটি কঙ্কাল দেখতে পাবেন।
  4. researcher এজেন্টকে সংজ্ঞায়িত করতে নিম্নলিখিত কোডটি যোগ করুন:
    # ... existing imports ...
    
    # Define the Researcher Agent
    researcher = Agent(
        name="researcher",
        model=MODEL,
        description="Gathers information on a topic using Google Search.",
        instruction="""
        You are an expert researcher. Your goal is to find comprehensive and accurate information on the user's topic.
        Use the `google_search` tool to find relevant information.
        Summarize your findings clearly.
        If you receive feedback that your research is insufficient, use the feedback to refine your next search.
        """,
        tools=[google_search],
    )
    
    root_agent = researcher
    

মূল ধারণা: সরঞ্জাম ব্যবহার

লক্ষ্য করুন, আমরা tools=[google_search] পাস করছি। ADK এই টুলটিকে LLM-এর কাছে বর্ণনা করার জটিলতা সামলে নেয়। যখন মডেলটি মনে করে যে তার তথ্যের প্রয়োজন, তখন এটি একটি স্ট্রাকচার্ড টুল কল তৈরি করে, ADK পাইথন ফাংশন google_search এক্সিকিউট করে এবং ফলাফলটি মডেলকে ফেরত পাঠায়।

৪. ⚖️ বিচারক এজেন্ট

বিচারক এজেন্ট

গবেষক কঠোর পরিশ্রম করেন, কিন্তু এলএলএম-রা অলস হতে পারে। কাজটি পর্যালোচনা করার জন্য আমাদের একজন বিচারক প্রয়োজন। বিচারক গবেষণাটি গ্রহণ করেন এবং একটি কাঠামোগত পাস/ফেল মূল্যায়নপত্র প্রদান করেন।

কাঠামোগত আউটপুট

গভীর বিশ্লেষণ: ওয়ার্কফ্লো স্বয়ংক্রিয় করতে আমাদের অনুমানযোগ্য আউটপুট প্রয়োজন। একটি অসংলগ্ন টেক্সট রিভিউ প্রোগ্রামগতভাবে বিশ্লেষণ করা কঠিন। পাইড্যান্টিক (Pydantic) ব্যবহার করে একটি JSON স্কিমা প্রয়োগের মাধ্যমে আমরা নিশ্চিত করি যে, জাজ (Judge) একটি বুলিয়ান pass বা fail রিটার্ন করবে, যার উপর ভিত্তি করে আমাদের কোড নির্ভরযোগ্যভাবে কাজ করতে পারবে।

  1. agents/judge/agent.py খুলুন।
  2. JudgeFeedback স্কিমা এবং judge এজেন্টকে সংজ্ঞায়িত করুন।
    # 1. Define the Schema
    class JudgeFeedback(BaseModel):
        """Structured feedback from the Judge agent."""
        status: Literal["pass", "fail"] = Field(
            description="Whether the research is sufficient ('pass') or needs more work ('fail')."
        )
        feedback: str = Field(
            description="Detailed feedback on what is missing. If 'pass', a brief confirmation."
        )
    
    # 2. Define the Agent
    judge = Agent(
        name="judge",
        model=MODEL,
        description="Evaluates research findings for completeness and accuracy.",
        instruction="""
        You are a strict editor.
        Evaluate the 'research_findings' against the user's original request.
        If the findings are missing key info, return status='fail'.
        If they are comprehensive, return status='pass'.
        """,
        output_schema=JudgeFeedback,
        # Disallow delegation because it should only output the schema
        disallow_transfer_to_parent=True,
        disallow_transfer_to_peers=True,
    )
    
    root_agent = judge
    

মূল ধারণা: এজেন্টের আচরণ সীমাবদ্ধ করা

আমরা disallow_transfer_to_parent=True এবং disallow_transfer_to_peers=True সেট করেছি। এটি Judge-কে শুধুমাত্র স্ট্রাকচার্ড JudgeFeedback ফেরত দিতে বাধ্য করে। এটি ব্যবহারকারীর সাথে "চ্যাট" করবে নাকি অন্য কোনো এজেন্টের কাছে দায়িত্ব অর্পণ করবে, সেই সিদ্ধান্ত নিতে পারে না। এটি আমাদের লজিক ফ্লো-তে এটিকে একটি ডিটারমিনিস্টিক কম্পোনেন্টে পরিণত করে।

৫. 🧪 বিচ্ছিন্নভাবে পরীক্ষা করা

সংযোগ করার আগে, আমরা যাচাই করে নিতে পারি যে প্রতিটি এজেন্ট কাজ করছে কিনা। ADK আপনাকে এজেন্টগুলোকে আলাদাভাবে চালানোর সুযোগ দেয়।

মূল ধারণা: ইন্টারেক্টিভ রানটাইম

adk run একটি হালকা পরিবেশ তৈরি করে যেখানে আপনিই 'ব্যবহারকারী'। এটি আপনাকে এজেন্টের নির্দেশাবলী এবং টুলের ব্যবহার আলাদাভাবে পরীক্ষা করার সুযোগ দেয়। যদি এজেন্ট এখানে ব্যর্থ হয় (যেমন, গুগল সার্চ ব্যবহার করতে না পারে), তবে এটি অর্কেস্ট্রেশনেও নিশ্চিতভাবে ব্যর্থ হবে।

  1. রিসার্চার-কে ইন্টারেক্টিভভাবে চালান। লক্ষ্য করুন, আমরা নির্দিষ্ট এজেন্ট ডিরেক্টরিটি নির্দেশ করছি:
    # This runs the researcher agent in interactive mode
    uv run adk run agents/researcher
    
  2. চ্যাট প্রম্পটে টাইপ করুন:
    Find the population of Tokyo in 2020
    
    এটি গুগল সার্চ টুল ব্যবহার করে উত্তরটি দেবে। দ্রষ্টব্য: যদি আপনি এমন কোনো ত্রুটি দেখতে পান যা নির্দেশ করে যে প্রজেক্ট, লোকেশন এবং ভার্টেক্সের ব্যবহার সেট করা নেই, তাহলে নিশ্চিত করুন যে আপনার প্রজেক্ট আইডি সেট করা আছে এবং নিম্নলিখিতটি সম্পাদন করুন:
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    
  3. চ্যাট থেকে বের হন (Ctrl+C)।
  4. বিচারককে ইন্টারেক্টিভভাবে চালান:
    uv run adk run agents/judge
    
  5. চ্যাট প্রম্পটে, নিম্নলিখিত ইনপুটটি অনুকরণ করুন:
    Topic: Tokyo. Findings: Tokyo is a city.
    
    এর status='fail' হওয়া উচিত , কারণ প্রাপ্ত ফলাফলগুলো খুবই সংক্ষিপ্ত।

৬. ✍️ কন্টেন্ট বিল্ডার এজেন্ট

কন্টেন্ট বিল্ডার

কন্টেন্ট বিল্ডার হলো সৃজনশীল লেখক। এটি অনুমোদিত গবেষণাকে একটি কোর্সে রূপান্তরিত করে।

  1. agents/content_builder/agent.py খুলুন।
  2. content_builder এজেন্টটি সংজ্ঞায়িত করুন।
    content_builder = Agent(
        name="content_builder",
        model=MODEL,
        description="Transforms research findings into a structured course.",
        instruction="""
        You are an expert course creator.
        Take the approved 'research_findings' and transform them into a well-structured, engaging course module.
    
        **Formatting Rules:**
        1. Start with a main title using a single `#` (H1).
        2. Use `##` (H2) for main section headings.
        3. Use bullet points and clear paragraphs.
        4. Maintain a professional but engaging tone.
    
        Ensure the content directly addresses the user's original request.
        """,
    )
    root_agent = content_builder
    

মূল ধারণা: প্রসঙ্গ প্রচার

আপনার মনে প্রশ্ন জাগতে পারে: "কন্টেন্ট বিল্ডার কীভাবে জানে যে রিসার্চার কী খুঁজে পেয়েছে?" ADK-তে, একটি পাইপলাইনের এজেন্টরা একটি session.state শেয়ার করে। পরবর্তীতে, অর্কেস্ট্রেটরে, আমরা রিসার্চার এবং জাজকে তাদের আউটপুট এই শেয়ার করা স্টেটে সংরক্ষণ করার জন্য কনফিগার করব। কন্টেন্ট বিল্ডারের প্রম্পট কার্যকরভাবে এই হিস্টোরিতে অ্যাক্সেস পায়।

৭. 🎻 দ্য অর্কেস্ট্রেটর

অর্কেস্ট্রেটর এজেন্ট

অর্কেস্ট্রেটর আমাদের একাধিক এজেন্টের দলের ব্যবস্থাপক। বিশেষজ্ঞ এজেন্টরা (গবেষক, বিচারক, কন্টেন্ট নির্মাতা) নির্দিষ্ট কাজ সম্পাদন করলেও, অর্কেস্ট্রেটরের কাজ হলো কর্মপ্রবাহের সমন্বয় সাধন করা এবং তাদের মধ্যে তথ্যের সঠিক প্রবাহ নিশ্চিত করা।

🌐 স্থাপত্য: এজেন্ট-টু-এজেন্ট (A2A)

এ২এ আর্কিটেকচার

এই ল্যাবে আমরা একটি ডিস্ট্রিবিউটেড সিস্টেম তৈরি করছি। সমস্ত এজেন্টকে একটিমাত্র পাইথন প্রসেসে চালানোর পরিবর্তে, আমরা সেগুলোকে স্বাধীন মাইক্রোসার্ভিস হিসেবে ডেপ্লয় করি। এর ফলে প্রতিটি এজেন্ট স্বাধীনভাবে স্কেল করতে পারে এবং পুরো সিস্টেম ক্র্যাশ না করেই ব্যর্থ হতে পারে।

এটি সম্ভব করার জন্য, আমরা এজেন্ট-টু-এজেন্ট (A2A) প্রোটোকল ব্যবহার করি।

A2A প্রোটোকল

বিস্তারিত: একটি প্রোডাকশন সিস্টেমে, এজেন্টরা বিভিন্ন সার্ভারে (বা এমনকি বিভিন্ন ক্লাউডে) চলে। A2A প্রোটোকল তাদের জন্য HTTP-এর মাধ্যমে একে অপরকে খুঁজে বের করা এবং যোগাযোগ করার একটি আদর্শ উপায় তৈরি করে। RemoteA2aAgent হলো এই প্রোটোকলের জন্য ADK ক্লায়েন্ট।

  1. agents/orchestrator/agent.py খুলুন।
  2. # TODO: Define connections to remote agents কমেন্টটি অথবা রিমোট এজেন্ট ডেফিনিশন সেকশনটি খুঁজুন।
  3. কানেকশনগুলো নির্ধারণ করতে নিম্নলিখিত কোডটি যোগ করুন। খেয়াল রাখবেন যেন এটি ইম্পোর্টগুলোর পরে এবং অন্য যেকোনো এজেন্ট ডেফিনিশনের আগে থাকে।
    # ... existing code ...
    
    # Connect to the Researcher (Localhost port 8001)
    researcher_url = os.environ.get("RESEARCHER_AGENT_CARD_URL", "http://localhost:8001/a2a/agent/.well-known/agent-card.json")
    researcher = RemoteA2aAgent(
        name="researcher",
        agent_card=researcher_url,
        description="Gathers information using Google Search.",
        # IMPORTANT: Save the output to state for the Judge to see
        after_agent_callback=create_save_output_callback("research_findings"),
        # IMPORTANT: Use authenticated client for communication
        httpx_client=create_authenticated_client(researcher_url)
    )
    
    # Connect to the Judge (Localhost port 8002)
    judge_url = os.environ.get("JUDGE_AGENT_CARD_URL", "http://localhost:8002/a2a/agent/.well-known/agent-card.json")
    judge = RemoteA2aAgent(
        name="judge",
        agent_card=judge_url,
        description="Evaluates research.",
        after_agent_callback=create_save_output_callback("judge_feedback"),
        httpx_client=create_authenticated_client(judge_url)
    )
    
    # Content Builder (Localhost port 8003)
    content_builder_url = os.environ.get("CONTENT_BUILDER_AGENT_CARD_URL", "http://localhost:8003/a2a/agent/.well-known/agent-card.json")
    content_builder = RemoteA2aAgent(
        name="content_builder",
        agent_card=content_builder_url,
        description="Builds the course.",
        httpx_client=create_authenticated_client(content_builder_url)
    )
    

৮. 🛑 এস্কেলেশন চেকার

একটি লুপ থামার জন্য একটি উপায় প্রয়োজন। যদি জাজ "পাস" বলেন, আমরা অবিলম্বে লুপ থেকে বেরিয়ে কন্টেন্ট বিল্ডারে যেতে চাই।

BaseAgent সহ কাস্টম লজিক

গভীর বিশ্লেষণ: সব এজেন্ট LLM ব্যবহার করে না। কখনও কখনও আপনার সাধারণ পাইথন লজিকের প্রয়োজন হয়। BaseAgent আপনাকে এমন একটি এজেন্ট সংজ্ঞায়িত করার সুযোগ দেয় যা শুধু কোড চালায়। এক্ষেত্রে, আমরা সেশনের অবস্থা পরীক্ষা করি এবং LoopAgent থামার সংকেত দিতে EventActions(escalate=True) ব্যবহার করি।

  1. এখনও agents/orchestrator/agent.py ফাইলে আছে।
  2. EscalationChecker TODO প্লেসহোল্ডারটি খুঁজুন।
  3. এটিকে নিম্নলিখিত বাস্তবায়ন দ্বারা প্রতিস্থাপন করুন :
    class EscalationChecker(BaseAgent):
        """Checks the judge's feedback and escalates (breaks the loop) if it passed."""
    
        async def _run_async_impl(
            self, ctx: InvocationContext
        ) -> AsyncGenerator[Event, None]:
            # Retrieve the feedback saved by the Judge
            feedback = ctx.session.state.get("judge_feedback")
            print(f"[EscalationChecker] Feedback: {feedback}")
    
            # Check for 'pass' status
            is_pass = False
            if isinstance(feedback, dict) and feedback.get("status") == "pass":
                is_pass = True
            # Handle string fallback if JSON parsing failed
            elif isinstance(feedback, str) and '"status": "pass"' in feedback:
                is_pass = True
    
            if is_pass:
                # 'escalate=True' tells the parent LoopAgent to stop looping
                yield Event(author=self.name, actions=EventActions(escalate=True))
            else:
                # Continue the loop
                yield Event(author=self.name)
    
    escalation_checker = EscalationChecker(name="escalation_checker")
    

মূল ধারণা: ইভেন্টের মাধ্যমে নিয়ন্ত্রণ প্রবাহ

এজেন্টরা শুধু টেক্সটের মাধ্যমেই নয়, ইভেন্টের মাধ্যমেও যোগাযোগ করে। escalate=True সহ একটি ইভেন্ট ইয়েল্ড করার মাধ্যমে, এই এজেন্ট তার প্যারেন্টের ( LoopAgent ) কাছে একটি সিগন্যাল পাঠায়। LoopAgent এই সিগন্যালটি গ্রহণ করে লুপটি বন্ধ করে দেওয়ার জন্য প্রোগ্রাম করা থাকে।

৯. 🔁 গবেষণা চক্র

গবেষণা চক্র

আমাদের একটি ফিডব্যাক লুপ প্রয়োজন: গবেষণা -> বিচার -> (ব্যর্থতা) -> গবেষণা -> ...

  1. এখনও agents/orchestrator/agent.py ফাইলে আছে।
  2. research_loop ডেফিনিশনটি যোগ করুন। এটিকে EscalationChecker ক্লাস এবং escalation_checker ইনস্ট্যান্সের পরে রাখুন।
    research_loop = LoopAgent(
        name="research_loop",
        description="Iteratively researches and judges until quality standards are met.",
        sub_agents=[researcher, judge, escalation_checker],
        max_iterations=3,
    )
    

মূল ধারণা: লুপএজেন্ট

LoopAgent তার sub_agents ক্রমানুসারে আবর্তন করে।

  1. researcher : তথ্য খুঁজে বের করেন।
  2. judge : তথ্য মূল্যায়ন করেন।
  3. escalation_checker : yield Event(escalate=True) কিনা তা নির্ধারণ করে। যদি escalate=True ঘটে, তাহলে লুপটি সময়ের আগেই থেমে যায়। অন্যথায়, এটি researcher থেকে পুনরায় শুরু হয় ( max_iterations পর্যন্ত)।

১০. 🔗 চূড়ান্ত পাইপলাইন

চূড়ান্ত পাইপলাইন

সবশেষে, সবকিছু একসাথে সেলাই করে দিন।

  1. এখনও agents/orchestrator/agent.py ফাইলে আছে।
  2. ফাইলের একদম শেষে root_agent নির্ধারণ করুন। নিশ্চিত করুন যে এটি বিদ্যমান root_agent = None প্লেসহোল্ডারকে প্রতিস্থাপন করে।
    root_agent = SequentialAgent(
        name="course_creation_pipeline",
        description="A pipeline that researches a topic and then builds a course from it.",
        sub_agents=[research_loop, content_builder],
    )
    

মূল ধারণা: স্তরক্রমিক গঠন

লক্ষ্য করুন যে research_loop নিজেই একটি এজেন্ট (একটি LoopAgent )। আমরা এটিকে SequentialAgent এর অন্য যেকোনো সাব-এজেন্টের মতোই বিবেচনা করি। এই কম্পোজেবিলিটি আপনাকে সাধারণ প্যাটার্নগুলোকে নেস্ট করার মাধ্যমে জটিল লজিক তৈরি করতে সাহায্য করে (যেমন সিকোয়েন্সের ভেতরে লুপ, রাউটারের ভেতরে সিকোয়েন্স ইত্যাদি)।

১১. 💻 স্থানীয়ভাবে দৌড়ান

সবকিছু চালানোর আগে, চলুন দেখে নেওয়া যাক ADK কীভাবে স্থানীয়ভাবে ডিস্ট্রিবিউটেড এনভায়রনমেন্টকে সিমুলেট করে।

গভীর বিশ্লেষণ: স্থানীয় উন্নয়ন কীভাবে কাজ করে

মাইক্রোসার্ভিসেস আর্কিটেকচারে, প্রতিটি এজেন্ট তার নিজস্ব সার্ভার হিসেবে চলে। যখন আপনি ডিপ্লয় করবেন, তখন আপনার ৪টি ভিন্ন ক্লাউড রান সার্ভিস থাকবে। স্থানীয়ভাবে এর অনুকরণ করা কষ্টকর হতে পারে, যদি আপনাকে ৪টি টার্মিনাল ট্যাব খুলে ৪টি কমান্ড চালাতে হয়।

এই স্ক্রিপ্টটি রিসার্চার (পোর্ট 8001), জাজ (8002), এবং কন্টেন্ট বিল্ডার (8003)-এর জন্য uvicorn প্রসেসগুলো চালু করে। এটি RESEARCHER_AGENT_CARD_URL এর মতো এনভায়রনমেন্ট ভেরিয়েবল সেট করে এবং সেগুলোকে অর্কেস্ট্রেটর (পোর্ট 8004)-এর কাছে পাঠিয়ে দেয়। পরবর্তীতে আমরা ক্লাউডে ঠিক এভাবেই এটি কনফিগার করব!

অ্যাপ চলছে

  1. অর্কেস্ট্রেশন স্ক্রিপ্টটি চালান:
    ./run_local.sh
    
    এটি ৪টি পৃথক প্রক্রিয়া শুরু করে।
  2. এটি পরীক্ষা করুন:
    • ক্লাউড শেল ব্যবহার করলে: ওয়েব প্রিভিউ বাটনে (টার্মিনালের উপরের ডানদিকে) ক্লিক করুন -> পোর্ট ৮০৮০-তে প্রিভিউ করুন -> পোর্ট পরিবর্তন করে 8000 করুন।
    • স্থানীয়ভাবে চালালে: আপনার ব্রাউজারে http://localhost:8000 খুলুন।
    • নির্দেশনা: "কফির ইতিহাস নিয়ে একটি কোর্স তৈরি করুন।"
    • লক্ষ্য করুন: অর্কেস্ট্রেটর গবেষককে ডাকবে। এর আউটপুট বিচারকের কাছে যাবে। যদি বিচারক এতে ব্যর্থ হন, তবে চক্রটি চলতে থাকবে!
    সমস্যা সমাধান:
    • "অভ্যন্তরীণ সার্ভার ত্রুটি" / প্রমাণীকরণ ত্রুটি: আপনি যদি প্রমাণীকরণ ত্রুটি (যেমন, google-auth সম্পর্কিত) দেখতে পান, তাহলে স্থানীয় মেশিনে চালালে নিশ্চিত করুন যে আপনি gcloud auth application-default login চালিয়েছেন। ক্লাউড শেলে, নিশ্চিত করুন যে আপনার GOOGLE_CLOUD_PROJECT এনভায়রনমেন্ট ভেরিয়েবলটি সঠিকভাবে সেট করা আছে।
    • টার্মিনাল ত্রুটি: যদি একটি নতুন টার্মিনাল উইন্ডোতে কমান্ডটি ব্যর্থ হয়, তাহলে আপনার এনভায়রনমেন্ট ভেরিয়েবলগুলো (যেমন GOOGLE_CLOUD_PROJECT ) পুনরায় এক্সপোর্ট করতে মনে রাখবেন।
  3. বিচ্ছিন্নভাবে এজেন্ট পরীক্ষা করা: সম্পূর্ণ সিস্টেম চালু থাকা অবস্থাতেও, আপনি সরাসরি নির্দিষ্ট এজেন্টের পোর্ট টার্গেট করে তা পরীক্ষা করতে পারেন। পুরো চেইনটি চালু না করেই কোনো নির্দিষ্ট কম্পোনেন্ট ডিবাগ করার জন্য এটি কার্যকর। দ্রষ্টব্য: এগুলো এপিআই এন্ডপয়েন্ট, ওয়েব পেজ নয়। আপনি ব্রাউজারের মাধ্যমে এগুলো অ্যাক্সেস করতে পারবেন না। এর পরিবর্তে, এগুলো চালু আছে কিনা তা যাচাই করতে curl ব্যবহার করুন (যেমন, তাদের এজেন্ট কার্ড ফেচ করে)।
    • শুধুমাত্র গবেষকদের জন্য (পোর্ট ৮০০১):
      • স্ট্যাটাস চেক করুন (এবং url এন্ডপয়েন্টটি খুঁজুন):
        curl http://localhost:8001/a2a/agent/.well-known/agent-card.json
        
      • একটি কোয়েরি পাঠান (A2A JSON-RPC প্রোটোকল ব্যবহার করে):
        curl -X POST http://localhost:8001/a2a/agent \
          -H "Content-Type: application/json" \
          -d '{
            "jsonrpc": "2.0",
            "method": "message/send",
            "id": 1,
            "params": {
              "message": {
                "message_id": "test-1",
                "role": "user",
                "parts": [
                  {
                    "text": "What is the capital of France?",
                    "kind": "text"
                  }
                ]
              }
            }
          }'
        
    • শুধুমাত্র বিচারক (পোর্ট ৮০০২):
      • অবস্থা যাচাই করুন:
        curl http://localhost:8002/a2a/agent/.well-known/agent-card.json
        
      • একটি প্রশ্ন পাঠান:
        curl -X POST http://localhost:8002/a2a/agent \
          -H "Content-Type: application/json" \
          -d '{
            "jsonrpc": "2.0",
            "method": "message/send",
            "id": 1,
            "params": {
              "message": {
                "message_id": "test-2",
                "role": "user",
                "parts": [
                  {
                    "text": "Topic: Tokyo. Findings: Tokyo is the capital of Japan.",
                    "kind": "text"
                  }
                ]
              }
            }
          }'
        
    • শুধুমাত্র কন্টেন্ট বিল্ডারের জন্য (পোর্ট ৮০০৩):
      curl http://localhost:8003/a2a/agent/.well-known/agent-card.json
      
    • অর্কেস্ট্রেটর (পোর্ট ৮০০৪):
      curl http://localhost:8004/a2a/agent/.well-known/agent-card.json
      

১২. 🚀 ক্লাউড রান-এ ডিপ্লয় করুন

চূড়ান্ত যাচাইকরণটি ক্লাউডে চলছে। আমরা প্রতিটি এজেন্টকে একটি পৃথক পরিষেবা হিসাবে স্থাপন করব।

ডেপ্লয়মেন্ট কনফিগারেশন বোঝা

ক্লাউড রান-এ এজেন্ট স্থাপন করার সময়, আমরা তাদের আচরণ ও সংযোগ কনফিগার করার জন্য বেশ কিছু এনভায়রনমেন্ট ভেরিয়েবল পাস করি:

  • GOOGLE_CLOUD_PROJECT : এটি নিশ্চিত করে যে এজেন্ট লগিং এবং ভার্টেক্স এআই কলের জন্য সঠিক গুগল ক্লাউড প্রজেক্ট ব্যবহার করছে।
  • GOOGLE_GENAI_USE_VERTEXAI : এজেন্ট ফ্রেমওয়ার্ককে (ADK) নির্দেশ দেয় যেন এটি সরাসরি জেমিনি এপিআই (Gemini APIs) কল করার পরিবর্তে মডেল ইনফারেন্সের জন্য ভার্টেক্স এআই (Vertex AI) ব্যবহার করে।
  • [AGENT]_AGENT_CARD_URL : এটি অর্কেস্ট্রেটরের জন্য অত্যন্ত গুরুত্বপূর্ণ। এটি অর্কেস্ট্রেটরকে বলে দেয় যে রিমোট এজেন্টদের কোথায় খুঁজে পাওয়া যাবে। এটিকে ডেপ্লয় করা ক্লাউড রান ইউআরএল-এ (বিশেষত এজেন্ট কার্ড পাথে) সেট করার মাধ্যমে, আমরা অর্কেস্ট্রেটরকে ইন্টারনেটের মাধ্যমে রিসার্চার, জাজ এবং কন্টেন্ট বিল্ডারকে খুঁজে বের করতে ও তাদের সাথে যোগাযোগ করতে সক্ষম করি।
  1. সাব-এজেন্টগুলো স্থাপন করুন (সমান্তরালভাবে): সময় বাঁচাতে, আমরা রিসার্চার, জাজ এবং কন্টেন্ট বিল্ডারকে একই সাথে স্থাপন করব। তিনটি নতুন টার্মিনাল ট্যাব খুলুন। প্রতিটি নতুন ট্যাবে, আপনার পরিবেশ সেটআপ করার জন্য নিম্নলিখিত কমান্ডটি চালান:
    cd ~/prai-roadshow-lab-1-starter
    source .env
    
    ট্যাব ১: গবেষক ডেপ্লয়মেন্টটি চালান:
    gcloud run deploy researcher \
      --source agents/researcher/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    ট্যাব ২: জাজ ডেপ্লয়মেন্টটি চালান:
    gcloud run deploy judge \
      --source agents/judge/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    ট্যাব ৩: কন্টেন্ট বিল্ডার ডেপ্লয়মেন্টটি চালান:
    gcloud run deploy content-builder \
      --source agents/content_builder/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
  2. URL-গুলো ক্যাপচার করুন: তিনটি ডেপ্লয়মেন্টই সম্পন্ন হয়ে গেলে, আপনার মূল টার্মিনালে ফিরে যান (যেখানে আপনি অর্কেস্ট্রেটর ডেপ্লয় করবেন)। সার্ভিস URL-গুলো ক্যাপচার করতে নিম্নলিখিত কমান্ডগুলো চালান:
    RESEARCHER_URL=$(gcloud run services describe researcher --region us-central1 --format='value(status.url)')
    JUDGE_URL=$(gcloud run services describe judge --region us-central1 --format='value(status.url)')
    CONTENT_BUILDER_URL=$(gcloud run services describe content-builder --region us-central1 --format='value(status.url)')
    
    echo "Researcher: $RESEARCHER_URL"
    echo "Judge: $JUDGE_URL"
    echo "Content Builder: $CONTENT_BUILDER_URL"
    
  3. অর্কেস্ট্রেটর স্থাপন করুন: অর্কেস্ট্রেটর কনফিগার করতে সংগৃহীত এনভায়রনমেন্ট ভেরিয়েবলগুলো ব্যবহার করুন।
    gcloud run deploy orchestrator \
      --source agents/orchestrator/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars RESEARCHER_AGENT_CARD_URL=$RESEARCHER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars JUDGE_AGENT_CARD_URL=$JUDGE_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars CONTENT_BUILDER_AGENT_CARD_URL=$CONTENT_BUILDER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    URL-টি ক্যাপচার করুন:
    ORCHESTRATOR_URL=$(gcloud run services describe orchestrator --region us-central1 --format='value(status.url)')
    echo $ORCHESTRATOR_URL
    
  4. ফ্রন্টএন্ড স্থাপন করুন:
    gcloud run deploy course-creator \
        --source app \
        --region us-central1 \
        --allow-unauthenticated \
        --labels dev-tutorial=prod-ready-1 \
        --set-env-vars AGENT_SERVER_URL=$ORCHESTRATOR_URL \
        --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT
    
  5. রিমোট ডেপ্লয়মেন্ট পরীক্ষা করুন: আপনার ডেপ্লয় করা অর্কেস্ট্রেটরের URL খুলুন। এটি এখন সম্পূর্ণরূপে ক্লাউডে চলছে এবং আপনার এজেন্টদের স্কেল করার জন্য গুগলের সার্ভারলেস পরিকাঠামো ব্যবহার করছে! ইঙ্গিত : আপনি ক্লাউড রান ইন্টারফেসে সমস্ত মাইক্রো-সার্ভিস এবং তাদের URL খুঁজে পাবেন।

১৩. সারসংক্ষেপ

অভিনন্দন! আপনি সফলভাবে একটি প্রোডাকশন-রেডি, ডিস্ট্রিবিউটেড মাল্টি-এজেন্ট সিস্টেম তৈরি এবং স্থাপন করেছেন।

আমরা যা অর্জন করেছি

  • জটিল কাজকে খণ্ডিত করা : একটি বিশাল নির্দেশনার পরিবর্তে, আমরা কাজটিকে বিশেষায়িত ভূমিকায় (গবেষক, বিচারক, বিষয়বস্তু নির্মাতা) ভাগ করেছি।
  • বাস্তবায়িত গুণমান নিয়ন্ত্রণ : শুধুমাত্র উচ্চ-মানের তথ্যই যেন চূড়ান্ত ধাপে পৌঁছায়, তা নিশ্চিত করতে আমরা একটি LoopAgent এবং একটি কাঠামোগত Judge ব্যবহার করেছি।
  • প্রোডাকশনের জন্য নির্মিত : এজেন্ট-টু-এজেন্ট (A2A) প্রোটোকল এবং ক্লাউড রান ব্যবহার করে, আমরা এমন একটি সিস্টেম তৈরি করেছি যেখানে প্রতিটি এজেন্ট একটি স্বাধীন, স্কেলেবল মাইক্রোসার্ভিস। একটিমাত্র পাইথন স্ক্রিপ্টে সবকিছু চালানোর চেয়ে এটি অনেক বেশি শক্তিশালী।
  • সমন্বয় : আমরা সুস্পষ্ট নিয়ন্ত্রণ প্রবাহের ধরণ নির্ধারণ করতে SequentialAgent এবং LoopAgent ব্যবহার করেছি।

পরবর্তী পদক্ষেপ

এখন যেহেতু আপনার ভিত্তি তৈরি হয়ে গেছে, আপনি এই সিস্টেমটিকে আরও প্রসারিত করতে পারেন:

  • আরও টুল যোগ করুন : গবেষককে অভ্যন্তরীণ নথি বা এপিআই (API)-তে অ্যাক্সেস দিন।
  • বিচারককে উন্নত করুন : আরও সুনির্দিষ্ট মানদণ্ড অথবা এমনকি একটি 'হিউম্যান ইন দ্য লুপ' ধাপ যোগ করুন।
  • মডেল অদলবদল করুন : বিভিন্ন এজেন্টের জন্য ভিন্ন ভিন্ন মডেল ব্যবহার করে দেখুন (যেমন, বিচারকের জন্য একটি দ্রুততর মডেল, কন্টেন্ট রাইটারের জন্য একটি শক্তিশালী মডেল)।

আপনি এখন গুগল ক্লাউডে জটিল ও নির্ভরযোগ্য এজেন্টিক ওয়ার্কফ্লো তৈরি করতে প্রস্তুত!