ADK সহ এজেন্টিক ওয়ার্কফ্লো

১. ভূমিকা

ভাইবস্টুডিও

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

দৃশ্যপট

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

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

একটি ধারণা থেকে প্রকাশিত ক্লিপ পর্যন্ত আপনার তৈরি করা কর্মপ্রবাহ।

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

১০-সারাংশ

  • গ্রাফ ইঞ্জিনিয়ারিংয়ের ভিত্তি : বহু-ধাপের এজেন্ট আর্কিটেকচারের জন্য সুস্পষ্ট নিয়ন্ত্রণ প্রবাহ এবং কাঠামোগত নির্বাহ পথের প্রয়োজন হয়। আপনি এজ টাপল, START এন্ট্রি পয়েন্ট, সমান্তরাল ফ্যান Workflow আউট অ্যাগ্রিগেশনের জন্য JoinNode এবং অবস্থার উপর ভিত্তি করে নির্বাহ পরিচালনা করার জন্য ডিটারমিনিস্টিক রাউটার নোড ব্যবহার করে একটি ADK ওয়ার্কফ্লো তৈরি করেন।
  • এজেন্ট মোড এবং লাইফসাইকেল কলব্যাক : বিশেষায়িত কাজগুলোর জন্য স্বতন্ত্র কার্যপ্রণালী এবং সুনির্দিষ্ট সুরক্ষাব্যবস্থা প্রয়োজন। আপনি ওয়ার্কফ্লো নোড হিসেবে chat , single_turn , এবং tool-enabled task মোড ব্যবহার করে ADK Agent ইনস্ট্যান্সগুলো কনফিগার করেন এবং before_model_callbackafter_agent_callback দিয়ে ইন্টারসেপ্টর প্রয়োগ করেন।
  • মানব-সমন্বিত পরিচালনা : গুরুত্বপূর্ণ সৃজনশীল পর্যায়ে মানুষের বিচার-বিবেচনার জন্য প্রোডাকশন পাইপলাইনগুলো থেমে যায়। আপনি ওয়ার্কফ্লো এক্সিকিউশন স্থগিত করতে, কাঠামোগত রেসপন্স স্কিমা প্রয়োগ করতে এবং নিষ্ক্রিয় রানটাইম প্রসেসগুলোকে চালু না রেখেই এক্সিকিউশন পুনরায় শুরু করতে RequestInput ব্যবহার করেন।
  • স্তরভিত্তিক এজেন্ট মেমরি : প্রোডাকশন সিস্টেমগুলো ক্ষণস্থায়ী এক্সিকিউশন স্টেটকে স্থায়ী কনটেক্সট থেকে আলাদা রাখে। আপনি Event(state=...) এবং প্যারামিটার বাইন্ডিং ব্যবহার করে স্বল্পমেয়াদী সেশন স্টেট পরিচালনা করেন, এবং বিভিন্ন রানের মধ্যে ক্রিয়েটর প্রেফারেন্সগুলো এক্সট্র্যাক্ট, কনসলিডেট ও পারসিস্ট করার জন্য GEAP মেমরি ব্যাংক সংযুক্ত করেন।
  • এন্টারপ্রাইজ নলেজ বেসের সাথে ভিত্তি স্থাপন : স্বায়ত্তশাসিত এজেন্টদের গতিশীল ডোমেইন প্রেক্ষাপট এবং শ্রোতাদের মনোভাব প্রয়োজন। এজেন্টের আউটপুটগুলোকে শব্দার্থগতভাবে ভিত্তি দেওয়ার জন্য, আপনি প্যারালাল ফ্যান-আউটের মধ্যে একটি ডেডিকেটেড রিট্রিভাল নোড হিসেবে একটি GEAP RAG ইঞ্জিন কর্পাস সংযুক্ত করেন।
  • দীর্ঘস্থায়ী ওয়ার্কফ্লো এবং ডেপ্লয়মেন্ট : মাল্টিমোডাল ভিডিও রেন্ডারিং দীর্ঘ সময় ধরে অ্যাসিঙ্ক্রোনাসভাবে পরিচালিত হয়। আপনি পেন্ডিং কল রিসিপ্ট সহ LongRunningFunctionTool প্রয়োগ করে কল আইডি অনুযায়ী ওয়ার্কফ্লোটি সাসপেন্ড ও রিজুম করেন এবং ক্লাউড রান-এ ADK Runner ব্যবহার করে সমাপ্ত পাইপলাইনটি ডেপ্লয় করেন।

এই কোডল্যাবটি যেভাবে সাজানো হয়েছে

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

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

ওয়ার্কবেঞ্চ অনুশীলনগুলো সম্পন্ন করার পর, আপনি একটি এন্ড-টু-এন্ড এজেন্টিক পাইপলাইন তৈরি করবেন এবং ভিডিও কন্টেন্ট তৈরির জন্য একটি চলমান ভাইবস্টুডিও অ্যাপ্লিকেশন ক্লাউড রান-এ ডেপ্লয় করবেন।

কোথায় কী চলে: ভাইবস্টুডিও ওয়ার্কবেঞ্চ, আপনার ব্যাকএন্ড, এবং গুগল ক্লাউড পরিষেবাগুলো।

এই পরিবেশটি তিনটি প্রধান উপাদান নিয়ে গঠিত: ভাইবস্টুডিও ওয়ার্কবেঞ্চ (কোড সম্পাদনা এবং রানটাইম যাচাইকরণের জন্য স্থানীয় ওয়েব ইন্টারফেস), আপনার ব্যাকএন্ড ( agent/ মধ্যে থাকা এডিকে Workflow এবং স্টেজ স্যান্ডবক্স), এবং গুগল ক্লাউড (জেমিনি মডেল, জিইএপি মেমোরি ব্যাংক, র‍্যাগ ইঞ্জিন, এবং ভিও ভিডিও জেনারেশন)।

২. সেটআপ

আপনার কর্মশালার ক্রেডিট দাবি করুন

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

ওপেন ক্লাউড শেল

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

ক্লাউড শেল চালু করতে:

  1. গুগল ক্লাউড কনসোলে যান।
  2. শীর্ষ নেভিগেশন হেডারে, অ্যাক্টিভেট ক্লাউড শেল (টার্মিনাল উইন্ডো আইকন)-এ ক্লিক করুন।

ক্লাউড শেল

ব্রাউজার উইন্ডোর নীচে একটি টার্মিনাল সেশন চালু হয়।

রিপোজিটরি ক্লোন এবং ইনিশিয়ালাইজ করুন

প্রজেক্টটি ক্লোন করতে ক্লাউড শেল টার্মিনালে নিম্নলিখিত কমান্ডগুলো চালান:

git clone https://github.com/gca-americas/vibetube-studio
cd ~/vibetube-studio

কনফিগারেশন প্রম্পট

সেটআপের সময় আপনার কাছে নিম্নলিখিত বিবরণগুলো জানতে চাওয়া হবে:

  • গুগল ক্লাউড প্রজেক্ট আইডি : setup_project.sh দ্বারা অনুরোধ করা হলে, স্বয়ংক্রিয়ভাবে একটি নতুন প্রজেক্ট তৈরি করতে এন্টার চাপুন। আপনি যদি একটি বিদ্যমান প্রজেক্ট (যেমন আগে থেকে বরাদ্দ করা কোনো প্রজেক্ট) ব্যবহার করতে চান, তাহলে আপনার প্রজেক্ট আইডি লিখুন এবং বিলিং সক্রিয় থাকা অবস্থায় বানানটি সঠিক কিনা তা নিশ্চিত করুন।
  • ইভেন্ট কোড : আপনার প্রশিক্ষকের দেওয়া রুম কোডটি প্রবেশ করান। যদি আপনি কোডটি না পেয়ে থাকেন, তবে কোনো টিচিং অ্যাসিস্ট্যান্ট বা পাশের জনের কাছে খোঁজ নিন। আপনি যদি এই ল্যাবটি বাড়িতে সম্পন্ন করেন, তবে ডিফল্ট sandbox রুমটি গ্রহণ করতে এন্টার চাপুন।
  • চ্যানেল প্রদর্শনের নাম : setup_codelab.sh এ অনুরোধ করা হলে আপনার নাম বা পছন্দের চ্যানেল হ্যান্ডেল লিখুন, অথবা আপনার গুগল অ্যাকাউন্ট থেকে তৈরি ডিফল্ট নামটি গ্রহণ করতে এন্টার চাপুন।

ক্রমানুসারে দুটি সেটআপ স্ক্রিপ্ট চালান:

./setup_project.sh
./setup_codelab.sh
  • setup_project.sh : সক্রিয় বিলিং সহ একটি গুগল ক্লাউড প্রজেক্ট তৈরি বা পুনঃব্যবহার করে, প্রজেক্ট আইডিটি ~/project_id.txt এ সংরক্ষণ করে এবং সক্রিয় gcloud কনটেক্সট কনফিগার করে।
  • setup_codelab.sh : .venv ফাইলে uv এবং Python ডিপেন্ডেন্সি ইনস্টল করে, প্রয়োজনীয় Google Cloud API সক্রিয় করে, .env ফাইলে আপনার চ্যানেল সেটিংস কনফিগার করে, Gemini-এর মাধ্যমে মডেল অ্যাক্সেস যাচাই করে, Memory Bank এবং RAG রিসোর্স প্রোভিশন করে, ওয়ার্কবেঞ্চ ইন্টারফেস বিল্ড করে এবং VibeStudio ওয়ার্কবেঞ্চ চালু করে।

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

7 · Preflight
   python 3.12
   auth path A: Vertex via ADC (STUDIO_VERTEX=1)
   Google Cloud ADC (project <your-project>)
   stage0_prompt loads
  ...
   stage6_video loads (13 edges)
   aiplatform.googleapis.com enabled (Gemini, Veo, Memory Bank, RAG Engine)
   vectorsearch.googleapis.com enabled (the vector store a RAG corpus is built on)
   Memory Bank connected
   RAG corpus connected
   VibeStudio Workbench running on port 4600

PREFLIGHT GREEN

Setup finished. The VibeStudio Workbench is already running.

  Open this and start at step 1
      https://4600-<your cloud shell host>/step/story

  It runs in the background. You do not need to start anything else.
      log      runs/lab.log
      stop     kill $(cat runs/lab.pid)
      start    scripts/start.sh

ওই লিঙ্কে ক্লিক করুন। একই ঠিকানাটি Web Preview → Change port → 4600 -এর অধীনে পাওয়া যাবে।

যেকোনো সময়ে পরিবেশ পুনরায় পরীক্ষা করতে, python scripts/preflight.py চালান। ওয়ার্কবেঞ্চ পুনরায় চালু করতে, scripts/restart.sh চালান। আবার সেট আপ করতে, ./setup_codelab.sh চালান; এটি আপনার কনফিগারেশন এবং অগ্রগতি সংরক্ষণ করে।

এটি খোলা রেখে, দৃশ্যকল্পের জন্য ধাপ ১, ‘গল্পটি’ , এবং তৈরি হওয়া গ্রাফটির আকৃতির জন্য ধাপ ২, ‘আপনি যা তৈরি করবেন ’, পড়ুন। দুটির কোনোটিতেই অনুশীলন নেই। তারপর ধাপ ৩-এর জন্য এখানে ফিরে আসুন।

VibeStudio Workbench-এর প্রতিটি হাতে-কলমে কাজ করার অংশ একটি যাচাইকরণ প্যানেলের মাধ্যমে শেষ হয়, যা আসল আর্টিফ্যাক্টগুলো—অর্থাৎ ডিস্কে থাকা ফাইল এবং রান দ্বারা লিখিত সেশনগুলো—পড়ে দেখে।

রিপোজিটরি লেআউট

রিপোজিটরিটি মূল ওয়ার্কফ্লো লজিক, ধাপে ধাপে স্যান্ডবক্স, ওয়ার্কবেঞ্চ এনভায়রনমেন্ট এবং প্রোডাকশন অ্যাপ্লিকেশনে বিভক্ত:

vibe-studio-lab/
├── agent/                  # Core ADK workflow, graph definition, and platform services
   ├── graph.py            # Workflow graph definition, node functions, and routers
   ├── desk.py             # Video render desk using LongRunningFunctionTool
   ├── schemas.py          # Pydantic schemas for directions, gates, and scripts
   ├── trends.py           # Trend generation and sampling utilities
   ├── backlog.txt         # Creator video ideas backlog
   ├── comments.md         # Audience comments for RAG Engine corpus seeding
   ├── policy_words.txt    # Blocked subject words for deterministic policy checks
   └── platform/           # Google Cloud service clients (Memory Bank, RAG, Veo)
       ├── config.py       # Environment variables, locations, and model configurations
       ├── memory.py       # GEAP Memory Bank callbacks and context injection
       ├── rag.py          # GEAP RAG Engine corpus creation and semantic retrieval
       └── videogen.py     # Veo video generation and operation polling
├── stage0_prompt/          # Step sandboxes: isolated agent.py files runnable in adk web
   └── ...                 # stage1_fanout through stage6_video for incremental steps
├── server/ & web/          # VibeStudio Workbench (FastAPI backend and React frontend)
├── vibestudio/             # Complete production application deployed to Cloud Run
   ├── server/             # FastAPI production server and event runner
   ├── web/                # End-user React web application
  • agent/ : এতে মূল ওয়ার্কফ্লো গ্রাফ থাকে। প্যারালাল ফ্যান-আউট নোড, ডিটারমিনিস্টিক পলিসি রাউটিং, মেমরি কলব্যাক এবং ভিডিও জেনারেশন টুলস বাস্তবায়নের জন্য আপনাকে এই ডিরেক্টরির ফাইলগুলো সম্পাদনা করতে হবে।
  • agent/platform/ : গুগল ক্লাউড পরিষেবাগুলির সাথে ইন্টারফেস করে, যার মধ্যে রয়েছে জেমিনি মডেল, জিইএপি মেমোরি ব্যাংক, জিইএপি র‍্যাগ ইঞ্জিন, এবং ভিও ভিডিও সিন্থেসিস।
  • stage0_prompt/ থেকে stage6_video/ : স্বয়ংসম্পূর্ণ স্যান্ডবক্স পরিবেশ। প্রতিটি ফোল্ডার একটি স্বতন্ত্র root_agent এক্সপোর্ট করে, যাতে আপনি এমবেডেড ADK ডেভেলপমেন্ট ইন্টারফেসের মাধ্যমে প্রতিটি ধাপকে আলাদাভাবে চালাতে ও পরীক্ষা করতে পারেন।
  • server/ এবং web/ : VibeStudio Workbench অ্যাপ্লিকেশনটি স্থানীয়ভাবে ৪৬০০ পোর্টে চলছে। এটিতে স্টেপ ডকুমেন্টেশন, ইন-পেজ কোড এডিটর, রানটাইম এভিডেন্স ভেরিফায়ার এবং গ্রাফ ভিজ্যুয়ালাইজেশন হোস্ট করা হয়।
  • vibestudio/ : চূড়ান্ত ধাপে সম্পূর্ণ প্রোডাকশন অ্যাপ্লিকেশনটি প্যাকেজ করে ক্লাউড রান-এ ডেপ্লয় করা হয়। এতে সম্পন্ন হওয়া ওয়ার্কফ্লো গ্রাফের নিজস্ব একটি স্বতন্ত্র কপি থাকে।

৩. মনোলিথিক এজেন্ট

একটি মাল্টি-নোড ওয়ার্কফ্লো গ্রাফ তৈরি করার আগে, আপনি stage0_prompt/agent.py ফাইলে একটিমাত্র এজেন্টের মাধ্যমে একটি আর্কিটেকচারাল বেসলাইন স্থাপন করেন। এই এজেন্টটি একটি মনোলিথিক সিস্টেম প্রম্পটের উপর নির্ভর করে, যা দুটি পাইথন ফাংশন টুলের সাহায্যে গদ্যে প্রোডাকশন পাইপলাইন বর্ণনা করে।

এই বেসলাইনটির মূল্যায়ন প্রম্পট-চালিত সমন্বয়ের কার্যগত সীমাবদ্ধতাগুলো তুলে ধরে এবং এটি প্রতিষ্ঠা করে যে কেন প্রোডাকশন সিস্টেমগুলোতে গ্রাফ অর্কেস্ট্রেশন প্রয়োজন।

ADK এজেন্ট স্থাপত্য (3A)

VibeStudio Workbench- এ, ধাপ 3 · Monolithic agent- এ যান এবং ADK agent architecture (3A) খুলুন। এই ভিউটি একটি ADK এজেন্টের ( LlmAgent ) মূল স্থাপত্য স্তরগুলি উপস্থাপন করে:

০৩-৩এ

from google.adk.agents import LlmAgent
from google.adk.tools import mcp_toolset

root_agent = LlmAgent(
    model="gemini-3.5-flash",                 # model
    instruction=BRAND_INSTRUCTION,            # instruction
    skills=[load_skill("brand-audit")],       # skills
    tools=[mcp_toolset("mcp_brand_style")],   # tools
    output_schema=BrandStyleReport,           # structured output
    before_agent_callback=setup_ctx,          # interceptor
    before_model_callback=require_image,      # interceptor
    after_model_callback=schema_guard,        # interceptor
)

ইন্টারেক্টিভ ডায়াগ্রামটি এজেন্ট উপাদানগুলোকে পাঁচটি অপারেশনাল ডোমেইনে বিভক্ত করে:

  • যুক্তি স্তর (মডেল) : মূল ভাষা মডেল (যেমন জেমিনি ৩ ফ্ল্যাশ) যা জ্ঞানীয় কাজ, প্রম্পট যুক্তি এবং টুল নির্বাচন সম্পাদন করে। আর্কিটেকচারের বাকি সবকিছু এই মডেলকে তথ্য সরবরাহ করে অথবা সীমাবদ্ধ করে।
  • প্রসঙ্গ স্তর (নির্দেশনা এবং দক্ষতা) : মডেলের যুক্তিবোধকে রূপদানকারী নির্দেশাবলী। instruction স্থায়ী সিস্টেম প্রম্পট, পার্সোনা এবং কার্যপ্রণালীর নিয়মাবলী স্থাপন করে। skills পুনরাবৃত্তিমূলক কর্মপ্রবাহের জন্য সংস্করণযুক্ত, পদ্ধতিগত নির্দেশনা ( SKILL.md ) প্রদান করে।
  • সহযোগিতা এবং কর্মস্তর (টুলস, সাবএজেন্টস, ওয়ার্কফ্লো, আউটপুট স্কিমা) : এই ইন্টারফেসগুলো এজেন্টকে বাহ্যিক সিস্টেমে কাজ করতে এবং টাইপ করা ডেটা নির্গত করতে সক্ষম করে। tools কলযোগ্য পাইথন ফাংশন বা মডেল কনটেক্সট প্রোটোকল (MCP) এন্ডপয়েন্ট সরবরাহ করে। subagents অধীনস্থ অর্পিত কাজগুলো সম্পাদন করে। workflow একাধিক এজেন্টের গ্রাফের মধ্যে সমন্বয় সাধন করে। output_schema পাইড্যান্টিক মডেল প্রয়োগ করে এটি নিশ্চিত করে যে ডাউনস্ট্রিম গ্রাহকরা অসংগঠিত টেক্সটের পরিবর্তে যাচাইকৃত JSON পায়।
  • ইন্টারসেপ্টর লেয়ার (লাইফসাইকেল কলব্যাকস) : এটি এমন একটি ডিটারমিনিস্টিক গার্ডরেল যা এজেন্ট এক্সিকিউশনের আগে ও পরে ( before_agent / after_agent ), মডেলের প্রতিটি টার্নের আগে ( before_model / after_model ), এবং টুল কলের আগে ( before_tool / after_tool ) কাস্টম কোড এক্সিকিউট করে। ইন্টারসেপ্টরগুলো মডেলের কমপ্লায়েন্সের উপর নির্ভর না করেই পলিসির নিয়মগুলো প্রয়োগ করে।
  • বাহ্যিক অবস্থা (সেশন এবং মেমরি) : এজেন্ট লজিক থেকে পৃথক স্টেটফুল পারসিস্টেন্স। Session বর্তমান এক্সিকিউশন থ্রেডের জন্য ক্ষণস্থায়ী ওয়ার্কিং মেমরি এবং ইভেন্ট ট্রেস সংরক্ষণ করে। Memory GEAP মেমরি ব্যাংকের মতো পরিচালিত পরিষেবা ব্যবহার করে টেকসই ক্রস-সেশন ফ্যাক্ট এবং প্রেফারেন্স বজায় রাখে।

এই ধাপে মনোলিথিক এজেন্টটি এই প্রিমিটিভগুলোর মধ্যে কেবল তিনটি বাস্তবায়ন করে: model , instruction এবং tools । পরবর্তী ধাপগুলোতে গ্রাফ ওয়ার্কফ্লো, স্ট্রাকচার্ড স্কিমা, ইন্টারসেপ্টর এবং পারসিস্টেন্ট মেমোরি সার্ভিস অন্তর্ভুক্ত করা হয়।

মনোলিথিক এজেন্ট স্পেসিফিকেশন (3B)

ওয়ার্কবেঞ্চে, মনোলিথিক এজেন্ট স্পেসিফিকেশন (3B) -তে যান। বেসলাইন এজেন্ট সংজ্ঞা পরীক্ষা করার জন্য stage0_prompt/agent.py খুলুন:

  • একক নির্দেশ : সিস্টেম প্রম্পটটি পাঁচটি স্বতন্ত্র প্রোডাকশন টাস্ককে অবিচ্ছিন্ন গদ্যে সংক্ষেপিত করে: প্ল্যাটফর্মের ট্রেন্ড আবিষ্কার করা, ব্যাকলগ আইডিয়া পর্যালোচনা করা, সৃজনশীল ধারণা প্রস্তাব করা, নিষিদ্ধ বিষয় নীতি প্রয়োগ করা এবং শট লিস্টের খসড়া তৈরি করা।
  • অন্তর্নিহিত ডেটা উৎসসমূহ : এজেন্টটি গ্রাফের পাশে সংজ্ঞায়িত দুটি উৎসকে নির্দেশ করে:
    • agent/trends.py : ২৫০টি ট্রেন্ডের একটি পুল থেকে ডাইনামিক হিট স্কোর সহ দশটি সক্রিয় ফরম্যাট এবং স্টাইল ট্রেন্ডের নমুনা সংগ্রহ করে।
    • agent/backlog.txt : নির্মাতার মূল ধারণাপত্রগুলো লাইন বাই লাইন পড়ে।

এজেন্ট (3C) এর সরঞ্জাম

ওয়ার্কবেঞ্চে, Agent (3C)-এর Tools- এ যান।

একজন এজেন্টের কাছে টুল কী?

একটি ল্যাঙ্গুয়েজ মডেল স্বভাবতই একটি ক্লোজড-ওয়ার্ল্ড রিজনিং ইঞ্জিন: এটি শুধুমাত্র প্রি-ট্রেইনড ওয়েট এবং এর ইমিডিয়েট কনটেক্সট উইন্ডোতে উপস্থিত টোকেনগুলোর ওপর ভিত্তি করে কাজ করে। এটি স্বাভাবিকভাবে কোনো ডাটাবেস কোয়েরি করতে, রিয়েল-টাইম এপিআই অ্যাক্সেস করতে বা কোড এক্সিকিউট করতে পারে না।

একটি টুল এই ব্যবধান দূর করে। এটি মডেলকে বাহ্যিক কার্যকারিতা প্রদান করে, যার ফলে মডেলটি বাস্তব তথ্য সংগ্রহ করতে এবং বাহ্যিক সিস্টেমে সুনির্দিষ্ট কার্যক্রম সম্পাদন করতে পারে।

০৩-৩সি

মডেল এবং ADK রানটাইমের মধ্যে টুল কলিং একটি সুনির্দিষ্ট পাঁচ-পর্যায়ের প্রোটোকল অনুসরণ করে:

  1. স্কিমা ঘোষণা : ডেভেলপার এজেন্টকে পাইথন ফাংশন সরবরাহ করেন। ADK প্রতিটি ফাংশনের নাম, টাইপ অ্যানোটেশন এবং ডকস্ট্রিং পরীক্ষা করে একটি OpenAPI-উপযোগী JSON স্কিমা ঘোষণা তৈরি করে, যা এর প্যারামিটার এবং উদ্দেশ্য বর্ণনা করে।
  2. মডেলের যুক্তি : অনুমানের সময়, মডেলটি মূল্যায়ন করে যে ব্যবহারকারীর অনুরোধের জন্য বাহ্যিক ডেটার প্রয়োজন আছে কিনা। প্রয়োজনে, মডেলটি একটি কাঠামোগত function_call ইভেন্ট নির্গত করে, যাতে স্কিমার সাথে মেলে এমন টার্গেট ফাংশনের নাম এবং আর্গুমেন্ট ডিকশনারি থাকে।
  3. রানটাইম এক্সিকিউশন : মডেলটি নিজে কোনো কোড এক্সিকিউট করে না। ADK রানটাইম function_call কলটিকে ইন্টারসেপ্ট করে, প্রদত্ত আর্গুমেন্টগুলো ব্যবহার করে প্রকৃত লোকাল পাইথন ফাংশনটি এক্সিকিউট করে এবং রিটার্ন ভ্যালুটি ক্যাপচার করে।
  4. কনটেক্সট রি-ইনজেকশন : ADK রানটাইম ফাংশনের রিটার্ন ভ্যালুকে একটি function_response ইভেন্টে প্যাকেজ করে এবং সক্রিয় সেশন হিস্ট্রিতে যুক্ত করে।
  5. চূড়ান্ত সংশ্লেষণ : মডেলটি এখন তার কনটেক্সট উইন্ডোতে উপস্থিত টুলের আউটপুট প্রক্রিয়াকরণ করে এবং তার প্রতিক্রিয়া সম্পন্ন করে।

stage0_prompt/agent.py ফাইলে, দুটি গবেষণা সরঞ্জামকে সাধারণ পাইথন ফাংশন হিসেবে সংজ্ঞায়িত করা হয়েছে:

def check_trends() -> dict:
    """Ten formats trending on the platform right now, with a heat score each."""
    from agent.trends import sample_trends
    return {"trends": sample_trends()}


def read_backlog() -> dict:
    """The creator's backlog: ideas they noted down to make someday."""
    from agent.graph import backlog_notes
    return {"backlog": backlog_notes()}

সরাসরি সম্পাদনা এবং বাস্তবায়ন

ওয়ার্কবেঞ্চ কোড এডিটরে, এজেন্টের tools লিস্টে দুটি ফাংশন রেফারেন্স যোগ করুন:

    tools=[check_trends, read_backlog],

আপনার পরিবর্তনটি সংরক্ষণ করুন। ফাইলটি ডিস্কে আপডেট হয়, এবং যাচাইকরণ সারিটি নিশ্চিত করে যে উভয় টুলই সংযুক্ত আছে।

এমবেডেড ADK ডেভেলপমেন্ট ইন্টারফেসটি চালু করতে Open adk web-এ ক্লিক করুন। প্রস্তাবিত আইডিয়া প্রম্পটটি পাঠান:

tonight's idea: a tiny robot doing laundry at midnight

কী আশা করা যায় এবং কেন

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

  • রেসপন্সের আগে দুটি টুল এক্সিকিউশন ইভেন্ট দেখা যায় : আপনি check_trends এবং read_backlog জন্য function_call এবং function_response ইভেন্টগুলো দেখতে পাবেন।
    • কারণ : জেমিনি সিস্টেমের প্রম্পট নির্দেশিকাটি ("কী ট্রেন্ডিং আছে তা দেখুন। আপনার জমে থাকা ধারণাগুলো দেখুন") মূল্যায়ন করে দেখেছে যে, এর গুরুত্বের তালিকায় প্ল্যাটফর্ম ট্রেন্ড এবং চ্যানেল নোটের অভাব রয়েছে, এবং এর প্রেক্ষাপটকে সুদৃঢ় করতে উভয় ফাংশনকেই কাজে লাগিয়েছে।
  • এজেন্ট একটি দিকনির্দেশনা প্রস্তাব করে এবং নিশ্চিতকরণের জন্য অপেক্ষা করে : প্রতিক্রিয়াটি প্রবণতা এবং জমে থাকা কাজের সারসংক্ষেপ করে একটি ভিডিও দিকনির্দেশনা প্রস্তাব করে এবং আপনাকে নিশ্চিত করতে বলে।
    • কারণ : নির্দেশনায় মডেলকে স্ক্রিপ্ট তৈরি করার আগে নির্মাতার সাথে দিকনির্দেশনা বিষয়ে একমত হতে বলা হয়েছিল।
  • পরবর্তী ধাপে নিশ্চিতকরণ এড়িয়ে যাওয়া : একটি দ্বিতীয় বার্তা পাঠান: skip the questions, just describe the video । এজেন্ট সঙ্গে সঙ্গে নিশ্চিতকরণ এড়িয়ে গিয়ে শিরোনাম এবং শটগুলোর খসড়া তৈরি করে ফেলেন।
    • কারণ : প্রম্পট নির্দেশাবলী সুনির্দিষ্ট বাধার পরিবর্তে পরামর্শমূলক নির্দেশিকা হিসেবে কাজ করে। একটি মনোলিথিক এজেন্টে, ব্যবহারকারীর নির্দেশাবলী সিস্টেমের বিদ্যমান প্রম্পট নিয়মগুলোকে অগ্রাহ্য করতে পারে, কারণ কোনো বাহ্যিক ওয়ার্কফ্লো কার্যপ্রবাহকে নিয়ন্ত্রণ করে না।

একটি মনোলিথিক প্রম্পটের স্থাপত্যগত সীমাবদ্ধতা

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

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

এই স্থাপত্যগত ফাঁকগুলোই পরবর্তী ধাপে নির্মিত সুস্পষ্ট গ্রাফ ওয়ার্কফ্লোতে মনোলিথিক এজেন্টকে বিভক্ত করার প্রেরণা জোগায়।

৪. এজেন্টিক ওয়ার্কফ্লোর মৌলিক বিষয়সমূহ

VibeStudio Workbench- এ, ধাপ ৪ · Agentic workflow fundamentals , অংশ ৪A থেকে ৪D- তে যান।

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

গ্রাফ স্থাপত্য এবং নির্বাহ শৃঙ্খল (4A)

ওয়ার্কবেঞ্চে, গ্রাফ আর্কিটেকচার এবং এক্সিকিউশন চেইন (4A) খুলুন।

একটি ADK Workflow এজেন্ট এক্সিকিউশনকে একটি ডিরেক্টেড গ্রাফ হিসাবে গঠন করে যা এজ লিস্ট দ্বারা সংজ্ঞায়িত হয়:

  • চেইন : ক্রমিক টাপলগুলো রৈখিক নোড এক্সিকিউশন সংজ্ঞায়িত করে ( (node_a, node_b, node_c) )।
  • সমান্তরাল শাখা : একটি উৎস নোড ভাগ করে নেওয়া স্বাধীন চেইনগুলো একযোগে কার্যকর হয়।
  • সিঙ্ক্রোনাইজেশন : একটি JoinNode এ একত্রিত হওয়া চেইনগুলো রিলিজ করার আগে সমস্ত আগত ব্রাঞ্চ রিপোর্ট করা পর্যন্ত অপেক্ষা করে।
  • ডিটারমিনিস্টিক কন্ট্রোল : এক্সিকিউশন ফ্লো প্রম্পট টেক্সট থেকে অনুমান করার পরিবর্তে ঘোষিত কোড স্ট্রাকচার দ্বারা পরিচালিত হয়।

০৪-৪এ

ADK-তে নোড আর্কিটাইপগুলি

ADK ওয়ার্কফ্লো বেশ কয়েকটি বিশেষায়িত নোড টাইপ নিয়ে গঠিত। প্রতিটি আর্কিটাইপ গ্রাফে একটি নির্দিষ্ট অপারেশনাল ভূমিকা পালন করে, যা ডিটারমিনিস্টিক কোড এক্সিকিউশনকে জেনারেটিভ মডেল রিজনিং থেকে পৃথক করে:

নোড আর্কিটাইপ

বাস্তবায়ন

পাইপলাইনে ভূমিকা

ফাংশন নোড

পাইথন ফাংশন যা একটি Event রিটার্ন করে

সুনির্দিষ্ট যুক্তি, তথ্য পুনরুদ্ধার এবং অবস্থার পরিবর্তন সম্পাদন করে।

নোডে যোগ দিন

অন্তর্নির্মিত JoinNode ইনস্ট্যান্স

সমান্তরাল শাখাগুলোকে একটি একত্রিত অভিধানে সিঙ্ক্রোনাইজ করে।

এজেন্ট নোড

Agent single_turn মোডে চলছে

আপস্ট্রিম ইনপুটের সাথে নির্দেশাবলী মূল্যায়ন করে এবং যাচাইকৃত ডেটা প্রদান করে।

রাউটার নোড

একটি ফাংশন যা route ট্যাগ সহ একটি Event রিটার্ন করে।

পরবর্তী নির্বাহ শাখা নির্বাচন করার জন্য শর্তাধীন যুক্তি মূল্যায়ন করে।

মানুষের ইনপুট নোড

ফাংশন যা RequestInput প্রদান করে

বাহ্যিক ব্যবহারকারীর প্রতিক্রিয়া না আসা পর্যন্ত কার্য সম্পাদনের অবস্থা স্থগিত রাখে।

root_agent = Workflow(
    name="stage1_fanout",
    description="2 real readers -> join -> one research dict",
    edges=[...])

এই কনফিগারেশনে, root_agent একটি স্বতন্ত্র Agent এর পরিবর্তে Workflow এর একটি ইনস্ট্যান্স। ADK ওয়ার্কফ্লোকে ফার্স্ট-ক্লাস এজেন্ট হিসেবে গণ্য করে, যা একটি সম্পূর্ণ গ্রাফকে একটি সমন্বিত অ্যাপ্লিকেশন হিসেবে লোড, পরিবেশন এবং পরিদর্শন করার সুযোগ দেয়। name ADK Web-এ অ্যাপ্লিকেশনটিকে রেজিস্টার করে, আর edges লিস্টটি এর এক্সিকিউশন টপোলজি নির্ধারণ করে।

সমান্তরাল গবেষণা ফ্যান-আউট (4B)

ওয়ার্কবেঞ্চে, Parallel research fan-out (4B) -তে যান। stage1_fanout/agent.py খুলুন।

০৪-৪বি

ফাংশন নোড এবং সিঙ্ক্রোনাইজেশন বাধা

গবেষণা পর্যায়ে agent/graph.py থেকে ইম্পোর্ট করা দুটি ফাংশন নোড ব্যবহার করা হয়:

  • scan_trends : দশটি স্কোর করা প্ল্যাটফর্ম ট্রেন্ড সম্বলিত Event(output={"trends": [...]}) রিটার্ন করে।
  • read_backlog : প্রাথমিক রান প্রম্পটের পাশাপাশি পনেরোটি চ্যানেল ব্যাকলগ আইডিয়া সম্বলিত Event(output={"backlog": [...], "idea": "..."}) রিটার্ন করে।

প্রতিটি ফাংশন node_input (পূর্ববর্তী নোডের আউটপুট) গ্রহণ করে এবং একটি Event রিটার্ন করে।

একটি JoinNode সিঙ্ক্রোনাইজেশন ব্যারিয়ার হিসেবে কাজ করে: এটি প্রতিটি ইনবাউন্ড চেইন একটি ইভেন্ট ডেলিভার না করা পর্যন্ত থেমে থাকে, তারপর নোডের নাম ( {"scan_trends": {...}, "read_backlog": {...}} ) দ্বারা কী করা একটি ডিকশনারিতে সমস্ত ব্রাঞ্চের ফলাফল একত্রিত করে।

হাতে-কলমে সম্পাদনা: সংযোগ এবং সমান্তরাল প্রান্তগুলি সংজ্ঞায়িত করা

stage1_fanout/agent.py ফাইলে, JoinNode টি ইনস্ট্যানশিয়েট করুন এবং START থেকে শুরু করে দুটি সমান্তরাল চেইনকে সংযুক্ত করুন:

join_research = JoinNode(name="join_research")
    edges=[(START, scan_trends, join_research),
           (START, read_backlog, join_research)])

আপনার পরিবর্তনগুলি সংরক্ষণ করুন। ওয়ার্কবেঞ্চ ভেরিফায়ার নিশ্চিত করে যে জয়েন এবং এজগুলি ওয়্যার করা আছে। রান স্টেজ ১ ব্যবহার করে অথবা এমবেডেড ADK ওয়েব ইন্টারফেসের মাধ্যমে স্টেজটি চালান।

কী আশা করা যায় এবং কেন

  • যুগপৎ রিডার নির্বাহ : এক্সিকিউশন গ্রাফে, scan_trends এবং read_backlog একই সাথে নির্বাহ হয়।
    • কারণ : উভয় চেইনই START থেকে শুরু হয়। ADK ইঞ্জিন স্বাধীন শাখাগুলোকে যুগপৎভাবে শিডিউল করে।
  • সমন্বিত অভিধান আউটপুট : ওয়ার্কফ্লোটি join_research ধাপে সম্পন্ন হয় এবং উভয় রিডারের এন্ট্রি সহ একটি অভিধান আউটপুট করে।
    • কারণ : JoinNode পরবর্তী নোডগুলোকে কার্যকর করার অনুমতি দেওয়ার আগে সম্পূর্ণ ডেটা ক্যাপচার নিশ্চিত করে।

এজেন্ট নোড (4C)

ওয়ার্কবেঞ্চে, এজেন্ট নোড (4C) -তে যান। stage2_direction/agent.py ফাইলটি খুলুন।

০৪-৪সি

অপারেটিং মোড এবং কাঠামোগত স্কিমা

যখন কোনো Workflow মধ্যে অন্তর্ভুক্ত থাকে, তখন একটি Agent ডিফল্টরূপে single_turn মোডে চলে:

  • এটি পূর্ববর্তী নোডের আউটপুটকে তার কনটেক্সট ইনপুট হিসেবে গ্রহণ করে।
  • এটি কোনো রকম কথোপকথনমূলক আদান-প্রদান ছাড়াই একটিমাত্র ইনফারেন্স কল সম্পাদন করে।
  • এটি পরবর্তী নোডে কাঠামোগত ডেটা আউটপুট করে।

output_schema=Directions নির্ধারণ করার মাধ্যমে, এজেন্ট মডেল আউটপুটে পাইড্যান্টিক ভ্যালিডেশন প্রয়োগ করে। ডাউনস্ট্রিম গ্রাফটি অসংগঠিত গদ্যের পরিবর্তে টাইপ করা অবজেক্ট গ্রহণ করে:

class Direction(BaseModel):
    title: str           # <=60 chars, filmable, characterful
    angle: str           # the twist, one line
    hook: str = ""       # 2-4 words, the video's sticker line
    evidence: list[Evidence]


class Directions(BaseModel):
    candidates: list[Direction]   # exactly 4

PROPOSE_INSTRUCTION মডেলটিকে ট্রেন্ড এবং ব্যাকলগ উভয় থেকেই প্রমাণ উল্লেখ করে চারটি সম্ভাব্য বিকল্প প্রস্তাব করতে নির্দেশ দেয়। বিকল্প ১ থেকে ৩ পর্যন্ত কার্যকর চ্যানেল ধারণা প্রদান করে। পরবর্তী ধাপে সেফটি গেট পরীক্ষা করার জন্য বিকল্প ৪ ইচ্ছাকৃতভাবে একটি নীতি-লঙ্ঘনকারী ধারণা উপস্থাপন করে।

হাতে-কলমে সম্পাদনা: এজেন্ট নোড নির্ধারণ করা এবং জয়েন চেইন করা

stage2_direction/agent.py ফাইলে, propose_directions কনফিগার করুন এবং workflow edges-গুলো এক্সটেন্ড করুন:

propose_directions = Agent(
    name="propose_directions",
    model=config.MODEL,
    instruction=PROPOSE_INSTRUCTION,
    output_schema=Directions)
    edges=[(START, scan_trends, join_research),
           (START, read_backlog, join_research),
           (join_research, propose_directions, direction_gate)])

কী আশা করা যায় এবং কেন

  • সরাসরি ডিকশনারি ব্যবহার : propose_directions join_research দ্বারা নির্গত JSON পেলোডটি কোনো ম্যানুয়াল ফরম্যাটিং ছাড়াই ব্যবহার করে।
  • টাইপ করা ক্যান্ডিডেট আউটপুট : এজেন্ট একটি ভ্যালিডেটেড Directions অবজেক্ট নির্গত করে, যাতে চারটি স্বতন্ত্র ক্যান্ডিডেট থাকে। ডাউনস্ট্রিম নোডগুলো স্ট্রিং পার্সিং ছাড়াই অ্যাট্রিবিউটের নাম ( candidate.title ) দ্বারা ফিল্ডগুলো পড়ে।

মানব-সংযুক্তি (4D)

ওয়ার্কবেঞ্চে, Human-in-the-loop (4D) পর্যায়ে যান। agent/graph.py খুলুন।

০৪-৪ডি

তাৎক্ষণিক নির্দেশাবলী বনাম নিয়তবাদী স্থগিতাদেশ

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

  • RequestInput Yielding করলে ওয়ার্কফ্লো এক্সিকিউশন অবিলম্বে স্থগিত হয়ে যায়।
  • ADK সেশন স্টোরে একটি ওপেন ইন্টারাপ্ট কল রেকর্ড করে এবং একটি অনন্য interrupt_id প্রদান করে।
  • টোকেন বা সার্ভার থ্রেড ব্যবহার না করেই এক্সিকিউশন প্রক্রিয়াটি থেমে যায়।
  • স্কিমা এবং ইন্টারাপ্ট আইডির সাথে মেলে এমন একটি বৈধ function_response জমা দেওয়া হলেই গ্রাফ এক্সিকিউশন পুনরায় শুরু হয়।

হাতে-কলমে সম্পাদনা: RequestInput ব্যবহার করে এক্সিকিউশন স্থগিত করা

agent/graph.py ফাইলে, direction_gate ভিতরে সাসপেনশন কলটি ইমপ্লিমেন্ট করুন:

    yield RequestInput(
        message="Pick tonight's direction: 1, 2, 3 or 4.",
        response_schema={
            "type": "object",
            "properties": {
                "pick": {"type": "string", "enum": ["1", "2", "3", "4"]}}},
        payload={"candidates": cands})

RequestInput তিনটি অ্যাট্রিবিউট কনফিগার করে:

  • message : ব্যবহারকারীকে প্রদর্শিত পর্যালোচনার অনুরোধ।
  • response_schema : একটি JSON স্কিমা যা ফ্রন্টএন্ড ইনপুট ফর্ম হিসেবে রেন্ডার করে এবং সাবমিট করার পর ADK দ্বারা যাচাই করা হয়।
  • payload : অনুরোধের সাথে সংযুক্ত মেটাডেটা (চারটি সম্ভাব্য বিকল্প), যা ক্লায়েন্ট ইন্টারফেসকে সেশন স্টেট জিজ্ঞাসা না করেই রিভিউ কার্ড রেন্ডার করতে সক্ষম করে।

কী আশা করা যায় এবং কেন

  • ওয়ার্কফ্লোটি direction_gate-এ থেমে যায় : ADK Web বা ওয়ার্কবেঞ্চ ইন্টারফেসে, রানটি পজ হয় এবং একটি ইন্টারেক্টিভ ক্যান্ডিডেট সিলেকশন ফর্ম প্রদর্শন করে।
    • কারণ : ইঞ্জিনটি একটি yielded RequestInput সম্মুখীন হয়েছে এবং এক্সিকিউশন স্টেট runs/sessions.db তে সংরক্ষণ করেছে।
  • পুনরায় শুরু করার জন্য কাঠামোগত ইনপুট প্রয়োজন : যথেচ্ছ চ্যাট টেক্সট পাঠালে গ্রাফটি অগ্রসর হয় না। একটি বিকল্প (১, ২, ৩, বা ৪) নির্বাচন করলে একটি টাইপ করা function_response জমা হয় যা response_schema পূরণ করে এবং কার্য সম্পাদন পুনরায় শুরু করে।

৫. স্টেট এবং রাউটার

VibeStudio Workbench- এ, ধাপ 5 · State and Router , অংশ (5A) থেকে (5C) -তে যান।

আপনি ব্যবহারকারীর নির্বাচনসমূহ সেশন স্টেটে সংরক্ষণ করবেন, ডিটারমিনিস্টিক রাউটার নোড ব্যবহার করে চ্যানেল সুরক্ষা নীতি প্রয়োগ করবেন এবং ভিডিও স্ক্রিপ্ট তৈরি করার আগে নীতি লঙ্ঘন স্বয়ংক্রিয়ভাবে প্রতিকারের জন্য একটি পুনরাবৃত্তিমূলক টাস্ক এজেন্ট তৈরি করবেন।

কর্মপ্রবাহ অবস্থা (5A)

ওয়ার্কবেঞ্চে, ওয়ার্কফ্লো স্টেট (5A) -তে যান।

০৫-৫এ

সেশন অবস্থা বনাম নোড আউটপুট

একটি ADK ওয়ার্কফ্লোতে, ডেটা দুটি স্বতন্ত্র প্রক্রিয়ার মাধ্যমে গ্রাফ জুড়ে চলাচল করে:

  • নোড আউটপুট ( Event(output=...) ) : এজ লিস্টে সংজ্ঞায়িত শুধুমাত্র নিকটতম ডাউনস্ট্রিম কনজিউমারদের জন্য নির্দেশিত ডেটা।
  • সেশনের অবস্থা ( Event(state=...) ) : একটি শেয়ার্ড কী-ভ্যালু ডিকশনারি যা এক্সিকিউশন লাইফসাইকেলে পরবর্তী যেকোনো নোড দ্বারা অ্যাক্সেসযোগ্য।

০৫-৫এ

যখন কোনো ব্যবহারকারী direction_gate এ একটি ক্যান্ডিডেট নির্বাচন করেন, তখন সেই নির্বাচনটি একটি সাংখ্যিক সূচক ( {"pick": "2"} ) হিসেবে আসে। ডাউনস্ট্রিম নোডগুলোর সম্পূর্ণ direction অবজেক্টটির প্রয়োজন হয়: টাইটেল, ন্যারেটিভ অ্যাঙ্গেল এবং হুক লাইন। প্রতিটি মধ্যবর্তী নোড পেলোডের মাধ্যমে বিশদ মেটাডেটা পাঠানোর পরিবর্তে, persist_direction সমাধানকৃত ক্যান্ডিডেটটিকে শেয়ার্ড সেশন স্টেটে লিখে রাখে।

নোডগুলোকে সম্পূর্ণ সেশন স্টেট ডিকশনারি পাস করার প্রয়োজন নেই। যখন কোনো নোড Event(state=...) প্রদান করে, তখন এটি শুধুমাত্র নতুন বা আপডেট করা কী-ভ্যালু পেয়ারগুলো সরবরাহ করে। ADK স্বয়ংক্রিয়ভাবে এই আপডেটগুলোকে সেশন স্টোরে মার্জ করে নেয়।

    yield Event(state={"direction": chosen["title"], "angle": chosen.get("angle", ""),
                       "hook": hook, "user:prefs": {"last_direction": chosen["title"]}})

এই Event অনুমোদন করলে নিয়ন্ত্রণ Workflow রানটাইমের হাতে চলে যায়, যা নতুন মানগুলোকে runs/sessions.db এর সেশন জার্নালে সংরক্ষণ করে।

প্যারামিটার বাইন্ডিং

ADK ফাংশন নোডগুলো প্যারামিটার ইন্সপেকশনের মাধ্যমে স্বয়ংক্রিয়ভাবে সেশন স্টেট পড়ে। যদি কোনো ফাংশন সিগনেচারে এমন একটি প্যারামিটার নাম ঘোষণা করা হয় যা বিদ্যমান কোনো স্টেট কী-এর সাথে মিলে যায়, তাহলে ADK স্টেট থেকে সেই কী-টি বের করে সরাসরি পাস করে দেয়:

def persist_direction(node_input, candidates: list = []):
    ni = node_input if isinstance(node_input, dict) else {}
    raw = ni.get("pick")
    pick = str(raw).strip() if raw is not None else ""
    if candidates:
        i = int(pick) - 1 if pick.isdigit() else 0
        chosen = candidates[max(0, min(len(candidates) - 1, i))]
    else:
        chosen = {"title": "untitled", "angle": "", "evidence": []}
    hook = chosen.get("hook") or " ".join(chosen["title"].split()[:4])

এখানে, direction_gate মাধ্যমে candidates সেশন স্টেটে লেখা হয়েছিল। ADK কোনো সুস্পষ্ট ডিকশনারি অনুসন্ধানের প্রয়োজন ছাড়াই এটিকে সরাসরি persist_direction(node_input, candidates: list = []) ফাংশনে বাইন্ড করে।

user: উপসর্গযুক্ত কী-গুলো ব্যবহারকারী-স্তরের স্টোরেজে সেশন জুড়ে স্থায়ী থাকে, যা পরবর্তী ওয়ার্কফ্লো রানগুলোকে নির্মাতার পছন্দসমূহ অ্যাক্সেস করার সুযোগ দেয়।

হাতে-কলমে সম্পাদনা: অবস্থা সংরক্ষণ এবং নোডের সংযোগ স্থাপন

  1. agent/graph.py persist_direction ভিতরে, TODO: PERSIST_STATE লাইনটিকে state event yield দিয়ে প্রতিস্থাপন করুন:
    yield Event(state={"direction": chosen["title"], "angle": chosen.get("angle", ""),
                       "hook": hook, "user:prefs": {"last_direction": chosen["title"]}})
  1. stage3_router/agent.py ফাইলে, edges তালিকার তৃতীয় চেইনে persist_direction যুক্ত করুন:
           (join_research, propose_directions, direction_gate,
            persist_direction)

আপনার ফাইলগুলো সংরক্ষণ করুন। ওয়ার্কবেঞ্চে যাচাই করে দেখুন যে state write in place এবং persist_direction in the chain উভয়টিতেই সবুজ টিক চিহ্ন দেখাচ্ছে।

রাউটার নোড (5B)

ওয়ার্কবেঞ্চে, রাউটার নোড (5B) -তে যান।

০৫-৫বি

নির্ণায়ক নীতি রাউটিং

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

একটি রাউটার একটি route ট্যাগ নির্দিষ্ট করে একটি Event ফেরত দেয়:

def length_check(node_input):
    too_long = len(node_input.get("title", "")) > 60
    return Event(output=node_input, route="TRIM" if too_long else "PASS")

ওয়ার্কফ্লো সংজ্ঞায়, একটি ডিকশনারি হিসাবে সংজ্ঞায়িত এজ টার্গেট, রুটের নামগুলোকে গন্তব্য নোডের সাথে ম্যাপ করে:

    (length_check, {"TRIM": shorten, "PASS": scripter}),

ওয়ার্কফ্লো রাউটার policy_check agent/policy_words.txt থেকে নিষিদ্ধ বাক্যাংশগুলো পড়ে এবং নির্বাচিত ডিরেকশনের টাইটেল ও অ্যাঙ্গেলের সাথে সম্পূর্ণ শব্দ মেলানোর কাজটি করে:

    return Event(output=node_input, route="BLOCK" if bad else "OK")

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

গন্তব্য: স্ক্রিপ্টার এবং কোয়ারেন্টাইন

রাউটারটি ট্র্যাফিককে দুটি ডাউনস্ট্রিম নোডের একটিতে প্রেরণ করে:

  • scripter : একটি single_turn এজেন্ট নোড যা অনুমোদিত নির্দেশনাকে Script পাইড্যান্টিক স্কিমা মেনে একটি কাঠামোগত প্রোডাকশন স্ক্রিপ্টে রূপান্তর করে:
scripter = Agent(
    name="scripter",
    model=config.MODEL,
    instruction=SCRIPT_INSTRUCTION,
    output_schema=Script)
  • quarantine : প্রাথমিকভাবে এটি একটি প্লেসহোল্ডার ফাংশন যা চিহ্নিত নির্দেশনাগুলো থামিয়ে দেয়, যা পরবর্তী অংশে একটি স্বয়ংক্রিয় প্রতিকারকারী এজেন্ট দ্বারা প্রতিস্থাপিত হয়েছে।

হাতে-কলমে সম্পাদনা: পলিসি চেক রাউটিং করা

  1. agent/graph.py ফাইলের policy_check ভিতরে return স্টেটমেন্টটি সম্পূর্ণ করুন:
    return Event(output=node_input, route="BLOCK" if bad else "OK")
  1. stage3_router/agent.py ফাইলে, policy_check রাউট করার জন্য edges আপডেট করুন এবং quarantine ব্রাঞ্চটিকে scripter এ পুনরায় যুক্ত করুন:
           (join_research, propose_directions, direction_gate,
            persist_direction, policy_check),
           (policy_check, {"OK": scripter, "BLOCK": quarantine}),
           (quarantine, scripter)])

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

এজেন্ট মোড এবং টাস্ক নোড (5C)

ওয়ার্কবেঞ্চে, এজেন্ট মোড এবং টাস্ক নোড (5C) -তে যান।

০৫-৫সি

এজেন্ট এক্সিকিউশন মোড

ADK Agent ইনস্ট্যান্সগুলো নির্দিষ্ট পাইপলাইন প্রয়োজনীয়তা অনুসারে তৈরি তিনটি এক্সিকিউশন মোড সমর্থন করে:

মোড

এক্সিকিউশন লাইফসাইকেল

পাইপলাইনে ভূমিকা

chat

একাধিক পালাবিশিষ্ট কথোপকথন চক্র। মডেলটি নির্ধারণ করে কখন টুল ব্যবহার করতে হবে, মতামত চাইতে হবে, বা পালা শেষ করতে হবে।

রুট এজেন্টরা একজন ইন্টারেক্টিভ মানব ব্যবহারকারীর মুখোমুখি হচ্ছে।

single_turn

একক মডেল ইনফারেন্স কল। এটি পূর্ববর্তী নোডের ইনপুট গ্রহণ করে এবং একটি স্ট্রাকচার্ড স্কিমা অবজেক্ট প্রদান করে।

ক্রমিক গ্রাফ রূপান্তর ( propose_directions , scripter )।

task

টুল এক্সিকিউশন সহ স্বায়ত্তশাসিত লুপ। এজেন্টটি বিল্ট-ইন finish_task টুলটি কল না করা পর্যন্ত পুনরাবৃত্তি করতে থাকে।

বহু-ধাপীয় প্রতিকার ও পরিদর্শন ( quarantine )।

স্বায়ত্তশাসিত নীতি প্রতিকার

একটি চিহ্নিত নির্দেশনা পুনর্লিখনের জন্য task মোড প্রয়োজন, কারণ প্রতিকারমূলক পুনরাবৃত্তির সংখ্যা পরিবর্তনশীল। এজেন্ট চিহ্নিত নির্দেশনাটি গ্রহণ করে, লঙ্ঘন শনাক্ত করার জন্য find_policy_hits চালু করে, suggest_replacement মাধ্যমে অনুমোদিত বিকল্পের জন্য অনুরোধ করে, নির্দেশনাটি পুনর্লিখন করে এবং অগ্রসর হওয়ার আগে এর পরিচ্ছন্নতা যাচাই করে।

উভয় টুলই agent/cleanup_tools.py ফাইলে টাইপড সিগনেচার এবং ডকস্ট্রিং সহ সংজ্ঞায়িত করা হয়েছে:

def find_policy_hits(text: str) -> dict:
    """Which refused words appear in `text`. Matches whole words and phrases
    from agent/policy_words.txt, case-insensitive.

    Returns {"hits": [...], "clean": bool}. clean is true when hits is empty.
    """


def suggest_replacement(word: str) -> dict:
    """The channel's approved stand-in for a refused word, read from
    agent/policy_replacements.txt.

    Returns {"word", "replacement", "listed"}. When the word has no entry,
    listed is false and replacement is a hint to pick a gentle synonym.
    """

হাতে-কলমে সম্পাদনা: কোয়ারেন্টাইন টাস্ক এজেন্ট একত্রিত করা

stage3_router/agent.py ফাইলে, প্লেসহোল্ডার quarantine ফাংশনটিকে টাস্ক এজেন্ট ডেফিনিশন দিয়ে প্রতিস্থাপন করুন:

quarantine = Agent(
    name="quarantine",
    model=config.MODEL,
    instruction=QUARANTINE_INSTRUCTION,
    mode="task",
    tools=[find_policy_hits, suggest_replacement],
    output_schema=CleanedDirection,
)

টাস্ক মোড এজেন্টকে বিভিন্ন টুল দিয়ে সজ্জিত করে এবং finish_task কল করার মাধ্যমে এক্সিকিউশন সমাপ্ত করে। যখন mode="task" কনফিগার করা থাকে, ADK স্বয়ংক্রিয়ভাবে finish_task সরবরাহ করে এবং এর প্যারামিটারগুলো output_schema থেকে গ্রহণ করে, যা নিশ্চিত করে যে নোডটি স্ক্রিপ্টার নোডের ইনপুট স্কিমার সাথে মেলে এমন একটি টাইপড CleanedDirection অবজেক্ট প্রদান করে।

০৫-৫সি

কী আশা করা যায় এবং কেন

ADK Web অথবা VibeStudio Workbench-এ উভয় এক্সিকিউশন পাথ পরীক্ষা করুন:

  • অনুমোদিত পথ (প্রার্থী ১, ২, বা ৩) :
    • অনুমোদিত প্রার্থী নির্বাচন করলে policy_check থেকে সরাসরি scripter এ রুট চলে যায় ( route="OK" )।
    • স্ক্রিপ্টার Script স্কিমা মেনে একটি ৩-শট প্রোডাকশন স্ক্রিপ্ট তৈরি করে।
  • কোয়ারেন্টাইন প্রতিকারের পথ (প্রার্থী ৪) :
    • প্রার্থী ৪-এ চিহ্নিত শব্দভান্ডার ('ক্লিকবেইট', 'ভাইরাল হ্যাক') রয়েছে।
    • policy_check রুটগুলিকে quarantine পাঠায় ( route="BLOCK" )।
    • সেশন ট্রেসে লক্ষ্য করুন, quarantine find_policy_hits কল করছে, প্রতিটি লঙ্ঘনের জন্য suggest_replacement কল করছে, শিরোনামটি পুনর্লিখন করছে এবং finish_task কল করছে।
    • এক্সিকিউশন scripter সাথে পুনরায় যুক্ত হয় এবং পরিমার্জিত দিক থেকে একটি স্ক্রিপ্ট তৈরি করে।

৬. স্মৃতি ভান্ডার

VibeStudio Workbench- এ, ধাপ 6 · মেমরি ব্যাংক , অংশ (6A) এবং (6B) -তে যান।

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

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

স্মৃতি ব্যাংক (6A)

ওয়ার্কবেঞ্চে, মেমরি ব্যাংক (6A) -তে যান।

০৬-৬এ

পরিচালিত ব্যবহারকারী-স্তরের মেমরি

মেমোরি ব্যাংক হলো ব্যবহারকারীর দীর্ঘমেয়াদী স্মৃতির জন্য একটি পরিচালিত পরিষেবা। এটি একটি নির্দিষ্ট পরিধির মধ্যে কোনো ব্যক্তি সম্পর্কিত তথ্য সংগঠিত করে, যা এখানে অ্যাপ্লিকেশন নাম এবং ইউজার আইডি দ্বারা চিহ্নিত করা হয়:

SCOPE = {"app_name": config.APP, "user_id": config.USER}
TOPICS = {
    "CREATOR_TASTE": "Which video directions this creator picks and passes on, "
                     "and how that preference changes over time.",
    "CHANNEL_RULES": "Standing instructions the creator states for every video "
                     "(style, subjects to avoid, format rules).",
}

কাস্টম মেমরি টপিকগুলো নির্ধারণ করে যে ব্যাংক কী রেকর্ড করবে তার সীমানা:

  • বিষয় নিষ্কাশন : যখন memories.generate এর মাধ্যমে নতুন কথোপকথনের টেক্সট জমা দেওয়া হয়, তখন পরিষেবাটি প্রতিটি বিষয়ের বিবরণের উপর একটি নিষ্কাশন মডেল প্রয়োগ করে। যে টেক্সট কোনো বিষয়ের সাথে মেলে না, তা থেকে কোনো স্মৃতি তৈরি হয় না।
  • Consolidation and deduplication : The service converts newly extracted facts into embeddings and compares them with existing memories in the scope. When an observation aligns with an existing memory, the service updates that memory. When it represents novel information, the service creates a new entry. This consolidation process ensures multiple sessions about a topic merge into a coherent summary instead of producing redundant entries.
  • Retrieval : Calling memories.retrieve with the user scope returns stored facts, ordered oldest first.

Both operations are implemented in agent/platform/memory.py . The provisioned bank resource name is cached locally in runs/memorybank.json .

Setting up the Memory Bank

Use the workbench controls or run the CLI commands in your terminal:

  1. Connect and provision the bank :
    python -m agent.platform.bank
    
    Creates the Agent Engine instance and configures the CREATOR_TASTE and CHANNEL_RULES topics.
  2. Seed historical sessions :
    python -m agent.platform.bank load
    
    Loads four historical creator sessions (two animal themes with style constraints, one gadget theme, and one recent fantasy theme).
  3. Inspect consolidated facts :
    python -m agent.platform.bank list
    
    Examine the output. Notice how narrative transcripts were converted into structured, consolidated statements of fact.

Callbacks (6B)

In the workbench, navigate to Callbacks (6B) . Open stage4_memory/agent.py .

06-6A

ADK agent lifecycle callbacks

A callback is a function passed as an argument to an Agent . ADK invokes callbacks at predefined lifecycle moments, passing the active context. Returning None continues normal execution; returning a replacement object overrides or intercepts the operation.

06-6A

ADK provides three pairs of callbacks:

Callback Pair

Invocation Point

Parameters Received

Return Value Behavior

before_agent_callback
after_agent_callback

Surrounding the entire agent turn

CallbackContext (state, session, invocation)

Returning Content replaces the agent reply; None proceeds normally.

before_model_callback
after_model_callback

Surrounding each LLM inference call

LlmRequest or LlmResponse

Returning LlmResponse intercepts or skips the model call; None proceeds.

before_tool_callback
after_tool_callback

Surrounding each tool execution

Tool definition, arguments, result

Returning a dict overrides the tool output; None proceeds.

Callbacks provide a clean location for context injection, guardrails, telemetry, and cache lookups without introducing extraneous nodes into the workflow graph.

Hands-on edit: wiring recall and remember callbacks

  1. In stage4_memory/agent.py , update propose_directions to attach before_model_callback=recall_taste :
    output_schema=Directions,
    before_model_callback=recall_taste)

recall_taste executes immediately before Gemini generates candidate directions. It fetches the creator's history from Memory Bank, formats the memories oldest first, and appends them to the outgoing LlmRequest . The prompt directs the model to lean candidates 1 to 3 toward the creator's current taste while treating channel rules as strict constraints.

  1. In stage4_memory/agent.py , update scripter to attach after_agent_callback=remember_pick :
    output_schema=Script,
    after_agent_callback=remember_pick)

remember_pick runs after scripter completes its turn. It reads the chosen direction from session state, synthesizes a concise statement summarizing the creator's decision, and calls memories.generate to update the Memory Bank.

What to expect and why

Test the callback-augmented workflow in the workbench or ADK Web:

  1. Execute a run with an empty prompt:
    • In the session trace, inspect the LlmRequest for propose_directions . Notice the appended memory context detailing the creator's preference for fantasy themes and concise pacing.
    • Observe the proposed directions: candidates 1 to 3 align with the creator's historical preferences even when trends emphasize other topics.
  2. Select a candidate at direction_gate .
  3. After scripter completes, review the Memory Bank records:
    python -m agent.platform.bank list
    
    The bank now reflects the latest choice, consolidating it with previous taste records.

7. RAG Engine

In the VibeStudio Workbench , navigate to Step 7 · RAG Engine , parts (7A) and (7B) .

07-7A

Published videos accumulate ongoing viewer feedback. Thirty representative comments are collected in agent/comments.md , capturing viewer praises, critique of sponsored pacing, and audio preferences. In this step, you index these comments using Vertex AI RAG Engine and connect semantic retrieval into the research fan-out.

Retrieval over documents (7A)

In the workbench, navigate to RAG Engine (7A) .

Memory Bank vs RAG Engine

Both tools ground workflows in external data, but they serve distinct architectural purposes:

মাত্রা

Memory Bank

RAG Engine

Primary Use Case

Long-term user preferences and operational rules

Semantic retrieval over large document collections

পরিধি

Scoped to individual user IDs and application names

Scoped to shared corpus resources across all users

ডেটা প্রক্রিয়াকরণ

Real-time extraction, embedding, and semantic consolidation

Document chunking, vector embedding, and nearest-neighbor search

Graph Integration

Agent lifecycle callbacks ( before_model_callback , after_agent_callback )

Dedicated function node in research fan-out ( read_feedback )

07-7A

Document chunking and embeddings

RAG Engine indexes documents by dividing text into semantic passages and storing their vectors in a managed database:

corpus = rag.create_corpus(
    display_name="vibestudio-feedback",
    description="Vibe Studio: what the audience wrote under the channel's past videos.",
    backend_config=rag.RagVectorDbConfig(
        rag_embedding_model_config=rag.RagEmbeddingModelConfig(
            vertex_prediction_endpoint=rag.VertexPredictionEndpoint(
                publisher_model="publishers/google/models/text-embedding-005"))))

rag.upload_file(
    corpus_name=corpus.name, path="agent/comments.md", display_name="comments.md",
    transformation_config=rag.TransformationConfig(
        chunking_config=rag.ChunkingConfig(chunk_size=120, chunk_overlap=20)))
  • Chunk size : Configured to 120 tokens with 20 tokens of overlap. This captures two to three comments per passage, ensuring each vector represents a cohesive sentiment without diluting meaning across unrelated feedback.
  • Embedding model : text-embedding-005 converts text into high-dimensional vectors. When a query is submitted, the model converts the query into a vector and finds nearest matches based on semantic distance. A comment about a tiny dragon guarding socks matches a prompt about magical creatures without requiring exact keyword overlap.

Setting up the RAG corpus

Initialize the corpus using the workbench buttons or terminal commands:

  1. Create the corpus :
    python -m agent.platform.rag
    
    Provisions the managed vector database and records the resource ID in runs/ragcorpus.json .
  2. Upload and index comments : Uploads agent/comments.md with chunking configuration and waits for indexing to complete.
  3. Query the corpus : Test similarity retrieval with queries that do not share exact words with the comments (for example, query "small magical creatures" to retrieve comments about dragons).

The retrieval node (7B)

In the workbench, navigate to The third reader (7B) . Open stage5_rag/agent.py .

07-7B

Retrieval as a graph node

Audience feedback represents research data shared across the workflow. Unlike personal creator memory, viewer sentiment feeds directly into join_research alongside trends and backlog data. It is therefore implemented as a function node:

07-7B

def read_feedback(node_input):
    """The third reader (step 7): what the audience wrote under past videos,
    the passages nearest to tonight's idea. Retrieval, not a model call."""
    from .platform import rag
    idea = idea_text(node_input)
    query = idea or "what viewers liked and what they complained about"
    try:
        hits = rag.retrieve(query)
    except Exception as e:
        print(f"  [rag] feedback unavailable ({str(e)[:80]})")
        return Event(output={"query": query, "feedback": [],
                             "note": "no corpus connected - run: python -m agent.platform.rag"})
    return Event(output={"query": query, "feedback": [h["text"] for h in hits]})

read_feedback extracts the user's initial idea and executes a vector query against the RAG Engine corpus. It emits the retrieved comments in an Event(output=...) payload.

Hands-on edit: wiring the third reader into the fan-out

In stage5_rag/agent.py , update edges to add read_feedback as a third parallel branch entering join_research :

           (START, read_backlog, join_research),
           (START, read_feedback, join_research),

Because join_research is a JoinNode , it synchronizes all incoming branches, waiting until scan_trends , read_backlog , and read_feedback have all emitted events before passing the aggregated bundle downstream.

What to expect and why

Run the workflow in the workbench:

  1. Submit an idea prompt (such as "a miniature dragon guarding a kitchen counter").
  2. In the execution trace, verify that all three reader nodes execute concurrently.
  3. Observe join_research : its output dictionary now contains trends , backlog , and feedback .
  4. Inspect the generated candidates from propose_directions : the model incorporates viewer comments into its proposals and references audience sentiment in the evidence fields.
  5. Notice that RAG retrieval is deterministic (identical queries return identical comment passages), whereas the generative proposal node produces creative variations.

8. Asynchronous video generation with Veo

In the VibeStudio Workbench , navigate to Step 8 · The video , parts (8A) and (8B) .

Generating high-definition video with Google Veo requires several minutes per render. Blocking graph execution during this period wastes compute resources, locks thread pools, and exposes the run to HTTP connection dropouts. In this step, you make video rendering asynchronous using ADK's LongRunningFunctionTool .

Long-running tools (8A)

In the workbench, navigate to A long-running tool (8A) . Open stage6_video/agent.py and agent/deliver.py .

08-8A

Synchronous tools vs long-running tools

Standard ADK function tools execute synchronously inside an agent turn: the model calls the tool, awaits the return payload, and incorporates the result into the ongoing turn.

Video rendering cannot complete within a single turn. Instead, render_submit initiates the generation job and immediately returns an operational receipt with status "pending" :

def render_submit(prompt: str) -> dict:
    """Submit one Veo render of `prompt`. Returns at once with a pending
    receipt; the clip is delivered later, to this call, by id."""
    receipt = videogen.start(f"{prompt} {videogen.NO_TEXT}")
    return {"status": "pending", "operation": receipt["operation"], "prompt": receipt["prompt"]}

When wrapped with LongRunningFunctionTool , ADK intercepts the "pending" status. The agent's turn concludes, the workflow suspends at the node, and the pending call metadata (including call ID and receipt) is recorded in runs/sessions.db . The execution process exits cleanly without maintaining active network connections or worker threads.

Hands-on edit: wrapping the render tool

In stage6_video/agent.py , update render_desk to wrap render_submit in LongRunningFunctionTool :

    tools=[LongRunningFunctionTool(render_submit)])

Resuming by call ID

The universal resumption pattern

ADK applies an identical mechanism to suspend and resume workflows for both humans and external tools:

Suspension Trigger

Initiating Construct

Stored Suspension State

Resumption Event

Human Decision

yield RequestInput(...)

Open input prompt in session store

FunctionResponse carrying the suspension call ID

Long-Running Tool

LongRunningFunctionTool(...) returning pending

Open tool call in session store

FunctionResponse carrying the suspension call ID

In both scenarios, the workflow halts completely and resumes only when an event bearing a matching FunctionResponse arrives from an external source: a user interface, a webhook, or a background worker.

Hands-on edit: completing the delivery response

In agent/deliver.py , construct the resumption FunctionResponse part:

    part = Part(function_response=FunctionResponse(
        id=row["call_id"], name=row["name"], response=response))

The delivery daemon polls Veo until the video file is generated, then dispatches this FunctionResponse to the session. ADK matches the call ID and resumes the workflow directly at the next node. Completed nodes do not re-execute, and the agent does not take another generative turn.

Setting STUDIO_REAL_VIDEO=0 in .env enables mock rendering: start returns an immediate test receipt, and check simulates completion in five seconds without making billable Veo API calls.

Pipeline integration (8B)

In the workbench, navigate to render_desk in the graph (8B) . Open stage6_video/agent.py .

The terminal node in the pipeline is store_video . It reads the completed render information from runs/state.json (where the delivery process recorded it) and commits the video URL and generation status to shared session state.

08-8B

Hands-on edit: wiring the complete video pipeline

In stage6_video/agent.py , update edges to append render_desk and store_video :

           (quarantine, scripter),
           (scripter, render_desk, store_video)])

What to expect and why

Test the asynchronous generation flow in the workbench:

  1. Execute the workflow through candidate selection and script generation.
  2. At render_desk , observe the agent invoke render_submit .
  3. The workflow immediately suspends. In the workbench or ADK Web, observe the pending status: the session holds the open call ID, and no background processes are consuming resources.
  4. Run the delivery daemon using the workbench console or in your terminal:
    python -m agent.deliver
    
    The delivery process monitors Veo until the video is ready, then dispatches the resumption event.
  5. In ADK Web, refresh the session: execution resumes at store_video , commits the video URL to session state, and completes the workflow.

9. Deploy to Cloud Run

In the VibeStudio Workbench , navigate to Step 9 · Deploy .

You have developed and verified each component of the pipeline across dedicated sandboxes. In this step, you assemble the complete production pipeline and deploy it to Google Cloud Run .

09-9A

The ADK Runner

In development, adk web orchestrated the graph. In production, the application hosts the workflow using ADK's Runner class:

self._svc = DatabaseSessionService(db_url=config.DB_URL)
self._runner = Runner(app_name=config.APP, agent=wf, session_service=self._svc)

async for ev in self._runner.run_async(user_id=config.USER, session_id=run_id, new_message=message):
    self._absorb(ev)    # fold the ADK event into the run state, publish one app event

# the gate's answer and the render's delivery are the same call, with a function_response part
part = Part(function_response=FunctionResponse(id=call_id, name=name, response=response))
  • run_async : Drives workflow execution, yielding events sequentially as nodes execute and persisting updates to the session service.
  • Unified resumption : Both user decisions at direction_gate and completed video deliveries from Veo resume execution through identical FunctionResponse objects submitted to run_async .

The production application architecture

The production application in vibestudio/ integrates the complete pipeline:

vibestudio/
  server/
    main.py                 FastAPI: application server, REST routes, static assets
    api.py                  REST API endpoints: run, pick, publish, backlog, profile, history
    runner.py               Runner orchestration over the workflow, background render poller
    platform/               Event bus (SSE stream), file storage, publishing, telemetry
    agent/                  Production agent package, verified by checks/verify_app.py
      graph.py              The complete workflow graph and node definitions
      desk.py               render_desk and render_submit wrapped with LongRunningFunctionTool
      schemas.py            Pydantic schemas: Directions, CleanedDirection, Script
      cleanup_tools.py      Deterministic policy tools: find_policy_hits, suggest_replacement
      platform/             Memory Bank, RAG Engine, and Veo integrations
  web/                      Production React user interface
  Dockerfile · deploy.py · run.sh
  • Single event stream : The FastAPI backend publishes events across a single Server-Sent Events (SSE) stream. The React frontend visualizes graph progression in real time and handles late connections without losing state.
  • Decoupled execution : The application manages the event loop. The workflow graph focuses entirely on execution logic, unaware of the frontend interface.

The complete workflow edge list in agent/graph.py combines every architectural pattern built throughout this codelab:

        (START, scan_trends, join_research),
        (START, read_backlog, join_research),
        (START, read_feedback, join_research),
        (join_research, propose_directions, direction_gate,
         persist_direction, policy_check),
        (policy_check, {"OK": scripter, "BLOCK": quarantine}),
        (quarantine, scripter),
        (scripter, render_desk, store_video),

Deploying to Cloud Run

Google Cloud Run provides serverless hosting with automatic scaling, request routing, and integrated container builds:

gcloud run deploy vibestudio --source vibestudio \
  --project $GOOGLE_CLOUD_PROJECT --region us-central1 \
  --labels dev-tutorial-codelab=vibetube --allow-unauthenticated \
  --memory 2Gi --cpu 2 --timeout 3600 --concurrency 40 \
  --max-instances 1 --min-instances 1 --session-affinity \
  --set-env-vars GOOGLE_CLOUD_PROJECT=...,STUDIO_VERTEX=1,STUDIO_MEMORY_BANK=...,STUDIO_RAG_CORPUS=...,VIBETUBE_URL=...,VIBETUBE_EVENT=...,VIBETUBE_NAME=...,VIBETUBE_PROJECT=...
  • Container build : gcloud run deploy --source packages the vibestudio/ directory, builds the container image using Cloud Build, and deploys the service in a single operation.
  • Session affinity : Directs requests from the same user to the same container instance, preserving local session state across iterative steps.
  • Observability : Cloud Trace integration records distributed spans for every node, LLM call, and tool execution, accessible in the Google Cloud Console under Trace Explorer.

Click the Deploy button in the workbench to execute the deployment script. When the build completes, the terminal displays the live service URL.

অ্যাপ

10. Summary

In the VibeStudio Workbench , navigate to Step 10 · Summary to review the completed architecture.

10-summary

ধাপ

Architecture & Concepts

Implementation Pattern

A single prompt

Single prompt, function tools, sequential chat loop

Agent(tools=[...]) , function_call / function_response

Agentic workflow fundamentals

Graph workflow, parallel research, schema outputs, human gate

Workflow , START , JoinNode , output_schema , RequestInput

State and Router

Shared session state, parameter binding, deterministic routing, task agent

Event(state=...) , Event(route=...) , mode="task" , finish_task

Memory Bank

User-level long-term memory, semantic consolidation, lifecycle hooks

memories.generate / retrieve , before_model_callback , after_agent_callback

RAG Engine

Document retrieval over audience comments, semantic embeddings

rag.create_corpus , RagEmbeddingModelConfig , read_feedback node

Asynchronous video generation with Veo

Long-running tools, pending receipts, external delivery daemon

LongRunningFunctionTool , FunctionResponse(id=...) resumption

Deploy to Cloud Run

Programmatic orchestration, Server-Sent Events, serverless container

Runner(agent=wf) , run_async , Cloud Run deployment

Core architectural principles

  1. Suspend instead of waiting : Workflows pause cleanly for human input ( RequestInput ) or long-running operations ( LongRunningFunctionTool ). Processes do not wait idle on threads or network sockets.
  2. Universal resumption : Every suspension resumes through an identical mechanism: a single function_response carrying the call ID of the suspended node.
  3. Decoupled state management : Nodes share data through named session state keys and parameter binding instead of verbose, tightly coupled intermediate payloads.
  4. Deterministic routing before generative cost : Rule-based routers and regex filters evaluate policy at zero token cost before generative models run.
  5. Separation of concerns : Context specific to an individual agent belongs in lifecycle callbacks, while shared data dependencies belong

10-output