Agents may be unreliable and may require human input to successfully perform tasks.
Similarly, for some tasks, you may want to require human intervention and “approval” before execution to ensure that everything is running as intended.
LangGraph supports human-in-the-loop workflows in several ways.
We'll start this tutorial by using LangGraph's interrupt_before function to always interrupt the tool node.
Copy
# Configuration file for managing API keys as environment variables
from dotenv import load_dotenv
# Load API key information
load_dotenv()
Copy
True
Copy
# LangSmith set up 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
Now compile the graph and specify interrupt_before before the tools node.
Copy
Copy
Copy
Copy
Let's check the graph status to make sure it's working properly.
Copy
Copy
(In the previous tutorial) .next did not exist because END was reached.
However, now .next is designated as tools.
Now let's check the tool call.
Copy
Copy
Next, we will continue the graph from where it left off.
LangGraph makes it easy to continue traversing a graph.
Just pass None as input.
Copy
Copy
Now, we have added human-intervention-capable execution to our chatbot using interrupts, allowing for human supervision and intervention when needed. This could potentially provide a UI for our system later on.
Since we have already added a checkpointer, the graph will be paused indefinitely and can be resumed at any time. Below is how to get the state history using the get_state_history method.
You can specify a desired state through the state history and start over from that point.
Copy
Copy
It is important to note that a checkpoint is saved for every step of the graph.
The desired point is stored in the to_replay variable. This can be used to specify a point from which to restart.
Copy
Copy
to_replay.config contains checkpoint_id.
Copy
Copy
Providing this checkpoint_id value allows LangGraph's checkpointer to load the state at that point in time.
However, in this case, the input value must be passed as None.
from langchain_teddynote.messages import pretty_print_messages
from langchain_core.runnables import RunnableConfig
# question
question = "Tell me the latest news about AI."
# Define the initial input State
input = State(messages=[("user", question)])
# config settings
config = RunnableConfig(
recursion_limit=10, # Visit up to 10 nodes, more than that will result in RecursionError
configurable={"thread_id": "1"}, # Thread ID setting
tags=["my-rag"], # Tag
)
for event in graph.stream(
input=input,
config=config,
stream_mode="values",
interrupt_before=["tools"], # tools 실행 전 interrupt(Stop before running the tools node)
):
for key, value in event.items():
# key is the node name
print(f"\n[{key}]\n")
# value is the output value of the node
# print(value)
pretty_print_messages(value)
# In value, state is stored in dict format (key value of values)
if "messages" in value:
print(f"number of messages: {len(value['messages'])}")
[messages]
================================ Human Message =================================
Please tell me the latest news related to AI.
[messages]
================================ Human Message =================================
Please tell me the latest news related to AI.
================================== Ai Message ==================================
Tool Calls:
search_keyword (call_Axca1RLkFvDATzG0WtrS7T04)
Call ID: call_Axca1RLkFvDATzG0WtrS7T04
Args:
query: AI
# Create a graph state snapshot
snapshot = graph.get_state(config)
# Next snapshot status
snapshot.next
('tools',)
from langchain_teddynote.messages import display_message_tree
# Extract the last message from a message snapshot
existing_message = snapshot.values["messages"][-1]
# Show message tree
display_message_tree(existing_message.tool_calls)
# `None` adds nothing to the current state
events = graph.stream(None, config, stream_mode="values")
# Repeating events
for event in events:
# If a message is included in an event
if "messages" in event:
# Pretty output of the last message
event["messages"][-1].pretty_print()
================================== Ai Message ==================================
Tool Calls:
search_keyword (call_Axca1RLkFvDATzG0WtrS7T04)
Call ID: call_Axca1RLkFvDATzG0WtrS7T04
Args:
query: AI
================================= Tool Message =================================
Name: search_keyword
[{"url": "https://news.google.com/rss/articles/CBMidkFVX3", "content": "Data center in the ocean?… AI company fighting fever - Dong-A Ilbo"}, {"url": "https://news.google.com/rss/articles/CBMiakFVX3", "content": "OpenAI officially launches search function in 'ChatGPT'... Google counters with 'search support for developers' - AI Times"}, {"url": "https://news.google.com/rss/articles/CBMiswJBVV", "content": "Column | The Worsening OpenAI-Microsoft Relations - CIO.com"}, {"url": "https://news.google.com/rss/articles/CBMigw", "content": "“AI 활용한 무기 가공할 위력… 오용되면 끝장” - 조선일보"}, {"url": "https://news.google.com/rss/articles/CBMiYEFVX", "content": "Following Naver and the three major mobile carriers, Kakao joins the AI war… Will AI become the growth engine of Korea’s IT? [Money-making AI, Part 2] - 뉴시스"}]
================================== Ai Message ==================================
Here are some recent AI-related news:
1. **[Data Center in the Ocean?… AI Companies Fighting with Heat](https://news.google.com/rss/articles/CBMidkFVX)** - AI 기업들이 발열 문제를 해결하기 위해 바다 속에 데이터센터를 설치하는 방안에 대해 다루고 있습니다.
2. **[OpenAI officially launches search function in 'ChatGPT'... Google counters with 'search support for developers'](https://news.google.com/rss/articles/CBMiakF)** - 오픈AI가 챗GPT에 새로운 검색 기능을 추가한 반면, 구글은 개발자용 검색 지원을 강화하고 있다는 소식입니다.
3. **[Column | The Worsening OpenAI-Microsoft Relations](https://news.google.com/rss/articles/CBMiswJBV)** - 오픈AI와 마이크로소프트 간의 관계가 악화되고 있다는 내용을 다룬 칼럼입니다.
4. **[“AI-powered weapons have incredible power… If misused, it’s over”](https://news.google.com/rss/articles/CBMigwFBV)** - AI의 힘을 무기로 가공할 수 있지만, 잘못 사용될 경우 심각한 결과를 초래할 수 있다는 경고가 담긴 기사입니다.
5. **[Following Naver and the three major mobile carriers, Kakao joins the AI war… Will AI become the growth engine of Korea’s IT? [Money-making AI, Part 2](https://news.google.com/rss/articles/CBMiYEFVX)** - 카카오가 AI 전쟁에 합류하면서 AI가 한국 IT의 성장 동력이 될 수 있을지에 대한 논의입니다.
In addition to this, there are various AI-related news reports. Please take a closer look at the topics that interest you!
to_replay = None
# Get status log
for state in graph.get_state_history(config):
# Number of messages and next status output
print("메시지 수: ", len(state.values["messages"]), "다음 노드: ", state.next)
print("-" * 80)
# Select specific status criteria: Number of chat messages
if len(state.values["messages"]) == 3:
to_replay = state
Number of messages: 4 Next node: ()
--------------------------------------------------------------------------------
Number of messages: 3 Next node: ('chatbot',)
--------------------------------------------------------------------------------
Number of messages: 2 Next node: ('tools',)
--------------------------------------------------------------------------------
Number of messages: 1 Next node: ('chatbot',)
--------------------------------------------------------------------------------
Number of messages: 0 Next node: ('__start__',)
--------------------------------------------------------------------------------
# Output the next element of the next item
print(to_replay.next)
# Output settings information for the following items
print(to_replay.config)
# `to_replay.config` is `checkpoint_id`corresponds to the state stored in the checkpointer
for event in graph.stream(None, to_replay.config, stream_mode="values"):
# If a message is included in an event
if "messages" in event:
# Print last message
event["messages"][-1].pretty_print()
================================= Tool Message =================================
Name: search_keyword
[{"url": "https://news.google.com/rss/articles/CBMidkFV", "content": "Data center in the sea? AI Companies Fighting Fever - Dong-A IIbo"}, {"url": "https://news.google.com/rss/articles/CBMiakFVX", "content": "OpenAI, 'ChatGPT'Search function officially launched...Google is 'Counterattack with 'Search Support for Developers' - AI타임스"}, {"url": "https://news.google.com/rss/articles/CBMiswJB", "content": "칼럼 | 악화하는 오픈AI-마이크로소프트의 관계 - CIO.com"}, {"url": "https://news.google.com/rss/articles/CBMigwFBV", "content": "“AI 활용한 무기 가공할 위력… 오용되면 끝장” - 조선일보"}, {"url": "https://news.google.com/rss/articles/CBMiYEFV", "content": "Following Naver and the three major mobile carriers, Kakao joins the AI war... Will AI become the growth engine of Korea's IT? [Money-making AI, Part 2] - Newsis"}]
================================== Ai Message ==================================
Here are the latest news related to AI:
1. [Data Center in the Ocean?… AI Companies Struggling with Heat - Dong-A Ilbo](https://news.google.com/rss/articles/CBMidkFVX)
2. [OpenAI officially launches search function in 'ChatGPT'... Google counters with 'search support for developers' - AI Times](https://news.google.com/rss/articles/CBMiakFV)
3. [Column | The Worsening OpenAI-Microsoft Relations - CIO.com](https://news.google.com/rss/articles/CBMiswJB)
4. [“AI-powered weapons have incredible power… If misused, it’s over” - Chosun Ilbo](https://news.google.com/rss/articles/CBMigwFBV)
5. [Following Naver and the three major mobile carriers, Kakao joins the AI war… Will AI become the growth engine of Korea’s IT? [Money-making AI, Part 2] - 뉴시스](https://news.google.com/rss/articles/CBMiYEFV)
These news articles cover a variety of recent AI-related issues. Click on the article of interest to learn more.