জেমিনি এপিআই ব্যবহার করে একটি ম্যানেজড টেক ডাইজেস্ট এজেন্ট তৈরি করুন

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

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

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

এই কোডল্যাবে আপনি ঠিক সেই এজেন্টটিই তৈরি করবেন: একটি খালি ফাংশন থেকে শুরু করে, ধাপে ধাপে একটি কার্যকর দৈনিক সারসংক্ষেপ পর্যন্ত।

আপনি যা তৈরি করবেন

  • একটি বাস্তব লিনাক্স স্যান্ডবক্সে আপনার প্রথম পরিচালিত এজেন্ট তৈরি করুন এবং চালান।
  • বিস্তারিত নির্দেশাবলী দিয়ে এজেন্টটিকে কাস্টমাইজ করুন।
  • এজেন্টের পিডিএফ আউটপুট ডাউনলোড করুন
  • ওয়েব পুনরায় না খুঁজে সারসংক্ষেপটি পরিমার্জন করতে আলোচনা চালিয়ে যান।
  • এজেন্ট কনফিগারেশনটি সংরক্ষণ করুন এবং পরবর্তী রানগুলিতে আইডি দ্বারা এটিকে চালু করুন।

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

  • পাইথন ৩.১০+
  • বিলিং সক্ষম একটি জেমিনি এপিআই কী: aistudio.google.com/api-keys
  • প্রায় ১ ডলার এপিআই ক্রেডিট (প্রতিটি সম্পূর্ণ রানের খরচ ০.৩০-১.৩০ ডলার)

২. জেমিনি এপিআই-তে ম্যানেজড এজেন্ট বলতে কী বোঝায়?

এআই সিস্টেমের তিনটি স্তর

কোডে প্রবেশ করার আগে, দুটি বিকল্পের তুলনায় ম্যানেজড এজেন্ট কোথায় অবস্থান করে তা এখানে তুলে ধরা হলো:

স্তর

এটা কি

অবকাঠামো কে পরিচালনা করে?

স্ট্যান্ডার্ড এলএলএম

আপনি নির্দেশ দেন, এটি টেক্সটের মাধ্যমে উত্তর দেয়। হাত নেই, মেমরি নেই, ইন্টারনেটও নেই।

প্রযোজ্য নয়: এটি নিজে থেকে কিছুই করতে পারে না।

সেলফ-হোস্টেড এজেন্ট

আপনি ADK/LangChain/AutoGen + Docker + টুলস + মেমরি সংযুক্ত করেন।

আপনি: এই সব (অথবা এজেন্ট ইঞ্জিনের মতো একটি পরিচালিত প্ল্যাটফর্ম)

পরিচালিত এজেন্ট

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

গুগল: এর সবকিছু

এই কোডল্যাবটি তৃতীয় সারি সম্পর্কিত। আপনাকে একটি টাস্ক এবং কনফিগারেশন ফাইল সরবরাহ করতে হবে। বাকি সবকিছু গুগল সামলে নেবে।

ADK + ক্লাউড রান দিয়ে আপনি যা তৈরি করবেন

এমন একটি নিউজ ডাইজেস্ট এজেন্ট তৈরি করতে, যা ওয়েব ব্রাউজ করে, পাইথন চালায় এবং একটি পিডিএফ তৈরি করে, আপনার ADK + Cloud Run-এর সাথে এই সবকিছুর প্রয়োজন হবে:

# agent.py: define tools and wire up the agent
from google.adk.agents import LlmAgent
from google.adk.tools import google_search, built_in_code_execution

agent = LlmAgent(
    name="digest-agent",
    model=MODEL,
    instruction=AGENTS_MD,          # your editorial voice and rules
    tools=[google_search, built_in_code_execution],
)
# app.py: serve the agent over HTTP
from google.adk.runners import FastApiRunner
runner = FastApiRunner(agent=agent)
app = runner.app
# pdf_tool.py: custom tool, install reportlab, render PDF
# scraper.py: custom tool, fetch each news source
# streaming.py: wire agent events to your SSE endpoint
# Dockerfile: package everything
FROM python:3.12
COPY . /app
RUN pip install google-adk reportlab requests
CMD ["uvicorn", "app:app", "--host", "0.0.0.0"]
# Deploy to Cloud Run
gcloud run deploy digest-agent \
  --image gcr.io/your-project/digest-agent \
  --set-secrets GEMINI_API_KEY=gemini-key:latest \
  --memory 2Gi

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

ম্যানেজড এজেন্টরা এটিকে যা দিয়ে প্রতিস্থাপন করে

from google import genai
client = genai.Client()

stream = client.interactions.create(
    agent="antigravity-preview-05-2026",
    input="",
    stream=True,
    environment={
        "type": "remote",
        "sources": [          # your config files, mounted at startup
            {
                "type": "inline",
                "target": ".agents/AGENTS.md",
                "content": AGENTS_MD,
            },
            {
                "type": "inline",
                "target": ".agents/skills/digest-pdf/SKILL.md",
                "content": SKILL_MD,
            },
            {
                "type": "inline",
                "target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
                "content": GENERATE_PDF_PY,
            },
        ],
    },
)

ADK + ক্লাউড রানের যা প্রয়োজন

ম্যানেজড এজেন্টরা আপনার জন্য যা পরিচালনা করে

কন্টেইনার ইমেজ + ডকারফাইল + সিআই/সিডি

সম্পূর্ণরূপে পরিচালিত উবুন্টু স্যান্ডবক্স (পাইথন ৩.১২, নোড ২২, ৪ সিপিইউ / ১৬ জিবি র‍্যাম)

ক্লাউড রান ডেপ্লয়মেন্ট + স্কেলিং

প্রতিটি ব্যবহারের জন্য বরাদ্দকৃত, ৭ দিন নিষ্ক্রিয় থাকলে স্বয়ংক্রিয়ভাবে মেয়াদ শেষ হয়ে যায়।

স্যান্ডবক্স বিচ্ছিন্নতা

মিথস্ক্রিয়া অনুসারে বিচ্ছিন্ন

কাস্টম পিডিএফ টুল + pip install

এজেন্ট স্যান্ডবক্সের ভিতরে প্যাকেজ ইনস্টল করে।

এসএসই স্ট্রিমিং পরিকাঠামো

stream=True একটি ইভেন্ট ইটারেবল রিটার্ন করে।

পাইথনে টুলের সংজ্ঞা

অন্তর্নির্মিত সরঞ্জাম: ওয়েব ব্রাউজ, কোড এক্সিকিউশন, ফাইল সিস্টেম

টুল কলের মধ্যে অবস্থা ব্যবস্থাপনা

এজেন্ট রিজনিং লুপের মধ্যে নির্মিত

আপনি কনফিগারেশন ফাইলগুলো ( AGENTS.md , SKILL.md , একটি প্রি-বিল্ট স্ক্রিপ্ট) লেখেন এবং একটি এপিআই কল করেন। বাকি সবকিছু গুগল সামলে নেয়।

স্যান্ডবক্স কীভাবে কাজ করে

interactions.create() call
        
        
Google provisions Ubuntu sandbox (Python 3.12, Node 22, 4 CPU / 16 GB RAM)
        
        
Agent reasoning loop:
  plan  fetch URLs  run Python  write files  reason  repeat
        
        
Events stream back in real time: tool calls, text chunks, completion
        
        
interaction.completed  environment_id + interaction_id

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

৩. সেট আপ করুন

গুগল ক্লাউড শেলে এই কোডল্যাবটি খুলতে নিচের বোতামটি ক্লিক করুন। সমস্ত নির্ভরতা আগে থেকেই ইনস্টল করা আছে।

ক্লাউড শেলে খুলুন

বিকল্প বি: স্থানীয় সেটআপ

git clone https://github.com/Saoussen-CH/tech-digest-managed-agent.git
cd tech-digest-managed-agent

প্রয়োজনে uv ইনস্টল করুন:

curl -LsSf https://astral.sh/uv/install.sh | sh

আপনার এপিআই কী কনফিগার করুন

cp .env.example .env
cloudshell edit .env

আপনার চাবি সেট করুন:

GEMINI_API_KEY=your-key-here

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

uv sync

৪. এজেন্টের সাথে প্রথমবার যোগাযোগ করুন

স্টার্টার ফাইলটি খুলুন

cloudshell edit run_digest.py

run_digest() এখন পূরণ করার জন্য একটি TODO এবং পরবর্তী ধাপের জন্য আরও তিনটি রয়েছে। এর উপরে দুটি হেল্পার ইতিমধ্যেই পূরণ করা আছে:

  • load_source(path) : স্ক্রিপ্টের সাপেক্ষে .agents/ থেকে একটি ফাইল পড়ে। পরবর্তী অনুশীলনীতে স্যান্ডবক্সে এডিটোরিয়াল ভয়েস, পিডিএফ প্লেবুক এবং রেন্ডারার মাউন্ট করার জন্য আপনি এটি ব্যবহার করবেন।
  • run_stream(stream) : ইভেন্ট স্ট্রিমটি প্রসেস করে এবং (environment_id, interaction_id) রিটার্ন করে। আপনাকে নিজে থেকে ইভেন্ট লুপ লিখতে হবে না।

কী যোগ করতে হবে

করণীয় ১: pass এর পরিবর্তে ব্যবহার করুন (আপাতত করণীয় ৩ ও ৪ উপেক্ষা করুন — ওগুলো পরবর্তী ধাপের জন্য):

    from google import genai
    client = genai.Client()

    stream = client.interactions.create(
        agent=BASE_AGENT,
        input="Fetch the Hacker News front page and list the top 5 stories.",
        stream=True,
        environment="remote",
    )

    environment_id, interaction_id = run_stream(stream)
    print(f"\nDone. environment_id={environment_id}")

প্রতিটি অংশ কী করে

genai.Client() এনভায়রনমেন্ট থেকে GEMINI_API_KEY পড়ে নেয়। বাকি সবকিছু এই ক্লায়েন্টের মাধ্যমেই সম্পন্ন হয়।

interactions.create() হলো মূল কল। চারটি প্যারামিটার এটিকে কার্যকর করে তোলে:

  • agent=BASE_AGENT : এটি অ্যান্টিগ্র্যাভিটি এজেন্ট ( antigravity-preview-05-2026 ) নির্বাচন করে, যা জেমিনি ৩.৫ ফ্ল্যাশ দ্বারা চালিত একটি সাধারণ-উদ্দেশ্যমূলক পরিচালিত এজেন্ট। এটিতে ডিফল্টরূপে তিনটি বিল্ট-ইন টুল সক্রিয় থাকে: code_execution (Bash, Python, Node.js চালানোর জন্য), google_search , এবং url_context (ওয়েব পেজ আনা ও পড়ার জন্য)। আপনি যখন environment প্যারামিটারটি পাস করেন, তখন ফাইলসিস্টেম টুলগুলো ( read_file , write_file , list_files ) স্বয়ংক্রিয়ভাবে সক্রিয় হয়ে যায়। একবার কল করলেই Python 3.12, Node.js 22, git, pip, এবং curl আগে থেকে ইনস্টল করা একটি সম্পূর্ণ পরিচালিত উবুন্টু এনভায়রনমেন্ট প্রস্তুত হয়ে যায়। কোনো কন্টেইনার তৈরি করার বা ডেপ্লয়মেন্ট চালানোর প্রয়োজন নেই।
  • input : এই রানের জন্য নির্ধারিত কাজ। এজেন্টটি হ্যাকার নিউজ ব্রাউজ করে এবং প্রাপ্ত ফলাফলগুলো নিয়ে যুক্তি-তর্ক করে।
  • environment="remote" : এই ইন্টারঅ্যাকশনের জন্য একটি নতুন ক্লাউড স্যান্ডবক্স প্রস্তুত করা হবে।
  • stream=True : ব্লক করার পরিবর্তে ইভেন্টগুলোর একটি ইটারেবল রিটার্ন করে। এটি ছাড়া, কলটি ৩০-৯০ সেকেন্ড অপেক্ষা করে এবং interaction.output_text হিসেবে সমস্ত আউটপুট একবারে রিটার্ন করে। স্ট্রিমিং চালু থাকলে, এজেন্ট যখন যা করে, আপনি তখনই তা দেখতে পান। এখানে স্ট্রিমিং কোনো অ্যাডভান্সড ফিচার নয়: এটিই সঠিক ডিফল্ট, কারণ ৯০-সেকেন্ডের একটি ব্ল্যাক বক্স আপনাকে কোনো সংকেত দেয় না যে এজেন্ট কাজ করছে নাকি আটকে আছে।

আপনি এইমাত্র যা প্রস্তুত করেছেন: প্রতিটি interactions.create() কল একটি ডেডিকেটেড স্যান্ডবক্স চালু করে:

উপাদান

স্পেসিফিকেশন

অপারেটিং সিস্টেম

বিচ্ছিন্ন উবুন্টু লিনাক্স পরিবেশ

আগে থেকে ইনস্টল করা রানটাইম

পাইথন ৩.১২, নোড.জেএস ২২, ব্যাশ

গণনা করুন

৪টি সিপিইউ কোর, ১৬ জিবি র‍্যাম

প্রসঙ্গ ব্যবস্থাপনা

প্রায় ১৩৫ হাজার টোকেনে স্বয়ংক্রিয় সংকোচন সক্রিয় হয়

নেটওয়ার্কিং

ইগ্রেস প্রক্সির মাধ্যমে বহির্গামী ওয়েব অ্যাক্সেস

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

environment_id হলো এইমাত্র চালানো স্যান্ডবক্সটির একটি হ্যান্ডেল। interaction.completed পরে, স্যান্ডবক্সটি বন্ধ হয় না: এটি ৭ দিন পর্যন্ত সচল থাকে। environment_id এর মাধ্যমেই আপনি এতে ফিরে যেতে পারবেন। দ্বিতীয় একটি interactions.create() কলে এটি পাস করলে এজেন্টটি একই ফাইলসিস্টেমে, একই ফাইল এবং ইনস্টল করা প্যাকেজসহ পুনরায় চালু হয়, যেন এটি কখনও বন্ধই হয়নি। পরবর্তী ধাপে এজেন্টকে পুনরায় না চালিয়েই পিডিএফ ডাউনলোড করার জন্য এটি ব্যবহৃত হয়, এবং তার পরের ধাপে কথোপকথন চালিয়ে যাওয়ার জন্য এটি ব্যবহার করা হয়।

interaction_id হলো এইমাত্র শেষ হওয়া কথোপকথনের পালাটির একটি হ্যান্ডেল। পরবর্তী কলে এটিকে previous_interaction_id হিসেবে পাস করুন, তাহলে এই পালায় এজেন্ট কী বলেছে এবং কী করেছে তার সম্পূর্ণ স্মৃতি তার মনে থাকবে।

যাচাই করুন

uv run python run_digest.py

এজেন্ট কাজ করার সময় আপনি সরাসরি আউটপুট দেখতে পাবেন:

[agent started]
  [tool] run_code
Here are the top 5 stories currently on the Hacker News front page, retrieved via the official Hacker News API:

1. **Qwen 3.6 27B is the sweet spot for local development** — 471 points
2. **.self: A new top-level domain designed to support self-hosting** — 116 points
...
Done. environment_id=e3de58774073f75a6ef42924c6ce2e88

environment="remote" করা থাকলেও API-টি একটি আসল environment_id রিটার্ন করে। স্যান্ডবক্সটি চলেছে। যা নেই তা হলো কনফিগারেশন: কোনো ভয়েস, স্কিল বা পিডিএফ জেনারেটর নেই। এজেন্টটি শুধু স্টোরিগুলো টেক্সট হিসেবে প্রিন্ট করে থেমে গেছে। পরবর্তী ধাপে এগুলো যোগ করা হবে।

আউটপুটের প্রতিটি লাইন run_stream() থেকে আসা একটি ইভেন্টের সাথে সম্পর্কিত:

step.type

এটা কি

run_stream() যা প্রিন্ট করে

"url_context_call"

এজেন্ট একটি URL আনছে

[tool] url_context (https://...)

"code_execution_call"

এজেন্ট স্যান্ডবক্সে কোড চালাচ্ছে

[tool] run_code

"google_search_call"

এজেন্ট ওয়েব অনুসন্ধান করছে

[tool] google_search

"function_call"

ফাইল টুল এবং অন্যান্য

[tool] read_file (/workspace/...)

step.delta যেখানে delta.type == "text"

এজেন্ট টেক্সট লিখছে

সরাসরি stdout-এ স্ট্রিম করা হয়েছে

৫. এজেন্টকে কাস্টমাইজ করুন

এজেন্টের কোনো নির্দেশনা ছিল না: কোনো ভয়েস, কোনো স্কিল, কোনো পিডিএফ জেনারেটর ছিল না। এই ধাপে আপনি .agents/ থেকে কনফিগারেশন ফাইলগুলো লোড করে স্যান্ডবক্সে মাউন্ট করবেন।

কী পরিবর্তন করতে হবে

run_digest.py ফাইলে চারটি পরিবর্তন করুন:

করণীয় ২: load_source() এর নিচে, তিনটি মডিউল-স্তরের কনস্ট্যান্ট যোগ করুন (এগুলো run_digest() এর বাইরে, ফাইলের শীর্ষে থাকবে):

AGENTS_MD       = load_source(".agents/AGENTS.md")
SKILL_MD        = load_source(".agents/skills/digest-pdf/SKILL.md")
GENERATE_PDF_PY = load_source(".agents/skills/digest-pdf/scripts/generate_pdf.py")

আপনি কী লোড করছেন তা দেখতে প্রতিটি ফাইল খুলুন: AGENTS.md ফাইলটি সম্পাদকীয় ভাষা এবং কর্মপ্রবাহের নিয়মাবলী নির্ধারণ করে; SKILL.md হলো ধাপে ধাপে নির্দেশিকা সম্বলিত পিডিএফ প্লেবুক; generate_pdf.py হলো আগে থেকে তৈরি করা রেন্ডারার যা এজেন্টটি চালাবে।

এখন run_digest() এর ভিতরে আরও দুটি পরিবর্তন করুন:

করণীয় ৩: environment "remote" থেকে sources ডিক্টে পরিবর্তন করুন, এবং input "" এ সেট করুন:

        environment={
            "type": "remote",
            "sources": [
                {
                    "type": "inline",
                    "target": ".agents/AGENTS.md",
                    "content": AGENTS_MD,
                },
                {
                    "type": "inline",
                    "target": ".agents/skills/digest-pdf/SKILL.md",
                    "content": SKILL_MD,
                },
                {
                    "type": "inline",
                    "target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
                    "content": GENERATE_PDF_PY,
                },
            ],
        },

করণীয় ৪: print(f"\nDone. environment_id={environment_id}") এর ঠিক পরেই এই লাইনগুলো যোগ করুন:

    set_key(".env", "ENVIRONMENT_ID", environment_id)
    set_key(".env", "INTERACTION_ID", interaction_id)

( run_digest.py ফাইলের শুরুতেই set_key ইম্পোর্ট করা হয়েছে।)

এই রান চলাকালীন এটি উভয় আইডি-ই .env ফাইলে লিখে দেয়, ফলে পরবর্তী ধাপে এজেন্টটি পুনরায় না চালিয়েই পিডিএফটি ডাউনলোড করা যায়।

প্রতিটি উৎস যা করে

প্রতিটি সোর্স হলো একটি ফাইল যা এজেন্ট চালু হওয়ার আগে স্টার্টআপের সময় স্যান্ডবক্স ফাইলসিস্টেমে মাউন্ট করা হয়। target পাথগুলো সেই জায়গার সাথে মিলে যায় যেখানে অ্যান্টিগ্র্যাভিটি হারনেস সেগুলোকে খুঁজে পাওয়ার আশা করে:

.agents/
├── AGENTS.md                               auto-loaded as global instructions
└── skills/
    └── digest-pdf/
        ├── SKILL.md                        auto-discovered and registered as a skill
        └── scripts/
            └── generate_pdf.py             pre-built renderer the agent can run

target পথ

পরিবর্তনশীল

হারনেসটি এটি দিয়ে যা করে

.agents/AGENTS.md

AGENTS_MD

স্থায়ী নির্দেশাবলী হিসেবে স্বয়ংক্রিয়ভাবে লোড হয়: সম্পাদকীয় ভাষা, কর্মপ্রবাহ, কার্যনির্বাহের নিয়মাবলী

.agents/skills/digest-pdf/SKILL.md

SKILL_MD

স্বয়ংক্রিয়ভাবে আবিষ্কৃত এবং একটি নামযুক্ত দক্ষতা হিসাবে নিবন্ধিত; এজেন্ট এটিকে নাম ধরে আহ্বান করে।

.agents/skills/digest-pdf/scripts/generate_pdf.py

GENERATE_PDF_PY

পূর্ব-নির্মিত পিডিএফ রেন্ডারার; এজেন্টটি summaries.json ফাইলটি লেখে এবং তারপর এই স্ক্রিপ্টটি চালায়।

যাচাই করুন

uv run python run_digest.py

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

[agent started]
  [tool] read_file (/.agents/skills/digest-pdf/SKILL.md)
  [tool] list_files (/.agents/skills/digest-pdf/scripts)
  [tool] read_file (/.agents/skills/digest-pdf/scripts/generate_pdf.py)
  [tool] run_code
  [tool] write_file (/workspace/summaries.json)
  [tool] run_code
  [tool] delete_file (/tmp/test_scrape.py)
I have successfully generated today's tech news digest and saved the formatted document to /workspace/digest.pdf.
Done. environment_id=4129ffd75574e308748e9425d7ec828f

environment_id এখন একটি বাস্তব মান: স্যান্ডবক্সটি আপনার কনফিগারেশন ফাইলগুলো দিয়ে চলেছে এবং এজেন্টটি digest.pdf তৈরি করেছে। পরবর্তী ধাপে এটি ডাউনলোড করা হবে।

৬. পিডিএফটি ডাউনলোড করুন।

এজেন্ট স্যান্ডবক্সের ভিতরে /workspace/digest.pdfdigest.pdf লিখেছে। পরিবেশের স্ন্যাপশটটি জেমিনি ফাইলস এপিআই (Gemini Files API)-এর মাধ্যমে একটি ট্যার (tar) আর্কাইভ হিসেবে পাওয়া যাচ্ছে।

প্রয়োজনে requests ইনস্টল করুন:

uv pip install requests

কী পূরণ করতে হবে

download_pdf.py খুলুন। এতে দুটি TODO আছে।

করণীয় ১: requests.get() কলটি পূরণ করুন:

    r = requests.get(
        f"https://generativelanguage.googleapis.com/v1beta/files/environment-{environment_id}:download",
        params={"alt": "media"},
        headers={"x-goog-api-key": api_key},
        allow_redirects=True,
    )
    r.raise_for_status()

URL-টি স্যান্ডবক্স স্ন্যাপশটকে নির্দেশ করে। params={"alt": "media"} মেটাডেটার পরিবর্তে সরাসরি বাইট ফেরত দেয়। আপনার বিদ্যমান GEMINI_API_KEY ফাইলস এপিআই-কেও প্রমাণীকরণ করে।

করণীয় ২: tar আর্কাইভ থেকে PDF ফাইলটি খুঁজুন এবং এক্সট্র্যাক্ট করুন:

            member = next(m for m in tar.getmembers() if m.name.endswith("workspace/digest.pdf"))
            tar.extract(member, path=tmp, filter="data")

টার পাথের প্রিফিক্স একেকবার একেক রকম হয়, তাই সঠিক পাথটি হার্ডকোড করার পরিবর্তে সাফিক্স দিয়ে সার্চ করুন। filter="data" অনিরাপদ টার এক্সট্র্যাকশন সংক্রান্ত পাইথন ৩.১৩-এর ডেপ্রিকেশন ওয়ার্নিংটি দমন করে।

যাচাই করুন

uv run python download_pdf.py
Saved digest.pdf (48,231 bytes)

একই ডিরেক্টরিতে থাকা digest.pdf খুলুন। এতে এজেন্টের তৈরি করা লাইভ ওয়েব পেজগুলোর ফরম্যাট করা সারসংক্ষেপটি রয়েছে।

৭. কথোপকথন চালিয়ে যান

আপনার কাছে ইতিমধ্যে digest.pdf আছে। আপনি যদি শুধু ফাইলটিই চেয়ে থাকেন, তাহলে আপনার কাজ শেষ। এই ধাপটি ভিন্ন একটি বিষয় নিয়ে: ওয়েব পুনরায় ফেচ না করেই এজেন্টকে ডাইজেস্ট পরিবর্তন করতে বলা।

স্যান্ডবক্সটি এখনও সচল আছে। এজেন্টের কাছে এখনও /workspace/digest.pdf আছে এবং এটি তার সারসংক্ষেপ করা প্রতিটি স্টোরি মনে রেখেছে। দ্বিতীয়বার interactions.create() কল করলে সেই একই স্যান্ডবক্সে একটি ফলো-আপ মেসেজ পাঠানো হয়। এখানে আপনি প্রতিটি স্টোরির নিচে একটি "Why it matters" নোট যোগ করতে বলেন, এবং এটি কোনো রকম রি-ফেচিং বা রি-সামারাইজিং ছাড়াই পিডিএফটি সরাসরি আপডেট করে দেয়।

কী পূরণ করতে হবে

refine_digest.py খুলুন। এতে তিনটি করণীয় কাজ (TODO) রয়েছে।

করণীয় ১ ও ২: interactions.create() এর ভিতরে দুটি মাল্টি-টার্ন প্যারামিটার পূরণ করুন:

    environment=environment_id,
    previous_interaction_id=interaction_id,

environment=environment_id একই স্যান্ডবক্সকে তার ফাইল ও প্যাকেজসহ পুনরায় চালু করে। previous_interaction_id=interaction_id এজেন্টকে তার কথোপকথনের ইতিহাস প্রদান করে। প্রথম কল থেকে আর কিছুই পরিবর্তন হয় না।

করণীয় ৩: ইভেন্ট লুপের পরে নতুন interaction_id .env ফাইলে সংরক্ষণ করুন:

set_key(".env", "INTERACTION_ID", interaction_id)

প্রতিটি interactions.create() কল একটি নতুন interaction_id তৈরি করে। এটিকে আবার লিখে রাখলে পরবর্তী রান এই পরিমার্জনটিকে previous_interaction_id হিসেবে পাস করে, ফলে টার্নগুলো সঠিকভাবে চেইন হয়। স্যান্ডবক্স আইডি কখনও পরিবর্তন হয় না, তাই ENVIRONMENT_ID আপডেট করার প্রয়োজন হয় না।

যে দুটি প্যারামিটার মাল্টি-টার্নকে কার্যকর করে তোলে

আইডি

এটি যা সংরক্ষণ করে

সাদৃশ্য

environment=environment_id

ফাইল, ইনস্টল করা প্যাকেজ, সিস্টেমের অবস্থা: লিনাক্স ফাইলসিস্টেমের সবকিছু।

মিটিংয়ের মাঝে একই অফিসের ডেস্ক রাখা

previous_interaction_id=interaction_id

কথোপকথনের ইতিহাস: পূর্ববর্তী পালাগুলোতে এজেন্ট যা বলেছিল এবং করেছিল

গত বৈঠকে যা আলোচনা হয়েছিল তা স্মরণ করে

আপনি যেকোনো একটি আইডি আলাদাভাবে পাস করতে পারেন:

  • শুধু environment_id : ফাইল ও প্যাকেজ পুনরায় ব্যবহার করুন, কিন্তু একটি নতুন আলোচনা শুরু করুন। একই ওয়ার্কস্পেসে নতুন কোনো কাজের জন্য এটি উপযোগী।
  • শুধুমাত্র previous_interaction_id ক্ষেত্রে: কথোপকথনের প্রেক্ষাপট চালিয়ে যান, কিন্তু একটি নতুন স্যান্ডবক্সে (ফাইলগুলো মুছে ফেলা হবে)।
  • উভয় ক্ষেত্রেই: পূর্ণ ধারাবাহিকতা, যা এই ধাপে ব্যবহৃত হয়।

environment_id ছাড়া: ফাঁকা স্যান্ডবক্স, কোনো পিডিএফ নেই। previous_interaction_id ছাড়া: কোনো কনটেক্সট নেই, এজেন্ট কোনো নির্দিষ্ট সেকশন পরিমার্জন করতে পারে না।

যাচাই করুন

uv run python refine_digest.py

স্ট্রিমটি দ্রুত হওয়া উচিত; এজেন্ট কোনো কিছু পুনরায় ফেচ করছে না। এটি শেষ হওয়ার পর:

Refinement done.
Saved digest_v2.pdf (52,418 bytes)

digest_v2.pdf খুলুন এবং digest.pdf এর সাথে তুলনা করুন। এখন প্রতিটি গল্পের সাথে 'কেন এটি গুরুত্বপূর্ণ' এই লাইনটি যুক্ত থাকা উচিত।

৮. একটি পরিচালিত এজেন্ট কনফিগারেশন স্থায়ী করুন

এখন পর্যন্ত প্রতিটি কলে AGENTS.md , SKILL.md এবং generate_pdf.py ফাইলগুলো ইনলাইনভাবে পাস করা হয়েছে। এটা কাজ করে, কিন্তু আপনার কলিং কোড প্রতিটি রানে ফাইলের সম্পূর্ণ বিষয়বস্তু বহন করে। agents.create() ফাংশনটি গুগলের দিকে একটি সংরক্ষিত নামযুক্ত এজেন্টের মধ্যে কনফিগারেশনটি স্থায়ীভাবে যুক্ত করে দেয়। পরবর্তী আহ্বানে শুধু এজেন্ট আইডিটি পাস করা হয়:

Inline calls:   send sources on every call
Named agent:    bake once → invoke by ID, no sources

কী পূরণ করতে হবে

save_agent.py খুলুন। এটির একটি TODO (TODO 1) রয়েছে।

লক্ষ্য করুন যে ধ্রুবকগুলি সরাসরি run_digest.py থেকে আমদানি করা হয়েছে (কোন পুনরাবৃত্তি নেই):

from run_digest import BASE_AGENT, AGENTS_MD, SKILL_MD, GENERATE_PDF_PY

করণীয় ১: agents.create() কলটি পূরণ করুন:

agent = client.agents.create(
    id="my-digest",
    base_agent=BASE_AGENT,
    description="Daily tech digest with editorial voice and PDF generation.",
    base_environment={
        "type": "remote",
        "sources": [
            {
                "type": "inline",
                "target": ".agents/AGENTS.md",
                "content": AGENTS_MD,
            },
            {
                "type": "inline",
                "target": ".agents/skills/digest-pdf/SKILL.md",
                "content": SKILL_MD,
            },
            {
                "type": "inline",
                "target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
                "content": GENERATE_PDF_PY,
            },
        ],
    },
)

আগের ধাপের ইনলাইন কলের সাথে মূল পার্থক্যটি হলো base_environment ( environment নয়): সোর্সগুলো গুগলের দিকে সংরক্ষিত থাকে এবং পরবর্তী প্রতিটি আহ্বানে স্বয়ংক্রিয়ভাবে মাউন্ট হয়। এটি একবার চালান, প্রতিটি ডাইজেস্ট রানের সময় নয়।

যাচাই করুন: এজেন্টটি সংরক্ষণ করুন

uv run python save_agent.py
Saved: my-digest
my-digest: Daily tech digest with editorial voice and PDF generation.

সংরক্ষিত এজেন্টকে আহ্বান করুন

invoke_agent.py খুলুন। এটি কোনো সোর্স ছাড়াই আইডি দ্বারা সেভ করা এজেন্টকে কল করে:

stream = client.interactions.create(
    agent="my-digest",
    input="",
    stream=True,
    environment="remote",
)

ইনলাইন কলের সাথে এটি তুলনা করুন: agent=BASE_AGENT এর পরিবর্তে "my-digest" ব্যবহৃত হয়েছে, এবং তিনটি ইনলাইন সোর্স সহ সম্পূর্ণ environment ব্লকটির পরিবর্তে environment="remote" ব্যবহৃত হয়েছে। কনফিগারেশনটি গুগলের পক্ষ থেকে আগে থেকেই অন্তর্ভুক্ত করা আছে।

যাচাই করুন: সংরক্ষিত এজেন্টটি চালু করুন

uv run python invoke_agent.py

আপনি ইনলাইন রানের মতোই একই লাইভ স্ট্রিম দেখতে পাবেন, কিন্তু এই কলে কোনো সোর্স ফাইল থাকে না। রান শেষ হওয়ার পর, .env ফাইলের ENVIRONMENT_ID এবং INTERACTION_ID আপডেট হয়ে যায়, ফলে আপনি আগের মতোই refine_digest.py নিয়ে কাজ চালিয়ে যেতে পারেন।

[agent started]
  [tool] read_file
  [tool] write_file
  [tool] run_code
I have successfully created today's tech news digest.
Done. environment_id=9a1c3e02-...

৯. পরিষ্কার করা

৭ দিন নিষ্ক্রিয় থাকার পর স্যান্ডবক্সটি স্বয়ংক্রিয়ভাবে মেয়াদোত্তীর্ণ হয়ে যায়। কোনো সার্ভার বন্ধ করার প্রয়োজন নেই। কোনো কন্টেইনার মুছে ফেলার প্রয়োজন নেই।

আপনি যদি কোনো এজেন্ট কনফিগ সংরক্ষণ করে থাকেন, তাহলে সেটি মুছে ফেলুন:

uv run python delete_agent.py

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

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

ব্যায়াম

ধারণা

মূল এপিআই

আপনার প্রথম কলটি করুন

একটি বাস্তব লিনাক্স স্যান্ডবক্স প্রস্তুত করুন এবং এর ইভেন্টগুলো সরাসরি স্ট্রিম করুন।

interactions.create(agent, input, environment, stream=True) , event.event_type

এজেন্টকে কাস্টমাইজ করুন

একই রানে কনফিগারেশন ফাইল মাউন্ট করুন; .env ফাইলে আইডিগুলো সংরক্ষণ করুন।

environment.sources , set_key

পিডিএফ ডাউনলোড করুন

এজেন্টটি পুনরায় না চালিয়ে পিডিএফটি ডাউনলোড করুন।

জেমিনি ফাইলস এপিআই :download download_pdf.py তে ডাউনলোড করুন

কথোপকথন চালিয়ে যান

ওয়েব পুনরায় না খুলেই কথোপকথন চালিয়ে যান।

environment=environment_id , previous_interaction_id=interaction_id

এজেন্ট কনফিগারেশন স্থায়ী করুন

এজেন্ট কনফিগারেশন সংরক্ষণ করুন; আইডি দ্বারা আহ্বান করুন, কোনো উৎসের প্রয়োজন নেই।

agents.create() , agents.list()

মূল নিদর্শনগুলি

  1. একটি কল, একটি স্যান্ডবক্স : interactions.create() সমস্ত পরিকাঠামো পরিচালনা করে (কোনো কন্টেইনার স্থাপন করার প্রয়োজন নেই, স্থানীয়ভাবে কোনো প্যাকেজ ইনস্টল করার দরকার নেই)।
  2. প্রগতিশীল স্ট্রিমিং : stream=True একটি ৯০-সেকেন্ডের ব্ল্যাক বক্সকে টুল কল এবং টেক্সট খণ্ডের একটি লাইভ ফিডে পরিণত করে।
  3. ইনলাইন সোর্স : কোনো আপলোড বা ডেপ্লয়মেন্ট ধাপ ছাড়াই AGENTS.md , SKILL.md এবং প্রি-বিল্ট স্ক্রিপ্টগুলোকে স্যান্ডবক্সে মাউন্ট করুন।
  4. স্বয়ংক্রিয় আবিষ্কারের সুবিধা নিন : .agents/ ফোল্ডারে রাখা ফাইলগুলো স্বয়ংক্রিয়ভাবে খুঁজে নেওয়া হয় (কোনো SDK কনফিগারেশনের প্রয়োজন নেই)।
  5. দ্বি-মাত্রিক অবস্থা : environment_id ফাইল এবং প্যাকেজ ট্র্যাক করে; previous_interaction_id কথোপকথনের প্রেক্ষাপট ট্র্যাক করে; যেকোনো একটি স্বাধীনভাবে পাস করা যেতে পারে।
  6. স্ন্যাপশট ডাউনলোড : পরিবেশটি একটি সম্পূর্ণ ফাইলসিস্টেম tar, যা Gemini Files API-এর মাধ্যমে অ্যাক্সেসযোগ্য।
  7. নামযুক্ত এজেন্ট : agents.create() কনফিগারেশন স্থায়ীভাবে তৈরি করে; পরবর্তী কলগুলিতে শুধুমাত্র এজেন্ট আইডি এবং environment="remote" পাঠানো হয়, কোনো সোর্স ছাড়া।

ADK + ক্লাউড রান বনাম ম্যানেজড এজেন্ট: এক নজরে পার্থক্য

সক্ষমতা

ADK + ক্লাউড রান

জেমিনি এপিআই-তে পরিচালিত এজেন্ট

একটি স্যান্ডবক্স সরবরাহ করুন

docker build + gcloud run deploy

interactions.create()

সরঞ্জাম সংজ্ঞায়িত করুন

এজেন্টের সাথে নিবন্ধিত পাইথন ফাংশন

অন্তর্নির্মিত: ওয়েব ব্রাউজ, কোড এক্সিকিউশন, ফাইল সিস্টেম

প্যাকেজ ইনস্টল করুন

ডকারফাইলে pip install

এজেন্ট স্যান্ডবক্সের ভিতরে pip install চালায়।

স্ট্রিম ইভেন্ট

কাস্টম এসএসই পরিকাঠামো

stream=True

একটি সেশন চালিয়ে যান

সেশন ডাটাবেস + কনটেক্সট ইনজেকশন

environment_id + previous_interaction_id

কনফিগারেশন ফাইল

এজেন্টে হার্ড-কোড করা অথবা স্টার্টআপের সময় ইনজেক্ট করা

environment.sources এর মাধ্যমে মাউন্ট করা হয়েছে

ব্যবস্থাপনার জন্য অবকাঠামো

কন্টেইনার, ক্লাউড রান, আইএএম, সিক্রেটস

কোনোটিই না

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