Skip to content

feat: Adding PGChatMessageHistory #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
314 changes: 314 additions & 0 deletions examples/pg_chat_message_history.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,314 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# PGChatMessageHistory\n",
"\n",
"`PGChatMessageHistory` is a an implementation of the the LangChain ChatMessageHistory abstraction using `postgres` as the backend.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "IR54BmgvdHT_"
},
"source": [
"## Install\n",
"\n",
"Install the `langchain-postgres` package."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "0ZITIDE160OD",
"outputId": "e184bc0d-6541-4e0a-82d2-1e216db00a2d",
"tags": []
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain-postgres"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QuQigs4UoFQ2"
},
"source": [
"## Create an engine\n",
"\n",
"The first step is to create a `PGEngine` instance, which does the following:\n",
"\n",
"1. Allows you to create tables for storing documents and embeddings.\n",
"2. Maintains a connection pool that manages connections to the database. This allows sharing of the connection pool and helps to reduce latency for database calls."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain_postgres import PGEngine\n",
"\n",
"# See docker command above to launch a Postgres instance with pgvector enabled.\n",
"# Replace these values with your own configuration.\n",
"POSTGRES_USER = \"langchain\"\n",
"POSTGRES_PASSWORD = \"langchain\"\n",
"POSTGRES_HOST = \"localhost\"\n",
"POSTGRES_PORT = \"6024\"\n",
"POSTGRES_DB = \"langchain\"\n",
"\n",
"CONNECTION_STRING = (\n",
" f\"postgresql+asyncpg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}\"\n",
" f\":{POSTGRES_PORT}/{POSTGRES_DB}\"\n",
")\n",
"\n",
"pg_engine = PGEngine.from_connection_string(url=CONNECTION_STRING)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To use psycopg3 driver, set your connection string to `postgresql+psycopg://`"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "D9Xs2qhm6X56"
},
"source": [
"### Initialize a table\n",
"The `PGChatMessageHistory` class requires a database table with a specific schema in order to store the chat message history.\n",
"\n",
"The `PGEngine` engine has a helper method `init_chat_history_table()` that can be used to create a table with the proper schema for you."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"TABLE_NAME = \"chat_history\"\n",
"\n",
"pg_engine.init_chat_history_table(table_name=TABLE_NAME)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### PGChatMessageHistory\n",
"\n",
"To initialize the `PGChatMessageHistory` class you need to provide only 3 things:\n",
"\n",
"1. `engine` - An instance of a `PGEngine` 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 PG database to store the chat message history.\n",
"1. `schema_name` : The name of the database schema containing the chat message history table."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "z-AZyzAQ7bsf",
"tags": []
},
"outputs": [],
"source": [
"from langchain_postgres import PGChatMessageHistory\n",
"\n",
"history = PGChatMessageHistory.create_sync(\n",
" pg_engine,\n",
" session_id=\"test_session\",\n",
" table_name=TABLE_NAME,\n",
" # schema_name=SCHEMA_NAME,\n",
")\n",
"history.add_user_message(\"hi!\")\n",
"history.add_ai_message(\"whats up?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"history.messages"
]
},
{
"cell_type": "markdown",
"metadata": {},
"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 Postgres and is gone forever."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"history.clear()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Chaining\n",
"\n",
"We can easily combine this message history class with [LCEL Runnables](https://python.langchain.com/docs/concepts/lcel/) such as `RunnableWithMessageHistory`.\n",
"\n",
"To create an agent or chain, you will need a model. This example will use one of [Google's Vertex AI chat models](https://python.langchain.com/docs/integrations/chat/google_vertex_ai_palm)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# enable Vertex AI API\n",
"!gcloud services enable aiplatform.googleapis.com"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"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": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"## Please update the project id\n",
"GOOGLE_CLOUD_PROJECT_ID = \"\"\n",
"\n",
"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(\n",
" project=GOOGLE_CLOUD_PROJECT_ID, model_name=\"gemini-2.0-flash-exp\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" lambda session_id: PGChatMessageHistory.create_sync(\n",
" pg_engine,\n",
" session_id=session_id,\n",
" table_name=TABLE_NAME,\n",
" # schema_name=SCHEMA_NAME,\n",
" ),\n",
" input_messages_key=\"question\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# This is where we configure the session id\n",
"config = {\"configurable\": {\"session_id\": \"test_session\"}}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)"
]
}
],
"metadata": {
"colab": {
"provenance": [],
"toc_visible": true
},
"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.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
2 changes: 2 additions & 0 deletions langchain_postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from langchain_postgres.chat_message_histories import PostgresChatMessageHistory
from langchain_postgres.translator import PGVectorTranslator
from langchain_postgres.v2.chat_message_history import PGChatMessageHistory
from langchain_postgres.v2.engine import Column, ColumnDict, PGEngine
from langchain_postgres.v2.vectorstores import PGVectorStore
from langchain_postgres.vectorstores import PGVector
Expand All @@ -18,6 +19,7 @@
"ColumnDict",
"PGEngine",
"PostgresChatMessageHistory",
"PGChatMessageHistory",
"PGVector",
"PGVectorStore",
"PGVectorTranslator",
Expand Down
Loading