1. ভূমিকা

"গোল্ডফিশ" সমস্যা
কল্পনা করুন আপনি টোকিওতে আপনার স্বপ্নের ছুটির পরিকল্পনা করার জন্য একজন ট্রাভেল এজেন্ট নিয়োগ করেছেন। "দ্য গোল্ডফিশ প্রবলেম" বাস্তবে দেখতে সেশন এজেন্ট ব্যবহার করুন।
তুমি তাদের অফিসে গিয়ে বলো:
"হাই! আমি টোকিওতে ২ দিনের ভ্রমণের পরিকল্পনা করতে চাই। আমি ঐতিহাসিক স্থান এবং সুশিতে আগ্রহী।"
এজেন্ট উৎসাহের সাথে উত্তর দেয়:
"দারুন! আমি ইম্পেরিয়াল প্যালেসে যাওয়ার এবং সুকিয়াবাশি জিরোতে সুশি ডিনারের পরিকল্পনা করেছি।"
তুমি হেসে বলো:
"এটা তো দারুন লাগছে! তুমি কি আমাকে ভ্রমণপথটি পাঠাতে পারবে?"
এজেন্ট তোমার দিকে শূন্য দৃষ্টিতে তাকিয়ে জিজ্ঞেস করে:
"হাই! আজকে একটা ট্রিপ ঠিক করে দিতে আমি কীভাবে তোমাকে সাহায্য করতে পারি?"
এটাই "গোল্ডফিশ সমস্যা"। স্মৃতি ছাড়া, প্রতিটি মিথস্ক্রিয়া একটি ফাঁকা স্লেট। বুদ্ধিমত্তা আছে - এজেন্ট ভ্রমণের পরিকল্পনা করতে জানে - কিন্তু ধারাবাহিকতার অভাব রয়েছে। একজন এআই এজেন্টকে সত্যিকার অর্থে কার্যকর হতে হলে, তাকে মনে রাখতে হবে।
আজ তোমার লক্ষ্য
এই কর্মশালায়, আপনি এমন একটি ট্র্যাভেল এজেন্ট তৈরি করে গোল্ডফিশ সমস্যার সমাধান করবেন যিনি মনে রাখবেন, শিখবেন এবং খাপ খাইয়ে নেবেন। আপনি এজেন্ট মেমোরির 6টি স্তরের মধ্য দিয়ে অগ্রসর হবেন, এমন একটি সিস্টেম তৈরি করবেন যা চ্যাটবটের মতো কম এবং একজন নিবেদিতপ্রাণ ব্যক্তিগত সহকারীর মতো আচরণ করবে।
স্তর | ধারণা | "মহাশক্তি" |
স্তর ১ | অধিবেশন ও রাষ্ট্র | ভুলে না গিয়ে কথোপকথন চালিয়ে যাওয়া |
স্তর ২ | মাল্টি-এজেন্ট স্টেট | দলের সদস্যদের মধ্যে নোট শেয়ার করা |
স্তর ৩ | অধ্যবসায় | সিস্টেম রিবুট করার পরেও তোমাকে মনে রাখা |
স্তর ৪ | কলব্যাক | সম্পূর্ণ স্বয়ংক্রিয়ভাবে মেমোরি আপডেট করা |
স্তর ৫ | কাস্টম সরঞ্জাম | স্ট্রাকচার্ড ইউজার প্রোফাইল পড়া এবং লেখা |
স্তর ৬ | মাল্টিমোডাল মেমোরি | ছবি ও ভিডিও "দেখা" এবং মনে রাখা |
ADK মেমোরি স্ট্যাক
কোড লেখার আগে, আসুন আমরা কোন টুলগুলি ব্যবহার করছি তা বুঝতে পারি। গুগল এজেন্ট ডেভেলপমেন্ট কিট (ADK) মেমরি পরিচালনা করার জন্য একটি কাঠামোগত উপায় প্রদান করে:
- অধিবেশন : কথোপকথনের ধারক। এতে যা বলা হয়েছিল তার ইতিহাস ধারণ করা হয়।
- অবস্থা : সেশনের সাথে সংযুক্ত একটি কী-মান "স্ক্র্যাচপ্যাড"। এজেন্টরা নির্দিষ্ট তথ্য সংরক্ষণ করতে এটি ব্যবহার করে (যেমন,
destination="Tokyo")। - মেমোরি সার্ভিস : দীর্ঘমেয়াদী স্টোরেজ। এখানে আমরা ব্যবহারকারীর পছন্দ বা বিশ্লেষণ করা নথির মতো জিনিসগুলি চিরতরে সংরক্ষণ করি।
2. সেট আপ করুন
আমাদের এআই এজেন্টদের শক্তিশালী করার জন্য, আমাদের দুটি জিনিসের প্রয়োজন: ভিত্তি প্রদানের জন্য একটি গুগল ক্লাউড প্রকল্প।
প্রথম অংশ: বিলিং অ্যাকাউন্ট সক্ষম করুন
- ৫ ডলার ক্রেডিট দিয়ে আপনার বিলিং অ্যাকাউন্ট দাবি করার জন্য, আপনার এটি স্থাপনের জন্য প্রয়োজন হবে। আপনার জিমেইল অ্যাকাউন্টটি নিশ্চিত করুন।
দ্বিতীয় অংশ: উন্মুক্ত পরিবেশ
- 👉 সরাসরি ক্লাউড শেল এডিটরে যেতে এই লিঙ্কে ক্লিক করুন।
- 👉 আজই যদি যেকোনো সময় অনুমোদনের অনুরোধ জানানো হয়, তাহলে চালিয়ে যেতে অনুমোদনে ক্লিক করুন।

- 👉 যদি স্ক্রিনের নীচে টার্মিনালটি না দেখা যায়, তাহলে এটি খুলুন:
- ভিউ ক্লিক করুন
- টার্মিনাল ক্লিক করুন

- 👉💻 টার্মিনালে, নিম্নলিখিত কমান্ড ব্যবহার করে যাচাই করুন যে আপনি ইতিমধ্যেই প্রমাণীকরণপ্রাপ্ত এবং প্রকল্পটি আপনার প্রকল্প আইডিতে সেট করা আছে:
gcloud auth list - 👉💻 GitHub থেকে বুটস্ট্র্যাপ প্রকল্পটি ক্লোন করুন:
git clone https://github.com/cuppibla/memory_agent_starter - 👉💻 প্রজেক্ট ডিরেক্টরি থেকে সেটআপ স্ক্রিপ্টটি চালান।
স্ক্রিপ্টটি বাকি সেটআপ প্রক্রিয়াটি স্বয়ংক্রিয়ভাবে পরিচালনা করবে।cd ~/memory_agent_starter ./init.sh - 👉💻 প্রয়োজনীয় প্রজেক্ট আইডি সেট করুন:
gcloud config set project $(cat ~/project_id.txt) --quiet
তৃতীয় অংশ: অনুমতি সেট আপ করা
- 👉💻 নিম্নলিখিত কমান্ড ব্যবহার করে প্রয়োজনীয় API গুলি সক্রিয় করুন। এতে কয়েক মিনিট সময় লাগতে পারে।
gcloud services enable \ cloudresourcemanager.googleapis.com \ servicenetworking.googleapis.com \ run.googleapis.com \ aiplatform.googleapis.com \ compute.googleapis.com - 👉💻 টার্মিনালে নিম্নলিখিত কমান্ডগুলি চালিয়ে প্রয়োজনীয় অনুমতিগুলি প্রদান করুন:
. ~/memory_agent_starter/set_env.sh
লক্ষ্য করুন যে আপনার জন্য একটি .env ফাইল তৈরি করা হয়েছে। এটি আপনার প্রকল্পের তথ্য দেখায়।
৩. ফাউন্ডেশন - অধিবেশন ও রাষ্ট্র

ধারণা: প্রেক্ষাপটই রাজা
মেমোরির সবচেয়ে মৌলিক রূপ হল সেশন মেমোরি । এটিই একজন এজেন্টকে জানতে সাহায্য করে যে "আমি এটি কিনতে চাই" বাক্যে "এটি " বলতে আপনি যে জুতার কথা বলছিলেন তাকে বোঝায়।
ADK-তে, আমরা Session অবজেক্ট দিয়ে এটি পরিচালনা করি।
- স্টেটলেস পদ্ধতি : প্রতিটি বার্তার জন্য একটি নতুন সেশন তৈরি করা।
- স্টেটফুল অ্যাপ্রোচ : একটি সেশন তৈরি করা এবং পুরো কথোপকথনের জন্য এটি পুনঃব্যবহার করা ।
ধাপ ১: এজেন্টকে পরীক্ষা করুন
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/01_session_agent/agent.py
~/memory_agent_starter/01_session_agent/agent.py খুলুন।
👉 মন্তব্যটি সনাক্ত করুন # করণীয়: agent.py ফাংশনের ভিতরে # TODO: Create a root agent ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
root_agent = LlmAgent(
name="multi_day_trip_agent",
model="gemini-2.5-flash",
description="Agent that progressively plans a multi-day trip, remembering previous days and adapting to user feedback.",
instruction="""
You are the "Adaptive Trip Planner" 🗺️ - an AI assistant that builds multi-day travel itineraries step-by-step.
Your Defining Feature:
You have short-term memory. You MUST refer back to our conversation to understand the trip's context, what has already been planned, and the user's preferences. If the user asks for a change, you must adapt the plan while keeping the unchanged parts consistent.
Your Mission:
1. **Initiate**: Start by asking for the destination, trip duration, and interests.
2. **Plan Progressively**: Plan ONLY ONE DAY at a time. After presenting a plan, ask for confirmation.
3. **Handle Feedback**: If a user dislikes a suggestion (e.g., "I don't like museums"), acknowledge their feedback, and provide a *new, alternative* suggestion for that time slot that still fits the overall theme.
4. **Maintain Context**: For each new day, ensure the activities are unique and build logically on the previous days. Do not suggest the same things repeatedly.
5. **Final Output**: Return each day's itinerary in MARKDOWN format.
""",
tools=[google_search]
)
নির্দেশনাটি এলএলএমকে মনে রাখতে বলে, তবে কোডটি মনে রাখার ক্ষমতা প্রদান করতে হবে।
ধাপ ২: দুটি দৃশ্যপট
~/memory_agent_starter/01_session_agent/main.py খুলুন।
👉 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/01_session_agent/main.py
~/memory_agent_starter/01_session_agent/main.py খুলুন, মন্তব্যটি সনাক্ত করুন # করণীয়: main.py ফাংশনের ভিতরে # TODO: Create a runner with in memorysession service ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
runner = Runner(
agent=agent,
session_service=session_service,
app_name=agent.name
)
👉 মন্তব্যটি সনাক্ত করুন # করণীয়: main.py ফাংশনের ভিতরে # TODO: create a different session to test ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
tokyo_session_2 = await session_service.create_session(
app_name=multi_day_agent.name,
user_id=user_id
)
পরীক্ষা করো।
আমাদের দুটি ফাংশন আছে যা "গোল্ডফিশ" এবং "এলিফ্যান্ট" মেমোরির মধ্যে পার্থক্য প্রদর্শন করে।
দৃশ্যপট ১: স্টেটফুল (শেয়ার্ড সেশন)
async def run_trip_same_session_scenario(session_service, user_id):
# 1. Create ONE session
trip_session = await session_service.create_session(...)
# 2. Turn 1
await run_agent_query(..., trip_session, ...)
# 3. Turn 2 - REUSING the same session!
# The agent can "see" Turn 1 because it's in the session history.
await run_agent_query(..., trip_session, ...)
দৃশ্যপট ২: রাষ্ট্রহীন (প্রতিবার নতুন অধিবেশন)
async def run_trip_different_session_scenario(session_service, user_id):
# Turn 1
tokyo_session = await session_service.create_session(...)
await run_agent_query(..., tokyo_session, ...)
# Turn 2 - Creating a FREASH session
# The agent has NO IDEA what happened in Turn 1.
tokyo_session_2 = await session_service.create_session(...)
await run_agent_query(..., tokyo_session_2, ...)
ধাপ ৩: এজেন্ট চালান
চলুন কর্মের পার্থক্য দেখি। স্ক্রিপ্টটি চালান:
👉💻 কমান্ড লাইনে, নিচের কমান্ড লাইনটি চালান:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/01_session_agent/main.py
দৃশ্যপট ১ লক্ষ্য করুন : এজেন্ট প্রথম বার্তা থেকে আপনার পছন্দগুলি মনে রাখে এবং দ্বিতীয় বার্তায় পরিকল্পনাটি গ্রহণ করে।
দৃশ্যপট ২ লক্ষ্য করুন : দ্বিতীয় ধাপে ("খাবারের মধ্যে আমার কী পছন্দ হয়েছিল মনে আছে?"), এজেন্ট সম্পূর্ণরূপে ব্যর্থ হয় কারণ এটি একটি নতুন অধিবেশন। এটি কার্যকরভাবে বলে, "আমি জানি না তুমি কী সম্পর্কে কথা বলছো।"
কী টেকওয়ে
মেমোরির নিয়ম #১: কথোপকথনের প্রেক্ষাপট বজায় রাখতে সর্বদা session.id পুনরায় ব্যবহার করুন। Session অবজেক্টটি হল আপনার এজেন্টের স্বল্প-মেয়াদী মেমোরি বাফার।
৪. দল - মাল্টি-এজেন্ট স্টেট

ধারণা: "টেলিফোন গেম"
যখন একাধিক এজেন্ট একসাথে কাজ করে, তখন তারা এমনভাবে কাজ করে যেন সহকর্মীরা একটি ফাইল ফোল্ডার এদিক-ওদিক করে যাচ্ছে। যদি একজন এজেন্ট ফোল্ডারে একটি নোট লেখে, তাহলে পরবর্তী এজেন্টটি তা পড়তে সক্ষম হবে।
ADK-তে, এই "ফোল্ডার" হল State ।
- State হলো একটি অভিধান (
{"key": "value"}) যা সেশনের ভেতরে থাকে। - সেশনের যেকোনো এজেন্ট এটি থেকে পড়তে বা লিখতে পারবেন।
ধাপ ১: কর্মপ্রবাহ পরীক্ষা করুন
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/02_multi_agent/agent.py
👉 ~/memory_agent_starter/02_multi_agent/agent.py ফাইলে, # TODO: foodie agent মন্তব্যটি খুঁজুন।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
foodie_agent = LlmAgent(
name="foodie_agent",
model="gemini-2.5-flash",
tools=[google_search],
instruction="""You are an expert food critic. Your goal is to find the best restaurant based on a user's request.
When you recommend a place, you must output *only* the name of the establishment and nothing else.
For example, if the best sushi is at 'Jin Sho', you should output only: Jin Sho
""",
output_key="destination" # ADK will save the agent's final response to state['destination']
)
👉 agent.py ফাংশনের ভিতরে # TODO: transportation agent মন্তব্যটি সনাক্ত করুন।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
transportation_agent = LlmAgent(
name="transportation_agent",
model="gemini-2.5-flash",
tools=[google_search],
instruction="""You are a navigation assistant. Given a destination, provide clear directions.
The user wants to go to: {destination}.
Analyze the user's full original query to find their starting point.
Then, provide clear directions from that starting point to {destination}.
""",
)
👉 agent.py ফাংশনের ভিতরে # TODO: root_agent মন্তব্যটি সনাক্ত করুন।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
root_agent = SequentialAgent(
name="find_and_navigate_agent",
sub_agents=[foodie_agent, transportation_agent],
description="A workflow that first finds a location and then provides directions to it."
)
এখন আমাদের দুটি এজেন্ট একটি ক্রমানুসারে কাজ করছে:
- ভোজনরসিক এজেন্ট : একটি রেস্তোরাঁ খুঁজে বের করে।
- পরিবহন এজেন্ট : সেই রেস্তোরাঁর দিকনির্দেশনা দেয়।
ম্যাজিক হ্যান্ড-অফ : লক্ষ্য করুন কিভাবে foodie_agent transportation_agent কাছে হাত পাতছে।
foodie_agent = LlmAgent(
# ...
# CRITICAL: This tells ADK to save the agent's output to state['destination']
output_key="destination"
)
transportation_agent = LlmAgent(
# ...
# CRITICAL: This injects state['destination'] into the prompt
instruction="""
The user wants to go to: {destination}.
Provide clear directions...
""",
)
-
output_key="destination": ফুডি এজেন্টের উত্তর দক্ষতার সাথে সংরক্ষণ করা হয়েছে। -
{destination}: পরিবহন এজেন্ট স্বয়ংক্রিয়ভাবে উত্তরটি পড়ে।
(কোনও পদক্ষেপের প্রয়োজন নেই) ধাপ ২: অর্কেস্ট্রেটর
02_multi_agent/main.py খুলুন।
আমরা সেগুলিকে ক্রমানুসারে চালানোর জন্য একটি SequentialAgent ব্যবহার করি।
# 1. Create a single session for the sequential agent
session = await session_service.create_session(...)
# 2. Run the query
# The SequentialAgent manages the state flow:
# Query -> Foodie -> state['destination'] -> Transportation -> Final Answer
await run_agent_query(root_agent, query, ...)
ব্যবহারকারী একটি প্রম্পট পাঠায়:
"Find best sushi in Palo Alto and then tell me how to get there."
এজেন্টরা এর উত্তর দেওয়ার জন্য একসাথে কাজ করে।
ধাপ ৩: দল পরিচালনা করুন
👉💻 ক্লাউড শেল টার্মিনালে, মাল্টি-এজেন্ট ওয়ার্কফ্লো কার্যকর করুন:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/02_multi_agent/main.py
কি হয়?
- ফুডি এজেন্ট : "জিন শো" (অথবা অনুরূপ) খুঁজে বের করে।
- ADK : "জিন শো"
state['destination']এ সংরক্ষণ করে। - পরিবহন এজেন্ট : তার নির্দেশে "জিন শো" গ্রহণ করে।
- ফলাফল : "ক্যালট্রেন স্টেশন থেকে জিন শোতে যেতে, ইউনিভার্সিটি অ্যাভিনিউতে হেঁটে যান..."
কী টেকওয়ে
মেমোরির নিয়ম #২: এজেন্টদের মধ্যে কাঠামোগত তথ্য প্রেরণের জন্য State ব্যবহার করুন। লেখার জন্য output_key এবং পড়ার জন্য {placeholders} ব্যবহার করুন।
৫. রিবুট - অধ্যবসায়

ধারণা: "রিবুট সমস্যা"
এখন পর্যন্ত, আমাদের মেমোরি ছিল InMemory । যদি আপনি স্ক্রিপ্টটি বন্ধ করে আবার শুরু করেন, তাহলে এজেন্ট সবকিছু ভুলে যাবে। এটি এমন একটি কম্পিউটারের মতো যা প্রতিবার বন্ধ করার সময় তার হার্ড ড্রাইভ মুছে ফেলে।
এটি ঠিক করার জন্য, আমাদের Persistence প্রয়োজন। আমরা InMemorySessionService DatabaseSessionService সাথে অদলবদল করি।
ধাপ ১: ডাটাবেস সুইচ
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/03_persistent_agent/main.py
👉 ~/memory_agent_starter/03_persistent_agent/main.py ফাইলে, মন্তব্যটি সনাক্ত করুন # TODO: Configuration for Persistent Sessions ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
SESSIONS_DIR = Path(os.path.expanduser("~")) / ".adk_codelab" / "sessions"
os.makedirs(SESSIONS_DIR, exist_ok=True)
SESSION_DB_FILE = SESSIONS_DIR / "trip_planner.db"
SESSION_URL = f"sqlite:///{SESSION_DB_FILE}"
এখন, প্রতিটি সেশন এবং ইভেন্ট একটি SQLite ফাইলে সংরক্ষিত হয়।
ধাপ ২: ক্রস-সেশন পুনরুদ্ধার
অধ্যবসায় কেবল কথোপকথন পুনরায় শুরু করার সুযোগ দেয় না, বরং অতীতের ঘটনাগুলি থেকে শেখার সুযোগ দেয়।
একই ফাইলে ~/memory_agent_starter/03_persistent_agent/main.py , টেস্ট কেস 3 দেখুন: ক্রস-সেশন পুনরুদ্ধার ।
👉 মন্তব্যটি সনাক্ত করুন # TODO: retrieve the previous session manually
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
old_session = await session_service.get_session(
app_name=root_agent.name, user_id="user_01", session_id=session_id
)
👉 মন্তব্যটি সনাক্ত করুন # করণীয়: main.py ফাংশনের ভিতরে থাকা # TODO: Extract content from the OLD session ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
previous_context += f"- {role}: {text}\n"
👉 মন্তব্যটি সনাক্ত করুন # করণীয়: main.py ফাংশনের ভিতরে # TODO: Manually inject the context to the query ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
query_3 = f"""
{previous_context}
I'm planning a new trip to Osaka this time.
Based on my previous preferences (above), what should I eat?
"""
এটি এমনভাবে তৈরি করে যে ব্যবহারকারী কয়েক মাস পরে ফিরে আসবে। শুধুমাত্র একটি ডাটাবেসের সাহায্যে আপনি সেই পুরানো ইতিহাস পুনরুদ্ধার করতে পারবেন।
ধাপ ৩: রিবুট থেকে বেঁচে থাকা
👉💻 টার্মিনালে, স্ক্রিপ্টটি চালান:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/03_persistent_agent/main.py
এটি ~/memory_agent_starter/trip_planner.db একটি ফাইল তৈরি করে। এটি চেষ্টা করুন: স্ক্রিপ্টটি দুবার চালান।
- দ্বিতীয় দৌড়ে, "বিদ্যমান অধিবেশন পুনরায় শুরু হয়েছে" সন্ধান করুন।
- এজেন্ট প্রথম রানের প্রসঙ্গটি মনে রাখবে কারণ এটি ডাটাবেস ফাইল থেকে লোড হয়!
কী টেকওয়ে
মেমোরির নিয়ম #৩: উৎপাদনের জন্য DatabaseSessionService ব্যবহার করুন। এটি নিশ্চিত করে যে ব্যবহারকারীর কথোপকথন সার্ভার পুনরায় চালু হওয়ার পরেও টিকে থাকে এবং দীর্ঘমেয়াদী ইতিহাস বিশ্লেষণ সক্ষম করে।
৬. দ্য স্পাই - কলব্যাকস

কখনও কখনও, এজেন্ট কী বলে তা নয়, বরং তার কাজের উপর ভিত্তি করে আপনাকে স্বয়ংক্রিয়ভাবে মেমোরি আপডেট করতে হবে। আপনি এমন একজন "গুপ্তচর" চান যে এজেন্টের উপর নজর রাখবে এবং নোট নেবে।
ADK-তে, এই গুপ্তচরটি হল কলব্যাক । 
-
after_tool_callback: একটি ফাংশন যা এজেন্ট যখনই কাজ করে তখনই চলে। -
ToolContext: ফাংশনের ভেতর থেকে State লেখার একটি উপায়।
ধাপ ১: যুক্তি
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/04_stateful_agent/agent.py
👉 ~/memory_agent_starter/04_stateful_agent/agent.py ফাইলে, মন্তব্যটি সনাক্ত করুন # TODO: Implement call back logic
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
def save_activity_type_callback(
tool,
args: Dict[str, Any],
tool_context: ToolContext,
tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
"""
Callback to save the TYPE of activity just planned into the session state.
"""
# 1. Get the actual agent name.
if tool.name == "transfer_to_agent":
agent_name = args.get("agent_name")
else:
agent_name = tool.name
activity_type = "unknown"
# 2. Determine the type based on which agent was actually used
if agent_name == "museum_expert":
activity_type = "CULTURAL"
elif agent_name == "restaurant_expert":
activity_type = "FOOD"
elif agent_name == "outdoor_expert":
activity_type = "OUTDOOR"
print(f"\n🔔 [CALLBACK] The planner transferred to '{agent_name}'.")
# 3. Update the state directly
tool_context.state["last_activity_type"] = activity_type
print(f"💾 [STATE UPDATE] 'last_activity_type' is now set to: {activity_type}\n")
return tool_response
👉 একই ফাইলে , মন্তব্যটি খুঁজুন # TODO: 04_stateful_agent/agent.py ফাংশনের ভিতরে # TODO: add callback to root agent ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
after_tool_callback=save_activity_type_callback,
গতিশীল নির্দেশনা: এজেন্টের নির্দেশনা এখন একটি ফাংশন , স্ট্রিং নয়। এটি অবস্থার উপর ভিত্তি করে পরিবর্তিত হয়!
def get_planner_instruction(context):
last_activity = context.state.get("last_activity_type", "None")
return f"""
The last activity was: {last_activity}
If last_activity is 'CULTURAL' -> `museum_expert` is BANNED.
"""
ধাপ ৩: স্পাই পরীক্ষা করুন
👉💻 টার্মিনালে, নিচের কমান্ডটি কপি এবং পেস্ট করে স্ক্রিপ্টটি চালান:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/04_stateful_agent/main.py
যখন আপনি এই এজেন্টটি চালাবেন, তখন আপনি একটি লুপ দেখতে পাবেন।
- ১ম পালা: তুমি একটা জাদুঘর চাইছো। স্পাই
last_activity="CULTURAL"সেট করে। - দ্বিতীয় পালা: তুমি আরেকটি জাদুঘরের জন্য অনুরোধ করছো।
- এজেন্ট নির্দেশনার আপডেট: "সাংস্কৃতিক নিষিদ্ধ"।
- এজেন্ট বলে: "আমি আর একটা জাদুঘর করতে পারব না। একটা পার্কের কথা কেমন?"
[CALLBACK] এবং [STATE UPDATE] এর কনসোল লগগুলি দেখুন। এজেন্ট কাজ করার সাথে সাথে আপনি রিয়েল-টাইমে মেমরির পরিবর্তন দেখতে পাবেন।
কী টেকওয়ে
মেমোরির নিয়ম #৪: স্টেট ম্যানেজমেন্ট স্বয়ংক্রিয় করতে কলব্যাক ব্যবহার করুন। আপনার এজেন্ট কেবল তার কাজ করেই নিজস্ব প্রসঙ্গ তৈরি করে।
৭. ফাইল ক্যাবিনেট - কাস্টম টুলস
ধারণা: "কাঠামোগত স্মৃতি"

এখন পর্যন্ত, "মেমোরি" ছিল একটি চ্যাট লগ অথবা একটি সাধারণ কী-মান জোড়া। কিন্তু যদি আপনার একটি জটিল ব্যবহারকারীর প্রোফাইল মনে রাখার প্রয়োজন হয়? যেমন, diet: vegan, budget: high, pets: [cat, dog] ।
এর জন্য, আমরা মেমোরিকে একটি টুল হিসেবে বিবেচনা করি। এজেন্ট স্পষ্টভাবে সিদ্ধান্ত নেয় কখন ফাইল ক্যাবিনেট খুলতে হবে (পড়তে হবে) এবং কখন রিপোর্ট ফাইল করতে হবে (লিখতে হবে)। 
ধাপ ১: সরঞ্জামগুলি
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/05_profile_agent/tools.py
👉 এই ফাইলে: ~/memory_agent_starter/05_profile_agent/tools.py ।
আমাদের এই দুটি নির্দিষ্ট সরঞ্জাম বাস্তবায়ন করতে হবে:
-
save_user_preferences: একটি ডাটাবেসে লেখা হয়। -
recall_user_preferences: একটি ডাটাবেস থেকে পড়া হয়।
মন্তব্যটি খুঁজে বের করুন # TODO: ~/memory_agent_starter/05_profile_agent/tools.py ফাংশনের ভিতরে # TODO: implement save_user_preferences tools ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
def save_user_preferences(tool_context: ToolContext, new_preferences: Dict[str, Any]) -> str:
user_id = tool_context.session.user_id
with sqlite3.connect(USER_DB_FILE) as conn:
for key, value in new_preferences.items():
conn.execute("INSERT INTO user_preferences (user_id, pref_key, pref_value) VALUES (?, ?, ?) ON CONFLICT(user_id, pref_key) DO UPDATE SET pref_value = excluded.pref_value;",
(user_id, key, json.dumps(value)))
return f"Preferences updated: {list(new_preferences.keys())}"
👉 মন্তব্যটি সনাক্ত করুন # করণীয়: 05/tools.py ফাংশনের ভিতরে # TODO: implement recall_user_preferences tools ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
def recall_user_preferences(tool_context: ToolContext) -> Dict[str, Any]:
user_id = tool_context.session.user_id
preferences = {}
with sqlite3.connect(USER_DB_FILE) as conn:
rows = conn.execute("SELECT pref_key, pref_value FROM user_preferences WHERE user_id = ?", (user_id,)).fetchall()
if not rows: return {"message": "No preferences found."}
for key, value_str in rows: preferences[key] = json.loads(value_str)
return preferences
নির্দেশটি একটি কর্মপ্রবাহকে বাধ্য করে:
instruction="""
1. RECALL FIRST: First action MUST be `recall_user_preferences`.
3. LEARN: If a user states a new preference, use `save_user_preferences`.
"""
ধাপ ২: মৃত্যুদণ্ড
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/05_profile_agent/main.py
~/memory_agent_starter/05_profile_agent/main.py খুলুন।
পূর্ববর্তী মডিউলগুলির বিপরীতে যেখানে ADK স্বয়ংক্রিয়ভাবে অবস্থা পরিচালনা করত, এখানে এজেন্ট নিয়ন্ত্রণে থাকে।
- এটি শুরুতেই
recall_user_preferencesকল করতে পছন্দ করে । - "আমি নিরামিষ" বললে এটি
save_user_preferencesকল করতে পছন্দ করে ।
ধাপ ৩: প্রোফাইল তৈরি করুন
👉💻 স্ক্রিপ্টটি চালান:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/05_profile_agent/main.py
এই কথোপকথন প্রবাহটি চেষ্টা করে দেখুন:
- "হাই, একটা ডিনারের পরিকল্পনা করো।" -> এজেন্ট ডিবি চেক করে, কিছুই খুঁজে পায় না। পছন্দ জানতে চায়।
- "আমি নিরামিষ।" -> এজেন্ট "নিরামিষ" কে ডিবিতে সংরক্ষণ করে।
- স্ক্রিপ্টটি পুনরায় চালু করুন।
- "হাই, একটা ডিনারের পরিকল্পনা করো।" -> এজেন্ট ডিবি চেক করে, "ভেগান" দেখে, এবং সাথে সাথে একটা ভেগান রেস্তোরাঁর পরামর্শ দেয়।
কী টেকওয়ে
মেমোরির নিয়ম #৫: জটিল, কাঠামোগত ডেটার জন্য, আপনার এজেন্টকে Read/Write Tools দিন। LLM-কে তার নিজস্ব দীর্ঘমেয়াদী স্টোরেজ পরিচালনা করতে দিন।
৮. মস্তিষ্ক - মাল্টিমোডাল মেমোরি

ধারণা: "মানব অভিজ্ঞতা"
মানুষ লেখার চেয়ে বেশি কিছু মনে রাখে। আমরা একটি ছবির ভাব , একটি কণ্ঠস্বরের শব্দ , একটি ভিডিওর অনুভূতি মনে রাখি।
ভার্টেক্স এআই মেমোরি ব্যাংক আপনার এজেন্টকে মাল্টিমোডাল মেমোরি পরিচালনা করতে দেয়। এটি ছবি, ভিডিও এবং অডিও গ্রহণ করতে পারে, "বোঝতে" পারে এবং পরে পুনরুদ্ধার করতে পারে।
ধাপ ১: কনফিগারেশন
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/main.py
👉 06_multimodal_agent/main.py খুলুন। মন্তব্যটি খুঁজুন # TODO: Configure Memory Bank Topic ।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
travel_topics = [
MemoryTopic(
managed_memory_topic=ManagedMemoryTopic(
managed_topic_enum=ManagedTopicEnum.USER_PREFERENCES
)
),
MemoryTopic(
managed_memory_topic=ManagedMemoryTopic(
managed_topic_enum=ManagedTopicEnum.USER_PERSONAL_INFO
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_experiences",
description="""Memorable travel experiences including:
- Places visited and impressions
- Favorite restaurants, cafes, and food experiences
- Preferred accommodation types and locations
- Activities enjoyed (museums, hiking, beaches, etc.)
- Travel companions and social preferences
- Photos and videos from trips with location context""",
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_preferences",
description="""Travel style and preferences:
- Budget preferences (luxury, mid-range, budget)
- Transportation preferences (flying, trains, driving)
- Trip duration preferences
- Season and weather preferences
- Cultural interests and language abilities
- Dietary restrictions and food preferences""",
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_logistics",
description="""Practical travel information:
- Passport and visa information
- Frequent flyer numbers and hotel loyalty programs
- Emergency contacts
- Medical considerations and insurance
- Packing preferences and essentials
- Time zone preferences and jet lag strategies""",
)
),
]
মন্তব্যটি খুঁজুন # TODO: Configure Memory Bank Customization
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
memory_bank_config = {
"customization_configs": [
{
"memory_topics": travel_topics,
}
],
"similarity_search_config": {
"embedding_model": f"projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/gemini-embedding-001"
},
"generation_config": {
"model": f"projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/gemini-2.5-flash"
},
}
ধাপ ২: পৃথিবীকে গ্রাস করা
test_trip_planner এ, আমরা পাঠাই:
- একটি টেক্সট মেসেজ ("হ্যালো")
- একটি ছবি (ল্যান্ডমার্ক)
- একটি ভিডিও (ভূমধ্যসাগর)
- একটি অডিও ক্লিপ (গেটা সম্পর্কে ভয়েস নোট)
6_multimodal_agent/main.py ফাংশনের ভিতরে # TODO create session service and memory service মন্তব্যটি খুঁজুন।
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
session_service = VertexAiSessionService(
project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id
)
memory_service = VertexAiMemoryBankService(
project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id
)
👉 একই ফাইল 06_multimodal_agent/main.py তে, মন্তব্যটি সনাক্ত করুন # TODO: create memory from session
এই পুরো লাইনটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন :
await memory_service.add_session_to_memory(final_session_state)
এটাই জাদুর রেখা। এটি সমস্ত সমৃদ্ধ মিডিয়া ভার্টেক্স এআই-তে পাঠায়, যা এটিকে প্রক্রিয়াজাত করে এবং সূচীবদ্ধ করে।
ধাপ ৩: পুনরুদ্ধার
👉💻 আপনার ক্লাউড শেল টার্মিনালে, ক্লাউড শেল এডিটরে ফাইলটি খুলুন:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/agent.py
এজেন্টটির একটি PreloadMemoryTool আছে।
tools=[PreloadMemoryTool(), budget_tool]
যখন একটি নতুন সেশন শুরু হয়, তখন এই টুলটি স্বয়ংক্রিয়ভাবে মেমোরি ব্যাংকে প্রাসঙ্গিক অতীত অভিজ্ঞতা অনুসন্ধান করে এবং সেগুলিকে প্রসঙ্গে প্রবেশ করায়।
ধাপ ৪: মস্তিষ্ক চালান
👉💻 আপনার ক্লাউড শেল টার্মিনালে, স্ক্রিপ্টটি চালান (দ্রষ্টব্য: এর জন্য Vertex AI সক্ষম একটি Google ক্লাউড প্রকল্প প্রয়োজন):
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/06_multimodal_agent/main.py
চূড়ান্ত যাচাইকরণের ধাপটি দেখুন:
"আমি আগে আপনার সাথে যে ছবি, ভিডিও এবং অডিও শেয়ার করেছি তার উপর ভিত্তি করে..."
এজেন্ট উত্তর দেবে:
"তোমার গেটা দেখা উচিত! তুমি আমাকে ভূমধ্যসাগরের একটি ভিডিও এবং একটি অডিও ক্লিপ দেখিয়েছিলে যেখানে তুমি বলেছিলে যে তুমি গেটাকে ভালোবাসো।"
এটি অতীতের বিভিন্ন ধরণের মিডিয়া জুড়ে বিন্দুগুলিকে সংযুক্ত করেছে।
কী টেকওয়ে
মেমোরির নিয়ম #৬: সর্বোত্তম মেমোরি অভিজ্ঞতার জন্য ভার্টেক্স এআই মেমোরি ব্যাংক ব্যবহার করুন। এটি টেক্সট, ছবি এবং ভিডিওকে একটি একক, অনুসন্ধানযোগ্য মস্তিষ্কে একত্রিত করে।
9. উপসংহার
তুমি একটা ভুলে যাওয়া গোল্ডফিশ থেকে একটা মাল্টিমডাল হাতিতে যাত্রা করেছো।
তুমি তৈরি করেছো | ক্ষমতা |
সেশন এজেন্ট | স্বল্পমেয়াদী কথোপকথনের স্মৃতি |
মাল্টি-এজেন্ট | ভাগ করা দলের স্মৃতি |
স্থায়ী এজেন্ট | দীর্ঘমেয়াদী ইতিহাস |
স্টেটফুল এজেন্ট | গতিশীল, স্ব-আপডেটিং স্মৃতি |
প্রোফাইল এজেন্ট | স্ট্রাকচার্ড ডেটা মেমোরি |
মাল্টিমোডাল এজেন্ট | মানুষের মতো সংবেদনশীল স্মৃতি |
বিশ্বাস স্মৃতির উপর নির্মিত। এই ধরণগুলি বাস্তবায়নের মাধ্যমে, আপনি এমন এজেন্ট তৈরি করেন যা ব্যবহারকারীর সময় এবং ইতিহাসকে সম্মান করে, যা আরও গভীর, আরও কার্যকর মিথস্ক্রিয়ার দিকে পরিচালিত করে।
আজই আপনার ব্যক্তিগতকৃত এজেন্ট তৈরি শুরু করুন!