08. RunnableWithMessageHistory

Add message history (memory)

RunnableWithMessageHistory Using to add message history to certain types of tasks (chains) is a very useful feature in programming.

This feature is especially important when you need to keep the context of previous messages when implementing interactive applications or complex data processing tasks.

By managing message history, developers can better control the flow of applications and respond appropriately to user's previous requests.

Actual utilization example

  • Interactive chatbot development: You can adjust the chatbot's response based on the conversation history with the user.

  • Complex data processing: During the data processing process, you can refer to the results of the previous step to determine the logic of the next step.

  • Applications that require state management: You can remember the user's previous choices and provide the next screen or information accordingly.

RunnableWithMessageHistory Is a powerful tool that allows you to stay in the state of your application, improve your user experience, and implement more sophisticated response mechanisms.

tutorial

Copy

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI

model = ChatOpenAI()
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are an assistant who is proficient in {ability}. Please respond in 20 characters or less.",
        ),
        # Use conversation history as a variable, history becomes the key of MessageHistory
        MessagesPlaceholder(variable_name="history"),
        ("human", "{input}"),  # Use user input as a variable
    ]
)
runnable = prompt | model  # Create a runnable object by connecting a prompt and a model

Managing message history is very important for interactive applications or complex data processing tasks. Effective management of message records requires two main elements:

  1. Runnable : Mainly like Retriever, Chain BaseChatMessageHistory Interact with runnable Object.

  2. BaseChatMessageHistory Callable object (callable) returning an instance of : An object to manage message history. This object is used to store, search, and update message history. Message recording is necessary to maintain the context of the conversation and generate a response based on the user's previous input.

There are many ways to implement message recording, memory integrations The page introduces various storage options and integration methods.

Here we will look at two main methods.

Inmemory ChatMessageHistory use

This method manages message recording within memory. Mainly used in development stages or simple applications. The inmemory approach provides a fast approach speed, but it has the disadvantage of losing message history when restarting the application.

RedisChatMessageHistory Use to utilize permanent storage

The method of using Redis allows you to permanently save message history. Redis is an open source in-memory data structure repository that provides high performance, allowing you to reliably manage message records even in a distributed environment. This method is suitable for complex applications or long-running services.

When choosing how to manage message records, you should consider the application's requirements, the amount of traffic expected, the importance of message data, and the retention period. The inmemory method is simple and fast to implement, but if data permanence is required, it may be more appropriate to use a permanent repository like Redis.

Volatile Conversation: In-Memory

Below is a simple example where chat history is stored in memory.

RunnableWithMessageHistory Setting parameters

  • runnable

  • BaseChatMessageHistory Objects that have been or have been inherited. ex) ChatMessageHistory

  • input_messages_key : key to specify user query input when chain invoke()

  • history_messages_key : key specified by conversation record

Copy

input_messages_key Specifies the key to be processed with the latest input message, history_messages_key Specifies the key to add the previous message.

Looking at the following code RunnableWithMessageHistory At the initial value session_id You can see the key being inserted as Default, just by this code RunnableWithMessageHistory Manage conversation threads session_id You can indirectly know that it is Hanha.

In other words, conversation thread-specific management session_id You can see that it is implemented very much.

Reference code: RunnableWithMessageHistory With reference to implementation,

Copy

therefore, invoke() city config={"configurable": {"session_id": "세션ID입력"}} You can see that you must specify the code.

Copy

Copy

Copy

same session_id If you enter, you can get the contents of the previous conversation thread, so you can talk!

Copy

Copy

Copy

But different session_id If you specify, the answer will not be performed properly because there is no dialog.

(The example below session_id : def234 Since it doesn't exist, you can confirm that you are doing the wrong answer)

Copy

Copy

Copy

The configuration parameters used to track message history ConfigurableFieldSpec List of objects history_factory_config You can customize it by passing it as a parameter.

like this history_factory_config When you set up a new one session_id The setting is overwritten.

In the example below user_id Wow conversation_id LA uses two parameters.

Copy

Copy

Copy

Example using Runnable with various Keys

Enter Messages object, output in the form of dict

This is when you receive the message as input and return the dictionary as output.

  • [important]: input_messages_key Omit ="input". Then you will set the Message object to be inserted as input.

Copy

Copy

Copy

Copy

Enter Messages object, output of Messages object

  • [important]: output_messages_key Omit ="output_message". Then it returns the Message object as output.

Copy

Copy

Copy

Copy

Dict with single key for all message inputs and outputs

This is how you use a single key for all input and output messages.

  • itemgetter("input_messages") Extract input messages using

Copy

Copy

Copy

Permanent storage

Persistent storage refers to a storage mechanism that maintains data even when the program ends or the system reboots. This can be implemented through databases, file systems, or other non-volatile storage devices.

Permanent storage stores the status of the application, maintains user settings, Essential for long-term data retention is. This allows the program to restart from the point where it was stopped in the previous run, Users continue to do this without data loss You can.

  • RunnableWithMessageHistory has get_session_history Independent of how callable objects retrieve chat message history.

  • Examples using local file systems here See.

  • Below Redis Shows how to use. How to implement chat message history using other providers memory integrations Check the page.

Redis installation

If Redis is not installed, it must be installed first.

Copy

Redis server powered

If there is no Redis deployment to connect to the existing, launch a local Redis Stack server.

Here is the instruction that drives the Redis server with Docker.

Copy

REDIS_URL Assign the variable with the link URL of the Redis database.

  • URL "redis://localhost:6379/0" It is set to.

Copy

LangSmith tracking settings

Set LangSmith for tracking. LangSmith is not essential, but it can help.

Copy

To update the message recording implementation, define a new callable object, this time just return an instance of the RedisChatMessageHistory.

Copy

You can call it the same way as before.

Copy

Copy

same session_id Use to make a second call. This time, I'll ask you to answer the previous answer in Koreanglo.

Copy

Copy

Different this time session_id I will use to ask a question.

Copy

Copy

Last updated