1. Giới thiệu

Vấn đề "Cá vàng"
Hãy tưởng tượng bạn thuê một đại lý du lịch để lên kế hoạch cho chuyến đi trong mơ của mình đến Tokyo. Sử dụng Session Agent để xem "Vấn đề về cá vàng" trong thực tế.
Bạn bước vào văn phòng của họ và nói:
"Chào bạn! Tôi muốn lên kế hoạch cho chuyến đi 2 ngày đến Tokyo. Tôi quan tâm đến các di tích lịch sử và món sushi."
Nhân viên hỗ trợ nhiệt tình trả lời:
"Tuyệt vời! Tôi đã lên kế hoạch tham quan Cung điện Hoàng gia và thưởng thức bữa tối sushi tại Sukiyabashi Jiro."
Bạn mỉm cười và nói:
"Nghe có vẻ ổn đấy! Bạn có thể gửi cho tôi lịch trình không?"
Nhân viên nhìn bạn với vẻ mặt trống rỗng và hỏi:
"Chào bạn! Hôm nay tôi có thể giúp bạn lên kế hoạch cho chuyến đi như thế nào?"
Đây là "Vấn đề về cá vàng". Nếu không có bộ nhớ, mọi hoạt động tương tác đều sẽ bắt đầu từ con số 0. Trí thông minh vẫn còn đó – nhân viên hỗ trợ biết cách lên kế hoạch cho chuyến đi – nhưng tính liên tục lại không có. Để thực sự hữu ích, một trợ lý AI cần có khả năng ghi nhớ.
Nhiệm vụ của bạn hôm nay
Trong hội thảo này, bạn sẽ giải quyết Vấn đề về cá vàng bằng cách tạo một Đại lý du lịch có khả năng ghi nhớ, học hỏi và thích ứng. Bạn sẽ trải qua 6 Cấp độ của Bộ nhớ tác nhân, tạo ra một hệ thống hoạt động ít giống chatbot hơn và giống một trợ lý cá nhân chuyên dụng hơn.
Cấp độ | Khái niệm | "Siêu năng lực" |
Cấp 1 | Phiên và trạng thái | Tiếp tục trò chuyện mà không quên |
Cấp độ 2 | Trạng thái nhiều tác nhân | Chia sẻ ghi chú giữa các thành viên trong nhóm |
Cấp độ 3 | Tính liên tục | Ghi nhớ bạn ngay cả sau khi hệ thống khởi động lại |
Cấp độ 4 | Lệnh gọi lại | Cập nhật kỷ niệm hoàn toàn tự động |
Cấp độ 5 | Công cụ tuỳ chỉnh | Đọc và ghi hồ sơ người dùng có cấu trúc |
Cấp độ 6 | Bộ nhớ đa phương thức | "Nhìn thấy" và nhớ lại ảnh và video |
Ngăn xếp bộ nhớ ADK
Trước khi viết mã, hãy tìm hiểu các công cụ mà chúng ta sẽ sử dụng. Google Agent Development Kit (ADK) cung cấp một cách có cấu trúc để xử lý bộ nhớ:
- Phiên: Vùng chứa cho một cuộc trò chuyện. Nó lưu giữ nhật ký về những gì đã được nói.
- Trạng thái: Một "bảng nháp" khoá-giá trị được đính kèm vào phiên. Các tác nhân sử dụng thông tin này để lưu trữ các dữ kiện cụ thể (ví dụ:
destination="Tokyo"). - MemoryService: Bộ nhớ dài hạn. Đây là nơi chúng tôi lưu trữ dữ liệu vĩnh viễn, chẳng hạn như lựa chọn ưu tiên của người dùng hoặc tài liệu đã phân tích.
2. Thiết lập
Để hỗ trợ các tác nhân AI của chúng tôi, chúng tôi cần hai thứ: một Dự án Google Cloud để cung cấp nền tảng.
Phần 1: Bật tài khoản thanh toán
- Bạn sẽ cần tài khoản thanh toán có khoản tín dụng 5 đô la để triển khai. Đảm bảo bạn đã đăng nhập vào tài khoản gmail.
Phần 2: Môi trường mở
- 👉 Nhấp vào đường liên kết này để chuyển trực tiếp đến Cloud Shell Editor
- 👉 Nếu được nhắc uỷ quyền vào bất kỳ thời điểm nào trong ngày hôm nay, hãy nhấp vào Uỷ quyền để tiếp tục.

- 👉 Nếu thiết bị đầu cuối không xuất hiện ở cuối màn hình, hãy mở thiết bị đầu cuối:
- Nhấp vào Xem
- Nhấp vào Terminal (Thiết bị đầu cuối)

- 👉💻 Trong thiết bị đầu cuối, hãy xác minh rằng bạn đã được xác thực và dự án được đặt thành mã dự án của bạn bằng lệnh sau:
gcloud auth list - 👉💻 Sao chép dự án khởi động từ GitHub:
git clone https://github.com/cuppibla/memory_agent_starter - 👉💻 Chạy tập lệnh thiết lập trong thư mục dự án.
Tập lệnh sẽ tự động xử lý phần còn lại của quy trình thiết lập.cd ~/memory_agent_starter ./init.sh - 👉💻 Đặt mã dự án cần thiết:
gcloud config set project $(cat ~/project_id.txt) --quiet
Phần 3: Thiết lập quyền
- 👉💻 Bật các API bắt buộc bằng lệnh sau. Việc này có thể mất vài phút.
gcloud services enable \ cloudresourcemanager.googleapis.com \ servicenetworking.googleapis.com \ run.googleapis.com \ aiplatform.googleapis.com \ compute.googleapis.com - 👉💻 Cấp các quyền cần thiết bằng cách chạy các lệnh sau trong thiết bị đầu cuối:
. ~/memory_agent_starter/set_env.sh
Xin lưu ý rằng một tệp .env sẽ được tạo cho bạn. Thẻ này cho biết thông tin dự án của bạn.
3. Nền tảng – Phiên và trạng thái

Khái niệm: Bối cảnh là yếu tố then chốt
Dạng bộ nhớ cơ bản nhất là Bộ nhớ phiên. Đây là yếu tố giúp trợ lý biết rằng "nó" trong câu "Tôi muốn mua nó" đề cập đến đôi giày mà bạn đã nói đến 10 giây trước.
Trong ADK, chúng ta quản lý việc này bằng đối tượng Session.
- Phương pháp không trạng thái: Tạo một phiên mới cho mỗi thông báo.
- Phương pháp có trạng thái: Tạo một phiên và sử dụng lại phiên đó cho toàn bộ cuộc trò chuyện.
Bước 1: Kiểm tra Agent
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/01_session_agent/agent.py
Mở ~/memory_agent_starter/01_session_agent/agent.py.
👉 Tìm nhận xét # TODO: Create a root agent bên trong hàm agent.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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]
)
Chỉ dẫn này yêu cầu LLM ghi nhớ, nhưng mã phải cung cấp khả năng ghi nhớ.
Bước 2: Hai trường hợp
Mở ~/memory_agent_starter/01_session_agent/main.py.
👉 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/01_session_agent/main.py
Mở ~/memory_agent_starter/01_session_agent/main.py, tìm nhận xét # TODO: Create a runner with in memorysession service bên trong hàm main.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
runner = Runner(
agent=agent,
session_service=session_service,
app_name=agent.name
)
👉 Tìm nhận xét # TODO: create a different session to test bên trong hàm main.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
tokyo_session_2 = await session_service.create_session(
app_name=multi_day_agent.name,
user_id=user_id
)
Kiểm thử
Chúng ta có hai hàm minh hoạ sự khác biệt giữa bộ nhớ "Cá vàng" và "Voi".
Trường hợp 1: Có trạng thái (Phiên dùng chung)
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, ...)
Trường hợp 2: Không trạng thái (Mỗi lần đều là một phiên mới)
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, ...)
Bước 3: Chạy Agent
Hãy xem sự khác biệt trong thực tế. Chạy tập lệnh:
👉💻 Trong dòng lệnh, hãy chạy dòng lệnh bên dưới:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/01_session_agent/main.py
Quan sát Tình huống 1: Trợ lý ghi nhớ các lựa chọn ưu tiên của bạn trong tin nhắn đầu tiên và điều chỉnh kế hoạch trong tin nhắn thứ hai.
Quan sát tình huống 2: Ở lượt thứ hai ("do you remember what I liked about the food?"), tác nhân hoàn toàn thất bại vì đây là một phiên mới. Câu này có nghĩa là "Tôi không biết bạn đang nói gì".
Điểm chính cần ghi nhớ
Quy tắc 1 về Bộ nhớ: Luôn sử dụng session.id để duy trì ngữ cảnh trò chuyện. Đối tượng Session là vùng đệm bộ nhớ ngắn hạn của tác nhân.
4. Nhóm – Trạng thái nhiều nhân viên

Ý tưởng: "Trò chơi truyền tin"
Khi nhiều tác nhân làm việc cùng nhau, họ giống như những đồng nghiệp chuyền qua chuyền lại một thư mục tệp. Nếu một nhân viên viết ghi chú trong thư mục, thì nhân viên tiếp theo sẽ có thể đọc ghi chú đó.
Trong ADK, "thư mục" này là Trạng thái.
- State là một từ điển (
{"key": "value"}) nằm trong Phiên. - Mọi tác nhân trong phiên đều có thể đọc hoặc ghi vào đó.
Bước 1: Kiểm tra quy trình làm việc
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/02_multi_agent/agent.py
👉Trong tệp ~/memory_agent_starter/02_multi_agent/agent.py, hãy tìm nhận xét # TODO: foodie agent.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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']
)
👉 Tìm nhận xét # TODO: transportation agent bên trong hàm agent.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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}.
""",
)
👉 Tìm nhận xét # TODO: root_agent bên trong hàm agent.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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."
)
Giờ đây, chúng ta có 2 tác nhân hoạt động theo trình tự:
- Foodie Agent: Tìm nhà hàng.
- Đại lý vận tải: Chỉ đường đến nhà hàng đó.
Tính năng Bàn giao thần kỳ: Hãy lưu ý cách foodie_agent bàn giao cho 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": Câu trả lời của Foodie Agent được lưu một cách hiệu quả.{destination}: Trợ lý vận chuyển sẽ tự động đọc câu trả lời đó.
(Không cần làm gì cả) Bước 2: Orchestrator
Mở 02_multi_agent/main.py.
Chúng tôi sử dụng SequentialAgent để chạy các thao tác này theo thứ tự.
# 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, ...)
Người dùng gửi một câu lệnh:
"Find best sushi in Palo Alto and then tell me how to get there."
Các nhân viên hỗ trợ sẽ cùng nhau trả lời câu hỏi đó.
Bước 3: Chạy Team
👉💻 Trong Cloud Shell Terminal, hãy thực thi quy trình làm việc có nhiều tác nhân:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/02_multi_agent/main.py
Điều gì sẽ xảy ra?
- Tác nhân sành ăn: Tìm "Jin Sho" (hoặc tên tương tự).
- ADK: Lưu "Jin Sho" vào
state['destination']. - Đại lý vận chuyển: Nhận được "Jin Sho" trong hướng dẫn.
- Kết quả: "Để đến Jin Sho từ ga Caltrain, hãy đi bộ xuống đường University..."
Điểm chính cần ghi nhớ
Quy tắc 2 về bộ nhớ: Sử dụng Trạng thái để truyền thông tin có cấu trúc giữa các tác nhân. Sử dụng output_key để ghi và {placeholders} để đọc.
5. Khởi động lại – Tính liên tục

Khái niệm: "Vấn đề về việc khởi động lại"
Cho đến nay, bộ nhớ của chúng ta là InMemory. Nếu bạn dừng tập lệnh và bắt đầu lại, tác nhân sẽ quên mọi thứ. Nó giống như một chiếc máy tính xoá ổ đĩa cứng mỗi khi bạn tắt máy.
Để khắc phục vấn đề này, chúng ta cần Tính duy trì. Chúng ta hoán đổi InMemorySessionService cho DatabaseSessionService.
Bước 1: Chuyển đổi cơ sở dữ liệu
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/03_persistent_agent/main.py
👉 Trong tệp ~/memory_agent_starter/03_persistent_agent/main.py, hãy tìm nhận xét # TODO: Configuration for Persistent Sessions.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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}"
Giờ đây, mọi phiên và sự kiện đều được lưu vào một tệp SQLite.
Bước 2: Truy xuất trên nhiều phiên
Tính năng duy trì trạng thái không chỉ cho phép tiếp tục một cuộc trò chuyện mà còn học hỏi từ những cuộc trò chuyện trước đó.
Trong cùng một tệp ~/memory_agent_starter/03_persistent_agent/main.py, hãy xem Trường hợp kiểm thử 3: Truy xuất trên nhiều phiên.
👉 Tìm bình luận # TODO: retrieve the previous session manually
Thay thế toàn bộ dòng này bằng đoạn mã sau:
old_session = await session_service.get_session(
app_name=root_agent.name, user_id="user_01", session_id=session_id
)
👉 Tìm nhận xét # TODO: Extract content from the OLD session bên trong hàm main.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
previous_context += f"- {role}: {text}\n"
👉 Tìm nhận xét # TODO: Manually inject the context to the query bên trong hàm main.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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?
"""
Điều này mô phỏng một người dùng quay lại sau vài tháng. Bạn chỉ có thể truy xuất nhật ký cũ đó bằng cơ sở dữ liệu.
Bước 3: Vượt qua quá trình khởi động lại
👉💻 Trong dòng lệnh, hãy chạy tập lệnh:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/03_persistent_agent/main.py
Thao tác này sẽ tạo một tệp ~/memory_agent_starter/trip_planner.db. Hãy thử cách này: Chạy tập lệnh hai lần.
- Ở lần chạy thứ hai, hãy tìm "Resumed existing session" (Tiếp tục phiên hiện có).
- Tác nhân sẽ nhớ ngữ cảnh từ lần chạy đầu tiên vì tác nhân tải từ tệp cơ sở dữ liệu!
Điểm chính cần ghi nhớ
Quy tắc 3 về bộ nhớ: Sử dụng DatabaseSessionService cho quá trình sản xuất. Điều này đảm bảo các cuộc trò chuyện của người dùng vẫn diễn ra sau khi máy chủ khởi động lại và cho phép phân tích nhật ký dài hạn.
6. The Spy – Lệnh gọi lại

Đôi khi, bạn cần tự động cập nhật bộ nhớ dựa trên những gì mà tác nhân thực hiện, chứ không chỉ những gì mà tác nhân nói. Bạn muốn có một "gián điệp" theo dõi nhân viên hỗ trợ và ghi chú.
Trong ADK, đối tượng theo dõi này là Callback. 
after_tool_callback: Một hàm chạy mỗi khi tác nhân hoạt động.ToolContext: Một cách để ghi vào Trạng thái từ bên trong hàm đó.
Bước 1: Logic
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/04_stateful_agent/agent.py
👉 Trong tệp ~/memory_agent_starter/04_stateful_agent/agent.py, hãy tìm nhận xét # TODO: Implement call back logic
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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
👉 Trong cùng một tệp, hãy tìm nhận xét # TODO: add callback to root agent bên trong hàm 04_stateful_agent/agent.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
after_tool_callback=save_activity_type_callback,
Hướng dẫn linh hoạt: Hướng dẫn của tác nhân hiện là một hàm chứ không phải là một chuỗi. Nội dung này thay đổi tuỳ theo trạng thái!
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.
"""
Bước 3: Kiểm thử Spy
👉💻 Trong cửa sổ dòng lệnh, hãy chạy tập lệnh bằng cách sao chép và dán lệnh bên dưới:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/04_stateful_agent/main.py
Khi chạy tác nhân này, bạn sẽ thấy một vòng lặp.
- Lượt 1: Bạn yêu cầu tìm một bảo tàng. Bộ gián điệp
last_activity="CULTURAL". - Lượt 2: Bạn yêu cầu một bảo tàng khác.
- Nội dung cập nhật về hướng dẫn dành cho nhân viên hỗ trợ: "VĂN HOÁ là NỘI DUNG BỊ CẤM".
- Nhân viên nói: "Tôi không thể đề xuất một bảo tàng khác. Hay là đi công viên?"
Xem nhật ký bảng điều khiển cho [CALLBACK] và [STATE UPDATE]. Bạn có thể thấy bộ nhớ thay đổi theo thời gian thực khi tác nhân hoạt động.
Điểm chính cần ghi nhớ
Quy tắc số 4 về bộ nhớ: Sử dụng Lệnh gọi lại để tự động hoá việc quản lý trạng thái. Tác nhân của bạn tự xây dựng bối cảnh bằng cách thực hiện công việc của mình.
7. Tủ hồ sơ – Công cụ tuỳ chỉnh
Khái niệm: "Ký ức có cấu trúc"

Cho đến nay, "Bộ nhớ" là nhật ký trò chuyện hoặc một cặp khoá-giá trị đơn giản. Nhưng nếu bạn cần ghi nhớ một hồ sơ người dùng phức tạp thì sao? Ví dụ: diet: vegan, budget: high, pets: [cat, dog].
Vì vậy, chúng ta coi bộ nhớ là một Công cụ. Tác nhân sẽ quyết định rõ ràng thời điểm mở tủ đựng hồ sơ (đọc) và thời điểm nộp báo cáo (ghi). 
Bước 1: Công cụ
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/05_profile_agent/tools.py
👉 Trong tệp này: ~/memory_agent_starter/05_profile_agent/tools.py.
Chúng ta cần triển khai 2 công cụ cụ thể sau:
save_user_preferences: Ghi vào cơ sở dữ liệu.recall_user_preferences: Đọc từ cơ sở dữ liệu.
Tìm nhận xét # TODO: implement save_user_preferences tools bên trong hàm ~/memory_agent_starter/05_profile_agent/tools.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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())}"
👉 Tìm nhận xét # TODO: implement recall_user_preferences tools bên trong hàm 05/tools.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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
Chỉ dẫn này buộc một quy trình làm việc:
instruction="""
1. RECALL FIRST: First action MUST be `recall_user_preferences`.
3. LEARN: If a user states a new preference, use `save_user_preferences`.
"""
Bước 2: Thực hiện
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/05_profile_agent/main.py
Mở ~/memory_agent_starter/05_profile_agent/main.py.
Không giống như các mô-đun trước đây mà ADK tự động xử lý trạng thái, ở đây Agent (Tác nhân) sẽ kiểm soát.
- Nó chọn gọi
recall_user_preferenceskhi bắt đầu. - Ứng dụng chọn gọi
save_user_preferenceskhi bạn nói "Tôi là người ăn thuần chay".
Bước 3: Tạo hồ sơ
👉💻 Chạy tập lệnh:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/05_profile_agent/main.py
Hãy thử quy trình trò chuyện này:
- "Chào bạn, hãy lên kế hoạch cho bữa tối." -> Nhân viên hỗ trợ kiểm tra cơ sở dữ liệu nhưng không tìm thấy thông tin nào. Yêu cầu lựa chọn ưu tiên.
- "Tôi là người ăn thuần chay." -> Agent lưu "thuần chay" vào DB.
- Khởi động lại tập lệnh.
- "Chào bạn, hãy lên kế hoạch cho bữa tối." -> Agent kiểm tra cơ sở dữ liệu, thấy "thuần chay" và đề xuất ngay một nhà hàng thuần chay.
Điểm chính cần ghi nhớ
Quy tắc số 5 về bộ nhớ: Đối với dữ liệu có cấu trúc phức tạp, hãy cung cấp cho tác nhân của bạn Công cụ đọc/ghi. Cho phép LLM quản lý bộ nhớ dài hạn của riêng mình.
8. The Brain – Bộ nhớ đa phương thức

Ý tưởng: "Trải nghiệm của con người"
Con người nhớ nhiều hơn là văn bản. Chúng ta nhớ bầu không khí của một bức ảnh, âm thanh của một giọng nói, cảm xúc của một video.
Vertex AI Memory Bank cho phép tác nhân của bạn xử lý Bộ nhớ đa phương thức. Nó có thể tiếp nhận hình ảnh, video và âm thanh, "hiểu" chúng và truy xuất chúng sau này.
Bước 1: Cấu hình
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/main.py
👉 Mở 06_multimodal_agent/main.py. Tìm bình luận # TODO: Configure Memory Bank Topic.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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""",
)
),
]
Tìm bình luận # TODO: Configure Memory Bank Customization
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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"
},
}
Bước 2: Tiếp nhận thông tin trên thế giới
Tại test_trip_planner, chúng tôi gửi:
- Một tin nhắn văn bản ("Xin chào")
- Một Hình ảnh (Địa danh)
- Một Video (Địa Trung Hải)
- Một đoạn Âm thanh (Ghi chú bằng giọng nói về Gaeta)
Tìm nhận xét # TODO create session service and memory service bên trong hàm 6_multimodal_agent/main.py.
Thay thế toàn bộ dòng này bằng đoạn mã sau:
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
)
👉 Trong cùng một tệp 06_multimodal_agent/main.py, hãy tìm nhận xét # TODO: create memory from session
Thay thế toàn bộ dòng này bằng đoạn mã sau:
await memory_service.add_session_to_memory(final_session_state)
Đây là đường ma thuật. Ứng dụng này gửi tất cả nội dung đa phương tiện đó đến Vertex AI để xử lý và lập chỉ mục.
Bước 3: Truy xuất
👉💻 Trong cửa sổ dòng lệnh Cloud Shell, hãy mở tệp trong Trình chỉnh sửa Cloud Shell bằng cách chạy:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/agent.py
Nhân viên hỗ trợ có PreloadMemoryTool.
tools=[PreloadMemoryTool(), budget_tool]
Khi một phiên mới bắt đầu, công cụ này sẽ tự động tìm kiếm những trải nghiệm liên quan trong Ngân hàng bộ nhớ và đưa chúng vào ngữ cảnh.
Bước 4: Chạy Brain
👉💻 Trong thiết bị đầu cuối Cloud Shell, hãy chạy tập lệnh (Lưu ý: Bạn cần có một dự án trên Google Cloud đã bật Vertex AI):
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/06_multimodal_agent/main.py
Xem bước xác minh cuối cùng:
"Dựa trên hình ảnh, video VÀ âm thanh mà tôi đã chia sẻ với bạn trước đây..."
Nhân viên hỗ trợ sẽ trả lời:
"Bạn nên ghé thăm Gaeta! Bạn đã cho tôi xem một video về Địa Trung Hải và một đoạn âm thanh trong đó bạn nói rằng bạn yêu thích Gaeta."
Nó kết nối các điểm dữ liệu trên nhiều loại hình truyền thông từ trước đến nay.
Điểm chính cần ghi nhớ
Quy tắc số 6 về bộ nhớ: Sử dụng Vertex AI Memory Bank để có trải nghiệm bộ nhớ tối ưu. Công cụ này hợp nhất văn bản, hình ảnh và video thành một bộ não duy nhất có thể tìm kiếm.
9. Kết luận
Bạn đã đi từ một chú Cá vàng hay quên đến một chú Voi đa phương thức.
Bạn đã tạo | Chức năng |
Tác nhân phiên | Bộ nhớ ngắn hạn của cuộc trò chuyện |
Nhiều tác nhân | Kỷ niệm được chia sẻ của nhóm |
Tác nhân liên tục | Nhật ký dài hạn |
Tác nhân có trạng thái | Bộ nhớ động, tự cập nhật |
Profile Agent | Bộ nhớ dữ liệu có cấu trúc |
Tác nhân đa phương thức | Bộ nhớ cảm giác giống như con người |
Lòng tin được xây dựng dựa trên ký ức. Bằng cách triển khai những mẫu này, bạn sẽ tạo ra các tác nhân tôn trọng thời gian và nhật ký của người dùng, dẫn đến những lượt tương tác sâu sắc và hiệu quả hơn.
Bắt đầu xây dựng các tác nhân được cá nhân hoá ngay hôm nay!