1. Введение

Проблема "золотой рыбки"
Представьте, что вы нанимаете турагента, чтобы спланировать отпуск своей мечты в Токио. Используйте агента сеанса, чтобы увидеть, как работает "Проблема золотой рыбки".
Вы заходите в его кабинет и говорите:
"Здравствуйте! Я хочу спланировать двухдневную поездку в Токио. Меня интересуют исторические места и суши".
Агент с энтузиазмом отвечает:
"Отлично! Я запланировал посещение Императорского дворца и ужин в суши-ресторане Sukiyabashi Jiro".
Вы улыбаетесь и говорите:
"Отлично! Можешь отправить мне маршрут?"
Агент смотрит на вас пустым взглядом и спрашивает:
"Здравствуйте! Чем я могу помочь вам спланировать поездку сегодня?
Это так называемая проблема золотой рыбки. Без памяти каждое взаимодействие начинается с чистого листа. Интеллект есть – агент знает, как планировать поездки, – но нет непрерывности. Чтобы ИИ-агент был по-настоящему полезен, ему нужна память.
Ваша миссия на сегодня
На этом семинаре вы решите проблему золотой рыбки, создав туристическое агентство, которое запоминает, учится и адаптируется. Вы пройдете 6 уровней памяти агента и создадите систему, которая будет вести себя не как чат-бот, а как личный помощник.
Уровень | Концепция | "Суперспособность" |
Уровень 1 | Сеанс и состояние | Ведение разговора без забывания |
Уровень 2 | Multi-Agent State | Обмен заметками между участниками команды |
Уровень 3 | Постоянство | Запоминает вас даже после перезагрузки системы. |
Уровень 4 | Обратные вызовы | Обновление памяти полностью автономно |
Уровень 5 | Специальные инструменты | Чтение и запись структурированных профилей пользователей |
Уровень 6 | Мультимодальная память | "Просмотр" и запоминание фотографий и видео |
Стек памяти ADK
Прежде чем писать код, давайте разберемся с инструментами, которые мы используем. Google Agent Development Kit (ADK) предоставляет структурированный способ работы с памятью:
- Сеанс. Контейнер для разговора. В нем хранится история того, что было сказано.
- Состояние. Ключ-значение, прикрепленный к сеансу. Агенты используют ее для хранения определенных фактов (например,
destination="Tokyo"). - MemoryService – долгосрочное хранилище. Здесь мы храним данные, которые не удаляются, например настройки пользователей или проанализированные документы.
2. Настроить
Для работы ИИ-агентов нужны две вещи: облачный проект Google Cloud в качестве основы.
Часть 1. Включите платежный аккаунт
Чтобы выполнить эту практическую работу, вам понадобится платежный аккаунт с положительным балансом. Чтобы начать, используйте бонусы из баннера в верхней части этой практической работы. Если вы уже подключены к платежному аккаунту, пропустите этот шаг.
Часть 2. Открытая среда
- 👉 Нажмите на эту ссылку, чтобы перейти в редактор Cloud Shell.
- 👉 Если в какой-то момент вам будет предложено авторизоваться, нажмите Авторизовать, чтобы продолжить.

- 👉 Если терминал не появился внизу экрана, откройте его:
- Нажмите Вид.
- Выберите Терминал.

- 👉💻 В терминале убедитесь, что вы уже прошли аутентификацию и что в качестве проекта указан идентификатор вашего проекта. Для этого используйте следующую команду:
gcloud auth list - 👉💻 Клонируйте проект bootstrap из 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
Часть 3. Настройка разрешений
- 👉💻 Включите необходимые 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. Здесь вы увидите информацию о проекте.
3. Основа – сеанс и состояние

Концепция: контекст – это главное
Самая базовая форма памяти – это память сеанса. Благодаря этому агент понимает, что местоимение "его" в предложении "Я хочу купить его" относится к товару, о котором вы говорили 10 секунд назад.
В ADK для этого используется объект Session.
- Подход без сохранения состояния. Создание нового сеанса для каждого сообщения.
- Подход с сохранением состояния. Создание одного сеанса и его повторное использование для всего разговора.
Шаг 1. Изучите агента
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
cloudshell edit ~/memory_agent_starter/01_session_agent/agent.py
Открыть чат "~/memory_agent_starter/01_session_agent/agent.py".
👉 Найдите комментарий # TODO: Create a root agent в функции agent.py.
Замените всю эту строку следующим кодом:
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]
)
Инструкция говорит LLM, что нужно запомнить, а код должен предоставить возможность для запоминания.
Шаг 2. Два сценария
Открыть чат "~/memory_agent_starter/01_session_agent/main.py".
👉 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
cloudshell edit ~/memory_agent_starter/01_session_agent/main.py
Откройте файл ~/memory_agent_starter/01_session_agent/main.py и найдите комментарий # TODO: Create a runner with in memorysession service в функции main.py.
Замените всю эту строку следующим кодом:
runner = Runner(
agent=agent,
session_service=session_service,
app_name=agent.name
)
👉 Найдите комментарий # TODO: create a different session to test в функции main.py.
Замените всю эту строку следующим кодом:
tokyo_session_2 = await session_service.create_session(
app_name=multi_day_agent.name,
user_id=user_id
)
Проверить
У нас есть две функции, которые демонстрируют разницу между памятью "золотой рыбки" и "слона".
Сценарий 1. С сохранением состояния (общий сеанс)
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, ...)
Сценарий 2. Без сохранения состояния (каждый раз новый сеанс)
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, ...)
Шаг 3. Запустите агент
Давайте посмотрим, в чем разница. Запустите скрипт:
👉💻 В командной строке выполните следующую команду:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/01_session_agent/main.py
Сценарий 1. Агент запоминает ваши предпочтения из первого сообщения и адаптирует план во втором сообщении.
Сценарий 2. На втором шаге ("Ты помнишь, что мне понравилось в еде?") агент не справляется с задачей, потому что это новый сеанс. Это означает, что сервер не понимает, о чем идет речь.
Вывод
Правило № 1. Всегда используйте session.id повторно, чтобы сохранять контекст разговора. Объект Session – это буфер краткосрочной памяти агента.
4. Команда – состояние нескольких агентов

Концепция: "Испорченный телефон"
Когда несколько агентов работают вместе, они похожи на коллег, передающих друг другу папку с файлами. Если один агент пишет заметку в папке, следующий агент должен иметь возможность ее прочитать.
В ADK эта "папка" называется State (Состояние).
- State – это словарь (
{"key": "value"}), который находится внутри сеанса. - Любой агент в сеансе может читать и записывать в него данные.
Шаг 1. Изучите рабочий процесс
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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']
)
👉 Найдите комментарий # TODO: transportation agent в функции agent.py.
Замените всю эту строку следующим кодом:
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}.
""",
)
👉 Найдите комментарий # TODO: root_agent в функции agent.py.
Замените всю эту строку следующим кодом:
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": Ответ агента Foodie успешно сохранен.{destination}: агент по перевозкам автоматически считывает этот ответ.
Шаг 2. Оркестратор (действий не требуется)
Открыть чат "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."
Агенты работают вместе, чтобы ответить на него.
Шаг 3. Запустите команду
👉💻 В терминале Cloud Shell выполните рабочий процесс с несколькими агентами:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/02_multi_agent/main.py
Что происходит?
- Агент-гурман находит ресторан Jin Sho или похожий.
- ADK: сохраняет Jin Sho в
state['destination']. - Агент по транспорту. Получает в инструкции имя "Джин Шо".
- Результат: "Чтобы добраться до Jin Sho от станции Caltrain, идите по University Ave…"
Вывод
Правило 2. Используйте состояние, чтобы передавать структурированную информацию между агентами. Используйте output_key для записи и {placeholders} для чтения.
5. Перезагрузка – настойчивость

Концепция: "Проблема перезагрузки"
Пока что мы запомнили следующее: InMemory. Если вы остановите скрипт и запустите его снова, агент забудет все, что было до этого. Это как компьютер, который стирает свой жесткий диск каждый раз, когда вы его выключаете.
Чтобы решить эту проблему, нам нужно сохранение. Мы меняем InMemorySessionService на DatabaseSessionService.
Шаг 1. Переход на новую базу данных
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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.
Шаг 2. Извлечение данных из разных сеансов
Благодаря этому можно не только продолжать разговор, но и учиться на основе предыдущих.
В том же файле ~/memory_agent_starter/03_persistent_agent/main.py найдите раздел Test Case 3: Cross-Session Retrieval (Тестовый пример 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
)
👉 Найдите комментарий # TODO: Extract content from the OLD session в функции main.py.
Замените всю эту строку следующим кодом:
previous_context += f"- {role}: {text}\n"
👉 Найдите комментарий # TODO: Manually inject the context to the query в функции main.py.
Замените всю эту строку следующим кодом:
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?
"""
Это имитирует возвращение пользователя через несколько месяцев. Только с помощью базы данных вы можете получить эту старую историю.
Шаг 3. Перезагрузка
👉💻 Запустите скрипт в терминале:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/03_persistent_agent/main.py
Будет создан файл ~/memory_agent_starter/trip_planner.db. Решение. Запустите скрипт дважды.
- При втором запуске найдите строку "Resumed existing session" (Возобновлен существующий сеанс).
- Агент запомнит контекст первого запуска, поскольку он загружается из файла базы данных.
Вывод
Правило 3. Используйте DatabaseSessionService для рабочей версии. Это гарантирует, что разговоры пользователей сохранятся после перезапуска сервера, и позволяет анализировать историю за длительный период.
6. Шпион – обратные вызовы

Иногда нужно, чтобы память обновлялась автоматически на основе действий агента, а не только его слов. Вам нужен "шпион", который будет следить за агентом и делать заметки.
В ADK это обратный вызов. 
after_tool_callback– функция, которая выполняется каждый раз, когда агент работает.ToolContext– способ записи в State изнутри этой функции.
Шаг 1. Логика
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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: add callback to root agent в функции 04_stateful_agent/agent.py.
Замените всю эту строку следующим кодом:
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.
"""
Шаг 3. Протестируйте Spy
👉💻 В терминале запустите скрипт, скопировав и вставив команду ниже:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/04_stateful_agent/main.py
При запуске этого агента вы увидите цикл.
- Реплика 1. Вы спрашиваете, где находится музей. Шпионские наборы
last_activity="CULTURAL". - Реплика 2. Вы просите порекомендовать другой музей.
- Обновление инструкций для агента: "КУЛЬТУРНЫЕ ТЕМЫ ЗАПРЕЩЕНЫ".
- Агент говорит: "Я не могу пойти в ещё один музей. Может, в парк?"
Проверьте журналы консоли на наличие [CALLBACK] и [STATE UPDATE]. Вы можете наблюдать за тем, как меняется память агента в реальном времени.
Вывод
Правило 4. Используйте обратные вызовы, чтобы автоматизировать управление состоянием. Агент создает собственный контекст, просто выполняя свою работу.
7. Картотека – настраиваемые инструменты
Концепция: структурированная память

До сих пор "память" представляла собой журнал чата или простую пару "ключ-значение". Но что, если вам нужно запомнить сложный профиль пользователя, например diet: vegan, budget: high, pets: [cat, dog]?
Для этого мы рассматриваем память как инструмент. Агент сам решает, когда открыть картотеку (прочитать), а когда составить отчет (записать). 
Шаг 1. Инструменты
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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: implement save_user_preferences tools в функции ~/memory_agent_starter/05_profile_agent/tools.py.
Замените всю эту строку следующим кодом:
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())}"
👉 Найдите комментарий # TODO: implement recall_user_preferences tools в функции 05/tools.py.
Замените всю эту строку следующим кодом:
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`.
"""
Шаг 2. Выполнение
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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, когда вы говорите "Я веган".
Шаг 3. Создайте профиль
👉💻 Запустите скрипт:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/05_profile_agent/main.py
Попробуйте следующий сценарий:
- "Привет, спланируй ужин". -> Агент проверяет базу данных и ничего не находит. Запрашивает предпочтения.
- "Я веган". -> Агент сохраняет "веган" в БД.
- Перезапустите скрипт.
- "Привет, спланируй ужин". -> Агент проверяет базу данных, видит "веган" и сразу предлагает веганский ресторан.
Вывод
Правило № 5. Для работы со сложными структурированными данными предоставьте агенту инструменты чтения и записи. Позвольте LLM управлять собственным долгосрочным хранилищем.
8. The Brain – мультимодальная память

Концепция: "Человеческий опыт"
Люди запоминают не только текст. Мы помним атмосферу фотографии, звучание голоса, ощущение от видео.
Vertex AI Memory Bank позволяет агенту работать с мультимодальной памятью. Она может принимать изображения, видео и аудио, "понимать" их и извлекать позже.
Шаг 1. Настройка
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
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"
},
}
Шаг 2. Сбор данных со всего мира
В test_trip_planner мы отправляем:
- Текстовое сообщение ("Привет")
- Изображение (достопримечательность)
- Видео (Средиземное море)
- Аудиозапись (голосовая заметка о Гаэте)
Найдите комментарий # TODO create session service and memory service в функции 6_multimodal_agent/main.py.
Замените всю эту строку следующим кодом:
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)
Это волшебная линия. Она отправляет все эти мультимедийные данные в Vertex AI, который обрабатывает и индексирует их.
Шаг 3. Извлечение
👉💻 В терминале Cloud Shell откройте файл в редакторе Cloud Shell, выполнив следующую команду:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/agent.py
У агента есть PreloadMemoryTool.
tools=[PreloadMemoryTool(), budget_tool]
Когда начинается новый сеанс, этот инструмент автоматически ищет в банке памяти релевантный прошлый опыт и вставляет его в контекст.
Шаг 4. Запустите мозг
👉💻 В терминале Cloud Shell запустите скрипт (примечание: для этого требуется облачный проект Google Cloud с включенным Vertex AI):
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/06_multimodal_agent/main.py
Посмотрите видео о последнем этапе проверки:
"На основе изображения, видео И аудио, которыми я поделился с тобой ранее…"
Агент ответит:
"Посетите Гаэту! Ты показал мне видео Средиземного моря и аудиозапись, где ты говоришь, что любишь Гаэту".
Она объединила разные типы медиа из прошлого.
Вывод
Правило 6. Используйте Vertex AI Memory Bank для максимальной эффективности. Она объединяет текст, изображения и видео в единую базу знаний с возможностью поиска.
9. Заключение
Вы прошли путь от забывчивой Золотой рыбки до Мультимодального слона.
Вы построили | Функция |
Агент сеанса | Краткосрочная память диалога |
Мультиагентные системы | Общее воспоминание команды |
Постоянный агент | Долгосрочная история |
Агент с сохранением состояния | Динамическое, самообновляющееся воспоминание |
Агент профиля | Память структурированных данных |
Мультимодальный агент | Сенсорная память, как у человека |
Доверие строится на памяти. Реализуя эти шаблоны, вы создаете агентов, которые уважают время и историю пользователя, что приводит к более глубокому и эффективному взаимодействию.
Начните создавать персонализированных агентов уже сегодня!