gemini/agent-engine/tutorial_langgraph.ipynb (721 lines of code) (raw):

{ "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 Application 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 src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" 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://cloud.google.com/ml-engine/images/colab-enterprise-logo-32px.png\" 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 src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" 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 simple LangGraph application using [Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) in Vertex AI. You'll learn how to combine LangGraph's workflow orchestration with the scalability of Vertex AI, which enables you to build custom generative AI applications.\n", "\n", "Note that the approach used in this notebook defines a [custom application template in Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/customize), which can be extended to LangChain or other orchestration frameworks. If just want to use Agent Engine to build agentic generative AI applications, refer to the documentation for [developing with the LangChain template in Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/develop/overview).\n", "\n", "This notebook covers the following steps:\n", "\n", "- **Define Tools**: Create custom Python functions to act as tools your AI application can use.\n", "- **Define Router**: Set up routing logic to control conversation flow and tool selection.\n", "- **Build a LangGraph Application**: Structure your application using LangGraph, including the Gemini model and custom tools that you define.\n", "- **Local Testing**: Test your LangGraph application locally to ensure functionality.\n", "- **Deploying to Vertex AI**: Seamlessly deploy your LangGraph application to Agent Engine for scalable execution.\n", "- **Remote Testing**: Interact with your deployed application through Vertex AI, testing its functionality in a production-like environment.\n", "- **Cleaning Up Resources**: Delete your deployed application on Vertex AI 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 custom generative AI applications using LangGraph, Agent Engine, and Vertex AI." ] }, { "cell_type": "markdown", "metadata": { "id": "61RBz8LLbxCR" }, "source": [ "## Get started" ] }, { "cell_type": "markdown", "metadata": { "id": "No17Cw5hgx12" }, "source": [ "### Install Vertex AI SDK and other required packages" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "tFy3H3aPgx12" }, "outputs": [], "source": [ "%pip install --upgrade --user --quiet \\\n", " \"google-cloud-aiplatform[agent_engines,langchain]\" \\\n", " cloudpickle==3.0.0 \\\n", " \"pydantic==2.11.2\" \\\n", " langgraph \\\n", " httpx" ] }, { "cell_type": "markdown", "metadata": { "id": "R5Xep4W9lq-Z" }, "source": [ "### Restart 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 restarts the current kernel.\n", "\n", "The restart might take a minute or longer. After it's restarted, continue to the next step." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "XRvKdaPDTznN" }, "outputs": [], "source": [ "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. Wait until it's finished before continuing to the next step. ⚠️</b>\n", "</div>" ] }, { "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": 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": "EdvJRUWRNGHE" }, "source": [ "## Building and deploying a LangGraph app 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 necessary Python libraries. These libraries provide the tools we need to interact with LangGraph, Vertex AI, and other components of our application." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "67acfba81563" }, "outputs": [], "source": [ "from typing import Literal\n", "\n", "from langchain_core.messages import BaseMessage, HumanMessage\n", "from langchain_google_vertexai import ChatVertexAI\n", "from langgraph.graph import END, MessageGraph\n", "from langgraph.prebuilt import ToolNode\n", "from vertexai import agent_engines" ] }, { "cell_type": "markdown", "metadata": { "id": "94db54ba756b" }, "source": [ "### Define tools\n", "\n", "You'll start by defining the a tool for your LangGraph application. You'll define a custom Python function that act as tools in our agentic application.\n", "\n", "In this case, we'll define a simple tool that returns a product description based on the product that the user asks about. In reality, you can write functions to call APIs, query databases, or anything other tasks that you might want your agent to be able to use." ] }, { "cell_type": "code", "execution_count": 6, "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": "be70714d9fae" }, "source": [ "### Define router\n", "\n", "Then, you'll define a router to control the flow of the conversation, determining which tool to use based on user input or the state of the interaction. Here we'll use a simple router setup, and you can customize the behavior of your router to handle multiple tools, custom logic, or multi-agent workflows." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "516b5108d327" }, "outputs": [], "source": [ "def router(state: list[BaseMessage]) -> Literal[\"get_product_details\", \"__end__\"]:\n", " \"\"\"Initiates product details retrieval if the user asks for a product.\"\"\"\n", " # Get the tool_calls from the last message in the conversation history.\n", " tool_calls = state[-1].tool_calls\n", " # If there are any tool_calls\n", " if len(tool_calls):\n", " # Return the name of the tool to be called\n", " return \"get_product_details\"\n", " else:\n", " # End the conversation flow.\n", " return \"__end__\"" ] }, { "cell_type": "markdown", "metadata": { "id": "d32ce189d989" }, "source": [ "### Define LangGraph application\n", "\n", "Now you'll bring everything together to define your LangGraph application as a custom template in Agent Engine.\n", "\n", "This application will use the tool and router that you just defined. LangGraph provides a powerful way to structure these interactions and leverage the capabilities of LLMs." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "6eeff14856cd" }, "outputs": [], "source": [ "class SimpleLangGraphApp:\n", " def __init__(self, project: str, location: str) -> None:\n", " self.project_id = project\n", " self.location = location\n", "\n", " # The set_up method is used to define application initialization logic\n", " def set_up(self) -> None:\n", " model = ChatVertexAI(model=\"gemini-2.0-flash\")\n", "\n", " builder = MessageGraph()\n", "\n", " model_with_tools = model.bind_tools([get_product_details])\n", " builder.add_node(\"tools\", model_with_tools)\n", "\n", " tool_node = ToolNode([get_product_details])\n", " builder.add_node(\"get_product_details\", tool_node)\n", " builder.add_edge(\"get_product_details\", END)\n", "\n", " builder.set_entry_point(\"tools\")\n", " builder.add_conditional_edges(\"tools\", router)\n", "\n", " self.runnable = builder.compile()\n", "\n", " # The query method will be used to send inputs to the agent\n", " def query(self, message: str):\n", " \"\"\"Query the application.\n", "\n", " Args:\n", " message: The user message.\n", "\n", " Returns:\n", " str: The LLM response.\n", " \"\"\"\n", " chat_history = self.runnable.invoke(HumanMessage(message))\n", "\n", " return chat_history[-1].content" ] }, { "cell_type": "markdown", "metadata": { "id": "be06c89a87aa" }, "source": [ "### Local testing\n", "\n", "In this section, you'll test your LangGraph app locally before deploying it to ensure that it behaves as expected before deployment." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "6e2cb6d16e34" }, "outputs": [], "source": [ "agent = SimpleLangGraphApp(project=PROJECT_ID, location=LOCATION)\n", "agent.set_up()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "fc70cda0aeb0" }, "outputs": [ { "data": { "text/plain": [ "'High-performance running shoes designed for comfort, support, and speed.'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.query(message=\"Get product details for shoes\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "9550ed5f509d" }, "outputs": [ { "data": { "text/plain": [ "'A rich, aromatic blend of ethically sourced coffee beans.'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.query(message=\"Get product details for coffee\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "id": "3675a218d107" }, "outputs": [ { "data": { "text/plain": [ "'A cutting-edge smartphone with advanced camera features and lightning-fast processing.'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.query(message=\"Get product details for smartphone\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "id": "72351589a51b" }, "outputs": [ { "data": { "text/plain": [ "\"I need more information about what you'd like to know about the weather. For example, I can tell you the weather in a specific location if you provide me with the location. \\n\"" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ask a question that cannot be answered using the defined tools\n", "agent.query(message=\"Tell me about the weather\")" ] }, { "cell_type": "markdown", "metadata": { "id": "5ccd4227e8c8" }, "source": [ "### Deploy your LangGraph app\n", "\n", "Now that you verified that your LangGraph application is working locally, it's time to deploy it to Agent Engine! This will make your application accessible remotely and allow you to integrate it into larger systems or provide it as a service." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "dced52d8c524" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using bucket your-bucket-name\n", "Writing to gs://your-bucket-name/agent_engine/agent_engine.pkl\n", "Writing to gs://your-bucket-name/agent_engine/requirements.txt\n", "Creating in-memory tarfile of extra_packages\n", "Writing to gs://your-bucket-name/agent_engine/dependencies.tar.gz\n", "Creating AgentEngine\n", "Create AgentEngine backing LRO: projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264/operations/701841121235435520\n", "AgentEngine created. Resource name: projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264\n", "To use this AgentEngine in another session:\n", "agent_engine = vertexai.agent_engines.get('projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264')\n" ] } ], "source": [ "remote_agent = agent_engines.create(\n", " SimpleLangGraphApp(project=PROJECT_ID, location=LOCATION),\n", " requirements=[\n", " \"google-cloud-aiplatform[agent_engines,langchain]\",\n", " \"cloudpickle==3.0.0\",\n", " \"pydantic==2.11.2\",\n", " \"langgraph\",\n", " \"httpx\",\n", " ],\n", " display_name=\"Agent Engine with LangGraph\",\n", " description=\"This is a sample custom application in Agent Engine that uses LangGraph\",\n", " extra_packages=[],\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "b876ca670960" }, "source": [ "### Remote test\n", "\n", "Now that your LangGraph app is running on Agent Engine, let's test it out by querying it in the remote environment:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "id": "8836a18a41f1" }, "outputs": [ { "data": { "text/plain": [ "'High-performance running shoes designed for comfort, support, and speed.'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "remote_agent.query(message=\"Get product details for shoes\")" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "id": "374c15e64016" }, "outputs": [ { "data": { "text/plain": [ "'A rich, aromatic blend of ethically sourced coffee beans.'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "remote_agent.query(message=\"Get product details for coffee\")" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "id": "5952d817da5e" }, "outputs": [ { "data": { "text/plain": [ "'A cutting-edge smartphone with advanced camera features and lightning-fast processing.'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "remote_agent.query(message=\"Get product details for smartphone\")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "id": "8b425533042c" }, "outputs": [ { "data": { "text/plain": [ "\"I'm sorry, I can't provide information about the weather. The available tools lack that functionality. \\n\"" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "remote_agent.query(message=\"Tell me about the weather\")" ] }, { "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 to avoid any unexpected charges on your Google Cloud account." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "id": "eb5fbfa43866" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Deleting AgentEngine : projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264\n", "AgentEngine deleted. . Resource name: projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264\n", "Deleting AgentEngine resource: projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264\n", "Delete AgentEngine backing LRO: projects/your-project-number/locations/us-central1/operations/5119309405732470784\n", "AgentEngine resource projects/your-project-number/locations/us-central1/reasoningEngines/8081041028246667264 deleted.\n" ] } ], "source": [ "remote_agent.delete()" ] } ], "metadata": { "colab": { "name": "tutorial_langgraph.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }