07. State correction and replay through reverting of intermediate intervention

LangGraph provides a way to manually update the state of intermediate steps.

Updating the state allows you to control the path by modifying the agent's behavior, and even modify the past.

This feature is especially useful when correcting an agent's mistakes, exploring alternative paths, or changing an agent's behavior based on a specific goal.

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

Copy

# Configuration file for managing API keys as environment variables
from dotenv import load_dotenv

# Load API key information
load_dotenv()

Copy

True

Copy

# Set up LangSmith tracking. https://smith.langchain.com
# !pip install -qU langchain-teddynote
from langchain_teddynote import logging

# Enter a project name.
logging.langsmith("CH17-LangGraph-Modules")

Copy

Copy

Copy

First, print out the channel list and print out the list to which interrupt_before and interrupt_after can be applied.

Copy

Copy

Copy

Copy

The current step was interrupted by a ToolNode.

If you check the most recent message, you can see that the ToolNode contains a query before performing the search.

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

Naturally, web search results may not be what we want.

Copy

Copy

human intervention (Human-in-the-loop)

  • Edit search results in TavilySearch tool

We often find ourselves not liking the results of a ToolMessage.

In particular, answers obtained through web searches can easily contain incorrect information, which can then affect the chatbot's responses.

What if a human being wants to intervene and modify the ToolMessage, which is the search result of the web search tool Tavily Tool, and send it to LLM?

Below I have created some modified virtual web search results that are slightly different from the original web search results.

Copy

Copy

Next, we inject the modified search results into ToolMessage.

importance

  • To edit a message here, you must specify the tool_call_id that matches the Message you want to edit.

Copy

Copy

Copy

Copy

StateGraph's update_state method

The update_state method updates the state of the graph with a given value. This method behaves as if the value came from as_node.

parameters

  • config (RunnableConfig): Running 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 value. Defaults to None.

return value

  • RunnableConfig

key features

  1. Load the previous state and save the new state via checkpointer.

  2. Handles state updates to subgraphs.

  3. If as_node is not specified, it finds the node that last updated its state.

  4. Updates the state by executing writers on the specified node.

  5. Save the updated state to a checkpoint.

Main Logic

  1. Checks the checkpointer and raises a ValueError if it is not found.

  2. If the update is to a subgraph, the update_state method of that subgraph is called.

  3. Loads a previous checkpoint and determines as_node if necessary.

  4. Updates the state using writers on the specified node.

  5. Save the updated state as a new checkpoint.

reference

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

  • Use checkpointers to ensure versioning and persistence of state.

  • If as_node is not specified, it is determined automatically, but an error may occur in ambiguous cases.

  • Writing to SharedValues ​​is not allowed while the state is being updated.

Copy

Copy

The graph is now complete.

Because you provided the final response message!

Since state updates simulate graph steps, they also generate corresponding traces.

wwwwww

The same logic applies here, the message passed to update_state will cause the message to be added in the same way.

The update_state function acts as if it were one of the nodes in the graph! By default, the update operation uses the last node that was executed, but you can specify it manually below. Let's add an update and tell the graph to treat it as if it came from a "chatbot".

Copy

Copy

Copy

Copy

Below is the code you can use if you also want to modify the status of the final answer.

Copy

Now, let's visualize the graph and check the overall output.

Copy

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

Copy

Copy

Check if there is a next node to proceed to. You can see that () is empty, which means that all the processes have proceeded normally.

Copy

Copy

Update message status after interrupt - continue

  • Modify search query in TavilySearch tool

This time, we will look at a method to stop by generating an interrupt before proceeding to the next node, update the state, and then proceed.

First, create a new thread_id.

Here we use the generate_random_hash function, which generates a random hash value.

Copy

Copy

Next, let's update the tool call for the agent. First, let's get the Message ID.

Copy

Copy

Copy

The last message is related to calling the tavily_web_search tool.

The main properties are:

  • name: Name of the tool

  • args: Search query

  • id: Tool Call ID

  • type: Tool call type (tool_call)

Copy

Copy

Let's update the query of args among the above property values.

Create a new tool, new_tool_call, by copying the existing existing_message.

Since we copied using the opy() method, all property values ​​are copied.

Then, enter the desired search query in the query parameter.

importance

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

Copy

Copy

Copy

Copy

You can see that the search query has been updated.

Copy

Copy

Copy

Check the tool_calls of the last message that was updated.

  • You can see that the query in args has been modified.

Copy

Copy

You can see that the search is performed with the changed search query "LangGraph site:teddylee777.github.io" instead of the existing search term "LangGraph".

Continue streaming the grwaph using the existing settings and None input.

Copy

Copy

Copy

Copy

In the final state, check the last message in messages (this is the final response message).

Copy

Copy

Modify and Replay Results from Previous Snapshots

This time, we'll look at how to Replay by modifying the results of a previous snapshot.

After checking the last snapshot, go back to a specific node, modify the state, and then proceed from that node again.

This is called Replay.

First, get the state of the last snapshot.

Copy

Copy

Check the contents of the selected message.

Copy

Open toolbar Write a caption​Check if the search query has been updated and reflected.

Copy

Copy

Create an updated AIMessage.

Copy

Copy

Below is the message before the update.

Copy

Copy

Update the state using the update_state method in graph.

Save the updated state to updated_state.

Copy

Copy

Now we stream the updated state, where the input is None and we replay it.

Copy

Copy

Prints the final result.

The config used at this time is not the one that retrieves the final state, but the initial config for retrieving the final state.

Copy

Copy

Last updated