chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:30:30 +08:00
commit 914fea506e
2793 changed files with 802106 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
# Agent Engine in Vertex AI
[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview)
is a managed service that helps you to build and deploy agent reasoning
frameworks. It gives you the flexibility to choose how much reasoning you want
to delegate to the LLM and how much you want to handle with customized code. You
can define Python functions that get used as tools via Gemini Function Calling.
Agent Engine integrates closely with the Python SDK for the Gemini model in
Vertex AI, and it can manage prompts, agents, and examples in a modular way.
Agent Engine is compatible with LangChain, LlamaIndex, or other Python
frameworks.
## Sample notebooks
| Description | Sample Name |
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| Intro to Building and Deploying an Agent with Agent Engine in Vertex AI | [intro_agent_engine.ipynb](intro_agent_engine.ipynb) |
| Debugging and Optimizing Agents: A Guide to Tracing in Agent Engine | [tracing_agents_in_agent_engine.ipynb](tracing_agents_in_agent_engine.ipynb) |
| Building a Conversational Search Agent with Agent Engine and RAG on Vertex AI Search | [tutorial_vertex_ai_search_rag_agent.ipynb](tutorial_vertex_ai_search_rag_agent.ipynb) |
| Building and Deploying a Google Maps API Agent with Agent Engine | [tutorial_google_maps_agent.ipynb](tutorial_google_maps_agent.ipynb) |
| Building and Deploying a LangGraph Application with Agent Engine in Vertex AI | [tutorial_langgraph.ipynb](tutorial_langgraph.ipynb) |
| Deploying a RAG Application with AlloyDB with Agent Engine | [tutorial_alloydb_rag_agent.ipynb](tutorial_alloydb_rag_agent.ipynb) |
| Deploying a RAG Application with Cloud SQL for PostgreSQL with Agent Engine | [tutorial_cloud_sql_pg_rag_agent.ipynb](tutorial_cloud_sql_pg_rag_agent.ipynb) |
@@ -0,0 +1,629 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4KG8heslwNdJ"
},
"outputs": [],
"source": [
"# Copyright 2025 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Vertex AI Agent Engine in Express Mode\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\">\n",
" <img width=\"32px\" src=\"https://storage.googleapis.com/github-repo/generative-ai/logos/GitHub_Invertocat_Dark.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<p>\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>\n",
"</p>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oWnJG6W9s9wz"
},
"source": [
"## Set up the environment\n",
"\n",
"https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/set-up#sdk-installation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qn8t6OZZBR2_"
},
"outputs": [],
"source": [
"%pip install \"google-cloud-aiplatform[agent_engines]\" --force-reinstall --quiet"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UlZrGQP1kquN"
},
"source": [
"# Sign up for Vertex AI Express mode"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AWXhFk3rkvHt"
},
"source": [
"We can use Vertex Services like Agent Engine and access models without requiring a credit card through Vertex AI Express Mode!\n",
"\n",
"Sign up with your google account here: https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview to unlock access to certain services and the latest google models models!\n",
"\n",
"Vertex Express Mode combined with ADK allow for the creation of advanced agents with customizable tools and a context layer with sessions and memories without any billing!\n",
"\n",
"Once you sign up, paste your api key here:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Zdr_R5zzkTJX"
},
"outputs": [],
"source": [
"express_mode_api_key = \"\" # @param {type:\"string\"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "h1ey_XgwFpOx"
},
"source": [
"# Develop an Adk agent locally"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KIsEeWOrfpvN"
},
"source": [
"### Step 1: Define a local simple agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c09iKPFwhtUL"
},
"source": [
"We will use AdkApp, which is a template to make Adk Agents to create a simple agent that has no tools, just a model. We will be able to converse with it, but it cannot help us with the currency conversion rates.\n",
"\n",
"With Vertex AI Express mode, you have access to the latest Google models. For the comprehensive list, see the [Available models and rate limits in express mode](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview#models). We will be using Gemini 2.5 Flash for this example."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "J5eBt442ntq4"
},
"outputs": [],
"source": [
"# Initialize Vertex AI SDK\n",
"import vertexai\n",
"from vertexai import agent_engines\n",
"\n",
"vertexai.init(api_key=express_mode_api_key)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "u6g_sWf8fVpj"
},
"outputs": [],
"source": [
"model = \"gemini-2.5-flash\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Xdvw9CqwfZeS"
},
"outputs": [],
"source": [
"from google.adk.agents import Agent\n",
"from google.adk.apps import App\n",
"\n",
"agent = Agent(\n",
" model=model, # Required.\n",
" name=\"currency_exchange_agent\", # Required.\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "r-zZiHpXfdIe"
},
"outputs": [],
"source": [
"app = agent_engines.AdkApp(\n",
" app=App(\n",
" name=\"currency_exchange_app\",\n",
" root_agent=agent,\n",
" )\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "oClJjHMyfeBG"
},
"outputs": [],
"source": [
"async for event in app.async_stream_query(\n",
" user_id=\"local user\", # Required\n",
" message=\"What is the exchange rate from US dollars to Swedish krona on 2025-09-25?\",\n",
"):\n",
" print(event)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rauCYC6ufmUe"
},
"source": [
"### Step 2: Define a tool"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vUaZGzUmh5ls"
},
"source": [
"Now that we know we can talk to the agent, lets add a tool. This tool allows the agent to check the exchange rate between two currencies ona given date using the frankfurter app."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "SSUldKSkflJW"
},
"outputs": [],
"source": [
"def get_exchange_rate(\n",
" currency_from: str = \"USD\",\n",
" currency_to: str = \"EUR\",\n",
" currency_date: str = \"latest\",\n",
"):\n",
" \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
" import requests\n",
"\n",
" response = requests.get(\n",
" f\"https://api.frankfurter.app/{currency_date}\",\n",
" params={\"from\": currency_from, \"to\": currency_to},\n",
" )\n",
" return response.json()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YwjPSaVof4LZ"
},
"source": [
"To test the function before you use it in your agent, run the following:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "AsR76YB2f2Od"
},
"outputs": [],
"source": [
"get_exchange_rate(currency_from=\"USD\", currency_to=\"SEK\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Fsk4g4fYf8ns"
},
"source": [
"### Step 3: Add the tool to your agent and test locally"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0FveK16ZgA6z"
},
"source": [
"You have to associate the tools with the Agent when it is initialized:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "FYhxaPnGf_oA"
},
"outputs": [],
"source": [
"from google.adk.agents import Agent\n",
"\n",
"agent = Agent(\n",
" model=model, # Required.\n",
" name=\"currency_exchange_agent\", # Required.\n",
" tools=[get_exchange_rate], # [new] Optional.\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "H3HTcZFmgHE2"
},
"source": [
"Then, we test locally it like we did before."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cQXwtqm_gI_1"
},
"outputs": [],
"source": [
"app = agent_engines.AdkApp(\n",
" app=App(\n",
" name=\"currency_exchange_app\",\n",
" root_agent=agent,\n",
" )\n",
")\n",
"async for event in app.async_stream_query(\n",
" user_id=\"local user\",\n",
" message=\"What is the exchange rate from US dollars to Swedish krona on 2025-09-25?\",\n",
"):\n",
" print(event)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nmyRh5qckedk"
},
"source": [
"# Deploy your Agent with Agent Engine"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6PbMnOLE25NA"
},
"source": [
"### Step 4: Write agent files"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ONXGYYIWgZdm"
},
"source": [
"Now that we know our agent will work locally, we can write our code to the local files and deploy it to Google Cloud without cost to Agent Engine with source based deployment! More info can be found at [Deploy an Agent Engine](https://docs.cloud.google.com/agent-builder/agent-engine/deploy#from-source-files)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "bqDemcnqHUG2"
},
"outputs": [],
"source": [
"!mkdir test"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "uJS6VpvKBZAN"
},
"outputs": [],
"source": [
"%%writefile test/requirements.txt\n",
"google-cloud-aiplatform[agent_engines,adk]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "l1G9gtSDw8yt"
},
"outputs": [],
"source": [
"%%writefile test/my_agent.py\n",
"from google.adk.agents import Agent\n",
"from vertexai import agent_engines\n",
"\n",
"def get_exchange_rate(\n",
" currency_from: str = \"USD\",\n",
" currency_to: str = \"EUR\",\n",
" currency_date: str = \"latest\",\n",
"):\n",
" \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
" import requests\n",
"\n",
" response = requests.get(\n",
" f\"https://api.frankfurter.app/{currency_date}\",\n",
" params={\"from\": currency_from, \"to\": currency_to},\n",
" )\n",
" return response.json()\n",
"\n",
"agent = Agent(\n",
" model=\"gemini-2.5-flash\", # Required.\n",
" name='currency_exchange_agent', # Required.\n",
" tools=[get_exchange_rate], # [new] Optional.\n",
")\n",
"\n",
"adk_app=agent_engines.AdkApp(agent=agent, enable_tracing=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "GnvSbk0-CY5V"
},
"outputs": [],
"source": [
"# Define Class Methods\n",
"class_methods = [\n",
" {\n",
" \"parameters\": {},\n",
" \"api_mode\": \"async_stream\",\n",
" \"description\": None,\n",
" \"name\": \"async_stream_query\",\n",
" },\n",
" {\n",
" \"parameters\": {},\n",
" \"api_mode\": \"async\",\n",
" \"description\": None,\n",
" \"name\": \"async_create_session\",\n",
" },\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GeXDv0UIFrC4"
},
"source": [
"### Step 5: Deploy your agent to Agent Engine"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yFcWb-zEicMr"
},
"source": [
"Deploying your agent to Agent Engine unlocks many Google Cloud services, including the Vertex AI Memory Bank and Session services and a suite of observability, logging, and tracing. All of the conversations with the agent are stored in Vertex AI and can be used to give the agent context for future conversations through long term memories. Visit the Vertex AI documentation to learn more about the [Vertex AI Session service](https://docs.cloud.google.com/agent-builder/agent-engine/sessions/overview) and the [Vertex AI Memory Bank service](https://docs.cloud.google.com/agent-builder/agent-engine/memory-bank/overview)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Yed9Q_OY3RI8"
},
"outputs": [],
"source": [
"client = vertexai.Client(api_key=express_mode_api_key)\n",
"\n",
"remote_agent = client.agent_engines.create(\n",
" config={\n",
" \"display_name\": \"test agent\",\n",
" \"description\": \"test agent\",\n",
" \"source_packages\": [\"test\"],\n",
" \"entrypoint_module\": \"test.my_agent\",\n",
" \"entrypoint_object\": \"adk_app\",\n",
" \"requirements_file\": \"test/requirements.txt\",\n",
" \"class_methods\": class_methods,\n",
" \"agent_framework\": \"google-adk\",\n",
" },\n",
")\n",
"remote_agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XsJsdx2XFjRN"
},
"source": [
"### Step 6: Talk to your deployed Agent Engine"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZlFJb6KP3g3G"
},
"outputs": [],
"source": [
"async for item in remote_agent.async_stream_query(\n",
" message=\"What is the exchange rate between USD and Korean Won on 2025-09-25?\",\n",
" user_id=\"user1\",\n",
"):\n",
" print(item)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "MydwzEUoEXDY"
},
"outputs": [],
"source": [
"async for item in remote_agent.async_stream_query(\n",
" message=\"What can you help me with?\",\n",
" user_id=\"user1\",\n",
"):\n",
" print(item)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vFXN8L1PnmT2"
},
"source": [
"# Manage your Agent Engine deployment"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "McPSMcn4mMv1"
},
"source": [
"### Step 7: Talk with your agent through the Agent Engine UI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "19m_DYgalznc"
},
"source": [
"You can also converse with your deployed agent though the Agent Engine UI in your express mode console. Visit the [Express mode UI](https://console.cloud.google.com/expressmode) and navigate to the Agent Engine menu.\n",
"\n",
"![agent-engine-ui](https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/express-mode/agent-engine-ui.png)\n",
"\n",
"Once you select your agent, use the Playground to converse with it!\n",
"\n",
"![playground](https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/express-mode/playground.png)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PDn4ZY03jf1E"
},
"source": [
"### Step 8: View conversation history with Vertex AI Session Service"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "SpqgjdNtitaG"
},
"outputs": [],
"source": [
"session = list(client.agent_engines.sessions.list(name=remote_agent.api_resource.name))[\n",
" 0\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "WK1xKnfsj9Wj"
},
"outputs": [],
"source": [
"list(client.agent_engines.sessions.events.list(name=session.name))"
]
}
],
"metadata": {
"colab": {
"name": "express-mode-agent-engine-deployment.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,831 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ijGzTHJJUCPY"
},
"outputs": [],
"source": [
"# Copyright 2024 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VEqbX8OhE8y9"
},
"source": [
"# Intro to Building and Deploying an Agent with Agent Engine in Vertex AI\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Fintro_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Run in Colab Enterprise\n",
" </a>\n",
" </td> \n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://goo.gle/4jeQzJW\">\n",
" <img width=\"32px\" src=\"https://cdn.qwiklabs.com/assets/gcp_cloud-e3a77215f0b8bfa9b3f611c0d2208c7e8708ed31.svg\" alt=\"Google Cloud logo\"><br> Open in Cloud Skills Boost\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a> \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84e7e432e6ff"
},
"source": [
"| | |\n",
"|-|-|\n",
"|Author(s) | [Kristopher Overholt](https://github.com/koverholt) |"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "CkHPv2myT2cx"
},
"source": [
"## Overview\n",
"\n",
"### Gemini\n",
"\n",
"Gemini is a family of generative AI models developed by Google DeepMind that is designed for multimodal use cases.\n",
"\n",
"### Function Calling in Gemini\n",
"\n",
"[Function calling](https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/function-calling) lets developers create a description of a function in their code, then pass that description to a language model in a request. The response from the model includes the name of a function that matches the description and the arguments to call it with.\n",
"\n",
"### Agent Engine in Vertex AI\n",
"\n",
"[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) is a managed service that helps you to build and deploy an agent framework. It gives you the flexibility to choose how much reasoning you want to delegate to the LLM and how much you want to handle with customized code. You can define Python functions that get used as tools via [Gemini Function Calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling). Agent Engine integrates closely with the Python SDK for the Gemini model in Vertex AI, and it can manage prompts, agents, and examples in a modular way. Agent Engine is compatible with LangChain, LlamaIndex, or other Python frameworks.\n",
"\n",
"<img width=\"60%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-engine-overview.png\" alt=\"Agent Engine on Vertex AI\" />"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DrkcqHrrwMAo"
},
"source": [
"### Objectives\n",
"\n",
"In this tutorial, you will learn how to build and deploy an agent (model, tools, and reasoning) using the Vertex AI SDK for Python.\n",
"\n",
"You'll build and deploy an agent that uses the Gemini model, Python functions as tools, and LangChain for orchestration.\n",
"\n",
"You will complete the following tasks:\n",
"\n",
"- Install the Vertex AI SDK for Python\n",
"- Use the Vertex AI SDK to build components of a simple agent\n",
"- Test your agent locally before deploying\n",
"- Deploy and test your agent on Vertex AI\n",
"- Customize each layer of your agent (model, tools, orchestration)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "C9nEPojogw-g"
},
"source": [
"### Costs\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "r11Gu7qNgx1p"
},
"source": [
"## Getting Started\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Vertex AI SDK for Python\n",
"\n",
"Install the latest version of the Vertex AI SDK for Python as well as extra dependencies related to Agent Engine and LangChain:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \\\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\" \\\n",
" cloudpickle==3.0.0 \\\n",
" \"pydantic>=2.10\" \\\n",
" requests"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "R5Xep4W9lq-Z"
},
"source": [
"### Restart current runtime\n",
"\n",
"To use the newly installed packages in this Jupyter runtime, you must restart the runtime. You can do this by running the cell below, which will restart the current kernel."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "XRvKdaPDTznN"
},
"outputs": [],
"source": [
"# Restart kernel after installs so that your environment can access the new packages\n",
"import IPython\n",
"\n",
"app = IPython.Application.instance()\n",
"app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SbmM4z7FOBpM"
},
"source": [
"<div class=\"alert alert-block alert-warning\">\n",
"<b>⚠️ The kernel is going to restart. Please wait until it is finished before continuing to the next step. ⚠️</b>\n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you are running this notebook on Google Colab, run the following cell to authenticate your environment. This step is not required if you are using [Vertex AI Workbench](https://cloud.google.com/vertex-ai-workbench)."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"if \"google.colab\" in sys.modules:\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information and initialize Vertex AI SDK\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
"LOCATION = \"us-central1\" # @param {type:\"string\"}\n",
"STAGING_BUCKET = \"gs://[your-staging-bucket]\" # @param {type:\"string\"}\n",
"\n",
"import vertexai\n",
"\n",
"vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1e5c96372296"
},
"source": [
"## Example: Build and deploy an agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jXHfaVS66_01"
},
"source": [
"### Import libraries"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "lslYAvw37JGQ"
},
"outputs": [],
"source": [
"from vertexai import agent_engines\n",
"from vertexai.preview.reasoning_engines import LangchainAgent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "43c61bf4c3f5"
},
"source": [
"### Define model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "f685ca44c1e9"
},
"source": [
"As you construct your agent from the bottom up, the first component deals with which generative model you want to use in your agent.\n",
"\n",
"<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-1.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
"\n",
"Here you'll use the Gemini 3 model:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "921890fcb875"
},
"outputs": [],
"source": [
"model = \"gemini-3.5-flash\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "60eba5468448"
},
"source": [
"### Define Python functions (tools)\n",
"\n",
"The second component of your agent includes tools and functions, which enable the generative model to interact with external systems, databases, document stores, and other APIs so that the model can get the most up-to-date information or take action with those systems.\n",
"\n",
"<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-2.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
"\n",
"In this example, you'll define a function called `get_exchange_rate` that uses the `requests` library to retrieve real-time currency exchange information from an API:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "ff7991bf37bf"
},
"outputs": [],
"source": [
"def get_exchange_rate(\n",
" currency_from: str = \"USD\",\n",
" currency_to: str = \"EUR\",\n",
" currency_date: str = \"latest\",\n",
"):\n",
" \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
" import requests\n",
"\n",
" response = requests.get(\n",
" f\"https://api.frankfurter.app/{currency_date}\",\n",
" params={\"from\": currency_from, \"to\": currency_to},\n",
" )\n",
" return response.json()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "971f56c167e7"
},
"source": [
"Test the function with sample inputs to ensure that it's working as expected:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "4ae49a2ccd2e"
},
"outputs": [],
"source": [
"get_exchange_rate(currency_from=\"USD\", currency_to=\"SEK\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "35ca52a9021c"
},
"source": [
"### Define agent\n",
"\n",
"The third component of your agent involves adding a reasoning layer, which helps your agent use the tools that you provided to help the end user achieve a higher-level goal.\n",
"\n",
"<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-3.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
"\n",
"If you were to use Gemini and Function Calling on their own without a reasoning layer, you would need to handle the process of calling functions and APIs in your application code, and you would need to implement retries and additional logic to ensure that your function calling code is resilient to failures and malformed requests.\n",
"\n",
"Here, you'll use the LangChain agent template provided in the Vertex AI SDK for Agent Engine, which brings together the model, tools, and reasoning that you've built up so far:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "68bc1b395f9d"
},
"outputs": [],
"source": [
"agent = LangchainAgent(\n",
" model=model,\n",
" tools=[get_exchange_rate],\n",
" agent_executor_kwargs={\"return_intermediate_steps\": True},\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fa3c33f6ec72"
},
"source": [
"Now we can test the model and agent behavior to ensure that it's working as expected before we deploy it:"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "68a527f87e42"
},
"source": [
"### Test your agent locally\n",
"\n",
"With all of the core components of your agent in place, you can send a prompt to your agent using `.query` to test that it's working as expected, including the intermediate steps that the agent performed between the input prompt and the generated summary output. In the default mode, the agent processes your input and returns the **entire agent output in a single response when complete**:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "e0c5c699de12"
},
"outputs": [],
"source": [
"agent.query(input=\"What's the exchange rate from US dollars to Swedish currency today?\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b1cf06f5fa46"
},
"source": [
"In addition to the default query mode, the `.stream_query` method allows you to **see the agent's intermediate steps and final output from the chain**.\n",
"\n",
"Instead of waiting for the agent to complete all sub-tasks, the agent sends back the response in **chunks as it's being generated**:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "7a931f086fc9"
},
"outputs": [],
"source": [
"message_types = {\"actions\": \"Action\", \"messages\": \"Message\", \"output\": \"Output\"}\n",
"for chunk in agent.stream_query(\n",
" input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
"):\n",
" for key, label in message_types.items():\n",
" if key in chunk:\n",
" print(\"\\n------\\n\")\n",
" print(f\"{label}:\")\n",
" print()\n",
" print(chunk[key])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bbe3d34ec106"
},
"source": [
"This allows you to observe the agent's actions in real-time (such as function calls, and intermediate steps), which is helpful for debugging purposes or for providing real-time updates to the end user."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "77b0a9f0d75b"
},
"source": [
"### Deploy your agent on Vertex AI\n",
"\n",
"Now that you've specified a model, tools, and reasoning for your agent and tested it out, you're ready to deploy your agent as a remote service in Vertex AI!\n",
"\n",
"<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-4.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
"\n",
"You can re-define the agent to avoid any stateful information in the agent due to our testing in the previous cell:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "b2f8365735d2"
},
"outputs": [],
"source": [
"agent = LangchainAgent(\n",
" model=model,\n",
" tools=[get_exchange_rate],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ebe2c3be1ca6"
},
"source": [
"Now you're ready to deploy your agent to Agent Engine in Vertex AI by calling `agent_engines.create()` along with:\n",
"\n",
"1. The instance of your agent class\n",
"2. The Python packages and versions that your agent requires at runtime, similar to how you would define packages and versions in a `requirements.txt` file."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"id": "fd3b88c73411"
},
"outputs": [],
"source": [
"remote_agent = agent_engines.create(\n",
" agent,\n",
" requirements=[\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\",\n",
" \"cloudpickle==3.0.0\",\n",
" \"pydantic>=2.10\",\n",
" \"requests\",\n",
" ],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "e698a4c3d786"
},
"source": [
"Now you can send a prompt to your remote agent using `.query` to test that it's working as expected:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"id": "d01b37cb77dc"
},
"outputs": [],
"source": [
"remote_agent.query(\n",
" input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ff3620f5fa01"
},
"source": [
"Or you can stream the results back from the remote agent interactively using `.stream_query`:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"id": "a4250671731e"
},
"outputs": [],
"source": [
"message_types = {\"actions\": \"Action\", \"messages\": \"Message\", \"output\": \"Output\"}\n",
"for chunk in remote_agent.stream_query(\n",
" input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
"):\n",
" for key, label in message_types.items():\n",
" if key in chunk:\n",
" print(\"\\n------\\n\")\n",
" print(f\"{label}:\")\n",
" print()\n",
" print(chunk[key])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9f2f7d3ed7bd"
},
"source": [
"### Querying your deployed agent\n",
"\n",
"You've now deployed your agent and can [interact with it in multiple ways](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), both within this notebook and from other applications or environments. The primary methods for accessing your deployed agent are via the Python client library or through REST API calls. Here's an overview of both methods:\n",
"\n",
"**Method 1: Reusing within this notebook or another Python environment**\n",
"\n",
"You can directly reuse and query the `remote_agent` instance you created in this notebook.\n",
"\n",
"Or, you can instantiate a new instance in another notebook or Python script. To do this, you'll need to retrieve your deployed agent's resource name that uniquely identifies your agent, which is a string that includes the project, location, and Agent Engine ID. You can retrieve it by running the following code in the notebook or environment where you created your agent:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"id": "fdaf8b91413f"
},
"outputs": [],
"source": [
"remote_agent.resource_name"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "060f8369d113"
},
"source": [
"Use the resource name to load the agent in your other notebook or Python script, then query the remote agent as usual:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"id": "78af4442827e"
},
"outputs": [],
"source": [
"# from vertexai import agent_engines\n",
"\n",
"# AGENT_ENGINE_RESOURCE_NAME = \"YOUR_AGENT_ENGINE_RESOURCE_NAME\" # Replace with the resource name of your deployed Agent Engine\n",
"\n",
"# remote_agent = agent_engines.get(AGENT_ENGINE_RESOURCE_NAME)\n",
"# response = remote_agent.query(input=query)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "63ab06554fc0"
},
"source": [
"**Method 2: Accessing from other environments via REST API**\n",
"\n",
"Beyond the Python client library, your deployed Vertex AI agent can be [queried using REST API calls](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), including:\n",
"\n",
"- Python: You can use Python's `requests` library or similar tools to make HTTP calls to the Vertex AI REST API.\n",
"- cURL: A command-line tool, cURL allows you to send HTTP requests directly. This is useful for testing and debugging.\n",
"- Other Programming Languages: If you prefer a different language for your application, you can use its native HTTP client library to make REST API calls.\n",
"\n",
"In summary, you have access to your deployed agent through the Python client library within Python environments, and more universally through its REST API via tools and programming languages of your choosing."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "82d321fd62e0"
},
"source": [
"## Customizing your agent"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "353d586b9b1b"
},
"source": [
"The example above includes the minimal amount of configuration required for each component within the agent to help you get started.\n",
"\n",
"But what if you want to swap to a different Gemini model version, change the generative model parameters or safety filters, or perform additional customizations to the agent? The following example shows some of the most common parameters that you'll want to customize in your agent. Agent Engine in Vertex AI works with [Gemini model versions that support Function Calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling) and LangChain agents."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fdda38e6dc6b"
},
"source": [
"### Model configuration\n",
"\n",
"You'll start with customizations for the model component within your agent. Refer to the Vertex AI documentation for more information about configuration parameters related to [generative AI model versions](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning), [safety attributes](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/configure-safety-attributes), and [model parameters](https://ai.google.dev/gemini-api/docs/models/gemini#model-attributes):"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"id": "5408d3da2726"
},
"outputs": [],
"source": [
"## Model variant and version\n",
"model = \"gemini-3.5-flash\"\n",
"\n",
"## Model safety settings\n",
"from langchain_google_vertexai import HarmBlockThreshold, HarmCategory\n",
"\n",
"safety_settings = {\n",
" HarmCategory.HARM_CATEGORY_UNSPECIFIED: HarmBlockThreshold.BLOCK_NONE,\n",
" HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,\n",
" HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,\n",
" HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,\n",
" HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH,\n",
"}\n",
"\n",
"## Model parameters\n",
"model_kwargs = {\n",
" \"temperature\": 0.3,\n",
" \"max_output_tokens\": 1000,\n",
" \"top_p\": 0.95,\n",
" \"top_k\": 40,\n",
" \"safety_settings\": safety_settings,\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5e48ed43107e"
},
"source": [
"### Agent configuration\n",
"\n",
"You can also customize aspects of the agent component, including whether it should return all of the intermediate steps for a given input prompt and output response, maximum number of iterations, how to handle parsing errors, and the size of the sliding context window that the agent has visibility into:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"id": "08623f46a9e4"
},
"outputs": [],
"source": [
"# Agent parameters\n",
"agent_executor_kwargs = {\n",
" \"return_intermediate_steps\": True,\n",
" \"max_iterations\": 3,\n",
" \"handle_parsing_errors\": False,\n",
" \"trim_intermediate_steps\": -1,\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "164b7a580493"
},
"source": [
"Each component within your agent has additional parameters that can be customized or overridden, including the system instructions, preamble prompts, ability to manage chat sessions and history so that your agent maintains context between multi-turn queries.\n",
"\n",
"Each component within your agent (model, tools, reasoning) is modular and composable so that you can customize your agent as little or as much as you want.\n",
"\n",
"Refer to the [Agent Engine documentation in Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) for more details on each agent component and the available options for customization."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6415b2a47a0e"
},
"source": [
"## Cleaning up\n",
"\n",
"After you've finished, it's a good practice to clean up your cloud resources. You can delete the deployed Agent Engine instance to avoid any unexpected charges on your Google Cloud account."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"id": "7cec827288b7"
},
"outputs": [],
"source": [
"remote_agent.delete()"
]
}
],
"metadata": {
"colab": {
"name": "intro_agent_engine.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,683 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2026 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Persisting LangChain History with Vertex AI Session Service\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Flangchain_vertex_ai_session_service.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\">\n",
" <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<p>\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/langchain_vertex_ai_session_service.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>\n",
"</p>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"This notebook will demonstrate how to use the Vertex AI Session Service to persist the conversational history with LangChain agents.\n",
"\n",
"You will lean how to:\n",
"- Create a Session with the Vertex AI Session Service\n",
"- Store conversation turns within the sessions you created\n",
"- Store tool calls and tool results within the sessions you created\n",
"- Access the stored conversational history"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Vertex AI SDK and LangChain for Google\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install \"google-cloud-aiplatform[agent_engines]\" --force-reinstall --quiet\n",
"# Install the Google Generative AI integration for LangChain\n",
"%pip install -U \"langchain-google-genai\" --quiet"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "r-ES3MMrMlxV"
},
"outputs": [],
"source": [
"# Restart the session to ensure packages are updated\n",
"import os\n",
"\n",
"os._exit(0)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment\n",
"\n",
"If you are running this notebook in **Google Colab**, run the cell below to authenticate your account."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"if \"google.colab\" in sys.modules:\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# fmt: off\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
"LOCATION = \"us-central1\" # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
"# fmt: on\n",
"\n",
"if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
" PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
"if not LOCATION:\n",
" LOCATION = os.environ.get(\"GOOGLE_CLOUD_REGION\")\n",
"os.environ[\"GOOGLE_GENAI_USE_VERTEXAI\"] = \"1\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5303c05f7aa6"
},
"source": [
"### Import libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6fc324893334"
},
"outputs": [],
"source": [
"import datetime\n",
"\n",
"import requests\n",
"from langchain_core.chat_history import BaseChatMessageHistory\n",
"from langchain_core.messages import (\n",
" BaseMessage,\n",
" HumanMessage,\n",
" message_to_dict,\n",
" messages_from_dict,\n",
")\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.runnables.history import RunnableWithMessageHistory\n",
"from langchain_core.tools import tool\n",
"from langchain_google_genai import ChatGoogleGenerativeAI\n",
"from vertexai import Client"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EdvJRUWRNGHE"
},
"source": [
"## Create Vertex AI Chat Message History\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ydzH42O6O-U5"
},
"source": [
"LangChain uses `BaseChatMessageHistory` to persist the chat history of a LangChain agent. It has 3 basic methods:\n",
"- messages: a property of the history, listing previous message history\n",
"- add_messages: add one or multiple messages to the conversation history\n",
"- clear: delete all messages in the conversation history\n",
"\n",
"We will create the VertexAISessionChatMessageHistory that extends BaseChatMessageHistory, which will use the Vertex AI Session service to implement the messages and add_messages methods."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "m814rnX7O7D5"
},
"outputs": [],
"source": [
"class VertexAISessionChatMessageHistory(BaseChatMessageHistory):\n",
" \"\"\"A LangChain message history backend that defers storage to\n",
" Vertex AI Agent Engine's Session Service via the vertexai Client.\n",
" \"\"\"\n",
"\n",
" def __init__(self, client: Client, session_name: str, author: str = \"user\"):\n",
" self.client = client\n",
" self.session_name = session_name\n",
" self.author = author\n",
"\n",
" @property\n",
" def messages(self) -> list[BaseMessage]:\n",
" # Call ListEvents from the Vertex AI Session service to return the list of messages.\n",
" events = self.client.agent_engines.sessions.events.list(name=self.session_name)\n",
"\n",
" lc_messages = []\n",
" for event in events:\n",
" # Convert directly from the LangChain message stored in raw_event\n",
" if event.raw_event and \"langchain_message\" in event.raw_event:\n",
" # `messages_from_dict` expects a list of serialized messages\n",
" extracted_message = messages_from_dict(\n",
" [event.raw_event[\"langchain_message\"]]\n",
" )[0]\n",
" lc_messages.append(extracted_message)\n",
" continue\n",
" return lc_messages\n",
"\n",
" def add_message(self, message: BaseMessage) -> None:\n",
" is_human = isinstance(message, HumanMessage)\n",
" author = self.author if is_human else \"agent\"\n",
"\n",
" # Dump the entire LangChain message structure (id, tool_calls, kwargs, response_metadata)\n",
" # into a JSON serializable dict\n",
" serialized_lc_message = message_to_dict(message)\n",
"\n",
" self.client.agent_engines.sessions.events.append(\n",
" name=self.session_name,\n",
" author=author,\n",
" invocation_id=\"langchain-invocation\",\n",
" timestamp=datetime.datetime.now(datetime.timezone.utc),\n",
" config={\n",
" # Store the full LangChain payload in the raw_event field\n",
" \"raw_event\": {\"langchain_message\": serialized_lc_message}\n",
" },\n",
" )\n",
"\n",
" def clear(self) -> None:\n",
" \"\"\"Clears the session. Vertex AI Session Service currently doesn't support\n",
" easily clearing individual events; typical workarounds include\n",
" deleting the session natively via `self.client.agent_engines.sessions.delete(...)`.\n",
" \"\"\"\n",
" raise NotImplementedError(\n",
" \"Clear is not natively supported without deleting the entire session via SDK.\"\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FRl1IPZPSXZi"
},
"source": [
"## Initialize Vertex AI\n",
"\n",
"We will use the Vertex AI SDK to create a session instance.\n",
"\n",
"Vertex AI Sessions are sub resources of Agent Engines, which is the managed solution for deploying agents to Google Cloud. For more details, see [link]. This means all sessions must be associated with an Agent Engine.\n",
"\n",
"For this demo, we don't need to deploy the agent. We will just use agent_engines.create to create an empty Agent Engine to store our sessions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "GhiU7PzERpOE"
},
"outputs": [],
"source": [
"import vertexai\n",
"\n",
"# Initialize the Vertex AI SDK Client with your project and location\n",
"client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
"\n",
"# Create an agent engine to hold the session\n",
"agent_engine = client.agent_engines.create(config={\"display_name\": \"langchain_test\"})\n",
"agent_engine_path = agent_engine.api_resource.name"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "mvZ4-TjoRrAh"
},
"outputs": [],
"source": [
"# Create a Vertex AI session resource\n",
"session_operation = client.agent_engines.sessions.create(\n",
" name=agent_engine_path, user_id=\"langchain_user\"\n",
")\n",
"\n",
"# Extract the full session resource name from the finished operation response\n",
"session_resource_name = session_operation.response.name"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "jfT0Zt0pRsce"
},
"outputs": [],
"source": [
"# Define a factory function that LangChain will call per session ID\n",
"def get_vertex_session_history(session_id: str) -> BaseChatMessageHistory:\n",
" return VertexAISessionChatMessageHistory(client=client, session_name=session_id)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JIhMzITHTNia"
},
"source": [
"## Start a conversation\n",
"Since you already signed into your Google Cloud project, we will use Gemini as the model for our agent.\n",
"\n",
"Here, we will just create a simple conversational agent. When we send messages to the LangChain agent, the messages will be stored in our Session using the `add_messages` method we defined in `VertexAISessionChatMessageHistory`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ydyerW-3RuXt"
},
"outputs": [],
"source": [
"# Create a standard LangChain Model and Prompt\n",
"model = ChatGoogleGenerativeAI(\n",
" model=\"gemini-2.5-flash\", project=PROJECT_ID, location=LOCATION\n",
")\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are a helpful assistant.\"),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{input}\"),\n",
" ]\n",
")\n",
"\n",
"chain = prompt | model\n",
"\n",
"# Wrap the chain with RunnableWithMessageHistory\n",
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" get_vertex_session_history,\n",
" input_messages_key=\"input\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "JWVTDPUXV9Pq"
},
"outputs": [],
"source": [
"# Invoke the chain using the session resource name we generated\n",
"input = \"Hi! My name is John Doe.\"\n",
"print(input)\n",
"response = chain_with_history.invoke(\n",
" {\"input\": input}, config={\"configurable\": {\"session_id\": session_resource_name}}\n",
")\n",
"print(\"Gemini: \", response.content)\n",
"\n",
"input = \"What is my name?\"\n",
"print(input)\n",
"response = chain_with_history.invoke(\n",
" {\"input\": input}, config={\"configurable\": {\"session_id\": session_resource_name}}\n",
")\n",
"print(\"Gemini: \", response.content)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3XQbxqL-T4-4"
},
"source": [
"We can view the entire chat history using the `messages` property we defined in `VertexAISessionChatMessageHistory`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "iLK18ollRv-r"
},
"outputs": [],
"source": [
"# View the conversation history\n",
"history = get_vertex_session_history(session_resource_name)\n",
"for message in history.messages:\n",
" print(f\"{message.type.capitalize()}: {message.content}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tZKASjWbSTaJ"
},
"source": [
"## Tool Call\n",
"\n",
"Now that we have used a simple agent, we will show how the Vertex AI Session service can store more advanced conversations from agents with Tools.\n",
"\n",
"In this example, we will use a tool called `get_weather` to allow the agent to check the weather in any city we ask."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "gBB4xZoORx14"
},
"outputs": [],
"source": [
"# Create a new Vertex AI session resource\n",
"session_operation = client.agent_engines.sessions.create(\n",
" name=agent_engine_path, user_id=\"langchain_user\"\n",
")\n",
"\n",
"# Extract the full session resource name from the finished operation response\n",
"session_resource_name = session_operation.response.name"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xjeed8KhVcuz"
},
"source": [
"## Define the get_weather tool\n",
"We will use a basic weather API for our tool. This allows the agent to check the weather for a given city."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EdSStEwTU1Tq"
},
"outputs": [],
"source": [
"# Define the tool\n",
"@tool\n",
"def get_weather(location: str) -> str:\n",
" \"\"\"Returns the current weather for a given city name.\"\"\"\n",
" # format=3 gives a simple string like: \"London: ⛅️ +15°C\"\n",
" try:\n",
" response = requests.get(f\"https://wttr.in/{location}?format=3\")\n",
" return response.text.strip()\n",
" except Exception:\n",
" return \"Sorry, I couldn't fetch the weather right now.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Ro3tWwbARzLC"
},
"outputs": [],
"source": [
"# Bind the tool to the model\n",
"# ChatVertexAI natively supports LangChain tool integration\n",
"model_with_tools = ChatGoogleGenerativeAI(\n",
" model=\"gemini-2.5-flash\", project=PROJECT_ID, location=LOCATION\n",
").bind_tools([get_weather])\n",
"\n",
"# Create a Prompt Template with STRICT system instructions\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\n",
" \"system\",\n",
" \"You are a specialized weather assistant. You MUST use the `get_weather` tool to answer any questions about the weather. Do not use your internal knowledge.\",\n",
" ),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{input}\"),\n",
" ]\n",
")\n",
"\n",
"# Combine the prompt and the model into a standard runnable chain\n",
"chain = prompt | model_with_tools\n",
"\n",
"# Wrap the chain with RunnableWithMessageHistory\n",
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" get_vertex_session_history,\n",
" input_messages_key=\"input\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7VkQ6H_VXe5I"
},
"source": [
"Now that we registered the tool with the model, lets try a basic conversation.\n",
"\n",
"In LangChain, the application logic is responsible for calling the tool. Here, if the model tells us to call get_weather, we call the function then provide the response to the model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "fkMq12VgWGuJ"
},
"outputs": [],
"source": [
"# --- Turn 1: AI Uses the Tool ---\n",
"input = \"What is the weather in Paris?\"\n",
"print(input)\n",
"response = chain_with_history.invoke(\n",
" {\"input\": input}, config={\"configurable\": {\"session_id\": session_resource_name}}\n",
")\n",
"\n",
"# If the system instruction worked, the model will output a tool call instead of text\n",
"print(\"(Gemini Tool Request):\", response.tool_calls)\n",
"\n",
"# --- Turn 2: Providing the tool result ---\n",
"if response.tool_calls:\n",
" tool_call = response.tool_calls[0]\n",
" # Execute the python function manually\n",
" tool_result = get_weather.invoke(tool_call)\n",
" print(\"(Tool Response):\", tool_result)\n",
" request_payload = {\n",
" # Pass the ToolMessage containing the tool_call_id directly into the input\n",
" \"input\": [tool_result]\n",
" }\n",
" final_response = chain_with_history.invoke(\n",
" request_payload, config={\"configurable\": {\"session_id\": session_resource_name}}\n",
" )\n",
" print(\"(Gemini Final Answer):\", final_response.content)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WH6c62lvXymu"
},
"source": [
"We can view the entire chat history using the `messages` property we defined in `VertexAISessionChatMessageHistory`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "bRp0xp88R1AS"
},
"outputs": [],
"source": [
"history = get_vertex_session_history(session_resource_name)\n",
"for message in history.messages:\n",
" print(f\"{message.type.capitalize()}: {message.content}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2a4e033321ad"
},
"source": [
"## Cleaning up\n",
"\n",
"Now that the demo is done, we can delete the Agent Engine instance to delete the sessions we created."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3ADJzvTWX9hB"
},
"outputs": [],
"source": [
"client.agent_engines.delete(name=agent_engine_path, force=True)"
]
}
],
"metadata": {
"colab": {
"name": "langchain_vertex_ai_session_service.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,603 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2025 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Get started with Vertex AI Memory Bank - ADK\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Fmemory%2Fget_started_with_memory_bank_adk.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\">\n",
" <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_adk.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84f0f73a0f76"
},
"source": [
"| Author(s) |\n",
"| --- |\n",
"| [ Kimberly Milam, Ivan Nardini](https://github.com/inardini)|"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"This tutorial demonstrates how to build an agent with long-term memory using the Google Agent Development Kit (ADK) and Vertex AI Memory Bank.\n",
"\n",
"Vertex AI Memory Bank enables you to dynamically generate and store long-term memories from user conversations. This allows an agent to access personalized information across multiple sessions for a particular user, leading to more contextual and continuous interactions.\n",
"\n",
"### What you'll learn\n",
"\n",
"By the end of this tutorial, you will be able to:\n",
"* Understand how long-term memory enhances agent capabilities.\n",
"* Create a Vertex AI Agent Engine instance to use Memory Bank.\n",
"* Build an ADK agent that uses the `PreloadMemoryTool` tool to retrieve information.\n",
"* See how the agent stores conversation history and recalls relevant facts from past sessions.\n",
"* Build more sophisticated, context-aware Agents.\n",
"\n",
"### Why this is important\n",
"\n",
"Traditional LLM-based agents often lack the ability to recall information from previous interactions, treating each conversation as a new one. This \"amnesia\" prevents them from maintaining context over time. Long-term memory, like that provided by Vertex AI Memory Bank, allows agents to:\n",
"\n",
"* Maintain context over extended periods.\n",
"* Personalize interactions based on user history.\n",
"* Build a deeper understanding of user preferences and needs.\n",
"\n",
"Google's ADK provides a robust framework for building agents, and by extending it with services like Memory Bank, you can unlock a new level of sophistication.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Google Gen AI SDK and other required packages\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \"google-cloud-aiplatform>=1.100.0\" \"google-adk>=1.5.0\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"# import sys\n",
"\n",
"# if \"google.colab\" in sys.modules:\n",
"# from google.colab import auth\n",
"\n",
"# auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"# Use the environment variable if the user doesn't provide Project ID.\n",
"import os\n",
"import uuid\n",
"\n",
"import vertexai\n",
"\n",
"# Project configuration\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
"if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
" PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
" if not PROJECT_ID:\n",
" raise ValueError(\"Project ID not found. Please set it in the form above or as the GOOGLE_CLOUD_PROJECT environment variable.\")\n",
"\n",
"LOCATION = os.environ.get(\"GOOGLE_CLOUD_REGION\", \"us-central1\")\n",
"\n",
"# Set environment variables required for ADK\n",
"os.environ[\"GOOGLE_GENAI_USE_VERTEXAI\"] = \"TRUE\"\n",
"os.environ[\"GOOGLE_CLOUD_PROJECT\"] = PROJECT_ID\n",
"os.environ[\"GOOGLE_CLOUD_LOCATION\"] = LOCATION\n",
"\n",
"# Agent configuration\n",
"MODEL_NAME = \"gemini-2.5-flash\"\n",
"USER_ID = f\"user_{uuid.uuid4()}\"\n",
"\n",
"print(f\"Project: {PROJECT_ID}\")\n",
"print(f\"Location: {LOCATION}\")\n",
"print(f\"Session User ID: {USER_ID}\")\n",
"\n",
"# Initialize Vertex AI client\n",
"_ = vertexai.Client(\n",
" project=PROJECT_ID,\n",
" location=LOCATION,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5303c05f7aa6"
},
"source": [
"### Import libraries\n",
"\n",
"Import the Python libraries required for this tutorial, including components from the ADK, Vertex AI SDK, and standard libraries.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6fc324893334"
},
"outputs": [],
"source": [
"import uuid\n",
"import vertexai\n",
"from vertexai import agent_engines\n",
"from google import adk\n",
"from google.adk.memory import VertexAiMemoryBankService\n",
"from google.adk.sessions import VertexAiSessionService\n",
"from google.genai import types"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qwEDAkpMqyR4"
},
"source": [
"### Helper functions\n",
"\n",
"We will define a helper function to simplify running the agent and capturing its response. This will make our interaction loop cleaner and easier to read.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "PlnHiogXq0JP"
},
"outputs": [],
"source": [
"def run_single_turn(query, session, user_id):\n",
" \"\"\"Run a single conversation turn.\"\"\"\n",
" content = types.Content(role=\"user\", parts=[types.Part(text=query)])\n",
" events = runner.run(user_id=user_id, session_id=session, new_message=content)\n",
"\n",
" response_content = None\n",
" for event in events:\n",
" if event.is_final_response():\n",
" response_content = event.content.parts[0].text\n",
" return response_content\n",
"\n",
"\n",
"def chat_loop(session, user_id) -> None:\n",
" \"\"\"Main chat interface loop.\"\"\"\n",
" print(\"\\nStarting chat. Type 'exit' or 'quit' to end.\")\n",
" print(\"Every message will be automatically stored in memory.\\n\")\n",
"\n",
" while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in [\"quit\", \"exit\", \"bye\"]:\n",
" print(\"\\nAssistant: Thank you for chatting. Have a great day!\")\n",
" break\n",
"\n",
" response = run_single_turn(user_input, session, user_id)\n",
" if response:\n",
" print(f\"\\nAssistant: {response}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EdvJRUWRNGHE"
},
"source": [
"## Creating the Agent Engine with Memory Bank\n",
"\n",
"Vertex AI Memory Bank is a component of the Vertex AI Agent Engine, a managed service that allows developers to deploy, manage, and scale AI agents.\n",
"\n",
"To use Memory Bank, you first need to create or get an existing Agent Engine instance. This provides the necessary APIs to store and retrieve memories associated with specific users.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "x5tUDbo8YVhe"
},
"outputs": [],
"source": [
"agent_engine = agent_engines.create()\n",
"print(f\"Created Agent Engine: {agent_engine.resource_name}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NXtRpE0KXvY6"
},
"source": [
"## Building an Agent with Memory Bank using ADK\n",
"\n",
"Now we will construct the core components of our memory-enabled agent."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "q0hfdld4X9yg"
},
"source": [
"### Define the Agent\n",
"\n",
"Define the ADK agent with a name, instructions (prompt), and specify the `load_memory` tool. This built-in ADK tool enables the agent to call our `VertexAiMemoryBankService` to search for information. The agent's prompt is crucial, as it instructs the LLM when and how to use this tool to recall user-specific context."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qz6Zmy_L6HwY"
},
"outputs": [],
"source": [
"agent = adk.Agent(\n",
" model=MODEL_NAME,\n",
" name=\"helpful_assistant\",\n",
" instruction=\"\"\"You are a helpful assistant with perfect memory.\n",
" Instructions:\n",
" - Use the context to personalize responses\n",
" - Naturally reference past conversations when relevant\n",
" - Build upon previous knowledge about the user\n",
" - If using semantic search, the memories shown are the most relevant to the current query\"\"\",\n",
" tools=[adk.tools.preload_memory_tool.PreloadMemoryTool()],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TnmlrAZkYJZ2"
},
"source": [
"### Configure the ADK Runner\n",
"\n",
"The `Runner` orchestrates the interaction between the user, the agent, and the various services. We will configure it with our `agent` and the `VertexAiSessionService` and `VertexAiMemoryBankService` to manage session state and long-term memory.\n",
"\n",
"> Notice that the `VertexAiMemoryBankService` released in ADK, you can also use a local session service."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "wPEy9Sgp7YLV"
},
"outputs": [],
"source": [
"app_name = \"my_agent_\" + str(uuid.uuid4())[:6]\n",
"agent_engine_id = agent_engine.name\n",
"\n",
"memory_bank_service = VertexAiMemoryBankService(\n",
" project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id\n",
")\n",
"\n",
"\n",
"session_service = VertexAiSessionService(\n",
" project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id\n",
")\n",
"\n",
"runner = adk.Runner(\n",
" agent=agent,\n",
" app_name=app_name,\n",
" session_service=session_service,\n",
" memory_service=memory_bank_service,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PMfVSv9EYQu_"
},
"source": [
"## Interacting with the Agent - Information gathering session\n",
"\n",
"Let's begin our first conversation. In this session, we will provide the agent with specific pieces of information that we expect it to remember later.\n",
"\n",
"The process is as follows:\n",
"\n",
"1. Create a new ADK session for the user.\n",
"2. Send a series of messages to the agent.\n",
"3. After the conversation, retrieve the completed session data.\n",
"4. Explicitly add the session to our Memory Bank, which triggers the memory generation process.\n",
"\n",
"In a production application, adding the session to memory might be handled by a background process or through hooks in a custom `Runner` or `SessionService`. For this tutorial, we perform this step explicitly to clearly illustrate the process.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tRqZ0Rz2YdXL"
},
"outputs": [],
"source": [
"session1 = await runner.session_service.create_session(\n",
" app_name=app_name,\n",
" user_id=USER_ID,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c4WVP3nuaIV-"
},
"source": [
"Try these example phrases:\n",
"\n",
"```\n",
"You: Hi, I work as an agent engineer\n",
"You: I love hiking and have a dog named Max\n",
"You: I'm working on a recommendation system project\n",
"You: Bye\n",
"```\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-tqSiFUzaKBC"
},
"outputs": [],
"source": [
"chat_loop(session1.id, USER_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Bzfm-l9caJkf"
},
"source": [
"Add the session to memory."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "55_1rmY2QufY"
},
"outputs": [],
"source": [
"completed_session = await runner.session_service.get_session(\n",
" app_name=app_name, user_id=USER_ID, session_id=session1.id\n",
")\n",
"await memory_bank_service.add_session_to_memory(completed_session)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gF0AX5rzZYXd"
},
"source": [
"## Interacting with the Agent - Memory Recall session\n",
"\n",
"Now, we will start a new session with the same user. This time, we will ask questions that require the agent to recall information from the first session. This is where the `load_memory` tool and our `VertexAIMemoryBankService.search_memory()` method will be invoked."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "vzBwJL8JZlwa"
},
"outputs": [],
"source": [
"session2 = await runner.session_service.create_session(\n",
" app_name=agent_engine.name,\n",
" user_id=USER_ID,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rzdQxPYuZuZb"
},
"source": [
"Try these example phrases:\n",
"\n",
"```\n",
"You: What do you remember about me?\n",
"You: What is my dog's name?\n",
"You: Bye\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "rbbqJEmDZqvv"
},
"outputs": [],
"source": [
"chat_loop(session2.id, USER_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c7jVCYtvaxbD"
},
"source": [
"## Cleaning up\n",
"\n",
"To avoid charges, delete the agent engine when you're done experimenting.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "CAtT65gEcAFB"
},
"outputs": [],
"source": [
"delete_engine = True\n",
"\n",
"if delete_engine:\n",
" agent_engines.delete(resource_name=agent_engine.resource_name, force=True)"
]
}
],
"metadata": {
"colab": {
"name": "get_started_with_memory_bank_adk.ipynb",
"toc_visible": true
},
"environment": {
"kernel": "python3",
"name": "workbench-notebooks.m130",
"type": "gcloud",
"uri": "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/workbench-notebooks:m130"
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": ""
}
},
"nbformat": 4,
"nbformat_minor": 4
}
@@ -0,0 +1,670 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2025 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Get started with Vertex AI Memory Bank - CrewAI\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Fmemory%2Fget_started_with_memory_bank_crewai.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\">\n",
" <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_crewai.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84f0f73a0f76"
},
"source": [
"| Author(s) |\n",
"| --- |\n",
"| [Ivan Nardini](https://github.com/inardini) |"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"This tutorial demonstrates how to integrate **Vertex AI Memory Bank** with **CrewAI** agents to provide them with persistent, long-term memory across conversations.\n",
"\n",
"### What you'll learn\n",
"\n",
"By the end of this tutorial, you will be able to:\n",
"\n",
" * Provision a Vertex AI Agent Engine to serve as the backend for Memory Bank.\n",
" * Implement a custom CrewAI `Storage` class that connects to the Memory Bank API.\n",
" * Instantiate CrewAI agents and tasks that leverage this external, long-term memory.\n",
" * Assemble and run a crew that can recall information from past interactions to provide personalized responses.\n",
"\n",
"### Why this is important\n",
"\n",
"CrewAI provides a powerful framework for orchestrating autonomous agents to solve complex tasks. However, by default, these agents are stateless. By integrating a dedicated long-term memory service like Vertex AI Memory Bank, you can empower your crews to:\n",
"\n",
" * **Maintain Context:** Remember user preferences, historical data, and previous interactions across multiple sessions.\n",
" * **Enhance Collaboration:** Allow different agents in a crew to access a shared pool of knowledge about a user or topic.\n",
" * **Deliver Personalization:** Build a deep, evolving understanding of users, leading to more effective and personalized assistance.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install required packages\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \"crewai\" \"google-cloud-aiplatform>=1.100.0\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"# import sys\n",
"\n",
"# if \"google.colab\" in sys.modules:\n",
"# from google.colab import auth\n",
"\n",
"# auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0Q9k7TmH59fd"
},
"outputs": [],
"source": [
"import json\n",
"import os\n",
"import uuid\n",
"\n",
"import vertexai\n",
"\n",
"# Set project configuration\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
"if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
" PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
" if not PROJECT_ID:\n",
" raise ValueError(\"Project ID not found. Please set it in the form above or as the GOOGLE_CLOUD_PROJECT environment variable.\")\n",
"\n",
"LOCATION = os.environ.get(\"GOOGLE_CLOUD_REGION\", \"us-central1\")\n",
"SERVICE_ACCOUNT_FILE = \"[your-service-account-file]\" # @param {type:\"string\"}\n",
"\n",
"# Set environment variables for CrewAI\n",
"os.environ[\"DEFAULT_VERTEXAI_PROJECT\"] = PROJECT_ID\n",
"os.environ[\"DEFAULT_VERTEXAI_LOCATION\"] = LOCATION\n",
"\n",
"# Agent configuration\n",
"MODEL_NAME = \"gemini-2.5-flash\"\n",
"USER_ID = f\"user_{uuid.uuid4()}\"\n",
"\n",
"print(f\"Project: {PROJECT_ID}\")\n",
"print(f\"Location: {LOCATION}\")\n",
"print(f\"Session User ID: {USER_ID}\")\n",
"\n",
"# Initialize Vertex AI client\n",
"client = vertexai.Client(\n",
" project=PROJECT_ID,\n",
" location=LOCATION,\n",
")\n",
"\n",
"# Load the service account credentials with Vertex AI User permission for the CrewAI LLM\n",
"with open(SERVICE_ACCOUNT_FILE, \"r\") as file:\n",
" vertex_credentials = json.load(file)\n",
"vertex_credentials_json = json.dumps(vertex_credentials)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5303c05f7aa6"
},
"source": [
"### Import libraries\n",
"\n",
"Import the necessary libraries for building our agent crew."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6fc324893334"
},
"outputs": [],
"source": [
"from datetime import datetime\n",
"from typing import Any, Dict, List\n",
"from crewai import LLM, Agent, Crew, Task\n",
"from crewai.memory.external.external_memory import ExternalMemory\n",
"from crewai.memory.storage.interface import Storage"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5INaBikJ89-k"
},
"source": [
"### Helper functions\n",
"\n",
"These functions create an interactive chat experience. The `run_single_turn` function encapsulates the logic for a single round of conversation, dynamically creating a new `Task` and `Crew` for each user input while reusing the same persistent memory object."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Axwi9upN8-4C"
},
"outputs": [],
"source": [
"def run_single_turn(query: str, agent: Agent, memory: ExternalMemory):\n",
" \"\"\"Runs a single conversational turn with the CrewAI agent.\"\"\"\n",
" task = Task(\n",
" description=f\"Respond to the user's query: '{query}'\",\n",
" expected_output=\"A helpful and personalized response based on your memory of the user.\",\n",
" agent=agent,\n",
" )\n",
" crew = Crew(\n",
" agents=[agent],\n",
" tasks=[task],\n",
" external_memory=memory,\n",
" )\n",
" return crew.kickoff()\n",
"\n",
"\n",
"def chat_loop(agent: Agent, memory: ExternalMemory) -> None:\n",
" \"\"\"Main chat interface loop.\"\"\"\n",
" print(\"\\nStarting chat. Type 'exit' or 'quit' to end.\")\n",
" print(\"Every message will be automatically stored in memory.\\n\")\n",
"\n",
" while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in [\"quit\", \"exit\", \"bye\"]:\n",
" print(\"\\nAssistant: Thank you for chatting. Have a great day!\")\n",
" break\n",
"\n",
" response = run_single_turn(user_input, agent, memory)\n",
" print(f\"\\nAssistant: {response}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uGTgIVPMA0kA"
},
"source": [
"## Creating the Agent Engine with Memory Bank\n",
"\n",
"Vertex AI Memory Bank is part of the Vertex AI Agent Engine. To use Memory Bank, you first create a new Agent Engine instance, which provides the APIs to store and retrieve user-specific memories."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "8RWs1bTXA2ZM"
},
"outputs": [],
"source": [
"agent_engine = client.agent_engines.create()\n",
"print(f\"Created Agent Engine: {agent_engine.api_resource.name}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y8oPi1rEO55v"
},
"source": [
"## (Optional) Initialize User Memory\n",
"\n",
"You can optionally pre-seed the Memory Bank with initial facts about a user. This demonstrates how to store information that the agent can reference from the very first interaction.\n",
"We'll create an initial memory entry for our user. This demonstrates how to store facts that the agent can reference in future conversations.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "B6xRZ6-sg_7L"
},
"outputs": [],
"source": [
"import_initial_memory_op = client.agent_engines.create_memory(\n",
" name=agent_engine.api_resource.name,\n",
" fact=f\"The user's name is {USER_ID} and they have a passion for learning new things.\",\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"\n",
"# Pretty print the created memory\n",
"memory = import_initial_memory_op.response\n",
"print(\"Created initial memory:\")\n",
"print(f\" Fact: {memory.fact}\")\n",
"print(f\" User ID: {memory.scope.get('user_id')}\")\n",
"print(f\" Created at: {memory.create_time}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VZwY1np4TyjF"
},
"outputs": [],
"source": [
"memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine.api_resource.name,\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"\n",
"for i, memory in enumerate(memories, 1):\n",
" if hasattr(memory, \"memory\") and hasattr(memory.memory, \"fact\"):\n",
" print(f\"{i}. {memory.memory.fact}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ogkz7RTi6_ly"
},
"source": [
"## Integrating Memory Bank with CrewAI\n",
"\n",
"To make Vertex AI Memory Bank compatible with CrewAI's memory system, we need to create a bridge between them.\n",
"\n",
"### Create a Custom Memory Storage Class\n",
"\n",
"The key to this integration is a custom storage class, `VertexAIMemoryBankStorage`, that inherits from CrewAI's `Storage` interface. This class translates CrewAI's generic `save` and `search` methods into specific API calls to the Vertex AI Memory Bank.\n",
"\n",
" * **`save(value, metadata)`**: This method takes a piece of text (`value`) and associated `metadata` from CrewAI. It then calls the `generate_memories` endpoint of the Memory Bank API to save the information.\n",
" * **`search(query, **kwargs)`**: This method receives a search `query` from CrewAI. It calls the `retrieve_memories` endpoint, using semantic search if a query is provided, and formats the results into the dictionary structure that CrewAI expects.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qjpgkilG7HkY"
},
"outputs": [],
"source": [
"class VertexAIMemoryBankStorage(Storage):\n",
" \"\"\"CrewAI storage implementation using Vertex AI Memory Bank.\"\"\"\n",
"\n",
" def __init__(\n",
" self,\n",
" project: str,\n",
" location: str,\n",
" agent_engine_name: str,\n",
" use_semantic_search: bool = True,\n",
" default_user_id: str = \"default_user\",\n",
" ):\n",
" \"\"\"Initialize Vertex AI Memory Bank storage.\"\"\"\n",
" self.project = project\n",
" self.location = location\n",
" self.agent_engine_name = agent_engine_name\n",
" self.use_semantic_search = use_semantic_search\n",
" self.default_user_id = default_user_id\n",
"\n",
" # Validate required parameters early\n",
" if not all([project, location, agent_engine_name]):\n",
" raise ValueError(\"project, location, and agent_engine_name are required\")\n",
"\n",
" def save(self, value: str, metadata: Dict[str, Any]) -> None:\n",
" \"\"\"Save a memory to Vertex AI Memory Bank.\"\"\"\n",
"\n",
" client = self._get_client()\n",
"\n",
" # Extract user_id from metadata or use default\n",
" user_id = metadata.get(\"user_id\", self.default_user_id)\n",
"\n",
" # Prepare memory event\n",
" event = {\n",
" \"content\": {\n",
" \"parts\": [{\"text\": value}],\n",
" \"role\": metadata.get(\"role\", \"user\"),\n",
" }\n",
" }\n",
"\n",
" # Add timestamp if provided\n",
" if \"timestamp\" in metadata:\n",
" event[\"timestamp\"] = metadata[\"timestamp\"]\n",
"\n",
" # Generate memory in Vertex AI\n",
" client.agent_engines.generate_memories(\n",
" name=self.agent_engine_name,\n",
" direct_contents_source={\"events\": [event]},\n",
" scope={\"user_id\": user_id},\n",
" config={\"wait_for_completion\": True},\n",
" )\n",
"\n",
" def search(self, query: str, limit: int = 5, **kwargs) -> List[Dict[str, Any]]:\n",
" \"\"\"Search memories in Vertex AI Memory Bank.\n",
"\n",
" Args:\n",
" query: Search query (used for semantic search if enabled)\n",
" limit: Maximum number of results to return\n",
" **kwargs: Additional parameters (e.g., user_id)\n",
"\n",
" Returns:\n",
" List of memory dictionaries with 'value' and 'metadata' keys\n",
" \"\"\"\n",
" client = self._get_client()\n",
"\n",
" # Extract user_id from kwargs or use default\n",
" user_id = kwargs.get(\"user_id\", self.default_user_id)\n",
" scope = {\"user_id\": user_id}\n",
"\n",
" # Determine search method\n",
" if self.use_semantic_search and query:\n",
" retrieved_memories = client.agent_engines.retrieve_memories(\n",
" name=self.agent_engine_name,\n",
" scope=scope,\n",
" similarity_search_params={\"search_query\": query, \"top_k\": limit},\n",
" )\n",
" else:\n",
" retrieved_memories = client.agent_engines.retrieve_memories(\n",
" name=self.agent_engine_name, scope=scope, simple_retrieval_params={}\n",
" )\n",
"\n",
" # Transform results to CrewAI format\n",
" results = []\n",
" for memory in retrieved_memories:\n",
" if hasattr(memory, \"memory\") and hasattr(memory.memory, \"fact\"):\n",
" result = {\n",
" \"memory\": memory.memory.fact,\n",
" \"metadata\": {\n",
" \"user_id\": user_id,\n",
" \"timestamp\": (\n",
" memory.memory.update_time.isoformat()\n",
" if hasattr(memory.memory, \"update_time\")\n",
" else datetime.now().isoformat()\n",
" ),\n",
" },\n",
" }\n",
"\n",
" results.append(result)\n",
"\n",
" return results\n",
"\n",
" def reset(self):\n",
" client = self._get_client()\n",
" client.agent_engines.delete(name=self.agent_engine_name)\n",
"\n",
" def _get_client(self):\n",
" \"\"\"Create a Vertex AI client instance.\n",
"\n",
" Returns a new client for each operation to ensure proper\n",
" event loop management in async contexts.\n",
" \"\"\"\n",
" return vertexai.Client(project=self.project, location=self.location)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Jh5pdQOb7Ook"
},
"source": [
"## Define the CrewAI Components\n",
"\n",
"With the storage bridge in place, we can now define the elements of our crew.\n",
"\n",
"1. **Instantiate the LLM**: We'll configure the Gemini model that our agent will use.\n",
"2. **Instantiate the Custom Storage and External Memory**: We create an instance of our `VertexAIMemoryBankStorage` class, passing in the necessary project and Agent Engine details. Then we initialize an `ExternalMemory` object configured with our custom `vertex_memory_bank` storage. This equips the entire crew with long-term memory.\n",
"3. **Create the Agent**: We define a `Personal Assistant` agent, providing it with a role, goal, backstory, and the configured LLM."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1aDYi0KQR1k6"
},
"outputs": [],
"source": [
"# Instantiate the LLM\n",
"llm = LLM(model=MODEL_NAME, temperature=0.7, vertex_credentials=vertex_credentials_json)\n",
"\n",
"# Instantiate your custom storage and the external memory\n",
"vertex_memory_bank_storage = VertexAIMemoryBankStorage(\n",
" project=PROJECT_ID,\n",
" location=LOCATION,\n",
" agent_engine_name=agent_engine.api_resource.name,\n",
" default_user_id=USER_ID,\n",
")\n",
"external_vertex_memory_bank = ExternalMemory(storage=vertex_memory_bank_storage)\n",
"\n",
"# Create a personal assistant agent\n",
"assistant = Agent(\n",
" role=\"Personal Assistant\",\n",
" goal=\"Remember user information and provide personalized help\",\n",
" backstory=\"You are a helpful assistant with perfect memory of past conversations.\",\n",
" llm=llm,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c4WVP3nuaIV-"
},
"source": [
"## Interacting with the Agent\n",
"\n",
"Now, let's interact with our memory-enabled agent. Try the following phrases to see how the agent builds and uses its memory.\n",
"\n",
"```\n",
"You: Hi\n",
"You: I work as an agent engineer\n",
"You: I love hiking and have a dog named Max\n",
"You: I'm working on a recommendation system project\n",
"You: What do you remember about me?\n",
"You: Bye\n",
"```\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-tqSiFUzaKBC"
},
"outputs": [],
"source": [
"chat_loop(assistant, external_vertex_memory_bank)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6nbPcSzu7-Ol"
},
"source": [
"## Check for Stored Memories\n",
"\n",
"After the run, we can query the Memory Bank directly to confirm that the information from our latest interaction (\"software engineer,\" \"love hiking\") has been successfully saved."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "r-0g4fvI8BHZ"
},
"outputs": [],
"source": [
"memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine.api_resource.name,\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"\n",
"for i, memory in enumerate(memories, 1):\n",
" if hasattr(memory, \"memory\") and hasattr(memory.memory, \"fact\"):\n",
" print(f\"{i}. {memory.memory.fact}\")\n",
"\n",
"print(f\"\\nTotal memories stored: {len(list(memories))}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2a4e033321ad"
},
"source": [
"## Cleaning Up\n",
"\n",
"To avoid incurring ongoing charges to your Google Cloud account for the resources used, it is important to delete the Agent Engine instance when you are finished."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3p_JZNCq8QEy"
},
"outputs": [],
"source": [
"delete_engine = True\n",
"\n",
"if delete_engine:\n",
" client.agent_engines.delete(name=agent_engine.api_resource.name, force=True)"
]
}
],
"metadata": {
"colab": {
"name": "get_started_with_memory_bank_crewai.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -0,0 +1,670 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2025 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Get started with Vertex AI Memory Bank - LangGraph\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/tree/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Fmemory%2Fget_started_with_memory_bank_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\">\n",
" <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/memory/get_started_with_memory_bank_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84f0f73a0f76"
},
"source": [
"| Author(s) |\n",
"| --- |\n",
"| [Ivan Nardini](https://github.com/inardini) |"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"This tutorial demonstrates how to build a conversational agent using **LangGraph** with the **Vertex AI Memory Bank API** to provide the agent with long-term memory. This enables the agent to personalize responses based on information learned from prior conversations.\n",
"\n",
"### What you'll learn\n",
"\n",
"By the end of this tutorial, you will be able to:\n",
"\n",
" * Provision a Vertex AI Agent Engine to use Memory Bank.\n",
" * Define a LangGraph agent state and graph structure.\n",
" * Create a graph node that retrieves memories, generates personalized responses, and stores new information.\n",
" * Build and run a conversational agent that maintains context across sessions.\n",
"\n",
"### Why this is important\n",
"\n",
"While standard chatbot frameworks can manage short-term conversation history, they often fail to retain information across different sessions. LangGraph allows you to build robust, stateful applications by defining agent workflows as graphs. Integrating it with a dedicated long-term memory service like Vertex AI Memory Bank unlocks the ability to create truly personalized and context-aware agents that build a continuous understanding of their users over time.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install required packages\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet google-cloud-aiplatform>=1.100.0 langgraph langchain-core langchain-google-vertexai"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"# import sys\n",
"\n",
"# if \"google.colab\" in sys.modules:\n",
"# from google.colab import auth\n",
"\n",
"# auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information and enviroment\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"# Use the environment variable if the user doesn't provide Project ID.\n",
"import os\n",
"import uuid\n",
"import vertexai\n",
"\n",
"# Project configuration\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
"if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
" PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
" if not PROJECT_ID:\n",
" raise ValueError(\"Project ID not found. Please set it in the form above or as the GOOGLE_CLOUD_PROJECT environment variable.\")\n",
"\n",
"LOCATION = os.environ.get(\"GOOGLE_CLOUD_REGION\", \"us-central1\")\n",
"\n",
"# Agent configuration\n",
"MODEL_NAME = \"gemini-2.5-flash\"\n",
"USER_ID = f\"user_{uuid.uuid4()}\"\n",
"\n",
"print(f\"Project: {PROJECT_ID}\")\n",
"print(f\"Location: {LOCATION}\")\n",
"print(f\"Session User ID: {USER_ID}\")\n",
"\n",
"# Initialize Vertex AI client\n",
"client = vertexai.Client(\n",
" project=PROJECT_ID,\n",
" location=LOCATION,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5303c05f7aa6"
},
"source": [
"### Import libraries\n",
"\n",
"Import the necessary libraries for building our conversational agent with LangGraph and Vertex AI."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6fc324893334"
},
"outputs": [],
"source": [
"from typing import TypedDict, Annotated\n",
"from functools import partial\n",
"from langchain_core.messages import SystemMessage, HumanMessage\n",
"from langchain_google_vertexai import ChatVertexAI\n",
"from langgraph.graph import StateGraph, START, END, add_messages"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZChEL1y9BIU7"
},
"source": [
"### Helper functions\n",
"\n",
"These helper functions will manage the user-facing chat loop and process a single turn of the conversation with our LangGraph agent.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "F7mGHiul1NQe"
},
"outputs": [],
"source": [
"def run_single_turn(user_input: str, user_id: str) -> str:\n",
" \"\"\"Run a single conversation turn.\"\"\"\n",
" config = {\"configurable\": {\"thread_id\": user_id}}\n",
" state = {\n",
" \"messages\": [HumanMessage(content=user_input)],\n",
" \"user_id\": user_id\n",
" }\n",
"\n",
" response_content = None\n",
" for event in compiled_graph.stream(state, config):\n",
" for value in event.values():\n",
" if value.get(\"messages\"):\n",
" response_content = value[\"messages\"][-1].content\n",
"\n",
" return response_content\n",
"\n",
"\n",
"def chat_loop(user_id: str) -> None:\n",
" \"\"\"Main chat interface loop.\"\"\"\n",
" print(\"\\nStarting chat. Type 'exit' or 'quit' to end.\")\n",
" print(\"Every message will be automatically stored in memory.\\n\")\n",
"\n",
" while True:\n",
" user_input = input(\"\\nYou: \")\n",
" if user_input.lower() in ['quit', 'exit', 'bye']:\n",
" print(\"\\nAssistant: Thank you for chatting. Have a great day!\")\n",
" break\n",
"\n",
" response = run_single_turn(user_input, user_id)\n",
" if response:\n",
" print(f\"\\nAssistant: {response}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EdvJRUWRNGHE"
},
"source": [
"## Creating the Agent Engine with Memory Bank\n",
"\n",
"Vertex AI Memory Bank is part of the Vertex AI Agent Engine, a managed service that enables developers to deploy, manage, and scale AI agents.\n",
"\n",
"To use Memory Bank, you first create a new Agent Engine instance, which provides the APIs to store and retrieve user-specific memories.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "x5tUDbo8YVhe"
},
"outputs": [],
"source": [
"agent_engine = client.agent_engines.create()\n",
"print(f\"Created Agent Engine: {agent_engine.api_resource.name}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y8oPi1rEO55v"
},
"source": [
"## (Optional) Initialize user memory\n",
"\n",
"You can optionally pre-seed the Memory Bank with initial facts about a user. This demonstrates how to store information that the agent can reference from the very first interaction.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "B6xRZ6-sg_7L"
},
"outputs": [],
"source": [
"import_initial_memory_op = client.agent_engines.create_memory(\n",
" name=agent_engine.api_resource.name,\n",
" fact=f\"The user's name is {USER_ID} and they have a passion for learning new things.\",\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"memory = import_initial_memory_op.response\n",
"print(\"Created initial memory:\")\n",
"print(f\" Fact: {memory.fact}\")\n",
"print(f\" User ID: {memory.scope.get('user_id')}\")\n",
"print(f\" Created at: {memory.create_time}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VZwY1np4TyjF"
},
"outputs": [],
"source": [
"memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine.api_resource.name,\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"\n",
"for i, memory in enumerate(memories, 1):\n",
" if hasattr(memory, 'memory') and hasattr(memory.memory, 'fact'):\n",
" print(f\"{i}. {memory.memory.fact}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ntRLeQdtCoj1"
},
"source": [
"## Building the LangGraph Agent\n",
"\n",
"Now, we will construct our conversational agent. The agent will be designed to:\n",
"\n",
"1. Retrieve relevant memories before generating a response.\n",
"2. Use these memories to personalize its conversation.\n",
"3. Automatically store each conversation turn to build its long-term memory.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "opi14Ez06rNU"
},
"source": [
"### Define the Agent State\n",
"\n",
"The `State` object is a central concept in LangGraph. It holds the data that persists and is passed between the nodes in our graph. For this agent, the state will track the conversation `messages` and the `user_id`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Z12_8xnH01WJ"
},
"outputs": [],
"source": [
"class State(TypedDict):\n",
" \"\"\"Agent state definition.\"\"\"\n",
" messages: Annotated[list, add_messages]\n",
" user_id: str"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KvZhpAbr6sWn"
},
"source": [
"### Create the Core Logic: The Chatbot Node\n",
"\n",
"This node contains the main logic of our agent. For each turn, it performs a sequence of actions:\n",
"\n",
"1. **Retrieve Memories**: It queries the Memory Bank API to find memories relevant to the user's latest message. It can use either semantic search for relevance or chronological retrieval for a complete history.\n",
"2. **Construct Prompt**: It injects the retrieved memories into the system prompt, providing the LLM with personalized context.\n",
"3. **Generate Response**: It calls the Gemini model with the context-enhanced prompt to generate a response.\n",
"4. **Store New Memories**: It sends the latest user message and agent response back to Memory Bank to be processed and stored for future conversations.\n",
"\n",
"This \"always store\" approach ensures the agent continuously learns from every interaction."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1c3RfqnE0zte"
},
"outputs": [],
"source": [
"def chatbot_node(state: State, agent_engine_name: str, use_semantic_search: bool = True) -> dict:\n",
" \"\"\"Main agent logic node - stores every interaction.\"\"\"\n",
"\n",
" user_id = state[\"user_id\"]\n",
" user_message = state[\"messages\"][-1].content\n",
"\n",
" # Check user_message is string\n",
" if not isinstance(user_message, str):\n",
" raise ValueError(\"User message must be a string\")\n",
"\n",
" # Retrieve memories based on the selected method\n",
" if use_semantic_search:\n",
" # Use semantic search to find relevant memories based on the user's current message\n",
" memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine_name,\n",
" scope={\"user_id\": user_id},\n",
" similarity_search_params={\n",
" \"search_query\": user_message,\n",
" \"top_k\": 10 # Retrieve top 10 most relevant memories\n",
" }\n",
" )\n",
" else:\n",
" # Retrieve all memories\n",
" memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine_name,\n",
" scope={\"user_id\": user_id},\n",
" simple_retrieval_params={}\n",
" )\n",
"\n",
" # Extract facts from memory objects\n",
" memory_facts = [\n",
" memory.memory.fact\n",
" for memory in memories\n",
" if hasattr(memory, 'memory') and hasattr(memory.memory, 'fact')\n",
" ]\n",
"\n",
" # Format memory context based on retrieval method\n",
" if memory_facts:\n",
" if use_semantic_search:\n",
" memory_context = \"Relevant memories from previous conversations:\\n\" + \"\\n\".join(\n",
" f\"- {fact}\" for fact in memory_facts\n",
" )\n",
" else:\n",
" memory_context = \"Previous conversation history:\\n\" + \"\\n\".join(\n",
" f\"- {fact}\" for fact in memory_facts\n",
" )\n",
" else:\n",
" memory_context = \"No previous conversations found.\"\n",
"\n",
" # Create system prompt with memory context\n",
" system_message = SystemMessage(\n",
" content=f\"\"\"You are a helpful assistant with perfect memory.\n",
"\n",
" {memory_context}\n",
"\n",
" Instructions:\n",
" - Use the context to personalize responses\n",
" - Naturally reference past conversations when relevant\n",
" - Build upon previous knowledge about the user\n",
" - If using semantic search, the memories shown are the most relevant to the current query\"\"\"\n",
" )\n",
"\n",
" # Generate response using LLM\n",
" messages = [system_message] + state[\"messages\"]\n",
" llm = ChatVertexAI(model=MODEL_NAME, project=PROJECT_ID, location=LOCATION)\n",
" response = llm.invoke(messages)\n",
"\n",
" # Store the conversation turn in memory\n",
" operation = client.agent_engines.generate_memories(\n",
" name=agent_engine_name,\n",
" direct_contents_source={\n",
" \"events\": [{\n",
" \"content\": {\n",
" \"role\": \"user\",\n",
" \"parts\": [{\"text\": user_message}],\n",
" }\n",
" }, {\n",
" \"content\": {\n",
" \"role\": \"model\",\n",
" \"parts\": [{\"text\": response.content}],\n",
" }\n",
" }]\n",
" },\n",
" scope={\"user_id\": user_id},\n",
" config={\"wait_for_completion\": True},\n",
" )\n",
" return {\"messages\": [response]}\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "apId5Vvi6_QA"
},
"source": [
"### Build and Compile the Conversation Graph\n",
"\n",
"LangGraph uses a state graph to define the conversational flow. Our graph is simple: it has a single `chatbot` node that processes each turn. We connect the `START` of the graph to our node and the node's output to the `END`.\n",
"\n",
"We use `functools.partial` to bind the `agent_engine_name` and `use_semantic_search` arguments to our node function ahead of time."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3G6Pax34R8tB"
},
"outputs": [],
"source": [
"graph_builder = StateGraph(State)\n",
"\n",
"\n",
"# Create chatbot node with agent engine name and search preference bound\n",
"chatbot_with_memory = partial(\n",
" chatbot_node,\n",
" agent_engine_name=agent_engine.api_resource.name,\n",
" use_semantic_search=True\n",
")\n",
"\n",
"# Assemble and compile the graph\n",
"graph_builder.add_node(\"chatbot\", chatbot_with_memory)\n",
"graph_builder.add_edge(START, \"chatbot\")\n",
"graph_builder.add_edge(\"chatbot\", END)\n",
"\n",
"compiled_graph = graph_builder.compile()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c4WVP3nuaIV-"
},
"source": [
"## Interacting with the Agent\n",
"\n",
"Now, let's interact with our memory-enabled agent. Try the following phrases to see how the agent builds and uses its memory.\n",
"\n",
"```\n",
"You: Hi, I work as an agent engineer\n",
"You: I love hiking and have a dog named Max\n",
"You: I'm working on a recommendation system project\n",
"You: What do you remember about me?\n",
"You: Bye\n",
"```\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-tqSiFUzaKBC"
},
"outputs": [],
"source": [
"chat_loop(USER_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vLG-474VXfzy"
},
"source": [
"## Check for Stored Memories\n",
"\n",
"After the conversation, we can retrieve all stored memories to see what the agent has learned about the user. This demonstrates that the information has been successfully processed and persisted by Vertex AI Memory Bank.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "8hpsMHAIOrxN"
},
"outputs": [],
"source": [
"print(\"Stored Memories\")\n",
"memories = client.agent_engines.retrieve_memories(\n",
" name=agent_engine.api_resource.name,\n",
" scope={\"user_id\": USER_ID},\n",
")\n",
"\n",
"for memory in memories:\n",
" if hasattr(memory, 'memory') and hasattr(memory.memory, 'fact'):\n",
" print(f\"{memory.memory.fact}\")\n",
"\n",
"# Show total memory count\n",
"print(f\"\\nTotal memories stored: {len(list(memories))}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2a4e033321ad"
},
"source": [
"## Cleaning up\n",
"\n",
"To avoid charges, delete the agent engine when you're done experimenting.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "CAtT65gEcAFB"
},
"outputs": [],
"source": [
"delete_engine = True\n",
"\n",
"if delete_engine:\n",
" client.agent_engines.delete(name=agent_engine.api_resource.name, force=True)"
]
}
],
"metadata": {
"colab": {
"name": "get_started_with_memory_bank_langgraph.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,905 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "z4UWyDywJ6tj"
},
"source": [
"# AG2 (formerly Autogen) Multi-Agents Example on Vertex AI Agent Engine\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Ftutorial_ag2_on_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\">\n",
" <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_ag2_on_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a>\n",
"\n",
"\n",
"<br>\n",
"<br>\n",
"<br>\n",
"<br>\n",
"\n",
"| | |\n",
"|-|-|\n",
"| Author(s) | [Emmanuel Awa](https://github.com/awaemmanuel)|\n",
"| Reviewer(s) | Turan Bulmus, [Rajesh Thallam](https://github.com/rthallam), Polong Lin|\n",
"| Last updated | 2026 02 05: Update to latest Gemini Model, Agent Engine SDK |\n",
"| | 2025 03 16: Update to latest Agent Engine SDK |\n",
"| | 2025 02 20: Update to latest AG2 SDK and report summarization using LLM |\n",
"| | 2025 01 16: Updated from `autogen[gemini]` to `ag2` |\n",
"| | 2024 12 20: Review |\n",
"| | 2024 12 19: Initial Publication|\n",
"\n",
"This notebook showcases how to deploy [AG2](https://ag2.ai/) on Vertex AI through [Agent Engine API](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/reasoning-engine). AG2 (formerly AutoGen) is an open-source framework for building AI agents that can collaborate to solve tasks. It simplifies agent development, supports LLMs and tools, and enables various workflows, making it suitable for building multiagent applications on Vertex AI."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VyKi7eTEgVwk"
},
"source": [
"## Prerequisites\n",
"In other to run this notebook, you will need to set up your Google Cloud project and enable the Vertex AI API. \n",
"\n",
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager).\n",
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
"1. [Enable the Service Usage API](https://console.cloud.google.com/apis/library/serviceusage.googleapis.com)\n",
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"1. [Enable Logs Explorer](https://console.cloud.google.com/logs/query;query=resource.type%3D%22aiplatform.googleapis.com%2FReasoningEngine%22)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7NX_Q-pOqMRi"
},
"source": [
"## Step 1: Environment Setup: Google Cloud and AG2"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8yfWpe5Nctnb"
},
"source": [
"### Authentication \n",
"\n",
"If you're using Colab, run the code in the next cell. Follow the pop ups and authenticate with an account that has access to your Google Cloud [project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects).\n",
"\n",
"If you're running this notebook somewhere besides Colab, make sure your environment has the right Google Cloud access. If that's a new concept to you, consider looking into [Application Default Credentials for your local environment](https://cloud.google.com/docs/authentication/provide-credentials-adc#local-dev) and [initializing the Google Cloud CLI](https://cloud.google.com/docs/authentication/gcloud).\n",
"\n",
"In many cases, running `gcloud auth application-default login` in a shell on the machine running the notebook kernel is sufficient.\n",
"\n",
"More authentication options are discussed [here](https://cloud.google.com/docs/authentication)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "rPZA1RYSj0Vs",
"outputId": "8b7e3844-ad6c-4282-bccc-97f120c95b87"
},
"outputs": [],
"source": [
"# @title Authenticate - Google Colab Only\n",
"import sys\n",
"\n",
"from google.colab import auth\n",
"\n",
"if \"google.colab.auth\" in sys.modules:\n",
" auth.authenticate_user()\n",
" print(\"Authenticated\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jQs3DQ4DxB_k"
},
"source": [
"### Install Dependencies and Import Packages"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Jv4YSAecekxA"
},
"outputs": [],
"source": [
"# @title Install AG2, Google Cloud SDK and Dependencies\n",
"%pip install -qqq ag2[gemini]==0.10.5 dask[dataframe]==2025.12.0 google-cloud-aiplatform[agent_engines,ag2]==1.135.0 cloudpickle==3.1.2\n",
"%pip show ag2 google-cloud-aiplatform dask"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "txTCLHoghI2F"
},
"outputs": [],
"source": [
"# @title Import relevant packages\n",
"import pprint\n",
"\n",
"from IPython.display import Markdown\n",
"from autogen import AssistantAgent, GroupChat, GroupChatManager, UserProxyAgent\n",
"from autogen.cache import Cache\n",
"from autogen.code_utils import content_str\n",
"import vertexai\n",
"from vertexai.agent_engines import AgentEngine, Queryable\n",
"\n",
"print(f\"Required libraries successfully imported.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6M7rdk_jw2bq"
},
"source": [
"Next, we need to first install AG2 with Gemini features."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UmnZKKAnxHz6"
},
"source": [
"### Configuration Parameters\n",
"\n",
"Before proceeding, you need to define the following parameters:\n",
"\n",
"1. **`MODEL`**: Specifies the Gemini model to utilize for the multi-agent conversation. Choose from available Gemini model options outlined [here](https://ai.google.dev/gemini-api/docs/models/gemini).\n",
"2. **`PROJECT_ID`**: Identifies the Google Cloud project where the executions will occur.\n",
"3. **`STAGING_BUCKET`**: Designates a Google Cloud Storage bucket that you own and have write access to. This bucket will be used for temporary storage during the execution process. Bucket name must begin with `gs://`\n",
"4. **`CACHING_SEED`**: Provides an integer value for best-effort deterministic sampling. Note that determinism is not guaranteed.\n",
"5. **`LOCATION`**: Indicates the Google Cloud region for the deployment. Currently, Agent Engine is only supported in `us-central1`.\n",
"\n",
"These parameters will be employed to configure the `AG2` framework and set up the remote deployment environment for the Agent Engine."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "-eVuRe2efbnj"
},
"outputs": [],
"source": [
"# @title Set Configuration Parameters\n",
"MODEL_NAME = \"gemini-2.5-flash\" # @param {'type': 'string'}\n",
"PROJECT_ID = \"<YOUR_PROJECT_ID>\" # @param {'type': 'string'}\n",
"STAGING_BUCKET = \"gs://<YOUR_GCS_BUCKET>\" # @param {'type': 'string'}\n",
"CACHING_SEED = 42 # @param {'type': 'integer'}\n",
"LOCATION = \"us-central1\"\n",
"\n",
"STAGING_BUCKET = (\n",
" STAGING_BUCKET if STAGING_BUCKET.startswith(\"gs://\") else f\"gs://{STAGING_BUCKET}\"\n",
")\n",
"\n",
"config_list = [\n",
" {\n",
" \"model\": MODEL_NAME,\n",
" \"project_id\": PROJECT_ID,\n",
" \"location\": LOCATION,\n",
" \"api_type\": \"google\",\n",
" }\n",
"]\n",
"seed = CACHING_SEED\n",
"all_config = {\n",
" \"gemini_config_list\": config_list,\n",
" \"caching_seed\": seed,\n",
" \"staging_bucket\": STAGING_BUCKET,\n",
"}\n",
"print(\"Configuration:\")\n",
"pprint.pprint(all_config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "30HHGyoChnay"
},
"outputs": [],
"source": [
"# @title Initialize Vertex AI\n",
"vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)\n",
"print(f\"Vertex AI successfully initialized\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TOPhtR7tfYls"
},
"source": [
"## Step 2: An AG2 Example of Multi-Agent Conversations\n",
"\n",
"AG2 supports multi-agent collaboration through a conversational pattern called **group chat**. This general pattern shares characteristics with known multi-agent patterns like **Router Agent (one-by-one)**, where a central agent delegates tasks sequentially, and **Dynamic (all-to-all)**, where agents communicate freely.\n",
"\n",
"However, AG2's `GroupChat` offers a distinct approach. A `GroupChatManager` orchestrates the conversation by selecting a speaker, broadcasting their message, and repeating the process. While not strictly sequential like a Router, the manager guides the flow depending on the strategy the user chooses.\n",
"\n",
"Unlike a purely Dynamic system, the manager provides a degree of control, preventing chaotic interactions. Agent selection strategies include: `round_robin`, `random`, `manual`, and the default `auto` (based on the manager's llm configuration). We have chosen the `auto` mode to allow Gemini's reasoning ability decide who the next speaker should be.\n",
"\n",
"This example showcases a research-focused group chat with five agents:\n",
"\n",
"* **Researcher:** Conducts research and identifies key information.\n",
"* **Data Analyst:** Analyzes data and extracts insights.\n",
"* **Literature Reviewer:** Synthesizes research into a literature review.\n",
"* **Fact Checker:** Verifies information accuracy.\n",
"* **User Proxy:** Represents the user, initiates the conversation, and can execute code.\n",
"\n",
"These agents reside in a `GroupChat` orchestrated by a `GroupChatManager` using the `auto` strategy. The `User_proxy` initiates the collaborative research workflow.\n",
"\n",
"The diagram below shows the `GroupChatManager` workflow.\n",
"\n",
"> **NOTE:** If the image is not legible, please right click and view in new tab"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DThm2rfjZCY_"
},
"source": [
"![Ag2](https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/ag2/ag2.jpeg)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CbqXfcfi5Zsm"
},
"source": [
"**Defining the Research Topic**\n",
"\n",
"This section allows you to specify the topic of interest for the multi-agent research team. By default, the agents will focus on \"Large Language Models.\" However, you can customize the research topic by modifying the `topic` below:\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "_-rGbQxQ5J8L"
},
"outputs": [],
"source": [
"research_topic = \"Agentic Workflows\" # @param [\"Large Language Models\", \"Real Estate\", \"Agentic Workflows\"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hvqc_EdH6cTX"
},
"source": [
"The specialized agents (researcher, fact-checker, data analysts and literature reviewer) utilize this topic as their primary focus for information gathering and analysis. By defining a clear research topic, you ensure that the multi-agent conversation remains relevant and productive."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"cellView": "form",
"id": "RTJBQ5_OngMh"
},
"outputs": [],
"source": [
"# @title Define Agents\n",
"\n",
"# Define the Researcher agent. This agent conducts thorough research on the given topic,\n",
"# identifying key trends, publications, experts, and relevant data sources.\n",
"researcher = AssistantAgent(\n",
" name=\"Researcher\",\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" description=\"Conducts thorough research on the given topic.\",\n",
" system_message=f\"\"\"You are a meticulous researcher. Your goal is to conduct thorough research, identifying key trends, publications, experts, and relevant data sources. You should provide accurate and well-cited information.\"\"\",\n",
")\n",
"\n",
"# Define the Literature Reviewer agent. This agent synthesizes research findings into a\n",
"# coherent and well-structured literature review, identifying key themes, connections, and gaps in the existing research.\n",
"literature_reviewer = AssistantAgent(\n",
" name=\"Literature_Reviewer\",\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" description=\"Synthesizes research findings into a coherent literature review.\",\n",
" system_message=f\"\"\"You are a skilled literature reviewer. Your goal is to synthesize the provided research findings into a coherent and well-structured literature review. You should identify key themes, connections, and gaps in the existing research.\"\"\",\n",
")\n",
"\n",
"# Define the Fact Checker agent. This agent verifies the accuracy and validity of information,\n",
"# checking sources, identifying potential biases, and ensuring consistency with established knowledge.\n",
"fact_checker = AssistantAgent(\n",
" name=\"Fact_Checker\",\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" description=\"Verifies the accuracy and validity of information.\",\n",
" system_message=\"\"\"You are a meticulous fact-checker. Your goal is to verify the accuracy and validity of any information presented to you. You should check sources, identify potential biases, and ensure the information is consistent with established knowledge.\"\"\",\n",
")\n",
"\n",
"# Define the Data Analyst agent. This agent analyzes data related to the research topic and\n",
"# extracts meaningful insights, identifying trends, patterns, and correlations.\n",
"data_analyst = AssistantAgent(\n",
" name=\"Data_Analyst\",\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" description=\"Analyzes data and extracts meaningful insights.\",\n",
" system_message=f\"\"\"You are a skilled data analyst. Your goal is to analyze data and extract meaningful insights. You should identify trends, patterns, and correlations in the data and present your findings in a clear and concise manner.\"\"\",\n",
")\n",
"\n",
"# Define the User Proxy agent. This agent represents the user and can run code to facilitate tasks.\n",
"user_proxy = UserProxyAgent(\n",
" name=\"User_proxy\",\n",
" code_execution_config={\n",
" \"last_n_messages\": 20,\n",
" \"work_dir\": \"coding\",\n",
" \"use_docker\": False,\n",
" },\n",
" human_input_mode=\"TERMINATE\",\n",
" is_termination_msg=lambda x: content_str(x.get(\"content\")).find(\"TERMINATE\") >= 0,\n",
" description=\"I represent the user, and can run code.\",\n",
")\n",
"\n",
"# Create the GroupChat, a conversable pattern, that facilitates the collaboration on tasks requiring interaction among multiple agents.\n",
"# All agents contribute to a single conversation thread and share the same context. We have set the max turns of conversation to 12\n",
"groupchat = GroupChat(\n",
" agents=[user_proxy, researcher, literature_reviewer, fact_checker, data_analyst],\n",
" messages=[],\n",
" max_round=12,\n",
")\n",
"\n",
"# Create the GroupChatManager, a specialized agent, to orchestrate the group chat. A GroupChatManager selects an agent to speak,\n",
"# broadcasts the message to all other agents, and repeats this process until the conversation stops or maximum number of turns is reached.\n",
"# The default selection strategy is \"auto\", where the manager's LLM, in our case Gemini, chooses the next speaker.\n",
"manager = GroupChatManager(\n",
" groupchat=groupchat,\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" is_termination_msg=lambda x: content_str(x.get(\"content\")).find(\"TERMINATE\") >= 0,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "fXcoq_nrBLgu"
},
"outputs": [],
"source": [
"# @title Start Multi-agent Conversations\n",
"msg = f\"\"\"Conduct research on the latest advancements in {research_topic}, analyze relevant data, and produce a comprehensive literature review with verified facts.\"\"\"\n",
"custom_summary_prompt = f\"Generate a final report on {research_topic} from the chat history. Just start the report immediately without adding any additional commentary before or after the report.\"\n",
"with Cache.disk() as cache: # enable caching to reduce inference cost\n",
" result = user_proxy.initiate_chat(\n",
" manager,\n",
" message=msg,\n",
" summary_method=\"reflection_with_llm\",\n",
" summary_args={\"summary_prompt\": custom_summary_prompt},\n",
" cache=cache,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "QpaKbuqs_ZwQ"
},
"outputs": [],
"source": [
"# @title Inspect Report Generated By Agents\n",
"summary = result.summary\n",
"final_report = content_str(\n",
" summary.get(\"content\") if isinstance(summary, dict) else summary\n",
")\n",
"display(Markdown(final_report))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "w1YCBTrbZtlg"
},
"source": [
"## Step 3. Deploy agents to Agent Engine"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uXgl1m3cxPW3"
},
"source": [
"### Deploying The AG2 Multi-Agent Conversations Example On Vertex AI Agent Engine.\n",
"\n",
"1. Create a class `ResearchApp`, that implements a agent engine `Queryable` class. This class will wrap the agents from cell above.\n",
"\n",
"2. The syntax used to create a register a agent engine resource needs to implement `set_up` and `query` methods. Here is an example of a Agent Engine [advanced app configuration](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/reasoning-engine#deploy_an_advanced_app_configuration) that show this.\n",
"\n",
"\n",
"> **NOTE:** All agents and boostrapping code must be initialized in the `set_up` method and not the `__init__` method. Multi-agent conversation and user proxy code will go into the `query` method.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "Gr24G_qzFhZ9"
},
"outputs": [],
"source": [
"# @title Define AG2 Agents As a Agent Engine QueryAble\n",
"\n",
"class ResearchApp(Queryable):\n",
" \"\"\"This class defines a research application using AG2. It facilitates multi-agent conversations for research tasks.\"\"\"\n",
"\n",
" base_question = \"Conduct research on the latest advancements in {topic}, analyze relevant data, and produce a comprehensive literature review with verified facts.\"\n",
" custom_summary_prompt = f\"Generate a final report on {research_topic} from the chat history. Just start the report immediately without adding any additional commentary before or after the report.\"\n",
"\n",
" def __init__(self, project_id: str, location: str):\n",
" \"\"\"\n",
" Initializes the ResearchApp instance.\n",
"\n",
" Args:\n",
" project_id (str): The project ID for AG2.\n",
" location (str): The location of the AG2 instance.\n",
" \"\"\"\n",
" self.project_id = project_id\n",
" self.location = location\n",
" self.set_up_complete = False\n",
"\n",
" def set_up(self):\n",
" \"\"\"Sets up the research agents and conversation environment.\"\"\"\n",
" self.researcher = AssistantAgent(\n",
" name=\"Researcher\",\n",
" llm_config={\n",
" \"config_list\": all_config[\"gemini_config_list\"],\n",
" \"seed\": all_config[\"caching_seed\"],\n",
" },\n",
" description=\"Conducts thorough research on the given topic.\",\n",
" system_message=\"\"\"You are a meticulous researcher. Your goal is to conduct thorough research, identifying key trends, publications, experts, and relevant data sources. You should provide accurate and well-cited information.\"\"\",\n",
" )\n",
"\n",
" self.literature_reviewer = AssistantAgent(\n",
" name=\"Literature_Reviewer\",\n",
" llm_config={\n",
" \"config_list\": all_config[\"gemini_config_list\"],\n",
" \"seed\": all_config[\"caching_seed\"],\n",
" },\n",
" description=\"Synthesizes research findings into a coherent literature review.\",\n",
" system_message=\"\"\"You are a skilled literature reviewer. Your goal is to synthesize the provided research findings into a coherent and well-structured literature review. You should identify key themes, connections, and gaps in the existing research.\"\"\",\n",
" )\n",
"\n",
" self.fact_checker = AssistantAgent(\n",
" name=\"Fact_Checker\",\n",
" llm_config={\n",
" \"config_list\": all_config[\"gemini_config_list\"],\n",
" \"seed\": all_config[\"caching_seed\"],\n",
" },\n",
" description=\"Verifies the accuracy and validity of information.\",\n",
" system_message=\"\"\"You are a meticulous fact-checker. Your goal is to verify the accuracy and validity of any information presented to you. You should check sources, identify potential biases, and ensure the information is consistent with established knowledge.\"\"\",\n",
" )\n",
"\n",
" self.data_analyst = AssistantAgent(\n",
" name=\"Data_Analyst\",\n",
" llm_config={\n",
" \"config_list\": all_config[\"gemini_config_list\"],\n",
" \"seed\": all_config[\"caching_seed\"],\n",
" },\n",
" description=\"Analyzes data and extracts meaningful insights.\",\n",
" system_message=\"\"\"You are a skilled data analyst. Your goal is to analyze data and extract meaningful insights. You should identify trends, patterns, and correlations in the data and present your findings in a clear and concise manner.\"\"\",\n",
" )\n",
"\n",
" self.user_proxy = UserProxyAgent(\n",
" name=\"User_proxy\",\n",
" code_execution_config={\n",
" \"last_n_messages\": 20,\n",
" \"work_dir\": \"coding\",\n",
" \"use_docker\": False,\n",
" },\n",
" human_input_mode=\"NEVER\",\n",
" is_termination_msg=lambda x: content_str(x.get(\"content\")).find(\"TERMINATE\")\n",
" >= 0,\n",
" description=\"I represent the user, and can run code.\",\n",
" )\n",
"\n",
" self.groupchat = GroupChat(\n",
" agents=[\n",
" self.user_proxy,\n",
" self.researcher,\n",
" self.literature_reviewer,\n",
" self.fact_checker,\n",
" self.data_analyst,\n",
" ],\n",
" messages=[],\n",
" max_round=12,\n",
" )\n",
" self.manager = GroupChatManager(\n",
" groupchat=self.groupchat,\n",
" llm_config={\"config_list\": config_list, \"seed\": seed},\n",
" is_termination_msg=lambda x: content_str(x.get(\"content\")).find(\"TERMINATE\")\n",
" >= 0,\n",
" )\n",
" self.set_up_complete = True\n",
"\n",
" def query(self, topic: str = \"Large Language Models\"):\n",
" \"\"\"\n",
" Queries the multi-agent research system.\n",
"\n",
" Args:\n",
" topic (str): The research topic. Defaults to \"Large Language Models\".\n",
"\n",
" Returns:\n",
" str: A summary of the research conducted by the multi-agent system.\n",
" \"\"\"\n",
" if not self.set_up_complete:\n",
" self.set_up()\n",
" question = self.base_question.format(topic=topic)\n",
" with Cache.disk() as cache:\n",
" result = self.user_proxy.initiate_chat(\n",
" self.manager,\n",
" message=question,\n",
" summary_method=\"reflection_with_llm\",\n",
" summary_args={\"summary_prompt\": custom_summary_prompt},\n",
" cache=cache,\n",
" )\n",
" summary = result.summary\n",
" return content_str(\n",
" summary.get(\"content\") if isinstance(summary, dict) else summary\n",
" )\n",
"\n",
"\n",
"print(f\"Research App with multi-agents created.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9Kwmo5QJx8Dv"
},
"source": [
"### Test\n",
"\n",
"This section demonstrates how to test the Agent Engine locally before deploying it to Vertex AI. By running the `ResearchApp` locally, you can observe a multi-agent conversation flow similar to the previous example. This local testing helps ensure that the agents and their interactions are functioning as expected before deploying to the cloud."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "z89kARQryAfb"
},
"outputs": [],
"source": [
"# @title Testing - Local Development\n",
"local_engine = ResearchApp(project_id=PROJECT_ID, location=LOCATION)\n",
"local_engine.set_up()\n",
"report = local_engine.query(topic=research_topic)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "uM5QZ77lfo0Q"
},
"outputs": [],
"source": [
"# @title Inspect Report\n",
"display(Markdown(report))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eOk6mEfYxl9n"
},
"source": [
"### Setup and Deploy to Vertex AI Agent Engine\n",
"\n",
"This section guides you through deploying the AG2 multi-agent application to Vertex AI Agent Engine. Before proceeding with the deployment, we'll ensure there are no existing deployments to avoid conflicts. This involves listing and deleting any previous Agent Engine deployments to start with a clean slate. Subsequently, we'll utilize the `AgentEngine.create` method to deploy the application, specifying dependencies and configurations.\n",
"\n",
"> **NOTE:** Please be patient as the deployment is a long running operation. Once successful, the cell will return the resource URI of deployment that can be used for subsequent executions. \n",
">**Example:**\n",
"> ` agent_engine = vertexai.agent_engines.get('projects/<YOUR_PROJECT_ID_NUMBER>/locations/us-central1/reasoningEngines/<DEPLOYED_AGENT_ENGINE_ID>')`\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "BpXwgjnrXLto"
},
"outputs": [],
"source": [
"# @title Clean up deployment if needed - If you know the reasoning engine ID please use it in the box\n",
"\n",
"def cleanup_deployments(dry_run: bool = True, engine_id: str = \"all\"):\n",
" if engine_id.lower() == \"all\":\n",
" agent_engine_list = AgentEngine.list()\n",
" else:\n",
" try:\n",
" # engine_id can be the numeric ID or the full resource name\n",
" re = vertexai.agent_engines.get(engine_id)\n",
" agent_engine_list = [re]\n",
" except Exception as e:\n",
" print(f\"Error retrieving engine '{engine_id}': {e}\")\n",
" return\n",
"\n",
" if agent_engine_list:\n",
" print(f\"Found {len(agent_engine_list)} deployment(s) to process:\")\n",
" for re in agent_engine_list:\n",
" display_name = re.display_name or \"Unnamed\"\n",
" resource_name = re.resource_name\n",
" if not dry_run:\n",
" print(f\"Deleting {display_name}...\")\n",
" print(f\"Resource URI: {resource_name}\")\n",
" re.delete()\n",
" print(f\" Successfully deleted.\")\n",
" else:\n",
" print(f\"DRY RUN: Would delete '{display_name}'\")\n",
" print(f\"Resource URI: '{resource_name}'\")\n",
" print(\" To execute the deletion, please uncheck 'dry_run_delete_step' and re-run this cell.\")\n",
" else:\n",
" print(f\"No deployments found matching criteria: {engine_id}\")\n",
"\n",
"\n",
"ENGINE_ID = \"all\" # @param {type:\"string\"}\n",
"dry_run_delete_step = True # @param {type:\"boolean\"}\n",
"cleanup_deployments(dry_run=dry_run_delete_step, engine_id=ENGINE_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DLNQyaOjLfAY"
},
"source": [
"Now, we'll deploy the multi-agent application to Vertex AI Agent Engine. This process might take a few minutes as it involves setting up the necessary infrastructure for remote execution.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"id": "4PK1o7dUXOdY"
},
"outputs": [],
"source": [
"# @title Define GCS bucket directory to stage the deployment artifacts\n",
"artifacts_gcs_dirname = \"ag2_research_app\" # @param {'type': 'string'}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3KXt3Kg7q08K"
},
"outputs": [],
"source": [
"# @title Deploy to Agent Engine - Please Wait\n",
"agent_engine = AgentEngine.create(\n",
" ResearchApp(project_id=PROJECT_ID, location=LOCATION),\n",
" display_name=\"AG2 Research Application\",\n",
" gcs_dir_name=artifacts_gcs_dirname,\n",
" description=\"AG2 example deployed on Vertex AI Agent Engine\",\n",
" requirements=[\n",
" \"ag2[gemini]==0.10.5\",\n",
" \"google-cloud-aiplatform[agent_engines,ag2]==1.135.0\",\n",
" \"google-generativeai==0.8.6\",\n",
" \"dask[dataframe]==2025.12.0\",\n",
" \"cloudpickle==3.1.2\",\n",
" ],\n",
" extra_packages=[],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "18I5QCPkagp2"
},
"source": [
"### Monitoring Deployment Progress with Google Cloud Logs Explorer\n",
"\n",
"You can track the progress of your deployment by examining the logs in the Google Cloud Logs Explorer - [Click Here!](https://console.cloud.google.com/logs/query;query=resource.type%3D%22aiplatform.googleapis.com%2FReasoningEngine%22). A successfully progressing deployment will typically exhibit log entries indicating the initialization of agents, the exchange of messages between agents, and the completion of various stages in the research process.\n",
"\n",
"**Here's what to look for in the logs:**\n",
"\n",
"* **Agent initialization messages:** Logs confirming that each agent (Researcher, Literature Reviewer, etc.) has been successfully initialized.\n",
"* **Conversation logs:** Entries showing the back-and-forth communication between agents as they collaborate on the research task.\n",
"* **Progress indicators:** Messages signaling the completion of key steps, such as data analysis, fact-checking, and literature review generation.\n",
"* **Absence of error messages:** A lack of error or warning messages suggests that the deployment is proceeding without issues.\n",
"\n",
"\n",
"Monitoring deployment progress through the deployment logs [here](https://console.cloud.google.com/logs/query;query=resource.type%3D%22aiplatform.googleapis.com%2FReasoningEngine%22) provides valuable insights into the health and functionality of your multi-agent application."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yDmacPdS1ONB"
},
"source": [
"### Testing the Deployed Multi-Agent Application\n",
"\n",
"Now that the multi-agent application is deployed to Vertex AI Agent Engines, we can test its functionality. We expect the interaction flow and results to be consistent with the local testing performed earlier. This ensures that the deployed application behaves as intended and provides the same user experience."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "e8q38AWUwjQI"
},
"outputs": [],
"source": [
"result = agent_engine.query(topic=research_topic)\n",
"display(Markdown(result))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zOt1dlPH5a5P"
},
"source": [
"### Writing Report To Disk (Optional)\n",
"\n",
"The comprehensive literature review generated by the multi-agent conversation can be saved to a file. This allows for easy access, review, and potential modifications by users or other stakeholders.\n",
"\n",
"**Here's how you can persist the report to disk:**"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"id": "zz15hGQRwj4e"
},
"outputs": [],
"source": [
"with open(\"report.md\", \"w\") as f:\n",
" f.write(str(result))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "83m7sycmZ9GI"
},
"source": [
"## Step 4: Clean up"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WuqHrWIXakMa"
},
"source": [
"To avoid incurring unnecessary costs, we can now safely remove the deployed Agent Engines.\n",
"\n",
"> **IMPORTANT:** You can find your deployed version above. \n",
">**Example:**\n",
"> ` agent_engine = vertexai.agent_engines.get('projects/<YOUR_PROJECT_ID_NUMBER>/locations/us-central1/reasoningEngines/<DEPLOYED_AGENT_ENGINE_ID>')`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "T2Vf4H2ZqtSw"
},
"outputs": [],
"source": [
"# @title Clean up\n",
"ENGINE_ID = \"<DEPLOYED_REASONING_ENGINE_ID>\" # @param {type:\"string\"}\n",
"dry_run_delete_step = True # @param {type:\"boolean\"}\n",
"cleanup_deployments(dry_run=dry_run_delete_step, engine_id=ENGINE_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "A1XZlgAKan8I"
},
"source": [
"## Conclusion\n",
"\n",
"This notebook demonstrated how to build and deploy a multi-agent AI system on Vertex AI using AG2 (formerly AutoGen) and its Agent Engines. We showcased a collaborative workflow where specialized agents worked together to perform complex research and analysis.\n",
"\n",
"### Agent Roles and Responsibilities\n",
"\n",
"The system comprises the following agents, each with a distinct role:\n",
"\n",
"* **Researcher:** Conducts in-depth research on the given topic, identifying key trends, publications, experts, and relevant data sources. The Researcher provides accurate and well-cited information as the foundation for subsequent analysis.\n",
"\n",
"* **Literature Reviewer:** Synthesizes the Researcher's findings into a coherent and structured literature review. This agent identifies key themes, connections, and gaps in the existing research to provide a comprehensive overview of the current state of knowledge.\n",
"\n",
"* **Fact Checker:** Verifies the accuracy and validity of information presented by other agents, particularly the Researcher and Literature Reviewer. The Fact Checker meticulously checks sources, identifies potential biases, and ensures consistency with established knowledge.\n",
"\n",
"* **Data Analyst:** Analyzes data related to the research topic, extracting meaningful insights, identifying trends, patterns, and correlations. The Data Analyst provides quantitative support for the research with clear and concise presentations of findings.\n",
"\n",
"* **User Proxy:** Represents the user, initiating the conversation with the initial prompt or task. This agent can also execute code to support other agents, acting as an interface between the user and the multi-agent system. It also uses Gemini to reflect and create a final report using a custom prompt.\n",
"\n",
"The `GroupChatManager` orchestrates the interaction between these agents. It selects an agent to contribute, broadcasts the message to all other agents, and repeats this process until the conversation concludes. The default \"auto\" selection strategy utilizes the manager's LLM to intelligently choose the next speaker based on the conversation's context. This collaborative approach enables more comprehensive and robust analyses than a single agent could achieve.\n",
"\n",
"### Key Takeaways\n",
"\n",
"* **Collaborative Multi-Agent Workflow:** Demonstrated a workflow where distinct agents (Researcher, Data Analyst, Literature Reviewer, Fact Checker, and User Proxy) collaborate to conduct research, analyze data, synthesize findings, and ensure accuracy.\n",
"* **Vertex AI Deployment:** Showcased the deployment and execution of this multi-agent system on Vertex AI Agent Engine, providing scalable and efficient cloud-based execution.\n",
"* **Simplified Agent Development with AG2:** Highlighted AG2's framework for building and managing AI agents, streamlining development and facilitating complex agent interactions.\n",
"\n",
"This example provides a foundation for building and deploying custom multi-agent applications on Vertex AI, leveraging the power of AG2 for collaborative AI solutions.\n"
]
}
],
"metadata": {
"colab": {
"name": "tutorial_ag2_on_agent_engine.ipynb",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,437 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2024 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Building and Deploying a LangGraph Agent with Agent Engine in Vertex AI\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Ftutorial_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td> \n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/tutorial_langgraph.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_langgraph.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a> "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84f0f73a0f76"
},
"source": [
"| | |\n",
"|-|-|\n",
"| Author(s) | [Kristopher Overholt](https://github.com/koverholt), [Shawn Yang](https://github.com/shawn-yang-google) |"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) is a managed service that helps you to build and deploy agent frameworks. [LangGraph](https://langchain-ai.github.io/langgraph/) is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows.\n",
"\n",
"This notebook demonstrates how to build, deploy, and test a LangGraph agent using [Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) in Vertex AI. You'll learn how to use the [LanggraphAgent template](https://cloud.google.com/agent-builder/agent-engine/develop/langgraph) in Agent Engine to deploy a LangGraph agent with custom tools.\n",
"\n",
"This notebook covers the following steps:\n",
"\n",
"- **Define a tool**: Create a custom Python function to act as a tool your AI agent can use.\n",
"- **Define a LangGraph agent**: Create a LangGraph agent using the Gemini model and the tool that you define.\n",
"- **Local testing**: Test your LangGraph agent locally to ensure functionality.\n",
"- **Deploy to Agent Engine**: Deploy your LangGraph agent to Agent Engine for scalable execution.\n",
"- **Remote testing**: Interact with your deployed agent through Agent Engine, testing its functionality in a production-like environment.\n",
"- **Clean up resources**: Delete your deployed agent on Agent Engine to avoid incurring unnecessary charges.\n",
"\n",
"By the end of this notebook, you'll have the skills and knowledge to build and deploy your own LangGraph agents using Agent Engine in Vertex AI."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Vertex AI SDK and extra packages"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \"google-cloud-aiplatform[agent_engines,langchain]\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"if \"google.colab\" in sys.modules:\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information and initialize Vertex AI SDK\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
"LOCATION = \"us-central1\" # @param {type:\"string\"}\n",
"STAGING_BUCKET = f\"gs://{PROJECT_ID}-agent-engine-staging\" # @param {type:\"string\"}\n",
"\n",
"import vertexai\n",
"\n",
"vertexai.init(project=PROJECT_ID, location=LOCATION)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EdvJRUWRNGHE"
},
"source": [
"## Building and deploying a LangGraph agent on Agent Engine\n",
"\n",
"In the following sections, we'll walk through the process of building and deploying a LangGraph application using Agent Engine in Vertex AI."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3b3004f33544"
},
"source": [
"### Import libraries\n",
"\n",
"Import the Vertex AI SDK libraries for Agent Engine."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "67acfba81563"
},
"outputs": [],
"source": [
"import vertexai\n",
"from vertexai import agent_engines"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "94db54ba756b"
},
"source": [
"### Define a tool\n",
"\n",
"Define a custom Python function that acts as a tool in your LangGraph agent.\n",
"\n",
"In this case, you'll define a simple tool that returns a product description based on the product that the user asks about. In practice, you can write functions to call APIs, query databases, or any other tasks that you might want your agent to be able to use."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "22981b2e1c59"
},
"outputs": [],
"source": [
"def get_product_details(product_name: str):\n",
" \"\"\"Gathers basic details about a product.\"\"\"\n",
" details = {\n",
" \"smartphone\": \"A cutting-edge smartphone with advanced camera features and lightning-fast processing.\",\n",
" \"coffee\": \"A rich, aromatic blend of ethically sourced coffee beans.\",\n",
" \"shoes\": \"High-performance running shoes designed for comfort, support, and speed.\",\n",
" \"headphones\": \"Wireless headphones with advanced noise cancellation technology for immersive audio.\",\n",
" \"speaker\": \"A voice-controlled smart speaker that plays music, sets alarms, and controls smart home devices.\",\n",
" }\n",
" return details.get(product_name, \"Product details not found.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d32ce189d989"
},
"source": [
"### Define LangGraph agent\n",
"\n",
"Define a LangGraph agent using the `LanggraphAgent` template in Agent Engine with the Gemini model and the tool that you defined."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "6eeff14856cd"
},
"outputs": [],
"source": [
"agent = agent_engines.LanggraphAgent(\n",
" model=\"gemini-2.5-flash\",\n",
" tools=[get_product_details],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "be06c89a87aa"
},
"source": [
"### Local test\n",
"\n",
"In this section, you'll test your LangGraph agent locally to ensure that it behaves as expected before deployment."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "6e2cb6d16e34"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wireless headphones with advanced noise cancellation technology for immersive audio.\n"
]
}
],
"source": [
"response = agent.query(\n",
" input={\"messages\": [(\"user\", \"Get product details for headphones\")]}\n",
")\n",
"\n",
"print(response[\"messages\"][-1][\"kwargs\"][\"content\"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5ccd4227e8c8"
},
"source": [
"### Deploy your LangGraph agent\n",
"\n",
"Now that you verified that your LangGraph agent is working locally, it's time to deploy it to Agent Engine! This will make your agent accessible remotely and allow you to integrate it into larger systems or provide it as a service."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dced52d8c524"
},
"outputs": [],
"source": [
"client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
"\n",
"remote_agent = client.agent_engines.create(\n",
" agent=agent,\n",
" config={\n",
" \"staging_bucket\": STAGING_BUCKET,\n",
" \"requirements\": [\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\",\n",
" ],\n",
" \"display_name\": \"Agent Engine with LangGraph\",\n",
" \"description\": \"This is a sample custom application in Agent Engine that uses LangGraph\",\n",
" },\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b876ca670960"
},
"source": [
"### Remote test\n",
"\n",
"Now that your LangGraph agent is running on Agent Engine, let's test it out by querying it in the remote environment:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "8836a18a41f1"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"High-performance running shoes designed for comfort, support, and speed.\n"
]
}
],
"source": [
"response = remote_agent.query(\n",
" input={\"messages\": [(\"user\", \"Get product details for shoes\")]}\n",
")\n",
"\n",
"print(response[\"messages\"][-1][\"kwargs\"][\"content\"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2a4e033321ad"
},
"source": [
"## Cleaning up\n",
"\n",
"After you've finished experimenting, it's a good practice to clean up your cloud resources. You can delete the deployed Agent Engine instance and optionally remove the staging bucket to avoid any unexpected charges on your Google Cloud account."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "eb5fbfa43866"
},
"outputs": [],
"source": [
"# Delete the deployed agent\n",
"client.agent_engines.delete(name=remote_agent.api_resource.name)\n",
"\n",
"# Optionally, delete the staging bucket\n",
"# from google.cloud import storage\n",
"# storage.Client().bucket(STAGING_BUCKET.replace(\"gs://\", \"\")).delete(force=True)"
]
}
],
"metadata": {
"colab": {
"name": "tutorial_langgraph.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,800 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ijGzTHJJUCPY"
},
"outputs": [],
"source": [
"# Copyright 2024 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VEqbX8OhE8y9"
},
"source": [
"# Building a Conversational Search Agent with Agent Engine and RAG on Vertex AI Search\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Ftutorial_vertex_ai_search_rag_agent.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Run in Colab Enterprise\n",
" </a>\n",
" </td> \n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tutorial_vertex_ai_search_rag_agent.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a> \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84e7e432e6ff"
},
"source": [
"| | |\n",
"|-|-|\n",
"|Author(s) | [Kristopher Overholt](https://github.com/koverholt) |"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CkHPv2myT2cx"
},
"source": [
"## Overview\n",
"\n",
"### Agent Engine in Vertex AI\n",
"\n",
"[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) is a managed service in Vertex AI that helps you to build and deploy agent frameworks. It gives you the flexibility to choose how much reasoning you want to delegate to the LLM and how much you want to handle with customized code. You can define Python functions that get used as tools via [Gemini Function Calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling). Agent Engine integrates closely with the Python SDK for the Gemini model in Vertex AI, and it can manage prompts, agents, and examples in a modular way. Agent Engine is compatible with LangChain, LlamaIndex, or other Python frameworks."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DrkcqHrrwMAo"
},
"source": [
"### Objectives\n",
"\n",
"In this tutorial, you will build and deploy an agent (model, tools, and reasoning) using the Vertex AI SDK for Python.\n",
"\n",
"Your agent will use [LangChain](https://python.langchain.com/docs/get_started/introduction) and [Vertex AI Search](https://cloud.google.com/generative-ai-app-builder/docs/enterprise-search-introduction) to retrieve structured data indexed from the [Movies Dataset on Kaggle](https://www.kaggle.com/datasets/rounakbanik/the-movies-dataset?select=movies_metadata.csv) using retrieval augmented generation (RAG).\n",
"\n",
"- Install the Vertex AI SDK for Python\n",
"- Define a model for your agent\n",
"- Define Python functions as tools so that our agent can:\n",
" - Search and retrieve movie information from Vertex AI Search\n",
"- Use the LangChain agent template provided in the Vertex AI SDK for Agent Engine\n",
"- Test your agent locally before deploying\n",
"- Deploy and test your agent on Agent Engine in Vertex AI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "C9nEPojogw-g"
},
"source": [
"### Enable APIs and Services\n",
"\n",
"This tutorial uses the following billable components of Google Cloud, which you'll need to enable for this tutorial:\n",
"\n",
"- [Enable Vertex AI API](https://console.cloud.google.com/apis/api/aiplatform.googleapis.com/overview)\n",
"- [Enable Vertex AI Search API](https://console.cloud.google.com/apis/api/discoveryengine.googleapis.com/overview)\n",
"- [Enable Resource Manager API](https://console.cloud.google.com/apis/api/cloudresourcemanager.googleapis.com/overview)\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "r11Gu7qNgx1p"
},
"source": [
"## Getting Started\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Vertex AI SDK for Python\n",
"\n",
"Install the latest version of the Vertex AI SDK for Python and extra dependencies related to Agent Engine, LangChain, and Vertex AI Search:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \\\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\" \\\n",
" langchain-google-community \\\n",
" google-cloud-discoveryengine \\\n",
" google-api-python-client"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you are running this notebook on Google Colab, run the following cell to authenticate your environment. This step is not required if you are using [Vertex AI Workbench](https://cloud.google.com/vertex-ai-workbench)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"if \"google.colab\" in sys.modules:\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information and initialize Vertex AI SDK\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
"LOCATION = \"us-central1\" # @param {type:\"string\"}\n",
"STAGING_BUCKET = f\"gs://{PROJECT_ID}-agent-engine-staging\" # @param {type:\"string\"}\n",
"\n",
"import vertexai\n",
"\n",
"vertexai.init(project=PROJECT_ID, location=LOCATION)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "15e71c08d80d"
},
"source": [
"## Example: Building and Deploying a Conversational Search Agent for Movies\n",
"\n",
"In this tutorial, you'll build Python functions as tools that the Gemini model will use to search for information about movies and ground its responses using a RAG implementation with Vertex AI Search."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jXHfaVS66_01"
},
"source": [
"### Import libraries"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "lslYAvw37JGQ"
},
"outputs": [],
"source": [
"import warnings\n",
"\n",
"from IPython.display import Markdown, display\n",
"from googleapiclient import discovery\n",
"from langchain.agents.format_scratchpad.tools import format_to_tool_messages\n",
"from langchain.memory import ChatMessageHistory\n",
"from langchain_core import prompts\n",
"from vertexai.agent_engines import LangchainAgent\n",
"\n",
"warnings.filterwarnings(\"ignore\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "275640d559e9"
},
"source": [
"### Define generative model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "47f07c83a754"
},
"source": [
"The first step of your agent involves the generative model you want to use. Here you'll define the Gemini model for your agent:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "921890fcb875"
},
"outputs": [],
"source": [
"model = \"gemini-2.5-flash\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "89b4bac5179a"
},
"source": [
"### Create a data store in Vertex AI Search\n",
"\n",
"Now you'll create a data store within Vertex AI Search and index records from a movie data set.\n",
"\n",
"Follow the tutorial steps in the Vertex AI Search documentation to [create a data store with structured data](https://cloud.google.com/generative-ai-app-builder/docs/try-enterprise-search#structured-data), then [create a search app](https://cloud.google.com/generative-ai-app-builder/docs/try-enterprise-search#structured-data_1) that points to that data store.\n",
"\n",
"You should also enable the **Enterprise edition features** and **Generative Responses** options so that you can use the [LangChain retriever for Vertex AI Search](https://python.langchain.com/docs/integrations/retrievers/google_vertex_ai_search/) within your agent to search indexed records.\n",
"\n",
"Once the import is complete, you can navigate to your data store's **Data** page and obtain the values of your data store ID and region, which you can paste into the cell below:\n",
"\n",
"<img width=\"60%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/vertex-ai-search-data-store-id.png\">"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "ed87f5b9d63e"
},
"outputs": [],
"source": [
"DATA_STORE_ID = \"[your-data-store-id]\" # @param {type:\"string\"}\n",
"LOCATION_ID = \"global\" # @param {type:\"string\"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ea02086bd8e8"
},
"source": [
"### Define Python functions as tools\n",
"\n",
"The second component of your agent involves Python functions as tools, which will enable the Gemini model to interact with external systems, databases, document stores, and other APIs so that the model can get the most up-to-date information or take action with those systems.\n",
"\n",
"In this example, you'll define a function that sends a query to Vertex AI Search and returns relevant records from the data store that you created in the previous section:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "766227a0e6cc"
},
"outputs": [],
"source": [
"def search_kaggle_movies(query: str) -> str:\n",
" \"\"\"Search across records in the Kaggle Movies data set.\"\"\"\n",
" from langchain_google_community import VertexAISearchRetriever\n",
"\n",
" retriever = VertexAISearchRetriever(\n",
" project_id=PROJECT_ID,\n",
" data_store_id=DATA_STORE_ID,\n",
" location_id=LOCATION_ID,\n",
" engine_data_type=1,\n",
" max_documents=10,\n",
" )\n",
"\n",
" result = str(retriever.invoke(query))\n",
" return result"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "709bf1f8e8b0"
},
"source": [
"Now you can test your search function with sample input to ensure that it's working as expected:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4e700cbb3c7a"
},
"outputs": [],
"source": [
"search_kaggle_movies(\"space exploration\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "99b00032a7aa"
},
"source": [
"<div class=\"alert alert-block alert-warning\">\n",
"<b>⚠️ Important notes:</b><br>\n",
"<br>\n",
"<b>If you get an empty response when running the previous cell:</b><br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;Check the status of your data store in Vertex AI Search and try running the cell again after indexing is complete.<br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;Once you've created your search app and data store, you can view the <b>Activity</b> tab within your data store's <b>Data</b> page to see the status of your data ingestion.<br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;For this dataset, the import and indexing process takes about 5 to 10 minutes.<br>\n",
"<br>\n",
"<b>If you get an error when running the previous cell:</b><br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;In order for this sample notebook to work with the Google Vertex AI Search retriever in LangChain,<br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;you'll need to create a <a href=\"https://cloud.google.com/generative-ai-app-builder/docs/try-enterprise-search#create_a_data_store\">data store</a> <b>and</b> a <a href=\"https://cloud.google.com/generative-ai-app-builder/docs/try-enterprise-search#create_a_search_app\">search app</a> associated with it in Vertex AI Search.<br>\n",
"&nbsp;&nbsp;&nbsp;&nbsp;If you only create a data store, the LangChain retriever might throw errors when making queries against the data store.\n",
"</div>\n",
"\n",
"</div>\n",
"\n",
"### Define agent\n",
"\n",
"The third component of your agent involves adding a reasoning layer, which helps your agent use the tools that you provided to help the end user achieve a higher-level goal.\n",
"\n",
"If you were to use Gemini and Function Calling on their own without a reasoning layer, you would need to handle the process of calling functions and APIs in your application code, and you would need to implement retries and additional logic to ensure that your function calling code is resilient to failures and malformed requests.\n",
"\n",
"Define the prompt template and initialize the chat session history:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "e1585c9c17de"
},
"outputs": [],
"source": [
"# Define prompt template\n",
"prompt = {\n",
" \"history\": lambda x: x[\"history\"],\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": (lambda x: format_to_tool_messages(x[\"intermediate_steps\"])),\n",
"} | prompts.ChatPromptTemplate.from_messages(\n",
" [\n",
" prompts.MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"user\", \"{input}\"),\n",
" prompts.MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
" ]\n",
")\n",
"\n",
"# Initialize session history\n",
"store = {}\n",
"\n",
"\n",
"def get_session_history(session_id: str):\n",
" if session_id not in store:\n",
" store[session_id] = ChatMessageHistory()\n",
" return store[session_id]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8e2f13d9a7df"
},
"source": [
"Now you'll use the LangChain agent template provided in the Vertex AI SDK for Agent Engine, which brings together the model, tools, and reasoning that you've built up so far:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "7fe4fa1e163d"
},
"outputs": [],
"source": [
"agent = LangchainAgent(\n",
" prompt=prompt,\n",
" model=model,\n",
" chat_history=get_session_history,\n",
" model_kwargs={\"temperature\": 0},\n",
" tools=[search_kaggle_movies],\n",
" agent_executor_kwargs={\"return_intermediate_steps\": True},\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "96a94352da0f"
},
"source": [
"### Test your agent locally\n",
"\n",
"Now you can test the model and agent behavior to ensure that it's working as expected before you deploy it:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "03b16998bc2e"
},
"outputs": [
{
"data": {
"text/markdown": "Here are some movies featuring robots:\n\n* **Robots** (2005): Rodney Copperbottom is a young robot inventor who dreams of making the world a better place, until the evil Ratchet takes over Big Weld Industries. Now, Rodney's dreams and those of his friends are in danger of becoming obsolete.\n* **The War of the Robots** (1978): An alien civilization, which facing eminent extinction, kidnaps two famous genetic scientists from Earth. A troop of soldiers is dispatched to combat the humanoid robots and rescue the victims.\n* **Robot Stories** (2003): Four stories including: \"My Robot Baby,\" in which a couple must care for a robot baby before adopting a human child; \"The Robot Fixer,\" in which a mother tries to connect with her dying son; \"Machine Love,\" in which an office worker android learns that he, too, needs love; and \"Clay,\" in which an old sculptor must choose between natural death and digital immortality.\n* **I, Robot** (2004): In 2035, where robots are common-place and abide by the three laws of robotics, a techno-phobic cop investigates an apparent suicide. Suspecting that a robot may be responsible for the death, his investigation leads him to believe that humanity may be in danger.\n* **Robot Wars** (1993): In the year 2041, the rebel Centros are a plague to the survivors of the great toxic gas scare of 1993. A renegade Megarobot pilot and an archaeologist must team up (despite personal differences, a reluctant romance, and official pressure to cease and desist) to thwart the Centro's attempts to resurrect a hidden Megarobot, with which they can challenge the prevailing order.\n* **Robot Monster** (1953): Ro-Man, an alien robot who greatly resembles a gorilla in a diving helmet, is sent to earth to destroy all human life. Ro-Man falls in love with one of the last six remaining humans, and struggles to understand how his programming can instruct him to kill her while his heart demands that he can't.\n* **Robot Overlords** (2015): Earth has been conquered by robots from another galaxy and the human survivors must stay in their homes, or risk incineration.\n* **OMG, I'm a Robot!** (2015): A sensitive guy finds out he's... a robot.\n* **Robot & Frank** (2012): A delightful dramatic comedy, a buddy picture, and, for good measure, a heist film. Curmudgeonly old Frank lives by himself. His routine involves daily visits to his local library, where he has a twinkle in his eye for the librarian. His grown children are concerned about their father's well-being and buy him a caretaker robot. Initially resistant to the idea, Frank soon appreciates the benefits of robotic support like nutritious meals and a clean house and eventually begins to treat his robot like a true companion. With his robot's assistance, Frank's passion for his old, unlawful profession is reignited, for better or worse.\n* **Robot Carnival** (1987): An anthology of various tales told in various styles with robots being the one common element among them.",
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"response = agent.query(\n",
" input=\"Tell me about movies featuring robots\",\n",
" config={\"configurable\": {\"session_id\": \"demo\"}},\n",
")\n",
"\n",
"display(Markdown(response[\"output\"]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9abc4a214f3c"
},
"source": [
"### Deploy your agent on Vertex AI\n",
"\n",
"Now that you've tested your agent locally, you're ready to deploy it to Agent Engine in Vertex AI. This will make your agent accessible remotely and allow you to integrate it into larger systems or provide it as a service."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "c3325266144e"
},
"outputs": [],
"source": [
"client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
"\n",
"remote_agent = client.agent_engines.create(\n",
" agent=agent,\n",
" config={\n",
" \"staging_bucket\": STAGING_BUCKET,\n",
" \"requirements\": [\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\",\n",
" \"langchain-google-community\",\n",
" \"google-cloud-discoveryengine\",\n",
" ],\n",
" },\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "db896f74fa3b"
},
"source": [
"### Grant Discovery Engine Editor access to Agent Engine service account\n",
"\n",
"Before you send queries to your remote agent, you'll need to grant the **Discovery Engine Editor** role to the Agent Engine service account.\n",
"\n",
"After you've completed this step, you remote agent will be able to retrieve documents from the data store that you created in Vertex AI Search:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "75ac983656be"
},
"outputs": [],
"source": [
"# Retrieve the project number associated with your project ID\n",
"service = discovery.build(\"cloudresourcemanager\", \"v1\")\n",
"request = service.projects().get(projectId=PROJECT_ID)\n",
"response = request.execute()\n",
"project_number = response[\"projectNumber\"]\n",
"project_number"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "53b3f4665183"
},
"outputs": [],
"source": [
"# Add a new role binding to the IAM policy\n",
"!gcloud projects add-iam-policy-binding {PROJECT_ID} \\\n",
" --member=serviceAccount:service-{project_number}@gcp-sa-aiplatform-re.iam.gserviceaccount.com \\\n",
" --role=roles/discoveryengine.editor"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "efee31ce8859"
},
"source": [
"### Test your remotely deployed agent\n",
"\n",
"With your conversational search agent deployed, you can send prompts to test that it's working as expected and that it can retrieve movie data from your Vertex AI Search data store:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"id": "5f08c5685b4e"
},
"outputs": [
{
"data": {
"text/markdown": "Here are some movies featuring robots:\n\n* **Robots** (2005): Rodney Copperbottom is a young robot inventor who dreams of making the world a better place, until the evil Ratchet takes over Big Weld Industries. Now, Rodney's dreams and those of his friends are in danger of becoming obsolete.\n* **The War of the Robots** (1978): An alien civilization, which facing eminent extinction, kidnaps two famous genetic scientists from Earth. A troop of soldiers is dispatched to combat the humanoid robots and rescue the victims.\n* **Robot Stories** (2003): Four stories including: \"My Robot Baby,\" in which a couple must care for a robot baby before adopting a human child; \"The Robot Fixer,\" in which a mother tries to connect with her dying son; \"Machine Love,\" in which an office worker android learns that he, too, needs love; and \"Clay,\" in which an old sculptor must choose between natural death and digital immortality.\n* **I, Robot** (2004): In 2035, where robots are common-place and abide by the three laws of robotics, a techno-phobic cop investigates an apparent suicide. Suspecting that a robot may be responsible for the death, his investigation leads him to believe that humanity may be in danger.\n* **Robot Wars** (1993): In the year 2041, the rebel Centros are a plague to the survivors of the great toxic gas scare of 1993. A renegade Megarobot pilot and an archaeologist must team up (despite personal differences, a reluctant romance, and official pressure to cease and desist) to thwart the Centro's attempts to resurrect a hidden Megarobot, with which they can challenge the prevailing order.\n* **Robot Monster** (1953): Ro-Man, an alien robot who greatly resembles a gorilla in a diving helmet, is sent to earth to destroy all human life. Ro-Man falls in love with one of the last six remaining humans, and struggles to understand how his programming can instruct him to kill her while his heart demands that he can't.\n* **Robot Overlords** (2015): Earth has been conquered by robots from another galaxy and the human survivors must stay in their homes, or risk incineration.\n* **OMG, I'm a Robot!** (2015): A sensitive guy finds out he's... a robot.\n* **Robot & Frank** (2012): A delightful dramatic comedy, a buddy picture, and, for good measure, a heist film. Curmudgeonly old Frank lives by himself. His routine involves daily visits to his local library, where he has a twinkle in his eye for the librarian. His grown children are concerned about their father's well-being and buy him a caretaker robot. Initially resistant to the idea, Frank soon appreciates the benefits of robotic support like nutritious meals and a clean house and eventually begins to treat his robot like a true companion. With his robot's assistance, Frank's passion for his old, unlawful profession is reignited, for better or worse.\n* **Robot Carnival** (1987): An anthology of various tales told in various styles with robots being the one common element among them.\n* **Robot Holocaust** (1986): Neo, a drifter from the atomic-blasted wastelands, arrives with his klutzy robot sidekick at a factory where slaves labor to fuel the sinister Dark One's Power Station. There, he meets a comely woman who convinces him to help rescue her scientist father, who has invented a device that can break the Dark One's control over the slaves. Gathering a motley crew of allies on the way, Neo and pals travel to the Power Station, where they confront the Dark One's evil servants.\n* **Robotropolis** (2011): A group of reporters are covering the unveiling of a new facility that is completely maintained by robot prototypes. When one of the robots goes haywire, the reporters find themselves not just reporting on the malfunction, but fighting for their lives.\n* **They Call Me Jeeg Robot** (2015): Enzo Ceccotti comes into contact with a radioactive substance, then accidently discovers he has superpowers. A touchy, navel-gazing introvert, he's sure his new capabilities will do wonders for his life of crime, but that all changes when he meets Alessia, who's convinced he's the hero from the famous Japanese comic strip, Steel Jeeg Robot.\n* **Wild, Wild Planet** (1965): A rogue cop must stop a scientist from taking over the world with his deadly female robots, who are shrinking the world leaders.",
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"response = remote_agent.query(\n",
" input=\"Tell me about movies featuring robots\",\n",
" config={\"configurable\": {\"session_id\": \"demo\"}},\n",
")\n",
"\n",
"display(Markdown(response[\"output\"]))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"id": "da6076427022"
},
"outputs": [
{
"data": {
"text/markdown": "\"I, Robot\" was released on July 15, 2004. It is an action and science fiction film with a runtime of 115 minutes. The movie's tagline is \"Laws are made to be broken.\"\n\nThe plot is set in 2035, where robots are commonplace and abide by the three laws of robotics. A techno-phobic cop investigates an apparent suicide, and suspecting that a robot may be responsible for the death, his investigation leads him to believe that humanity may be in danger.\n\nThe film had a budget of $120,000,000 and grossed $347,234,916. It was produced by Twentieth Century Fox Film Corporation, Laurence Mark Productions, Davis Entertainment, Overbrook Entertainment, Mediastream Vierte Film GmbH & Co. Vermarktungs KG, and Canlaws Productions. The primary spoken language is English, and it was produced in the United States of America and Germany. The movie has a vote average of 6.7 based on 3889 votes.",
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"response = remote_agent.query(\n",
" input=\"Tell me more about the movie I, Robot\",\n",
" config={\"configurable\": {\"session_id\": \"demo\"}},\n",
")\n",
"\n",
"display(Markdown(response[\"output\"]))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"id": "797098dd1f88"
},
"outputs": [
{
"data": {
"text/markdown": "Based on the descriptions, here are the robot movies that appear to be comedies:\n\n* **Robots** (2005): This is an animated film, often implying a comedic tone, and the description suggests a lighthearted adventure.\n* **OMG, I'm a Robot!** (2015): The title itself suggests a comedic premise.\n* **Robot & Frank** (2012): The description explicitly states it's \"A delightful dramatic comedy.\"\n* **Robot Monster** (1953): While a sci-fi film, its premise of a gorilla-like robot falling in love and struggling with programming vs. heart often leads to it being viewed as a cult classic with unintentional comedic elements due to its B-movie nature.\n* **Robot Carnival** (1987): As an anthology, it's possible some segments are comedic, but the overall description doesn't explicitly state it. However, animated anthologies often include comedic shorts.\n* **They Call Me Jeeg Robot** (2015): While it has action, the premise of a \"touchy, navel-gazing introvert\" who gets superpowers and is mistaken for a comic book hero suggests comedic elements.\n\nThe most explicitly comedic ones are **Robots**, **OMG, I'm a Robot!**, and **Robot & Frank**.",
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"response = remote_agent.query(\n",
" input=\"Which of those robot movies are comedies?\",\n",
" config={\"configurable\": {\"session_id\": \"demo\"}},\n",
")\n",
"\n",
"display(Markdown(response[\"output\"]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9f2f7d3ed7bd"
},
"source": [
"### Querying your deployed agent\n",
"\n",
"You've now deployed your Agent Engine agent and can [interact with it in multiple ways](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), both within this notebook and from other applications or environments. The primary methods for accessing your deployed agent are via the Python client library or through REST API calls. Here's an overview of both methods:\n",
"\n",
"**Method 1: Reusing within this notebook or another Python environment**\n",
"\n",
"You can directly reuse and query the `remote_agent` instance you created in this notebook.\n",
"\n",
"Or, you can instantiate a new instance in another notebook or Python script. To do this, you'll need to retrieve your deployed agent's resource name that uniquely identifies your agent, which is a string that includes the project, location, and Agent Engine ID. You can retrieve it by running the following code in the notebook or environment where you created your agent:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "fdaf8b91413f"
},
"outputs": [],
"source": [
"remote_agent.api_resource.name"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "060f8369d113"
},
"source": [
"Use the resource name to load the agent in your other notebook or Python script, then query the remote agent as usual:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"id": "78af4442827e"
},
"outputs": [],
"source": [
"# from vertexai import agent_engines\n",
"\n",
"# client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
"# AGENT_ENGINE_RESOURCE_NAME = \"YOUR_AGENT_ENGINE_RESOURCE_NAME\" # Replace with the resource name of your deployed Agent Engine\n",
"\n",
"# remote_agent = client.agent_engines.get(name=AGENT_ENGINE_RESOURCE_NAME)\n",
"# response = remote_agent.query(input=\"List some sci-fi movies from the 1990s\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "63ab06554fc0"
},
"source": [
"**Method 2: Accessing from other environments via REST API**\n",
"\n",
"Beyond the Python client library, your deployed Vertex AI agent can be [queried using REST API calls](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), including:\n",
"\n",
"- Python: You can use Python's `requests` library or similar tools to make HTTP calls to the Vertex AI REST API.\n",
"- cURL: A command-line tool, cURL allows you to send HTTP requests directly. This is useful for testing and debugging.\n",
"- Other Programming Languages: If you prefer a different language for your application, you can use its native HTTP client library to make REST API calls.\n",
"\n",
"In summary, you have access to your deployed Agent Engine agent through the Python client library within Python environments, and more universally through its REST API via tools and programming languages of your choosing."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "806f4e063a52"
},
"source": [
"## Cleaning up\n",
"\n",
"After you've finished experimenting, it's a good practice to clean up your cloud resources. You can delete the deployed Agent Engine instance and optionally remove the staging bucket to avoid any unexpected charges on your Google Cloud account."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "7cec827288b7"
},
"outputs": [],
"source": [
"# Delete the deployed agent\n",
"client.agent_engines.delete(name=remote_agent.api_resource.name)\n",
"\n",
"# Optionally, delete the staging bucket\n",
"# from google.cloud import storage\n",
"# storage.Client().bucket(STAGING_BUCKET.replace(\"gs://\", \"\")).delete(force=True)"
]
}
],
"metadata": {
"colab": {
"name": "tutorial_vertex_ai_search_rag_agent.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}