LangGraph Manual State Update

Open in ColabOpen in GitHub

Overview

LangGraph provides a way to manually update the intermediate state.

By updating the state, you can control the path by modifying the agent's behavior, and even revise the past.

This feature is especially useful for correcting the agent's mistakes, exploring alternative routes, or modifying the agent's behavior according to a specific goal.

  • Note: The agent used in this tutorial defines the same graph as the previous tutorial.

Table of Contents

References


Environment Setup

Set up the environment. You may refer to Environment Setup for more details.

[Note]

  • langchain-opentutorial is a package that provides a set of easy-to-use environment setup, useful functions and utilities for tutorials.

  • You can checkout the langchain-opentutorial for more details.

png

First, display the list of channels to show the options where interrupt_before and interrupt_after can be applied.

The current step is interrupted by ToolNode.

Check the most recent message to see that ToolNode contains the query before performing the search.

Here, the query contains only the word LangGraph. (The original question was "Please research and tell me what LangGraph is!")

Of course, the web search result may not be what we want.

Human in the loop

  • Modify the search result from TavilySearch tool

We often find that the result of ToolMessage is not satisfactory.

In particular, the answer obtained from web search may contain incorrect information, which can also affect the chatbot's answer.

If you want to modify the ToolMessage from the Tavily Tool and pass it to the LLM, how can you do it?

Below is a modified virtual web search result that is slightly different from the original web search result.

Next, inject the modified search result into the ToolMessage.

Important

  • To modify the message, you need to specify the tool_call_id that matches the message you want to modify.

StateGraph's update_state Method

The update_state method updates the state of the graph with the given values. This method operates as if the values originated from as_node.

Parameters

  • config (RunnableConfig): Execution configuration

  • values (Optional[Union[dict[str, Any], Any]]): Values to update

  • as_node (Optional[str]): The node name to consider as the source of the values. The default value is None

Return

  • RunnableConfig

Main Features

  1. Load the previous state through the checkpoint and save the new state.

  2. Process the state update for the subgraph.

  3. If as_node is not specified, find the node that last updated the state.

  4. Update the state using the writers of the specified node.

  5. Save the updated state to the checkpoint.

Main Logic

  1. Check the checkpoint and raise a ValueError if it is not found.

  2. If the update is for the subgraph, call the update_state method of the subgraph.

  3. Load the previous checkpoint and determine as_node if necessary.

  4. Update the state using the writers of the specified node.

  5. Save the updated state to the new checkpoint.

Note

  • This method is used when manually updating the state of the graph.

  • Use the checkpoint to ensure version management and persistence of the state.

  • as_node is automatically determined, but if it is ambiguous, an error may occur.

  • Writing to SharedValues is not allowed during state update.

Now, the graph is complete.

Since the final response message was provided!

State update simulates the graph step, so it also creates the corresponding traces.

messages were processed with the predefined add_messages function. (This ensures that the existing list is not overwritten directly in the graph and always adds values.)

The same logic is applied here, so the message passed to update_state is added in the same way.

The update_state function operates as if it were one of the nodes in the graph! By default, the update process uses the last executed node, but it can be manually specified as shown below. Let's add an update and instruct the graph to treat it as coming from "chatbot."

The following code can be used if you want to modify the state of the final answer.

Let's visualize the graph and check the entire output.

png

Check the current state as before to confirm that the checkpoint reflects the manual update.

Check if there is a next node to proceed. () is empty, indicating that the entire process has been completed normally.

Update the message state after an interrupt – continue the process.

  • Modify the search query in the TavilySearch tool

This time, interrupt before proceeding to the next node and update the state, then continue the process.

First, create a new thread_id.

Here, we use the generate_random_hash function to generate a random hash value.

Next, let's update the tool call for the agent.

First, get the Message ID.

The last message is a message related to the tavily_web_search tool call.

The main properties are as follows.

  • name: The name of the tool

  • args: The search query

  • id: The tool call ID

  • type: The tool call type (tool_call)

Let's update the query in args.

Copy the existing_message and create a new tool call new_tool_call.

Since we used the copy() method, all property values are copied.

Then, input the desired search query to the query parameter.

Important

  • The id uses the same id as the existing message. (If the id changes, the message reducer will not update the message but instead add it.)

We can see that the search query has been updated.

Check the tool_calls of the updated last message.

  • The query in args has been updated.

You can see that the search query has been changed from the original "LangGraph" to the updated query "LangGraph site:github.com/LangChain-OpenTutorial/LangChain-GitBook".

Continue streaming the graph using the previous settings and a None input.

Check the last message in messages of the final state. (This is the final response message.)

Modify the result of the past snapshot and replay

This time, we will look at how to modify the result of the past snapshot and replay.

Check the past snapshot and return to a specific node, then modify the state and continue from that node.

This is called Replay.

First, get the state of the past snapshot.

Check the content of the selected message.

Check if the search query has been updated.

Create an updated AIMessage.

Below is the message before the update.

Use the update_state method in graph to update the state.

Save the updated state to updated_state.

Now, stream the updated state. Here, the input is None to replay.

Output the final result.

The config used here is not to retrieve the final state but serves as the initial config to obtain the final state.

Last updated