চিন্তা মোড সহ ADK, MCP, এবং Gemini 2.5 Flash ব্যবহার করে QA টেস্ট প্ল্যানার এজেন্ট তৈরি করুন

১. ভূমিকা

782957a0266b13f6.png

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

এই কোডল্যাবে আমরা দেখব কীভাবে এমন একটি এজেন্ট তৈরি করা যায়, যা কনফ্লুয়েন্স থেকে প্রোডাক্ট রিকোয়ারমেন্টস ডকুমেন্ট সংগ্রহ করতে পারবে, গঠনমূলক মতামত দিতে পারবে এবং একটি বিস্তারিত টেস্ট প্ল্যান তৈরি করতে পারবে যা একটি CSV ফাইলে এক্সপোর্ট করা যাবে।

কোডল্যাবের মাধ্যমে, আপনি নিম্নলিখিত ধাপে ধাপে পদ্ধতিটি অনুসরণ করবেন:

  1. আপনার গুগল ক্লাউড প্রজেক্টটি প্রস্তুত করুন এবং এতে প্রয়োজনীয় সকল এপিআই (API) সক্রিয় করুন।
  2. আপনার কোডিং পরিবেশের জন্য কর্মক্ষেত্র প্রস্তুত করুন।
  3. কনফ্লুয়েন্সের জন্য স্থানীয় এমসিপি-সার্ভার প্রস্তুত করা হচ্ছে
  4. MCP সার্ভারে সংযোগ করার জন্য ADK এজেন্ট সোর্স কোড, প্রম্পট এবং টুলসের কাঠামো তৈরি করা।
  5. আর্টিফ্যাক্ট সার্ভিস এবং টুল কনটেক্সটের ব্যবহার বোঝা
  6. ADK লোকাল ওয়েব ডেভেলপমেন্ট UI ব্যবহার করে এজেন্টটি পরীক্ষা করা হচ্ছে
  7. ক্লাউড রানে অ্যাপ্লিকেশনটি ডেপ্লয় করার জন্য প্রয়োজনীয় এনভায়রনমেন্ট ভেরিয়েবল ও ফাইলগুলো সেটআপ করুন।
  8. অ্যাপ্লিকেশনটি ক্লাউড রানে স্থাপন করুন

স্থাপত্যের সংক্ষিপ্ত বিবরণ

af793beb2740233.jpeg

পূর্বশর্ত

  • পাইথন নিয়ে কাজ করতে স্বাচ্ছন্দ্যবোধ করি।
  • HTTP পরিষেবা ব্যবহার করে মৌলিক ফুল-স্ট্যাক আর্কিটেকচার সম্পর্কে ধারণা

আপনি যা শিখবেন

  • ADK এজেন্টের বিভিন্ন ক্ষমতা ব্যবহার করে এর স্থাপত্য নির্মাণ
  • কাস্টম টুল এবং এমসিপি-এর সাথে টুলের ব্যবহার
  • আর্টিফ্যাক্ট সার্ভিস ম্যানেজমেন্ট ব্যবহার করে এজেন্টের মাধ্যমে ফাইল আউটপুট সেট আপ করা
  • জেমিনি ২.৫ ফ্ল্যাশ থিঙ্কিং ক্যাপাবিলিটি ব্যবহার করে পরিকল্পনা করার মাধ্যমে বিল্টইনপ্ল্যানার দ্বারা কাজের সম্পাদন উন্নত করা।
  • ADK ওয়েব ইন্টারফেসের মাধ্যমে মিথস্ক্রিয়া এবং ডিবাগিং
  • Dockerfile ব্যবহার করে অ্যাপ্লিকেশনটি Cloud Run-এ ডেপ্লয় করুন এবং এনভায়রনমেন্ট ভেরিয়েবল সরবরাহ করুন।

আপনার যা যা লাগবে

  • ক্রোম ওয়েব ব্রাউজার
  • একটি জিমেইল অ্যাকাউন্ট
  • বিলিং সক্ষম একটি ক্লাউড প্রজেক্ট
  • (ঐচ্ছিক) প্রোডাক্ট রিকোয়ারমেন্ট ডকুমেন্টস পৃষ্ঠা(গুলি) সহ কনফ্লুয়েন্স স্পেস

সকল স্তরের (শিক্ষানবিশ সহ) ডেভেলপারদের জন্য ডিজাইন করা এই কোডল্যাবটির নমুনা অ্যাপ্লিকেশনে পাইথন ব্যবহার করা হয়েছে। তবে, এখানে উপস্থাপিত ধারণাগুলো বোঝার জন্য পাইথন জ্ঞান থাকা আবশ্যক নয়। আপনার কনফ্লুয়েন্স স্পেস না থাকলেও চিন্তার কোনো কারণ নেই, এই কোডল্যাবটি চেষ্টা করার জন্য আমরা ক্রেডেনশিয়াল সরবরাহ করব।

২. শুরু করার আগে

ক্লাউড কনসোলে সক্রিয় প্রজেক্ট নির্বাচন করুন

এই কোডল্যাবটি ধরে নেয় যে আপনার ইতিমধ্যেই বিলিং চালু করা একটি গুগল ক্লাউড প্রজেক্ট আছে। যদি আপনার এটি এখনও না থাকে, তবে শুরু করার জন্য আপনি নীচের নির্দেশাবলী অনুসরণ করতে পারেন।

  1. গুগল ক্লাউড কনসোলের প্রজেক্ট সিলেক্টর পেজে, একটি গুগল ক্লাউড প্রজেক্ট নির্বাচন করুন বা তৈরি করুন।
  2. আপনার ক্লাউড প্রোজেক্টের জন্য বিলিং চালু আছে কিনা তা নিশ্চিত করুন। কোনো প্রোজেক্টে বিলিং চালু আছে কিনা তা কীভাবে পরীক্ষা করবেন, তা জেনে নিন।

66ddfbce2eeba53e.png

ক্লাউড শেল টার্মিনালে ক্লাউড প্রজেক্ট সেটআপ করুন

  1. আপনি ক্লাউড শেল ব্যবহার করবেন, যা গুগল ক্লাউডে চালিত একটি কমান্ড-লাইন পরিবেশ। গুগল ক্লাউড কনসোলের শীর্ষে থাকা ‘Activate Cloud Shell’-এ ক্লিক করুন।

26f20e837ff06119.png

  1. ক্লাউড শেলে সংযুক্ত হওয়ার পর, আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করে যাচাই করে নিন যে আপনি ইতিমধ্যেই প্রমাণীকৃত এবং প্রজেক্টটি আপনার প্রজেক্ট আইডিতে সেট করা আছে:
gcloud auth list
  1. gcloud কমান্ডটি আপনার প্রজেক্ট সম্পর্কে অবগত আছে কিনা, তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।
gcloud config list project
  1. আপনার প্রজেক্টটি সেট করা না থাকলে, এটি সেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
gcloud config set project <YOUR_PROJECT_ID>

বিকল্পভাবে, আপনি কনসোলে PROJECT_ID আইডিটিও দেখতে পারেন।

bb98435b79995b15.jpeg

এটিতে ক্লিক করলে আপনি ডানদিকে আপনার সম্পূর্ণ প্রজেক্ট এবং প্রজেক্ট আইডি দেখতে পাবেন।

ffa73dee57de5307.jpeg

  1. নিচে দেখানো কমান্ডের মাধ্যমে প্রয়োজনীয় API-গুলো সক্রিয় করুন। এতে কয়েক মিনিট সময় লাগতে পারে, তাই অনুগ্রহ করে ধৈর্য ধরুন।
gcloud services enable aiplatform.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       cloudresourcemanager.googleapis.com

কমান্ডটি সফলভাবে কার্যকর হলে, আপনি নিচে দেখানো বার্তার মতো একটি বার্তা দেখতে পাবেন:

Operation "operations/..." finished successfully.

gcloud কমান্ডের বিকল্প হলো কনসোলের মাধ্যমে প্রতিটি পণ্য অনুসন্ধান করা অথবা এই লিঙ্কটি ব্যবহার করা।

যদি কোনো API বাদ পড়ে যায়, তাহলে আপনি বাস্তবায়ন চলাকালীন সময়েই তা সক্রিয় করে নিতে পারেন।

gcloud কমান্ড এবং এর ব্যবহার সম্পর্কে জানতে ডকুমেন্টেশন দেখুন।

ক্লাউড শেল এডিটর-এ যান এবং অ্যাপ্লিকেশন ওয়ার্কিং ডিরেক্টরি সেটআপ করুন।

এখন, আমরা কোডিং করার জন্য আমাদের কোড এডিটর সেট আপ করতে পারি। এর জন্য আমরা ক্লাউড শেল এডিটর ব্যবহার করব।

  1. ওপেন এডিটর বাটনে ক্লিক করুন, এটি একটি ক্লাউড শেল এডিটর খুলবে, আমরা এখানে আমাদের কোড লিখতে পারি। 168eacea651b086c.png
  2. নিশ্চিত করুন যে ক্লাউড শেল এডিটরের নিচের বাম কোণে (স্ট্যাটাস বারে) ক্লাউড কোড প্রজেক্টটি সেট করা আছে, যেমনটি নিচের ছবিতে হাইলাইট করা হয়েছে, এবং এটি সেই সক্রিয় গুগল ক্লাউড প্রজেক্টে সেট করা আছে যেখানে আপনার বিলিং চালু করা আছে। অনুরোধ করা হলে অনুমোদন করুন । আপনি যদি আগের নির্দেশাবলী অনুসরণ করে থাকেন, তাহলে বাটনটি সাইন ইন বাটনের পরিবর্তে সরাসরি আপনার সক্রিয় প্রজেক্টেও নির্দেশ করতে পারে।

613a4889dbcade3d.png

  1. এরপর, গিটহাব থেকে এই কোডল্যাবের টেমপ্লেট ওয়ার্কিং ডিরেক্টরিটি ক্লোন করে নিচের কমান্ডটি চালান। এটি qa-test-planner-agent ডিরেক্টরিতে ওয়ার্কিং ডিরেক্টরিটি তৈরি করবে।
git clone https://github.com/alphinside/qa-test-planner-agent.git qa-test-planner-agent
  1. এরপর, ক্লাউড শেল এডিটরের উপরের অংশে যান এবং File->Open Folder-এ ক্লিক করুন, আপনার ইউজারনেম ডিরেক্টরি এবং qa-test-planner-agent ডিরেক্টরিটি খুঁজুন, তারপর OK বোতামে ক্লিক করুন। এটি নির্বাচিত ডিরেক্টরিটিকে প্রধান ওয়ার্কিং ডিরেক্টরি হিসেবে সেট করবে। এই উদাহরণে, ইউজারনেম হলো alvinprayuda , তাই ডিরেক্টরি পাথটি নিচে দেখানো হলো।

c87d2b76896d0c59.png

efd32490d592dbb9.png

এখন, আপনার ক্লাউড শেল এডিটরটি দেখতে এইরকম হওয়া উচিত।

a1a380fb20ce3308.png

পরিবেশ সেটআপ

পাইথন ভার্চুয়াল পরিবেশ প্রস্তুত করুন

পরবর্তী ধাপ হলো ডেভেলপমেন্ট এনভায়রনমেন্ট প্রস্তুত করা। আপনার বর্তমান সক্রিয় টার্মিনালটি qa-test-planner-agent ওয়ার্কিং ডিরেক্টরির ভিতরে থাকা উচিত। আমরা এই কোডল্যাবে পাইথন ৩.১২ ব্যবহার করব এবং পাইথন ভার্সন ও ভার্চুয়াল এনভায়রনমেন্ট তৈরি ও পরিচালনার প্রয়োজনীয়তা সহজ করার জন্য ইউভি পাইথন প্রজেক্ট ম্যানেজার ব্যবহার করব।

  1. আপনি যদি এখনও টার্মিনাল না খুলে থাকেন, তাহলে Terminal -> New Terminal- এ ক্লিক করে অথবা Ctrl + Shift + C চেপে এটি খুলুন; এটি ব্রাউজারের নিচের অংশে একটি টার্মিনাল উইন্ডো খুলে দেবে।

8635b60ae2f45bbc.jpeg

  1. নিম্নলিখিত কমান্ডের সাহায্যে uv ডাউনলোড করুন এবং python 3.12 ইনস্টল করুন।
curl -LsSf https://astral.sh/uv/0.7.19/install.sh | sh && \
source $HOME/.local/bin/env && \
uv python install 3.12
  1. এখন uv ব্যবহার করে ভার্চুয়াল এনভায়রনমেন্টটি ইনিশিয়ালাইজ করা যাক, এই কমান্ডটি চালান।
uv sync --frozen

এটি .venv ডিরেক্টরি তৈরি করবে এবং ডিপেন্ডেন্সিগুলো ইনস্টল করবে। pyproject.toml- এ দ্রুত চোখ বোলালেই আপনি ডিপেন্ডেন্সিগুলো সম্পর্কে এইরকম তথ্য পেয়ে যাবেন।

dependencies = [
    "google-adk>=1.5.0",
    "mcp-atlassian>=0.11.9",
    "pandas>=2.3.0",
    "python-dotenv>=1.1.1",
]
  1. ভার্চুয়াল এনভ পরীক্ষা করার জন্য, main.py নামে একটি নতুন ফাইল তৈরি করুন এবং নিম্নলিখিত কোডটি কপি করুন।
def main():
   print("Hello from qa-test-planner-agent")

if __name__ == "__main__":
   main()
  1. তারপর, নিম্নলিখিত কমান্ডটি চালান।
uv run main.py

আপনি নীচে দেখানো ছবির মতো আউটপুট পাবেন।

Using CPython 3.12
Creating virtual environment at: .venv
Hello from qa-test-planner-agent!

এতে বোঝা যায় যে পাইথন প্রজেক্টটি সঠিকভাবে সেট আপ করা হচ্ছে।

এখন আমরা পরবর্তী ধাপে যেতে পারি, অর্থাৎ এজেন্ট এবং তারপর পরিষেবাগুলো তৈরি করতে পারি।

৩. গুগল এডিকে এবং জেমিনি ২.৫ ব্যবহার করে এজেন্টটি তৈরি করুন।

ADK ডিরেক্টরি কাঠামোর পরিচিতি

চলুন, ADK কী কী সুবিধা দেয় এবং কীভাবে এজেন্ট তৈরি করতে হয়, তা দিয়ে শুরু করা যাক। ADK-এর সম্পূর্ণ ডকুমেন্টেশন এই URL- এ পাওয়া যাবে। ADK তার CLI কমান্ড এক্সিকিউশনের মাধ্যমে আমাদের অনেক ইউটিলিটি প্রদান করে। সেগুলোর মধ্যে কয়েকটি নিচে দেওয়া হলো:

  • এজেন্ট ডিরেক্টরি কাঠামো সেটআপ করুন
  • CLI ইনপুট আউটপুটের মাধ্যমে দ্রুত ইন্টারঅ্যাকশন চেষ্টা করুন
  • দ্রুত স্থানীয় ডেভেলপমেন্ট UI ওয়েব ইন্টারফেস সেটআপ করুন

এখন, CLI কমান্ড ব্যবহার করে এজেন্ট ডিরেক্টরি কাঠামো তৈরি করা যাক। নিম্নলিখিত কমান্ডটি চালান।

uv run adk create qa_test_planner \
   --model gemini-2.5-flash \
   --project {your-project-id} \
   --region global

এটি আপনার বর্তমান ওয়ার্কিং ডিরেক্টরিতে নিম্নলিখিত এজেন্ট ডিরেক্টরি কাঠামো তৈরি করবে।

qa_test_planner/
├── __init__.py
├── .env
├── agent.py

এবং আপনি যদি init.py এবং agent.py ফাইলগুলো পরিদর্শন করেন, তাহলে এই কোডটি দেখতে পাবেন।

# __init__.py

from . import agent
# agent.py

from google.adk.agents import Agent

root_agent = Agent(
    model='gemini-2.5-flash',
    name='root_agent',
    description='A helpful assistant for user questions.',
    instruction='Answer user questions to the best of your knowledge',
)

আমাদের QA টেস্ট প্ল্যানার এজেন্ট তৈরি করা

চলুন আমাদের QA টেস্ট প্ল্যানার এজেন্ট তৈরি করি! qa_test_planner / agent.py ফাইলটি খুলুন এবং নিচের কোডটি কপি করুন, যেটিতে root_agent থাকবে।

# qa_test_planner/agent.py

from google.adk.agents import Agent
from google.adk.tools.mcp_tool.mcp_toolset import (
    MCPToolset,
    StdioConnectionParams,
    StdioServerParameters,
)
from google.adk.planners import BuiltInPlanner
from google.genai import types
from dotenv import load_dotenv
import os
from pathlib import Path
from pydantic import BaseModel
from typing import Literal
import tempfile
import pandas as pd
from google.adk.tools import ToolContext


load_dotenv(dotenv_path=Path(__file__).parent / ".env")

confluence_tool = MCPToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="uvx",
            args=[
                "mcp-atlassian",
                f"--confluence-url={os.getenv('CONFLUENCE_URL')}",
                f"--confluence-username={os.getenv('CONFLUENCE_USERNAME')}",
                f"--confluence-token={os.getenv('CONFLUENCE_TOKEN')}",
                "--enabled-tools=confluence_search,confluence_get_page,confluence_get_page_children",
            ],
            env={},
        ),
        timeout=60,
    ),
)


class TestPlan(BaseModel):
    test_case_key: str
    test_type: Literal["manual", "automatic"]
    summary: str
    preconditions: str
    test_steps: str
    expected_result: str
    associated_requirements: str


async def write_test_tool(
    prd_id: str, test_cases: list[dict], tool_context: ToolContext
):
    """A tool to write the test plan into file

    Args:
        prd_id: Product requirement document ID
        test_cases: List of test case dictionaries that should conform to these fields:
            - test_case_key: str
            - test_type: Literal["manual","automatic"]
            - summary: str
            - preconditions: str
            - test_steps: str
            - expected_result: str
            - associated_requirements: str

    Returns:
        A message indicating success or failure of the validation and writing process
    """
    validated_test_cases = []
    validation_errors = []

    # Validate each test case
    for i, test_case in enumerate(test_cases):
        try:
            validated_test_case = TestPlan(**test_case)
            validated_test_cases.append(validated_test_case)
        except Exception as e:
            validation_errors.append(f"Error in test case {i + 1}: {str(e)}")

    # If validation errors exist, return error message
    if validation_errors:
        return {
            "status": "error",
            "message": "Validation failed",
            "errors": validation_errors,
        }

    # Write validated test cases to CSV
    try:
        # Convert validated test cases to a pandas DataFrame
        data = []
        for tc in validated_test_cases:
            data.append(
                {
                    "Test Case ID": tc.test_case_key,
                    "Type": tc.test_type,
                    "Summary": tc.summary,
                    "Preconditions": tc.preconditions,
                    "Test Steps": tc.test_steps,
                    "Expected Result": tc.expected_result,
                    "Associated Requirements": tc.associated_requirements,
                }
            )

        # Create DataFrame from the test case data
        df = pd.DataFrame(data)

        if not df.empty:
            # Create a temporary file with .csv extension
            with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as temp_file:
                # Write DataFrame to the temporary CSV file
                df.to_csv(temp_file.name, index=False)
                temp_file_path = temp_file.name

            # Read the file bytes from the temporary file
            with open(temp_file_path, "rb") as f:
                file_bytes = f.read()

            # Create an artifact with the file bytes
            await tool_context.save_artifact(
                filename=f"{prd_id}_test_plan.csv",
                artifact=types.Part.from_bytes(data=file_bytes, mime_type="text/csv"),
            )

            # Clean up the temporary file
            os.unlink(temp_file_path)

            return {
                "status": "success",
                "message": (
                    f"Successfully wrote {len(validated_test_cases)} test cases to "
                    f"CSV file: {prd_id}_test_plan.csv"
                ),
            }
        else:
            return {"status": "warning", "message": "No test cases to write"}
    except Exception as e:
        return {
            "status": "error",
            "message": f"An error occurred while writing to CSV: {str(e)}",
        }


root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    description="You are an expert QA Test Planner and Product Manager assistant",
    instruction=f"""
Help user search any product requirement documents on Confluence. Furthermore you also can provide the following capabilities when asked:
- evaluate product requirement documents and assess it, then give expert input on what can be improved 
- create a comprehensive test plan following Jira Xray mandatory field formatting, result showed as markdown table. Each test plan must also have explicit mapping on 
    which user stories or requirements identifier it's associated to 

Here is the Confluence space ID with it's respective document grouping:

- "{os.getenv("CONFLUENCE_PRD_SPACE_ID")}" : space to store Product Requirements Documents

Do not making things up, Always stick to the fact based on data you retrieve via tools.
""",
    tools=[confluence_tool, write_test_tool],
    planner=BuiltInPlanner(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True,
            thinking_budget=2048,
        )
    ),
)

সেটআপ কনফিগারেশন ফাইল

এখন এই প্রজেক্টের জন্য আমাদের অতিরিক্ত কনফিগারেশন সেটআপ যোগ করতে হবে, কারণ এই এজেন্টের কনফ্লুয়েন্সে অ্যাক্সেস প্রয়োজন হবে।

qa_test_planner/.env ফাইলটি খুলুন এবং এতে নিম্নলিখিত এনভায়রনমেন্ট ভেরিয়েবলগুলোর মান যোগ করুন, নিশ্চিত করুন যে ফলস্বরূপ .env ফাইলটি দেখতে এইরকম হয়।

GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT={YOUR-CLOUD-PROJECT-ID}
GOOGLE_CLOUD_LOCATION=global
CONFLUENCE_URL={YOUR-CONFLUENCE-DOMAIN}
CONFLUENCE_USERNAME={YOUR-CONFLUENCE-USERNAME}
CONFLUENCE_TOKEN={YOUR-CONFLUENCE-API-TOKEN}
CONFLUENCE_PRD_SPACE_ID={YOUR-CONFLUENCE-SPACE-ID}

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

কোডের ব্যাখ্যা

এই স্ক্রিপ্টটিতে আমাদের এজেন্ট ইনিসিয়েশন রয়েছে, যেখানে আমরা নিম্নলিখিত বিষয়গুলো ইনিশিয়ালাইজ করি:

  • ব্যবহৃত মডেলটি gemini-2.5-flash এ সেট করুন।
  • কনফ্লুয়েন্স এমসিপি টুলস সেটআপ করুন যা স্টুডিওর মাধ্যমে যোগাযোগ করবে।
  • টেস্ট প্ল্যান লিখতে এবং আর্টিফ্যাক্টে সিএসভি ডাম্প করতে write_test_tool কাস্টম টুলটি সেটআপ করুন।
  • এজেন্টের বিবরণ এবং নির্দেশাবলী সেট আপ করুন
  • জেমিনি ২.৫ ফ্ল্যাশ থিঙ্কিং সক্ষমতা ব্যবহার করে চূড়ান্ত প্রতিক্রিয়া তৈরি বা তা কার্যকর করার আগে পরিকল্পনা সক্ষম করুন।

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

# qa-test-planner/agent.py

from google.adk.planners import BuiltInPlanner
from google.genai import types

...

# Provide the confluence tool to agent

root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    ...,
    tools=[confluence_tool, write_test_tool],
    planner=BuiltInPlanner(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True,
            thinking_budget=2048,
        )
    ),

...

এবং কোনো পদক্ষেপ নেওয়ার আগে, আমরা এর চিন্তাভাবনা দেখতে পারি।

7de7004af0fc8c90.png

কনফ্লুয়েন্স এমসিপি টুল

ADK থেকে MCP সার্ভারের সাথে সংযোগ করতে, আমাদের MCPToolSet ব্যবহার করতে হবে, যা google.adk.tools.mcp_tool.mcp_toolset মডিউল থেকে ইম্পোর্ট করা যায়। এখানে ইনিশিয়ালাইজ করার কোডটি নিচে দেখানো হলো (দক্ষতার জন্য সংক্ষিপ্ত করা হয়েছে)।

# qa-test-planner/agent.py

from google.adk.tools.mcp_tool.mcp_toolset import (
    MCPToolset,
    StdioConnectionParams,
    StdioServerParameters,
)

...

# Initialize the Confluence MCP Tool via Stdio Output

confluence_tool = MCPToolset(
    connection_params=StdioConnectionParams(
        server_params=StdioServerParameters(
            command="uvx",
            args=[
                "mcp-atlassian",
                f"--confluence-url={os.getenv('CONFLUENCE_URL')}",
                f"--confluence-username={os.getenv('CONFLUENCE_USERNAME')}",
                f"--confluence-token={os.getenv('CONFLUENCE_TOKEN')}",
                "--enabled-tools=confluence_search,confluence_get_page,confluence_get_page_children",
            ],
            env={},
        ),
        timeout=60,
    ),
)


...

# Provide the confluence tool to agent

root_agent = Agent(
    model="gemini-2.5-flash",
    name="qa_test_planner_agent",
    ...,
    tools=[confluence_tool, write_test_tool],

...

এই কনফিগারেশনের মাধ্যমে, এজেন্ট কনফ্লুয়েন্স এমসিপি সার্ভারকে একটি পৃথক প্রসেস হিসেবে চালু করবে এবং স্টুডিও আই/ও (Studio I/O)-এর মাধ্যমে সেই প্রসেসগুলোর সাথে যোগাযোগ পরিচালনা করবে। এই কার্যপ্রবাহটি নিচের লাল বাক্সে চিহ্নিত এমসিপি আর্কিটেকচার চিত্রে দেখানো হয়েছে।

8d8d8fd8e23d3c82.png

এছাড়াও, MCP ইনিশিয়ালাইজেশনের কমান্ড আর্গুমেন্টগুলোর মধ্যে, আমরা ব্যবহারযোগ্য টুলগুলোকে শুধুমাত্র এই টুলগুলোর মধ্যে সীমাবদ্ধ রাখি: confluence_search, confluence_get_page, এবং confluence_get_page_children , যেগুলো আমাদের QA টেস্ট এজেন্ট ব্যবহারের ক্ষেত্রগুলোকে সমর্থন করে। এই কোডল্যাব টিউটোরিয়ালের জন্য আমরা কমিউনিটি-প্রদত্ত অ্যাটলাসিয়ান MCP সার্ভার ব্যবহার করি (আরও বিস্তারিত জানতে সম্পূর্ণ ডকুমেন্টেশন দেখুন)।

টেস্ট টুল লিখুন

এজেন্টটি কনফ্লুয়েন্স এমসিপি টুল থেকে কনটেক্সট পাওয়ার পর, এটি ব্যবহারকারীর জন্য প্রয়োজনীয় টেস্ট প্ল্যান তৈরি করতে পারে। তবে আমরা এমন একটি ফাইল তৈরি করতে চাই যাতে এই টেস্ট প্ল্যানটি থাকে, যাতে এটি সংরক্ষণ করা যায় এবং অন্য ব্যক্তির সাথে শেয়ার করা যায়। এটি সমর্থন করার জন্য, আমরা নিচে write_test_tool নামক কাস্টম টুলটি প্রদান করেছি।

# qa-test-planner/agent.py

...

async def write_test_tool(
    prd_id: str, test_cases: list[dict], tool_context: ToolContext
):
    """A tool to write the test plan into file

    Args:
        prd_id: Product requirement document ID
        test_cases: List of test case dictionaries that should conform to these fields:
            - test_case_key: str
            - test_type: Literal["manual","automatic"]
            - summary: str
            - preconditions: str
            - test_steps: str
            - expected_result: str
            - associated_requirements: str

    Returns:
        A message indicating success or failure of the validation and writing process
    """
    validated_test_cases = []
    validation_errors = []

    # Validate each test case
    for i, test_case in enumerate(test_cases):
        try:
            validated_test_case = TestPlan(**test_case)
            validated_test_cases.append(validated_test_case)
        except Exception as e:
            validation_errors.append(f"Error in test case {i + 1}: {str(e)}")

    # If validation errors exist, return error message
    if validation_errors:
        return {
            "status": "error",
            "message": "Validation failed",
            "errors": validation_errors,
        }

    # Write validated test cases to CSV
    try:
        # Convert validated test cases to a pandas DataFrame
        data = []
        for tc in validated_test_cases:
            data.append(
                {
                    "Test Case ID": tc.test_case_key,
                    "Type": tc.test_type,
                    "Summary": tc.summary,
                    "Preconditions": tc.preconditions,
                    "Test Steps": tc.test_steps,
                    "Expected Result": tc.expected_result,
                    "Associated Requirements": tc.associated_requirements,
                }
            )

        # Create DataFrame from the test case data
        df = pd.DataFrame(data)

        if not df.empty:
            # Create a temporary file with .csv extension
            with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as temp_file:
                # Write DataFrame to the temporary CSV file
                df.to_csv(temp_file.name, index=False)
                temp_file_path = temp_file.name

            # Read the file bytes from the temporary file
            with open(temp_file_path, "rb") as f:
                file_bytes = f.read()

            # Create an artifact with the file bytes
            await tool_context.save_artifact(
                filename=f"{prd_id}_test_plan.csv",
                artifact=types.Part.from_bytes(data=file_bytes, mime_type="text/csv"),
            )

            # Clean up the temporary file
            os.unlink(temp_file_path)

            return {
                "status": "success",
                "message": (
                    f"Successfully wrote {len(validated_test_cases)} test cases to "
                    f"CSV file: {prd_id}_test_plan.csv"
                ),
            }
        else:
            return {"status": "warning", "message": "No test cases to write"}
    except Exception as e:
        return {
            "status": "error",
            "message": f"An error occurred while writing to CSV: {str(e)}",
        }


...

উপরে ঘোষিত ফাংশনটি নিম্নলিখিত কার্যকারিতাগুলো সমর্থন করার জন্য:

  1. প্রস্তুতকৃত টেস্ট প্ল্যানটি বাধ্যতামূলক ফিল্ড স্পেসিফিকেশনের সাথে সঙ্গতিপূর্ণ কিনা তা পাইড্যান্টিক মডেল ব্যবহার করে যাচাই করা হয়, এবং কোনো ত্রুটি ঘটলে আমরা এজেন্টের কাছে ত্রুটির বার্তাটি ফেরত পাঠাই।
  2. পান্ডাস কার্যকারিতা ব্যবহার করে ফলাফলটি CSV-তে ডাম্প করুন।
  3. তৈরি হওয়া ফাইলটি এরপর আর্টিফ্যাক্ট সার্ভিস ক্যাপাবিলিটি ব্যবহার করে আর্টিফ্যাক্ট হিসেবে সংরক্ষণ করা হয়, যা টুলকনটেক্সট অবজেক্টের মাধ্যমে অ্যাক্সেস করা যায় এবং এই অবজেক্টটি প্রতিটি টুল কলের সময় ব্যবহার করা যায়।

যদি আমরা তৈরি করা ফাইলগুলিকে আর্টিফ্যাক্ট হিসাবে সংরক্ষণ করি, তাহলে এটি ADK রানটাইমে একটি ইভেন্ট হিসাবে চিহ্নিত হবে এবং পরবর্তীতে ওয়েব ইন্টারফেসে এজেন্ট ইন্টারঅ্যাকশনে প্রদর্শিত হবে।

adafec781450c89a.png

এর মাধ্যমে, আমরা এজেন্ট থেকে প্রাপ্ত ফাইল রেসপন্সটি ডায়নামিকভাবে সেটআপ করতে পারি, যা ব্যবহারকারীকে দেওয়া হবে।

৪. এজেন্টকে পরীক্ষা করা

এখন CLI-এর মাধ্যমে এজেন্টের সাথে যোগাযোগ করার চেষ্টা করা যাক, নিম্নলিখিত কমান্ডটি চালান।

uv run adk run qa_test_planner

এটি এইরকম আউটপুট দেখাবে, যেখানে আপনি এজেন্টের সাথে পালাক্রমে চ্যাট করতে পারবেন, তবে এই ইন্টারফেসের মাধ্যমে শুধুমাত্র টেক্সট পাঠানো যাবে।

Log setup complete: /tmp/agents_log/agent.xxxx_xxx.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log
Running agent qa_test_planner_agent, type exit to exit.
user: hello
[qa_test_planner_agent]: Hello there! How can I help you today?
user: 

CLI-এর মাধ্যমে এজেন্টের সাথে চ্যাট করতে পারাটা বেশ ভালো। কিন্তু, এর সাথে যদি একটি চমৎকার ওয়েব চ্যাটের ব্যবস্থা থাকে, তবে তা আরও ভালো হয় এবং আমরা সেটাও করতে পারি! ADK আমাদের একটি ডেভেলপমেন্ট UI ব্যবহারের সুযোগও দেয়, যার মাধ্যমে ইন্টারঅ্যাকশনের সময় কী ঘটছে তা পর্যবেক্ষণ ও পরীক্ষা করা যায়। লোকাল ডেভেলপমেন্ট UI সার্ভারটি চালু করতে নিম্নলিখিত কমান্ডটি চালান।

uv run adk web --port 8080

এটি নিচের উদাহরণের মতো আউটপুট তৈরি করবে, যার মানে হলো আমরা ইতিমধ্যেই ওয়েব ইন্টারফেসটি অ্যাক্সেস করতে পারব।

INFO:     Started server process [xxxx]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8080.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

এখন, এটি পরীক্ষা করার জন্য, আপনার ক্লাউড শেল এডিটরের উপরের অংশে থাকা ওয়েব প্রিভিউ বোতামে ক্লিক করুন এবং পোর্ট ৮০৮০-তে প্রিভিউ নির্বাচন করুন।

edc73e971b9fc60c.png

আপনি নিম্নলিখিত ওয়েব পেজটি দেখতে পাবেন, যেখানে আপনি উপরের বাম দিকের ড্রপ-ডাউন বোতাম থেকে উপলব্ধ এজেন্ট নির্বাচন করতে পারবেন (আমাদের ক্ষেত্রে এটি qa_test_planner হওয়া উচিত) এবং বটটির সাথে ইন্টারঅ্যাক্ট করতে পারবেন। এজেন্ট চালু থাকার সময়কার লগ সম্পর্কিত অনেক তথ্য আপনি বাম দিকের উইন্ডোতে দেখতে পাবেন।

940b1e0391db4871.png

চলুন কিছু কাজ করে দেখি! এই নির্দেশাবলী ব্যবহার করে এজেন্টদের সাথে চ্যাট করুন:

  • অনুগ্রহ করে সমস্ত উপলব্ধ PRD-গুলির তালিকা দিন।
  • Snaprecipe PRD-এর জন্য টেস্ট প্ল্যান লিখুন

কিছু টুল ব্যবহার করার সময়, আপনি ডেভেলপমেন্ট UI-তে কী ঘটছে তা পর্যবেক্ষণ করতে পারেন।

35a3c928bd9dfb87.png

এজেন্ট আপনাকে কীভাবে সাড়া দেয় তা দেখুন এবং আরও পরীক্ষা করে দেখুন যে আমরা যখন টেস্ট ফাইলের জন্য অনুরোধ করি, তখন এটি আর্টিফ্যাক্ট হিসেবে একটি CSV ফাইলে টেস্ট প্ল্যানটি তৈরি করে।

183558cb042cb021.png

এখন, আপনি উদাহরণস্বরূপ গুগল শিটে CSV ফাইলটি ইম্পোর্ট করে এর বিষয়বস্তু যাচাই করতে পারেন।

78933239b66eddb2.png

অভিনন্দন! এখন আপনার লোকাল সিস্টেমে একটি কার্যকরী QA টেস্ট প্ল্যানার এজেন্ট চলছে! এবার চলুন দেখি, কীভাবে এটিকে ক্লাউড রান-এ ডেপ্লয় করা যায়, যাতে অন্যরাও এটি ব্যবহার করতে পারে!

৫. ক্লাউড রান-এ ডেপ্লয় করা

এখন, অবশ্যই আমরা এই চমৎকার অ্যাপটি যেকোনো জায়গা থেকে ব্যবহার করতে চাই। তা করার জন্য, আমরা এই অ্যাপ্লিকেশনটিকে প্যাকেজ করে ক্লাউড রান-এ ডেপ্লয় করতে পারি। এই ডেমোর জন্য, এই সার্ভিসটিকে একটি পাবলিক সার্ভিস হিসেবে প্রকাশ করা হবে যা অন্যরা ব্যবহার করতে পারবে। তবে, মনে রাখবেন যে এটি সর্বোত্তম পন্থা নয়!

af793beb2740233.jpeg

আপনার বর্তমান ওয়ার্কিং ডিরেক্টরিতে, ক্লাউড রান-এ আমাদের অ্যাপ্লিকেশনগুলো ডেপ্লয় করার জন্য প্রয়োজনীয় সমস্ত ফাইল ইতিমধ্যেই রয়েছে - এজেন্ট ডিরেক্টরি, ডকারফাইল, এবং server.py (প্রধান সার্ভিস স্ক্রিপ্ট) , চলুন এটি ডেপ্লয় করা যাক। ক্লাউড শেল টার্মিনালে যান এবং নিশ্চিত করুন যে বর্তমান প্রজেক্টটি আপনার সক্রিয় প্রজেক্ট হিসাবে কনফিগার করা আছে, যদি না থাকে তবে প্রজেক্ট আইডি সেট করার জন্য আপনাকে gcloud configure কমান্ডটি ব্যবহার করতে হবে:

gcloud config set project [PROJECT_ID]

এরপর, এটিকে ক্লাউড রান-এ ডেপ্লয় করতে নিম্নলিখিত কমান্ডটি চালান।

gcloud run deploy qa-test-planner-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --update-env-vars GOOGLE_GENAI_USE_VERTEXAI=1 \
                  --update-env-vars GOOGLE_CLOUD_PROJECT={YOUR_PROJECT_ID} \
                  --update-env-vars GOOGLE_CLOUD_LOCATION=global \
                  --update-env-vars CONFLUENCE_URL={YOUR_CONFLUENCE_URL} \
                  --update-env-vars CONFLUENCE_USERNAME={YOUR_CONFLUENCE_USERNAME} \
                  --update-env-vars CONFLUENCE_TOKEN={YOUR_CONFLUENCE_TOKEN} \
                  --update-env-vars CONFLUENCE_PRD_SPACE_ID={YOUR_PRD_SPACE_ID} \
                  --memory 1G

ডকার রিপোজিটরির জন্য একটি আর্টিফ্যাক্ট রেজিস্ট্রি তৈরির বিষয়টি স্বীকার করতে বলা হলে, শুধু 'Y' উত্তর দিন। উল্লেখ্য যে, এটি একটি ডেমো অ্যাপ্লিকেশন হওয়ায় আমরা এখানে প্রমাণীকরণবিহীন অ্যাক্সেসের অনুমতি দিচ্ছি। আপনার এন্টারপ্রাইজ এবং প্রোডাকশন অ্যাপ্লিকেশনগুলোর জন্য উপযুক্ত প্রমাণীকরণ ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।

ডেপ্লয়মেন্ট সম্পন্ন হলে, আপনি নীচের মতো একটি লিঙ্ক পাবেন:

https://qa-test-planner-agent-*******.us-central1.run.app

যখন আপনি ইউআরএল-টি অ্যাক্সেস করবেন, তখন আপনি ওয়েব ডেভ ইউআই-তে প্রবেশ করবেন, যা আপনার লোকাল ডিভাইসে চেষ্টা করার মতোই। এবার ইনকগনিটো উইন্ডো বা আপনার মোবাইল ডিভাইস থেকে অ্যাপ্লিকেশনটি ব্যবহার করে দেখুন। এটি ইতিমধ্যে লাইভ হয়ে যাওয়ার কথা।

এখন চলুন এই ভিন্ন প্রম্পটগুলো আবার ক্রমানুসারে চেষ্টা করে দেখি, সেখানে কী ঘটে:

  • আপনি কি মর্টগেজ এস্টিমেটরের সাথে সম্পর্কিত PRD খুঁজে পেতে পারেন?
  • এ ব্যাপারে আমরা কী কী উন্নতি করতে পারি, সে বিষয়ে আমাকে মতামত দিন।
  • এটির জন্য পরীক্ষার পরিকল্পনা লিখুন।

এছাড়াও, যেহেতু আমরা এজেন্টটিকে একটি FastAPI অ্যাপ হিসেবে চালাই, তাই আমরা /docs রুটে সমস্ত API রুট পরিদর্শন করতে পারি। উদাহরণস্বরূপ, আপনি যদি https://qa-test-planner-agent-*******.us-central1.run.app/docs- এর মতো URL-টি অ্যাক্সেস করেন, তাহলে আপনি নীচে দেখানো Swagger ডকুমেন্টেশন পৃষ্ঠার মতো একটি পৃষ্ঠা দেখতে পাবেন।

82d2d91fb3cb2dde.png

কোডের ব্যাখ্যা

এখন, চলুন দেখে নেওয়া যাক ডেপ্লয়মেন্টের জন্য আমাদের কোন ফাইলগুলো প্রয়োজন, শুরু করা যাক server.py দিয়ে।

# server.py

import os

from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))

app_args = {"agents_dir": AGENT_DIR, "web": True}

app: FastAPI = get_fast_api_app(**app_args)

app.title = "qa-test-planner-agent"
app.description = "API for interacting with the Agent qa-test-planner-agent"


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8080)

আমরা `get_fast_api_app` ফাংশনটি ব্যবহার করে সহজেই আমাদের এজেন্টকে একটি ফাস্টএপিআই অ্যাপে রূপান্তর করতে পারি। এই ফাংশনে আমরা বিভিন্ন কার্যকারিতা সেট আপ করতে পারি, যেমন সেশন সার্ভিস, আর্টিফ্যাক্ট সার্ভিস কনফিগার করা, বা এমনকি ক্লাউডে ডেটা ট্রেস করা।

আপনি চাইলে এখানে অ্যাপ্লিকেশন লাইফসাইকেলও সেট করতে পারেন। এরপর আমরা ফাস্ট এপিআই অ্যাপ্লিকেশনটি চালানোর জন্য ইউভিকর্ন (uvicorn) ব্যবহার করতে পারব।

এরপরে, অ্যাপ্লিকেশনটি চালানোর জন্য প্রয়োজনীয় ধাপগুলো Dockerfile-এ দেওয়া থাকবে।

# Dockerfile

FROM python:3.12-slim

RUN pip install --no-cache-dir uv==0.7.13

WORKDIR /app

COPY . .

RUN uv sync --frozen

EXPOSE 8080

CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]

৬. চ্যালেঞ্জ

এখন আপনার দক্ষতা দেখানোর এবং অন্বেষণ দক্ষতাকে আরও শাণিত করার সময়। আপনি কি এমন একটি টুলও তৈরি করতে পারেন, যার মাধ্যমে PRD পর্যালোচনার প্রতিক্রিয়াও একটি ফাইলে লেখা হবে?

৭. পরিষ্কার করুন

এই কোডল্যাবে ব্যবহৃত রিসোর্সগুলির জন্য আপনার গুগল ক্লাউড অ্যাকাউন্টে চার্জ হওয়া এড়াতে, এই ধাপগুলি অনুসরণ করুন:

  1. গুগল ক্লাউড কনসোলে, রিসোর্স পরিচালনা (Manage resources) পৃষ্ঠায় যান।
  2. প্রজেক্ট তালিকা থেকে, আপনি যে প্রজেক্টটি মুছতে চান সেটি নির্বাচন করুন এবং তারপর ডিলিট বোতামে ক্লিক করুন।
  3. ডায়ালগ বক্সে প্রজেক্ট আইডি টাইপ করুন এবং তারপর প্রজেক্টটি মুছে ফেলার জন্য 'শাট ডাউন'-এ ক্লিক করুন।
  4. বিকল্পভাবে, আপনি কনসোলে Cloud Run- এ গিয়ে, এইমাত্র ডেপ্লয় করা সার্ভিসটি নির্বাচন করে ডিলিট করে দিতে পারেন।