diff --git a/docs/chat_message_history.ipynb b/docs/chat_message_history.ipynb index 8b1a4cf..e869d6d 100644 --- a/docs/chat_message_history.ipynb +++ b/docs/chat_message_history.ipynb @@ -1,79 +1,551 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Google DATABASE\n", - "\n", - "[Google DATABASE](https://cloud.google.com/DATABASE).\n", - "\n", - "Save chat messages into `DATABASE`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Pre-reqs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "%pip install PACKAGE_NAME" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from PACKAGE import LOADER" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Basic Usage" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } + "cells": [ + { + "cell_type": "markdown", + "id": "f22eab3f84cbeb37", + "metadata": { + "id": "f22eab3f84cbeb37" + }, + "source": [ + "# Google Cloud SQL for MySQL\n", + "\n", + "> [Cloud SQL](https://cloud.google.com/sql) is a fully managed relational database service that offers high performance, seamless integration, and impressive scalability. It offers MySQL, PostgreSQL, and SQL Server database engines. Extend your database application to build AI-powered experiences leveraging Cloud SQL's Langchain integrations.\n", + "\n", + "This notebook goes over how to use `Cloud SQL for MySQL` to store chat message history with the `MySQLChatMessageHistory` class." + ] + }, + { + "cell_type": "markdown", + "id": "da400c79-a360-43e2-be60-401fd02b2819", + "metadata": { + "id": "da400c79-a360-43e2-be60-401fd02b2819" + }, + "source": [ + "## Before You Begin\n", + "\n", + "To run this notebook, you will need to do the following:\n", + " * [Create a Google Cloud Project](https://developers.google.com/workspace/guides/create-project)\n", + " * [Create a Cloud SQL for MySQL instance](https://cloud.google.com/sql/docs/mysql/create-instance)\n", + " * [Create a Cloud SQL database](https://cloud.google.com/sql/docs/mysql/create-manage-databases)\n", + " * [Add an IAM database user to the database](https://cloud.google.com/sql/docs/mysql/add-manage-iam-users#creating-a-database-user) (Optional)" + ] + }, + { + "cell_type": "markdown", + "source": [ + "### 🦜🔗 Library Installation\n", + "The integration lives in its own `langchain-google-cloud-sql-mysql` package, so we need to install it." + ], + "metadata": { + "id": "Mm7-fG_LltD7" + }, + "id": "Mm7-fG_LltD7" + }, + { + "cell_type": "code", + "source": [ + "%pip install --upgrade --quiet langchain-google-cloud-sql-mysql langchain-google-vertexai" + ], + "metadata": { + "id": "1VELXvcj8AId" + }, + "id": "1VELXvcj8AId", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "**Colab only:** Uncomment the following cell to restart the kernel or use the button to restart the kernel. For Vertex AI Workbench you can restart the terminal using the button on top." + ], + "metadata": { + "id": "98TVoM3MNDHu" + }, + "id": "98TVoM3MNDHu" + }, + { + "cell_type": "code", + "source": [ + "# # Automatically 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)" + ], + "metadata": { + "id": "v6jBDnYnNM08" + }, + "id": "v6jBDnYnNM08", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### 🔐 Authentication\n", + "Authenticate to Google Cloud as the IAM user logged into this notebook in order to access your Google Cloud Project.\n", + "\n", + "* If you are using Colab to run this notebook, use the cell below and continue.\n", + "* If you are using Vertex AI Workbench, check out the setup instructions [here](https://github.com/GoogleCloudPlatform/generative-ai/tree/main/setup-env)." + ], + "metadata": { + "id": "yygMe6rPWxHS" + }, + "id": "yygMe6rPWxHS" + }, + { + "cell_type": "code", + "source": [ + "from google.colab import auth\n", + "\n", + "auth.authenticate_user()" + ], + "metadata": { + "id": "PTXN1_DSXj2b" + }, + "execution_count": 1, + "outputs": [], + "id": "PTXN1_DSXj2b" + }, + { + "cell_type": "markdown", + "source": [ + "### ☁ Set Your Google Cloud Project\n", + "Set your Google Cloud project so that you can leverage Google Cloud resources within this notebook.\n", + "\n", + "If you don't know your project ID, try the following:\n", + "\n", + "* Run `gcloud config list`.\n", + "* Run `gcloud projects list`.\n", + "* See the support page: [Locate the project ID](https://support.google.com/googleapi/answer/7014113)." + ], + "metadata": { + "id": "NEvB9BoLEulY" + }, + "id": "NEvB9BoLEulY" + }, + { + "cell_type": "code", + "source": [ + "# @markdown Please fill in the value below with your Google Cloud project ID and then run the cell.\n", + "\n", + "PROJECT_ID = \"my-project-id\" # @param {type:\"string\"}\n", + "\n", + "# Set the project id\n", + "!gcloud config set project {PROJECT_ID}" + ], + "metadata": { + "cellView": "form", + "id": "gfkS3yVRE4_W" + }, + "id": "gfkS3yVRE4_W", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### 💡 API Enablement\n", + "The `langchain-google-cloud-sql-mysql` package requires that you [enable the Cloud SQL Admin API](https://console.cloud.google.com/flows/enableapi?apiid=sqladmin.googleapis.com) in your Google Cloud Project." + ], + "metadata": { + "id": "rEWWNoNnKOgq" + }, + "id": "rEWWNoNnKOgq" + }, + { + "cell_type": "code", + "source": [ + "# enable Cloud SQL Admin API\n", + "!gcloud services enable sqladmin.googleapis.com" + ], + "metadata": { + "id": "5utKIdq7KYi5" + }, + "id": "5utKIdq7KYi5", + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "markdown", + "id": "f8f2830ee9ca1e01", + "metadata": { + "id": "f8f2830ee9ca1e01" + }, + "source": [ + "## Basic Usage" + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Set Cloud SQL database values\n", + "Find your database values, in the [Cloud SQL Instances page](https://console.cloud.google.com/sql?_ga=2.223735448.2062268965.1707700487-2088871159.1707257687)." + ], + "metadata": { + "id": "OMvzMWRrR6n7" + }, + "id": "OMvzMWRrR6n7" + }, + { + "cell_type": "code", + "source": [ + "# @title Set Your Values Here { display-mode: \"form\" }\n", + "REGION = \"us-central1\" # @param {type: \"string\"}\n", + "INSTANCE = \"my-mysql-instance\" # @param {type: \"string\"}\n", + "DATABASE = \"my-database\" # @param {type: \"string\"}\n", + "TABLE_NAME = \"message_store\" # @param {type: \"string\"}" + ], + "metadata": { + "id": "irl7eMFnSPZr" + }, + "id": "irl7eMFnSPZr", + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### MySQLEngine Connection Pool\n", + "\n", + "One of the requirements and arguments to establish Cloud SQL as a ChatMessageHistory memory store is a `MySQLEngine` object. The `MySQLEngine` configures a connection pool to your Cloud SQL database, enabling successful connections from your application and following industry best practices.\n", + "\n", + "To create a `MySQLEngine` using `MySQLEngine.from_instance()` you need to provide only 4 things:\n", + "\n", + "1. `project_id` : Project ID of the Google Cloud Project where the Cloud SQL instance is located.\n", + "1. `region` : Region where the Cloud SQL instance is located.\n", + "1. `instance` : The name of the Cloud SQL instance.\n", + "1. `database` : The name of the database to connect to on the Cloud SQL instance.\n", + "\n", + "By default, [IAM database authentication](https://cloud.google.com/sql/docs/mysql/iam-authentication#iam-db-auth) will be used as the method of database authentication. This library uses the IAM principal belonging to the [Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/application-default-credentials) sourced from the envionment.\n", + "\n", + "For more informatin on IAM database authentication please see:\n", + "* [Configure an instance for IAM database authentication](https://cloud.google.com/sql/docs/mysql/create-edit-iam-instances)\n", + "* [Manage users with IAM database authentication](https://cloud.google.com/sql/docs/mysql/add-manage-iam-users)\n", + "\n", + "Optionally, [built-in database authentication](https://cloud.google.com/sql/docs/mysql/built-in-authentication) using a username and password to access the Cloud SQL database can also be used. Just provide the optional `user` and `password` arguments to `MySQLEngine.from_instance()`:\n", + "* `user` : Database user to use for built-in database authentication and login\n", + "* `password` : Database password to use for built-in database authentication and login.\n" + ], + "metadata": { + "id": "QuQigs4UoFQ2" + }, + "id": "QuQigs4UoFQ2" + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "4576e914a866fb40", + "metadata": { + "ExecuteTime": { + "end_time": "2023-08-28T10:04:38.077748Z", + "start_time": "2023-08-28T10:04:36.105894Z" }, - "nbformat": 4, - "nbformat_minor": 4 -} + "jupyter": { + "outputs_hidden": false + }, + "id": "4576e914a866fb40" + }, + "outputs": [], + "source": [ + "from langchain_google_cloud_sql_mysql import MySQLEngine\n", + "\n", + "engine = MySQLEngine.from_instance(\n", + " project_id=PROJECT_ID, region=REGION, instance=INSTANCE, database=DATABASE\n", + ")" + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Initialize a table\n", + "The `MySQLChatMessageHistory` class requires a database table with a specific schema in order to store the chat message history.\n", + "\n", + "The `MySQLEngine` engine has a helper method `init_chat_history_table()` that can be used to create a table with the proper schema for you." + ], + "metadata": { + "id": "qPV8WfWr7O54" + }, + "id": "qPV8WfWr7O54" + }, + { + "cell_type": "code", + "source": [ + "engine.init_chat_history_table(table_name=TABLE_NAME)" + ], + "metadata": { + "id": "TEu4VHArRttE" + }, + "id": "TEu4VHArRttE", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### MySQLChatMessageHistory\n", + "\n", + "To initialize the `MySQLChatMessageHistory` class you need to provide only 3 things:\n", + "\n", + "1. `engine` - An instance of a `MySQLEngine` engine.\n", + "1. `session_id` - A unique identifier string that specifies an id for the session.\n", + "1. `table_name` : The name of the table within the Cloud SQL database to store the chat message history." + ], + "metadata": { + "id": "zSYQTYf3UfOi" + }, + "id": "zSYQTYf3UfOi" + }, + { + "cell_type": "code", + "source": [ + "from langchain_google_cloud_sql_mysql import MySQLChatMessageHistory\n", + "\n", + "history = MySQLChatMessageHistory(\n", + " engine, session_id=\"test_session\", table_name=TABLE_NAME\n", + ")\n", + "history.add_user_message(\"hi!\")\n", + "history.add_ai_message(\"whats up?\")" + ], + "metadata": { + "id": "Kq7RLtfOq0wi" + }, + "id": "Kq7RLtfOq0wi", + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b476688cbb32ba90", + "metadata": { + "ExecuteTime": { + "end_time": "2023-08-28T10:04:38.929396Z", + "start_time": "2023-08-28T10:04:38.915727Z" + }, + "jupyter": { + "outputs_hidden": false + }, + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "b476688cbb32ba90", + "outputId": "a19e5cd8-4225-476a-d28d-e870c6b838bb" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[HumanMessage(content='hi!'), AIMessage(content='whats up?')]" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ], + "source": [ + "history.messages" + ] + }, + { + "cell_type": "markdown", + "source": [ + "#### Cleaning up\n", + "When the history of a specific session is obsolete and can be deleted, it can be done the following way.\n", + "\n", + "**Note:** Once deleted, the data is no longer stored in Cloud SQL and is gone forever." + ], + "metadata": { + "id": "ss6CbqcTTedr" + }, + "id": "ss6CbqcTTedr" + }, + { + "cell_type": "code", + "source": [ + "history.clear()" + ], + "metadata": { + "id": "3khxzFxYO7x6" + }, + "id": "3khxzFxYO7x6", + "execution_count": 12, + "outputs": [] + }, + { + "cell_type": "markdown", + "id": "2e5337719d5614fd", + "metadata": { + "id": "2e5337719d5614fd" + }, + "source": [ + "## 🔗 Chaining\n", + "\n", + "We can easily combine this message history class with [LCEL Runnables](/docs/expression_language/how_to/message_history)\n", + "\n", + "To do this we will use one of [Google's Vertex AI chat models](https://python.langchain.com/docs/integrations/chat/google_vertex_ai_palm) which requires that you [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com) in your Google Cloud Project.\n" + ] + }, + { + "cell_type": "code", + "source": [ + "# enable Vertex AI API\n", + "!gcloud services enable aiplatform.googleapis.com" + ], + "metadata": { + "id": "hYtHM3-TOMCe" + }, + "id": "hYtHM3-TOMCe", + "execution_count": 13, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6558418b-0ece-4d01-9661-56d562d78f7a", + "metadata": { + "id": "6558418b-0ece-4d01-9661-56d562d78f7a" + }, + "outputs": [], + "source": [ + "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", + "from langchain_core.runnables.history import RunnableWithMessageHistory\n", + "from langchain_google_vertexai import ChatVertexAI" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "82149122-61d3-490d-9bdb-bb98606e8ba1", + "metadata": { + "id": "82149122-61d3-490d-9bdb-bb98606e8ba1" + }, + "outputs": [], + "source": [ + "prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\"system\", \"You are a helpful assistant.\"),\n", + " MessagesPlaceholder(variable_name=\"history\"),\n", + " (\"human\", \"{question}\"),\n", + " ]\n", + ")\n", + "\n", + "chain = prompt | ChatVertexAI(project=PROJECT_ID)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2df90853-b67c-490f-b7f8-b69d69270b9c", + "metadata": { + "id": "2df90853-b67c-490f-b7f8-b69d69270b9c" + }, + "outputs": [], + "source": [ + "chain_with_history = RunnableWithMessageHistory(\n", + " chain,\n", + " lambda session_id: MySQLChatMessageHistory(\n", + " engine,\n", + " session_id=session_id,\n", + " table_name=TABLE_NAME,\n", + " ),\n", + " input_messages_key=\"question\",\n", + " history_messages_key=\"history\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0ce596b8-3b78-48fd-9f92-46dccbbfd58b", + "metadata": { + "id": "0ce596b8-3b78-48fd-9f92-46dccbbfd58b" + }, + "outputs": [], + "source": [ + "# This is where we configure the session id\n", + "config = {\"configurable\": {\"session_id\": \"test_session\"}}" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "38e1423b-ba86-4496-9151-25932fab1a8b", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "38e1423b-ba86-4496-9151-25932fab1a8b", + "outputId": "d5c93570-4b0b-4fe8-d19c-4b361fe74291" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "AIMessage(content=' Hello Bob, how can I help you today?')" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ], + "source": [ + "chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "2ee4ee62-a216-4fb1-bf33-57476a84cf16", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2ee4ee62-a216-4fb1-bf33-57476a84cf16", + "outputId": "288fe388-3f60-41b8-8edb-37cfbec18981" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "AIMessage(content=' Your name is Bob.')" + ] + }, + "metadata": {}, + "execution_count": 19 + } + ], + "source": [ + "chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + }, + "colab": { + "provenance": [], + "toc_visible": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file