LangGraph (4/4): personalização do estado e checkpoints

LangGraph (4/4): personalização do estado e checkpoints

Nas partes anteriores, construímos um agente com ferramentas, memória de curto e longo prazo e human-in-the-loop. Para encerrar o guia, veremos como **personalizar o estado** do grafo com esquemas e redutores próprios, e como trabalhar com **checkpoints** para inspecionar e percorrer o histórico de estados.

⚠️ Este capítulo continua o código das partes anteriores (Parte 1 · Parte 2 · Parte 3).

Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.

📚 **Esta entrada faz parte da série _Guia completo de LangGraph_**, dividida em quatro capítulos que são lidos em ordem:

> * Parte 1: Chatbot básico y herramientas

* Parte 2: Memória de curto prazo

* Parte 3: Memória de longo prazo e human-in-the-loop

* 👉 **Parte 4: Personalização do estado e checkpoints**

Personalização do estadolink image 9

Nota: Esta seção será feita usando Sonnet 3.7, já que, no momento da escrita deste post, é o melhor modelo para uso com agentes, e é o único que entende quando precisa chamar as tools e quando não precisa

Até agora, temos confiado em um estado simples com uma entrada, uma lista de mensagens. É possível ir longe com esse estado simples, mas, se desejar definir um comportamento complexo sem depender da lista de mensagens, podem ser adicionados campos adicionais ao estado.

Aqui vamos ver um novo cenário, no qual o chatbot está usando a ferramenta de busca para encontrar informações específicas e encaminhá-las para um ser humano para revisão. Vamos fazer com que o chatbot pesquise o aniversário de uma entidade. Adicionaremos name e birthday como chaves do estado.

Primeiro carregamos os valores das API KEYs

	
< > Input
Python
import os
import dotenv
dotenv.load_dotenv()
TAVILY_API_KEY = os.getenv("TAVILY_LANGGRAPH_API_KEY")
ANTHROPIC_TOKEN = os.getenv("ANTHROPIC_LANGGRAPH_API_KEY")
Copied

Criamos o novo estado

	
< > Input
Python
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
name: str
birthday: str
Copied

Adicionar essa informação ao estado a torna facilmente acessível por outros nós do grafo (por exemplo, um nó que armazena ou processa a informação), bem como pela camada de persistência do grafo.

Agora criamos o grafo

	
< > Input
Python
from langgraph.graph import StateGraph, START, END
graph_builder = StateGraph(State)
Copied

Definimos a tool de busca

	
< > Input
Python
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper
from langchain_community.tools.tavily_search import TavilySearchResults
wrapper = TavilySearchAPIWrapper(tavily_api_key=TAVILY_API_KEY)
search_tool = TavilySearchResults(api_wrapper=wrapper, max_results=2)
Copied

Agora criamos a ferramenta de assistência humana. Nesta ferramenta, preencheremos as chaves de estado dentro da nossa ferramenta human_assistance. Isso permite que um ser humano revise a informação antes de ser armazenada no estado. Voltaremos a usar Command, desta vez para emitir uma atualização de estado de dentro da nossa ferramenta.

	
< > Input
Python
from langchain_core.messages import ToolMessage
from langchain_core.tools import InjectedToolCallId, tool
from langgraph.types import Command, interrupt
@tool
# Note that because we are generating a ToolMessage for a state update, we
# generally require the ID of the corresponding tool call. We can use
# LangChain's InjectedToolCallId to signal that this argument should not
# be revealed to the model in the tool's schema.
def human_assistance(
name: str, birthday: str, tool_call_id: Annotated[str, InjectedToolCallId]
) -&gt; str:
"""
Request assistance from a human expert. Use this tool ONLY ONCE per conversation.
After receiving the expert's response, you should provide an elaborated response to the user based on the information received
based on the information received, without calling this tool again.
Args:
query: The query to ask the human expert.
Returns:
The response from the human expert.
"""
human_response = interrupt(
{
"question": "Is this correct?",
"name": name,
"birthday": birthday,
},
)
# If the information is correct, update the state as-is.
if human_response.get("correct", "").lower().startswith("y"):
verified_name = name
verified_birthday = birthday
response = "Correct"
# Otherwise, receive information from the human reviewer.
else:
verified_name = human_response.get("name", name)
verified_birthday = human_response.get("birthday", birthday)
response = f"Made a correction: {human_response}"
# This time we explicitly update the state with a ToolMessage inside
# the tool.
state_update = {
"name": verified_name,
"birthday": verified_birthday,
"messages": [ToolMessage(response, tool_call_id=tool_call_id)],
}
# We return a Command object in the tool to update our state.
return Command(update=state_update)
Copied

Usamos ToolMessage, que se usa para passar o resultado de executar uma tool de volta para um modelo, e InjectedToolCallId

Criamos uma lista de tools

	
< > Input
Python
tools_list = [search_tool, human_assistance]
Copied

Em seguida, o LLM com os bind_tools e o adicionamos ao grafo

	
< > Input
Python
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from langchain_anthropic import ChatAnthropic
# Create the LLM
llm = ChatAnthropic(model="claude-3-7-sonnet-20250219", api_key=ANTHROPIC_TOKEN)
# Modification: tell the LLM which tools it can call
llm_with_tools = llm.bind_tools(tools_list)
# Define the chatbot function
def chatbot_function(state: State):
message = llm_with_tools.invoke(state["messages"])
# Because we will be interrupting during tool execution,
# we disable parallel tool calling to avoid repeating any
# tool invocations when we resume.
assert len(message.tool_calls) &lt;= 1
return {"messages": [message]}
# Add the chatbot node
graph_builder.add_node("chatbot_node", chatbot_function)
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x120b4f380&gt;

Adicionamos a tool ao grafo

	
< > Input
Python
from langgraph.prebuilt import ToolNode, tools_condition
tool_node = ToolNode(tools=tools_list)
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges("chatbot_node", tools_condition)
graph_builder.add_edge("tools", "chatbot_node")
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x120b4f380&gt;

Adicionamos o nó de START ao grafo

	
< > Input
Python
graph_builder.add_edge(START, "chatbot_node")
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x120b4f380&gt;

Criamos um checkpointer MemorySaver.

	
< > Input
Python
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
Copied

Compilamos o grafo com o checkpointer

	
< > Input
Python
graph = graph_builder.compile(checkpointer=memory)
Copied

Representamo-lo graficamente

	
< > Input
Python
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception as e:
print(f"Error al visualizar el grafo: {e}")
Copied
>_ Output
			
&lt;IPython.core.display.Image object&gt;

Vamos pedir ao nosso chatbot que procure o "aniversário" da biblioteca de LangGraph.

Direcionaremos o chatbot até a ferramenta human_assistance assim que tiver a informação necessária. Os argumentos name e birthday são obrigatórios para a ferramenta human_assistance, então obrigam o chatbot a gerar propostas para esses campos.

	
< > Input
Python
user_input = (
"Can you look up when LangGraph was released? "
"When you have the answer, use the human_assistance tool for review."
)
config = {"configurable": {"thread_id": "1"}}
events = graph.stream(
{"messages": [{"role": "user", "content": user_input}]},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Can you look up when LangGraph was released? When you have the answer, use the human_assistance tool for review.
>_ Output
			
Failed to multipart ingest runs: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================== Ai Message ==================================
[{'text': "I'll help you look up when LangGraph was released, and then I'll use the human_assistance tool for review as requested. First, let me search for information about LangGraph's release date:", 'type': 'text'}, {'id': 'toolu_011KHWFxYbFnUvGEF6MPt3dE', 'input': {'query': 'LangGraph release date when was LangGraph released'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_011KHWFxYbFnUvGEF6MPt3dE)
Call ID: toolu_011KHWFxYbFnUvGEF6MPt3dE
Args:
query: LangGraph release date when was LangGraph released
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangGraph Studio: The first agent IDE | by Bhavik Jikadara - Medium", "url": "https://bhavikjikadara.medium.com/langgraph-studio-the-first-agent-ide-468132628274", "content": "LangGraph, launched in January 2023, is a low-level orchestration framework designed for building controllable and complex agentic applications.", "score": 0.80405265}, {"title": "langgraph - PyPI", "url": "https://pypi.org/project/langgraph/", "content": "langgraph · PyPI Skip to main content Switch to mobile version Search PyPI Search Help Sponsors Log in Register Menu Help Sponsors Log in Register Search PyPI Search langgraph 0.2.70 pip install langgraph Copy PIP instructions Latest versionReleased: Feb 6, 2025 Building stateful, multi-actor applications with LLMs Navigation Project description Release history Download files [...] 0.2.20 Sep 13, 2024 0.2.19 Sep 6, 2024 0.2.18 Sep 6, 2024 0.2.17 Sep 5, 2024 0.2.16 Sep 1, 2024 0.2.15 Aug 30, 2024 0.2.14 Aug 24, 2024 0.2.13 Aug 23, 2024 0.2.12 Aug 22, 2024 0.2.11 Aug 22, 2024 0.2.10 Aug 21, 2024 0.2.9 Aug 21, 2024 0.2.8 Aug 21, 2024 0.2.7 Aug 21, 2024 0.2.7a0 pre-release Aug 21, 2024 0.2.6 Aug 21, 2024 0.2.5 Aug 21, 2024 0.2.5a0 pre-release Aug 20, 2024 0.2.4 Aug 15, 2024 0.2.3 Aug 8, 2024 0.2.2 Aug 7, 2024 0.2.1 Aug 7, 2024 0.2.0 Aug 7, 2024 [...] Download URL: langgraph-0.2.70.tar.gz Upload date: Feb 6, 2025 Size: 129.7 kB Tags: Source Uploaded using Trusted Publishing? Yes Uploaded via: twine/6.1.0 CPython/3.12.8", "score": 0.75659186}]
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================== Ai Message ==================================
[{'text': 'Based on my search, I found that LangGraph was launched in January 2023. However, I noticed some inconsistencies in the information, as one source mentions it was launched in January 2023, while the PyPI page shows a version history starting from 2024. Let me request human assistance to verify this information:', 'type': 'text'}, {'id': 'toolu_019EopKn8bLi3ksvUVY2Mt5p', 'input': {'name': 'LangGraph', 'birthday': 'January 2023'}, 'name': 'human_assistance', 'type': 'tool_use'}]
Tool Calls:
human_assistance (toolu_019EopKn8bLi3ksvUVY2Mt5p)
Call ID: toolu_019EopKn8bLi3ksvUVY2Mt5p
Args:
name: LangGraph
birthday: January 2023
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')

Foi interrompido pelo interrupt na ferramenta human_assistance. Nesse caso, o chatbot, com a ferramenta de busca, determinou que a data do LangGraph é janeiro de 2023, mas não é a data exata; é 17 de janeiro de 2024, então podemos inseri-la nós mesmos.

	
< > Input
Python
human_command = Command(
resume={
"name": "LangGraph",
"birthday": "Jan 17, 2024",
},
)
events = graph.stream(human_command, config, stream_mode="values")
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================== Ai Message ==================================
[{'text': 'Based on my search, I found that LangGraph was launched in January 2023. However, I noticed some inconsistencies in the information, as one source mentions it was launched in January 2023, while the PyPI page shows a version history starting from 2024. Let me request human assistance to verify this information:', 'type': 'text'}, {'id': 'toolu_019EopKn8bLi3ksvUVY2Mt5p', 'input': {'name': 'LangGraph', 'birthday': 'January 2023'}, 'name': 'human_assistance', 'type': 'tool_use'}]
Tool Calls:
human_assistance (toolu_019EopKn8bLi3ksvUVY2Mt5p)
Call ID: toolu_019EopKn8bLi3ksvUVY2Mt5p
Args:
name: LangGraph
birthday: January 2023
================================= Tool Message =================================
Name: human_assistance
Made a correction: {'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}
================================== Ai Message ==================================
Thank you for the expert review and correction! Based on the human expert's feedback, I can now provide you with the accurate information:
LangGraph was released on January 17, 2024, not January 2023 as one of the search results incorrectly stated.
This is an important correction, as it means LangGraph is a relatively recent framework in the LLM orchestration space, having been available for less than a year at this point. LangGraph is developed by LangChain and is designed for building stateful, multi-actor applications with LLMs.
	
< > Input
Python
snapshot = graph.get_state(config)
{k: v for k, v in snapshot.values.items() if k in ("name", "birthday")}
Copied
>_ Output
			
{'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}

Agora a data está correta graças à intervenção humana para modificar os valores do estado

Volto a escrever todo o código para que seja mais fácil de entender

	
< > Input
Python
import os
import dotenv
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
from langgraph.graph import StateGraph, START, END
from langgraph.types import Command, interrupt
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import MemorySaver
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import ToolMessage
from langchain_core.tools import InjectedToolCallId, tool
from langchain_anthropic import ChatAnthropic
dotenv.load_dotenv()
TAVILY_API_KEY = os.getenv("TAVILY_LANGGRAPH_API_KEY")
ANTHROPIC_TOKEN = os.getenv("ANTHROPIC_LANGGRAPH_API_KEY")
# State
class State(TypedDict):
messages: Annotated[list, add_messages]
name: str
birthday: str
# Tools
wrapper = TavilySearchAPIWrapper(tavily_api_key=TAVILY_API_KEY)
search_tool = TavilySearchResults(api_wrapper=wrapper, max_results=2)
@tool
# Note that because we are generating a ToolMessage for a state update, we
# generally require the ID of the corresponding tool call. We can use
# LangChain's InjectedToolCallId to signal that this argument should not
# be revealed to the model in the tool's schema.
def human_assistance(
name: str, birthday: str, tool_call_id: Annotated[str, InjectedToolCallId]
) -&gt; str:
"""
Request assistance from a human expert. Use this tool ONLY ONCE per conversation.
After receiving the expert's response, you should provide an elaborated response to the user based on the information received
based on the information received, without calling this tool again.
Args:
query: The query to ask the human expert.
Returns:
The response from the human expert.
"""
human_response = interrupt(
{
"question": "Is this correct?",
"name": name,
"birthday": birthday,
},
)
# If the information is correct, update the state as-is.
if human_response.get("correct", "").lower().startswith("y"):
verified_name = name
verified_birthday = birthday
response = "Correct"
# Otherwise, receive information from the human reviewer.
else:
verified_name = human_response.get("name", name)
verified_birthday = human_response.get("birthday", birthday)
response = f"Made a correction: {human_response}"
# This time we explicitly update the state with a ToolMessage inside
# the tool.
state_update = {
"name": verified_name,
"birthday": verified_birthday,
"messages": [ToolMessage(response, tool_call_id=tool_call_id)],
}
# We return a Command object in the tool to update our state.
return Command(update=state_update)
tools_list = [search_tool, human_assistance]
tool_node = ToolNode(tools=tools_list)
# Create the LLM
llm = ChatAnthropic(model="claude-3-7-sonnet-20250219", api_key=ANTHROPIC_TOKEN)
llm_with_tools = llm.bind_tools(tools_list)
# Define the chatbot function
def chatbot_function(state: State):
message = llm_with_tools.invoke(state["messages"])
# Because we will be interrupting during tool execution,
# we disable parallel tool calling to avoid repeating any
# tool invocations when we resume.
assert len(message.tool_calls) &lt;= 1
return {"messages": [message]}
# Graph
graph_builder = StateGraph(State)
# Nodes
graph_builder.add_node("tools", tool_node)
graph_builder.add_node("chatbot_node", chatbot_function)
# Edges
graph_builder.add_edge(START, "chatbot_node")
graph_builder.add_conditional_edges("chatbot_node", tools_condition)
graph_builder.add_edge("tools", "chatbot_node")
# Checkpointer
memory = MemorySaver()
# Compile
graph = graph_builder.compile(checkpointer=memory)
# Visualize
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception as e:
print(f"Error al visualizar el grafo: {e}")
Copied
>_ Output
			
Error al visualizar el grafo: Failed to reach https://mermaid.ink/ API while trying to render your graph after 1 retries. To resolve this issue:
1. Check your internet connection and try again
2. Try with higher retry settings: `draw_mermaid_png(..., max_retries=5, retry_delay=2.0)`
3. Use the Pyppeteer rendering method which will render your graph locally in a browser: `draw_mermaid_png(..., draw_method=MermaidDrawMethod.PYPPETEER)`

Vamos pedir ao nosso chatbot que procure o "aniversário" da biblioteca LangGraph.

	
< > Input
Python
user_input = (
"Can you look up when LangGraph was released? "
"When you have the answer, use the human_assistance tool for review."
)
config = {"configurable": {"thread_id": "1"}}
events = graph.stream(
{"messages": [{"role": "user", "content": user_input}]},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Can you look up when LangGraph was released? When you have the answer, use the human_assistance tool for review.
>_ Output
			
Failed to multipart ingest runs: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================== Ai Message ==================================
[{'text': "I'll look up when LangGraph was released and then get human verification of the information.", 'type': 'text'}, {'id': 'toolu_017SLLSEnFQZVdBpj85BKHyy', 'input': {'query': 'when was LangGraph released launch date'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_017SLLSEnFQZVdBpj85BKHyy)
Call ID: toolu_017SLLSEnFQZVdBpj85BKHyy
Args:
query: when was LangGraph released launch date
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangChain Introduces LangGraph Studio: The First Agent IDE for ...", "url": "https://www.marktechpost.com/2024/08/03/langchain-introduces-langgraph-studio-the-first-agent-ide-for-visualizing-interacting-with-and-debugging-complex-agentic-applications/", "content": "LangGraph, launched in January 2023, is a highly controllable, low-level orchestration framework for building agentic applications. Since its inception, it has undergone significant improvements, leading to a stable 0.1 release in June. LangGraph features a persistence layer enabling human-in-the-loop interactions and excels at building complex applications requiring domain-specific cognitive architecture.", "score": 0.83742094}, {"title": "LangGraph Studio: The first agent IDE | by Bhavik Jikadara - Medium", "url": "https://bhavikjikadara.medium.com/langgraph-studio-the-first-agent-ide-468132628274", "content": "LangGraph, launched in January 2023, is a low-level orchestration framework designed for building controllable and complex agentic applications. It’s beneficial for creating applications requiring highly domain-specific cognitive architecture and human-in-the-loop interactions. LangGraph is open source, available in Python and JavaScript, and integrates seamlessly with LangSmith, whether or not you use LangChain. LangGraph: A Comprehensive Guide for Beginners", "score": 0.79369855}]
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
>_ Output
			
================================== Ai Message ==================================
[{'text': "Based on my search, I found that LangGraph was launched in January 2023. It's described as a low-level orchestration framework for building agentic applications. Since its release, it has seen significant improvements, including a stable 0.1 release in June (presumably 2024). Let me now get human verification of this information:", 'type': 'text'}, {'id': 'toolu_016h3391yFhtPDhQvwjNgs7W', 'input': {'name': 'Information Verification', 'birthday': 'January 2023'}, 'name': 'human_assistance', 'type': 'tool_use'}]
Tool Calls:
human_assistance (toolu_016h3391yFhtPDhQvwjNgs7W)
Call ID: toolu_016h3391yFhtPDhQvwjNgs7W
Args:
name: Information Verification
birthday: January 2023
>_ Output
			
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')
Failed to send compressed multipart ingest: langsmith.utils.LangSmithError: Failed to POST https://eu.api.smith.langchain.com/runs/multipart in LangSmith API. HTTPError('403 Client Error: Forbidden for url: https://eu.api.smith.langchain.com/runs/multipart', '{"error":"Forbidden"} ')

Foi interrompido pelo interrupt na ferramenta human_assistance. Nesse caso, o chatbot, com a ferramenta de busca, determinou que a data do LangGraph é em janeiro de 2023, mas não é a data exata; é 17 de janeiro de 2024, então podemos inseri-la nós mesmos.

	
< > Input
Python
human_command = Command(
resume={
"name": "LangGraph",
"birthday": "Jan 17, 2024",
},
)
events = graph.stream(human_command, config, stream_mode="values")
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================== Ai Message ==================================
[{'text': "Based on my search, I found that LangGraph was launched in January 2023. It's described as a low-level orchestration framework for building agentic applications. Since its release, it has seen significant improvements, including a stable 0.1 release in June (presumably 2024). Let me now get human verification of this information:", 'type': 'text'}, {'id': 'toolu_016h3391yFhtPDhQvwjNgs7W', 'input': {'name': 'Information Verification', 'birthday': 'January 2023'}, 'name': 'human_assistance', 'type': 'tool_use'}]
Tool Calls:
human_assistance (toolu_016h3391yFhtPDhQvwjNgs7W)
Call ID: toolu_016h3391yFhtPDhQvwjNgs7W
Args:
name: Information Verification
birthday: January 2023
================================= Tool Message =================================
Name: human_assistance
Made a correction: {'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}
================================== Ai Message ==================================
Thank you for the expert correction! I need to update my response with the accurate information.
LangGraph was actually released on January 17, 2024 - not January 2023 as I initially found in my search results. This is a significant correction, as it means LangGraph is a much more recent framework than the search results indicated.
The expert has provided the specific date (January 17, 2024) for LangGraph's release, making it a fairly new tool in the AI orchestration ecosystem. This timing aligns better with the mention of its stable 0.1 release in June 2024, as this would be about 5 months after its initial launch.
	
< > Input
Python
snapshot = graph.get_state(config)
{k: v for k, v in snapshot.values.items() if k in ("name", "birthday")}
Copied
>_ Output
			
{'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}

Agora a data está correta graças à intervenção humana para modificar os valores do estado

Atualização manual do estadolink image 10

LangGraph fornece um alto grau de controle sobre o estado da aplicação. Por exemplo, em qualquer momento (mesmo quando é interrompido), podemos sobrescrever manualmente uma key do estado usando graph.update_state:

Vamos atualizar o name do estado para LangGraph (library).

	
< > Input
Python
graph.update_state(config, {"name": "LangGraph (library)"})
Copied
>_ Output
			
{'configurable': {'thread_id': '1',
'checkpoint_ns': '',
'checkpoint_id': '1f010a5a-8a70-618e-8006-89107653db68'}}

Se agora vemos o estado com graph.get_state(config) veremos que o name foi atualizado.

	
< > Input
Python
snapshot = graph.get_state(config)
{k: v for k, v in snapshot.values.items() if k in ("name", "birthday")}
Copied
>_ Output
			
{'name': 'LangGraph (library)', 'birthday': 'Jan 17, 2024'}

As atualizações manuais de estado gerarão um rastreamento em LangSmith. Elas podem ser usadas para controlar fluxos de trabalho de human in the loop, como pode ser visto neste guia.

Checkpointslink image 11

Em um fluxo de trabalho típico de um chatbot, o usuário interage com o chatbot uma ou mais vezes para realizar uma tarefa. Nas seções anteriores, vimos como adicionar memória e um human in the loop para poder verificar nosso estado de grafo e controlar as respostas futuras.

Mas, talvez um usuário queira começar a partir de uma resposta anterior e queira ramificar para explorar um resultado separado. Isso é útil para aplicações de agentes, quando um fluxo falha, eles podem voltar a um checkpoint anterior e testar outra estratégia.

LangGraph dá essa possibilidade por meio dos checkpoints

Primeiro, carregamos os valores das API KEYs

	
< > Input
Python
import os
import dotenv
dotenv.load_dotenv()
HUGGINGFACE_TOKEN = os.getenv("HUGGINGFACE_LANGGRAPH")
TAVILY_API_KEY = os.getenv("TAVILY_LANGGRAPH_API_KEY")
Copied

Criamos o novo estado

	
< > Input
Python
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
Copied

Agora criamos o grafo

	
< > Input
Python
from langgraph.graph import StateGraph, START, END
graph_builder = StateGraph(State)
Copied

Definimos a tool de busca

	
< > Input
Python
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper
from langchain_community.tools.tavily_search import TavilySearchResults
wrapper = TavilySearchAPIWrapper(tavily_api_key=TAVILY_API_KEY)
search_tool = TavilySearchResults(api_wrapper=wrapper, max_results=2)
Copied

Criamos uma lista de tools

	
< > Input
Python
tools_list = [search_tool]
Copied

A seguir, o LLM com as bind_tools e o adicionamos ao grafo

	
< > Input
Python
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from huggingface_hub import login
os.environ["LANGCHAIN_TRACING_V2"] = "false" # Disable LangSmith tracing
# Create the LLM
login(token=HUGGINGFACE_TOKEN)
MODEL = "Qwen/Qwen2.5-72B-Instruct"
model = HuggingFaceEndpoint(
repo_id=MODEL,
task="text-generation",
max_new_tokens=512,
do_sample=False,
repetition_penalty=1.03,
)
# Create the chat model
llm = ChatHuggingFace(llm=model)
# Modification: tell the LLM which tools it can call
llm_with_tools = llm.bind_tools(tools_list)
# Define the chatbot function
def chatbot_function(state: State):
message = llm_with_tools.invoke(state["messages"])
return {"messages": [message]}
# Add the chatbot node
graph_builder.add_node("chatbot_node", chatbot_function)
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x10d8ce7b0&gt;

Adicionamos a tool ao grafo

	
< > Input
Python
from langgraph.prebuilt import ToolNode, tools_condition
tool_node = ToolNode(tools=tools_list)
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges("chatbot_node", tools_condition)
graph_builder.add_edge("tools", "chatbot_node")
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x10d8ce7b0&gt;

Adicionamos o nó START ao grafo

	
< > Input
Python
graph_builder.add_edge(START, "chatbot_node")
Copied
>_ Output
			
&lt;langgraph.graph.state.StateGraph at 0x10d8ce7b0&gt;

Criamos um checkpointer MemorySaver.

	
< > Input
Python
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
Copied

Compilamos o grafo com o checkpointer

	
< > Input
Python
graph = graph_builder.compile(checkpointer=memory)
Copied

Nós o representamos graficamente

	
< > Input
Python
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception as e:
print(f"Error al visualizar el grafo: {e}")
Copied
>_ Output
			
&lt;IPython.core.display.Image object&gt;

Vamos fazer nosso grafo dar alguns passos. Cada passo será salvo no histórico do estado.

Fazemos a primeira chamada ao modelo

	
< > Input
Python
config = {"configurable": {"thread_id": "1"}}
user_input = (
"I'm learning LangGraph. "
"Could you do some research on it for me?"
)
events = graph.stream(
{"messages": [{"role": "user","content": user_input},],},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
I'm learning LangGraph. Could you do some research on it for me?
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangGraph Quickstart - GitHub Pages", "url": "https://langchain-ai.github.io/langgraph/tutorials/introduction/", "content": "[](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-9-1)Assistant: LangGraph is a library designed to help build stateful multi-agent applications using language models. It provides tools for creating workflows and state machines to coordinate multiple AI agents or language model interactions. LangGraph is built on top of LangChain, leveraging its components while adding graph-based coordination capabilities. It's particularly useful for developing more complex, [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-6) LangGraph is a library designed for building stateful, multi-actor applications with Large Language Models (LLMs). It's particularly useful for creating agent and multi-agent workflows. [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-7) [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-8)2. Developer: [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-19)LangGraph is likely a framework or library designed specifically for creating AI agents with advanced capabilities. Here are a few points to consider based on this recommendation: [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-20)", "score": 0.9328032}, {"title": "langchain-ai/langgraph: Build resilient language agents as graphs.", "url": "https://github.com/langchain-ai/langgraph", "content": "LangGraph — used by Replit, Uber, LinkedIn, GitLab and more — is a low-level orchestration framework for building controllable agents. While langchain provides integrations and composable components to streamline LLM application development, the LangGraph library enables agent orchestration — offering customizable architectures, long-term memory, and human-in-the-loop to reliably handle complex tasks. ``` pip install -U langgraph ```", "score": 0.8884594}]
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangGraph Quickstart - GitHub Pages", "url": "https://langchain-ai.github.io/langgraph/tutorials/introduction/", "content": "[](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-9-1)Assistant: LangGraph is a library designed to help build stateful multi-agent applications using language models. It provides tools for creating workflows and state machines to coordinate multiple AI agents or language model interactions. LangGraph is built on top of LangChain, leveraging its components while adding graph-based coordination capabilities. It's particularly useful for developing more complex, [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-6) LangGraph is a library designed for building stateful, multi-actor applications with Large Language Models (LLMs). It's particularly useful for creating agent and multi-agent workflows. [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-7) [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-8)2. Developer: [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-19)LangGraph is likely a framework or library designed specifically for creating AI agents with advanced capabilities. Here are a few points to consider based on this recommendation: [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-20)", "score": 0.9328032}, {"title": "langchain-ai/langgraph: Build resilient language agents as graphs.", "url": "https://github.com/langchain-ai/langgraph", "content": "LangGraph — used by Replit, Uber, LinkedIn, GitLab and more — is a low-level orchestration framework for building controllable agents. While langchain provides integrations and composable components to streamline LLM application development, the LangGraph library enables agent orchestration — offering customizable architectures, long-term memory, and human-in-the-loop to reliably handle complex tasks. ``` pip install -U langgraph ```", "score": 0.8884594}]
...
### Tutorials and Resources
- **Official Documentation**: The official LangGraph documentation is a comprehensive resource for learning about its features and usage.
- **Tutorials**: Look for tutorials and guides specifically focused on building AI agents with LangGraph. You can find a tutorial video [here](https://www.youtube.com/watch?v=gqvFmK7LpDo).
### Companies Using LangGraph
- **Replit, Uber, LinkedIn, GitLab, and more**: These companies are using LangGraph to build resilient and controllable language agents.
### Next Steps
1. **Review the Documentation**: Start by going through the official LangGraph documentation to get a deeper understanding of its features and capabilities.
2. **Follow Tutorials**: Watch tutorials and follow step-by-step guides to build your first multi-agent application.
3. **Experiment with Examples**: Try out the examples provided in the documentation to get hands-on experience with LangGraph.
If you have any specific questions or need further assistance, feel free to ask!

E agora a segunda chamada

	
< > Input
Python
user_input = (
"Ya that's helpful. Maybe I'll "
"build an autonomous agent with it!"
)
events = graph.stream(
{"messages": [{"role": "user","content": user_input},],},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Ya that's helpful. Maybe I'll build an autonomous agent with it!
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph tutorial build autonomous agent
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangGraph Tutorial: Building LLM Agents with LangChain's ... - Zep", "url": "https://www.getzep.com/ai-agents/langgraph-tutorial", "content": "This article focuses on building agents with LangGraph rather than LangChain. It provides a tutorial for building LangGraph agents, beginning with a discussion of LangGraph and its components. These concepts are reinforced by building a LangGraph agent from scratch and managing conversation memory with LangGraph agents. Finally, we use Zep's long-term memory for egents to create an agent that remembers previous conversations and user facts. ‍ Summary of key LangGraph tutorial concepts [...] human intervention, and the ability to handle complex workflows with cycles and branches. Building a LangGraph agent | Creating a LangGraph agent is the best way to understand the core concepts of nodes, edges, and state. The LangGraph Python libraries are modular and provide the functionality to build a stateful graph by incrementally adding nodes and edges.Incorporating tools enables an agent to perform specific tasks and access", "score": 0.8338803}, {"title": "Build Autonomous AI Agents with ReAct and LangGraph Tools", "url": "https://www.youtube.com/watch?v=ZfjaIshGkmk", "content": "LangGraph Intro - Build Autonomous AI Agents with ReAct and LangGraph Tools GrabDuck! 4110 subscribers 18 likes 535 views 21 Jan 2025 In this video, LangGraph Intro: Build Autonomous AI Agents with ReAct and LangGraph Tools, we dive into creating a powerful agentic system where the LLM decides when to trigger tools and when to finalize results. You’ll see how to build a generic agent architecture using the ReAct principle, applying it to real-world examples like analyzing Tesla stock data. [...] reasoning like what they're doing so uh it's this way you're using tool and this is another thing from longchain core library and here you define the function and then you have to Define name description there are other parameters like for example you can provide very specific description of all the parameters like why you need them which one are those Etc but it's a bit over complicated for this tutorial I'm skipping it and uh interesting thing this one return direct is false and this is uh [...] Whether you’re wondering how to create AI agents, looking for a LangGraph tutorial, or eager to explore the power of LangChain agents, this video is packed with valuable insights to help you get started. Support the channel while you shop on Amazon! Use my affiliate link https://amzn.to/4hssSvT Every purchase via this Amazon link helps keep our content free for you! 🌟 Related Courses &amp; Tutorials", "score": 0.8286204}]
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph tutorial build autonomous agent
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "LangGraph Tutorial: Building LLM Agents with LangChain's ... - Zep", "url": "https://www.getzep.com/ai-agents/langgraph-tutorial", "content": "This article focuses on building agents with LangGraph rather than LangChain. It provides a tutorial for building LangGraph agents, beginning with a discussion of LangGraph and its components. These concepts are reinforced by building a LangGraph agent from scratch and managing conversation memory with LangGraph agents. Finally, we use Zep's long-term memory for egents to create an agent that remembers previous conversations and user facts. ‍ Summary of key LangGraph tutorial concepts [...] human intervention, and the ability to handle complex workflows with cycles and branches. Building a LangGraph agent | Creating a LangGraph agent is the best way to understand the core concepts of nodes, edges, and state. The LangGraph Python libraries are modular and provide the functionality to build a stateful graph by incrementally adding nodes and edges.Incorporating tools enables an agent to perform specific tasks and access", "score": 0.8338803}, {"title": "Build Autonomous AI Agents with ReAct and LangGraph Tools", "url": "https://www.youtube.com/watch?v=ZfjaIshGkmk", "content": "LangGraph Intro - Build Autonomous AI Agents with ReAct and LangGraph Tools GrabDuck! 4110 subscribers 18 likes 535 views 21 Jan 2025 In this video, LangGraph Intro: Build Autonomous AI Agents with ReAct and LangGraph Tools, we dive into creating a powerful agentic system where the LLM decides when to trigger tools and when to finalize results. You’ll see how to build a generic agent architecture using the ReAct principle, applying it to real-world examples like analyzing Tesla stock data. [...] reasoning like what they're doing so uh it's this way you're using tool and this is another thing from longchain core library and here you define the function and then you have to Define name description there are other parameters like for example you can provide very specific description of all the parameters like why you need them which one are those Etc but it's a bit over complicated for this tutorial I'm skipping it and uh interesting thing this one return direct is false and this is uh [...] Whether you’re wondering how to create AI agents, looking for a LangGraph tutorial, or eager to explore the power of LangChain agents, this video is packed with valuable insights to help you get started. Support the channel while you shop on Amazon! Use my affiliate link https://amzn.to/4hssSvT Every purchase via this Amazon link helps keep our content free for you! 🌟 Related Courses &amp; Tutorials", "score": 0.8286204}]
...
Once you have the basic structure in place, you can enhance your agent with advanced features such as:
- **Long-term Memory**: Use external storage (e.g., Zep) to remember user conversations and preferences.
- **Conditional Edges**: Define conditions for transitions between nodes to handle different scenarios.
- **Human-in-the-Loop**: Allow human intervention for complex tasks or error handling.
### Additional Resources
- **Official Documentation**: [LangGraph Documentation](https://langchain-ai.github.io/langgraph/tutorials/introduction/)
- **Comprehensive Guide**: [LangGraph Tutorial for Beginners](https://blog.futuresmart.ai/langgraph-tutorial-for-beginners)
- **Example Project**: [Building AI Agents with LangGraph](https://medium.com/@lorevanoudenhove/how-to-build-ai-agents-with-langgraph-a-step-by-step-guide-5d84d9c7e832)
### Conclusion
By following these steps, you can build a robust and flexible AI agent using LangGraph. Start with simple examples and gradually add more complex features to create powerful, stateful, and multi-actor applications. Happy coding!

Agora que fizemos duas chamadas ao modelo, vamos ver o histórico do estado.

	
< > Input
Python
to_replay = None
for state in graph.get_state_history(config):
print(f"Num Messages: {len(state.values["messages"])}, Next: {state.next}, checkpoint id = {state.config["configurable"]['checkpoint_id']}")
print("-" * 80)
# Get state when first iteracction us done
if len(state.next) == 0:
to_replay = state
Copied
>_ Output
			
Num Messages: 24, Next: (), checkpoint id = 1f027f2f-e5b4-6c84-8018-9fcb33b5f397
--------------------------------------------------------------------------------
Num Messages: 23, Next: ('chatbot_node',), checkpoint id = 1f027f2f-e414-6b0e-8017-3ad465b70767
--------------------------------------------------------------------------------
Num Messages: 22, Next: ('tools',), checkpoint id = 1f027f2f-d382-6692-8016-fcfaf9c9a9f7
--------------------------------------------------------------------------------
Num Messages: 21, Next: ('chatbot_node',), checkpoint id = 1f027f2f-d1cf-6930-8015-f64aa0e6f750
--------------------------------------------------------------------------------
Num Messages: 20, Next: ('tools',), checkpoint id = 1f027f2f-bca9-6164-8014-86452cb10d83
--------------------------------------------------------------------------------
Num Messages: 19, Next: ('chatbot_node',), checkpoint id = 1f027f2f-bac1-6d24-8013-b539f3e4cedb
--------------------------------------------------------------------------------
Num Messages: 18, Next: ('tools',), checkpoint id = 1f027f2f-aa0e-69fa-8012-4ca2d9109f4e
--------------------------------------------------------------------------------
Num Messages: 17, Next: ('chatbot_node',), checkpoint id = 1f027f2f-a861-62c4-8011-5707badab130
--------------------------------------------------------------------------------
Num Messages: 16, Next: ('tools',), checkpoint id = 1f027f2f-93cf-6112-8010-ee536e76cdf7
--------------------------------------------------------------------------------
Num Messages: 15, Next: ('chatbot_node',), checkpoint id = 1f027f2f-91f5-63fa-800f-6ff45b0ebf86
--------------------------------------------------------------------------------
...
Num Messages: 4, Next: ('tools',), checkpoint id = 1f027f2c-627b-6f6e-8003-22208fac7c89
--------------------------------------------------------------------------------
Num Messages: 3, Next: ('chatbot_node',), checkpoint id = 1f027f2c-6122-6190-8002-b745c42a724e
--------------------------------------------------------------------------------
Num Messages: 2, Next: ('tools',), checkpoint id = 1f027f2c-4c4c-6720-8001-8a1c73b894c1
--------------------------------------------------------------------------------
Num Messages: 1, Next: ('chatbot_node',), checkpoint id = 1f027f2c-4a91-6278-8000-56b65f6d77cd
--------------------------------------------------------------------------------
Num Messages: 0, Next: ('__start__',), checkpoint id = 1f027f2c-4a8d-6a1a-bfff-2f7cbde97290
--------------------------------------------------------------------------------

Guardamos em to_replay o estado do grafo quando recebemos a primeira resposta, justamente antes de introduzir a segunda mensagem. Podemos voltar a um estado passado e continuar o fluxo a partir daí.

A configuração do checkpoint contém o checkpoint_id, que é um timestamp do fluxo. Podemos vê-lo para verificar que estamos no estado em que queremos estar.

	
< > Input
Python
print(to_replay.config)
Copied
>_ Output
			
{'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f027f2c-8873-61d6-8007-8a1c60438002'}}

Se olharmos para a lista de estados anterior, vemos que o ID coincide com o momento de introduzir a segunda mensagem

Dando este checkpoint_id ao LangGraph carrega o estado naquele momento do fluxo. Assim, criamos uma nova mensagem e a passamos ao grafo

	
< > Input
Python
user_input = (
"Thanks"
)
# The `checkpoint_id` in the `to_replay.config` corresponds to a state we've persisted to our checkpointer.
events = graph.stream({"messages": [{"role": "user","content": user_input},],},
to_replay.config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Thanks
================================== Ai Message ==================================
You're welcome! If you have any more questions about LangGraph or any other topics, feel free to ask. Happy learning! 🚀
	
< > Input
Python
for state in graph.get_state_history(config):
print(f"Num Messages: {len(state.values["messages"])}, Next: {state.next}, checkpoint id = {state.config["configurable"]['checkpoint_id']}")
print("-" * 80)
Copied
>_ Output
			
Num Messages: 10, Next: (), checkpoint id = 1f027f43-71ae-67e0-800a-d84a557441fc
--------------------------------------------------------------------------------
Num Messages: 9, Next: ('chatbot_node',), checkpoint id = 1f027f43-5b1f-6ad8-8009-34f409789bc4
--------------------------------------------------------------------------------
Num Messages: 8, Next: ('__start__',), checkpoint id = 1f027f43-5b1b-68a2-8008-fbbcbd1c175e
--------------------------------------------------------------------------------
Num Messages: 24, Next: (), checkpoint id = 1f027f2f-e5b4-6c84-8018-9fcb33b5f397
--------------------------------------------------------------------------------
Num Messages: 23, Next: ('chatbot_node',), checkpoint id = 1f027f2f-e414-6b0e-8017-3ad465b70767
--------------------------------------------------------------------------------
Num Messages: 22, Next: ('tools',), checkpoint id = 1f027f2f-d382-6692-8016-fcfaf9c9a9f7
--------------------------------------------------------------------------------
Num Messages: 21, Next: ('chatbot_node',), checkpoint id = 1f027f2f-d1cf-6930-8015-f64aa0e6f750
--------------------------------------------------------------------------------
Num Messages: 20, Next: ('tools',), checkpoint id = 1f027f2f-bca9-6164-8014-86452cb10d83
--------------------------------------------------------------------------------
Num Messages: 19, Next: ('chatbot_node',), checkpoint id = 1f027f2f-bac1-6d24-8013-b539f3e4cedb
--------------------------------------------------------------------------------
Num Messages: 18, Next: ('tools',), checkpoint id = 1f027f2f-aa0e-69fa-8012-4ca2d9109f4e
--------------------------------------------------------------------------------
...
Num Messages: 4, Next: ('tools',), checkpoint id = 1f027f2c-627b-6f6e-8003-22208fac7c89
--------------------------------------------------------------------------------
Num Messages: 3, Next: ('chatbot_node',), checkpoint id = 1f027f2c-6122-6190-8002-b745c42a724e
--------------------------------------------------------------------------------
Num Messages: 2, Next: ('tools',), checkpoint id = 1f027f2c-4c4c-6720-8001-8a1c73b894c1
--------------------------------------------------------------------------------
Num Messages: 1, Next: ('chatbot_node',), checkpoint id = 1f027f2c-4a91-6278-8000-56b65f6d77cd
--------------------------------------------------------------------------------
Num Messages: 0, Next: ('__start__',), checkpoint id = 1f027f2c-4a8d-6a1a-bfff-2f7cbde97290
--------------------------------------------------------------------------------

Podemos ver no histórico que o grafo executou tudo o que fizemos primeiro, mas depois sobrescreveu o histórico e voltou a executar a partir de um ponto anterior

Escrevo novamente todo o grafo junto

	
< > Input
Python
import os
import dotenv
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import MemorySaver
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
from huggingface_hub import login
os.environ["LANGCHAIN_TRACING_V2"] = "false" # Disable LangSmith tracing
from IPython.display import Image, display
class State(TypedDict):
messages: Annotated[list, add_messages]
dotenv.load_dotenv()
HUGGINGFACE_TOKEN = os.getenv("HUGGINGFACE_LANGGRAPH")
TAVILY_API_KEY = os.getenv("TAVILY_LANGGRAPH_API_KEY")
# Tools
wrapper = TavilySearchAPIWrapper(tavily_api_key=TAVILY_API_KEY)
search_tool = TavilySearchResults(api_wrapper=wrapper, max_results=2)
tools_list = [search_tool]
tool_node = ToolNode(tools=tools_list)
# Create the LLM
login(token=HUGGINGFACE_TOKEN)
MODEL = "Qwen/Qwen2.5-72B-Instruct"
model = HuggingFaceEndpoint(
repo_id=MODEL,
task="text-generation",
max_new_tokens=512,
do_sample=False,
repetition_penalty=1.03,
)
# Create the chat model
llm = ChatHuggingFace(llm=model)
# Modification: tell the LLM which tools it can call
llm_with_tools = llm.bind_tools(tools_list)
# Define the chatbot function
def chatbot_function(state: State):
message = llm_with_tools.invoke(state["messages"])
return {"messages": [message]}
# Create the graph
graph_builder = StateGraph(State)
# Add nodes
graph_builder.add_node("chatbot_node", chatbot_function)
graph_builder.add_node("tools", tool_node)
graph_builder.add_edge("tools", "chatbot_node")
# Add edges
graph_builder.add_edge(START, "chatbot_node")
graph_builder.add_conditional_edges("chatbot_node", tools_condition)
# Add checkpointer
memory = MemorySaver()
# Compile
graph = graph_builder.compile(checkpointer=memory)
# Visualize
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception as e:
print(f"Error al visualizar el grafo: {e}")
Copied
>_ Output
			
Error al visualizar el grafo: Failed to reach https://mermaid.ink/ API while trying to render your graph after 1 retries. To resolve this issue:
1. Check your internet connection and try again
2. Try with higher retry settings: `draw_mermaid_png(..., max_retries=5, retry_delay=2.0)`
3. Use the Pyppeteer rendering method which will render your graph locally in a browser: `draw_mermaid_png(..., draw_method=MermaidDrawMethod.PYPPETEER)`

Fazemos a primeira chamada ao modelo

	
< > Input
Python
config = {"configurable": {"thread_id": "1"}}
user_input = (
"I'm learning LangGraph. "
"Could you do some research on it for me?"
)
events = graph.stream(
{"messages": [{"role": "user","content": user_input},],},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
I'm learning LangGraph. Could you do some research on it for me?
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "What is LangGraph? - IBM", "url": "https://www.ibm.com/think/topics/langgraph", "content": "LangGraph, created by LangChain, is an open source AI agent framework designed to build, deploy and manage complex generative AI agent workflows. It provides a set of tools and libraries that enable users to create, run and optimize large language models (LLMs) in a scalable and efficient manner. At its core, LangGraph uses the power of graph-based architectures to model and manage the intricate relationships between various components of an AI agent workflow. [...] Agent systems: LangGraph provides a framework for building agent-based systems, which can be used in applications such as robotics, autonomous vehicles or video games. LLM applications: By using LangGraph’s capabilities, developers can build more sophisticated AI models that learn and improve over time. Norwegian Cruise Line uses LangGraph to compile, construct and refine guest-facing AI solutions. This capability allows for improved and personalized guest experiences. [...] By using a graph-based architecture, LangGraph enables users to scale artificial intelligence workflows without slowing down or sacrificing efficiency. LangGraph uses enhanced decision-making by modeling complex relationships between nodes, which means it uses AI agents to analyze their past actions and feedback. In the world of LLMs, this process is referred to as reflection.", "score": 0.9353998}, {"title": "LangGraph Quickstart - GitHub Pages", "url": "https://langchain-ai.github.io/langgraph/tutorials/introduction/", "content": "[](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-9-1)Assistant: LangGraph is a library designed to help build stateful multi-agent applications using language models. It provides tools for creating workflows and state machines to coordinate multiple AI agents or language model interactions. LangGraph is built on top of LangChain, leveraging its components while adding graph-based coordination capabilities. It's particularly useful for developing more complex, [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-6) LangGraph is a library designed for building stateful, multi-actor applications with Large Language Models (LLMs). It's particularly useful for creating agent and multi-agent workflows. [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-7) [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-8)2. Developer: [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-19)LangGraph is likely a framework or library designed specifically for creating AI agents with advanced capabilities. Here are a few points to consider based on this recommendation: [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-20)", "score": 0.9328032}]
================================== Ai Message ==================================
Tool Calls:
tavily_search_results_json (0)
Call ID: 0
Args:
query: LangGraph
================================= Tool Message =================================
Name: tavily_search_results_json
[{"title": "What is LangGraph? - IBM", "url": "https://www.ibm.com/think/topics/langgraph", "content": "LangGraph, created by LangChain, is an open source AI agent framework designed to build, deploy and manage complex generative AI agent workflows. It provides a set of tools and libraries that enable users to create, run and optimize large language models (LLMs) in a scalable and efficient manner. At its core, LangGraph uses the power of graph-based architectures to model and manage the intricate relationships between various components of an AI agent workflow. [...] Agent systems: LangGraph provides a framework for building agent-based systems, which can be used in applications such as robotics, autonomous vehicles or video games. LLM applications: By using LangGraph’s capabilities, developers can build more sophisticated AI models that learn and improve over time. Norwegian Cruise Line uses LangGraph to compile, construct and refine guest-facing AI solutions. This capability allows for improved and personalized guest experiences. [...] By using a graph-based architecture, LangGraph enables users to scale artificial intelligence workflows without slowing down or sacrificing efficiency. LangGraph uses enhanced decision-making by modeling complex relationships between nodes, which means it uses AI agents to analyze their past actions and feedback. In the world of LLMs, this process is referred to as reflection.", "score": 0.9353998}, {"title": "LangGraph Quickstart - GitHub Pages", "url": "https://langchain-ai.github.io/langgraph/tutorials/introduction/", "content": "[](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-9-1)Assistant: LangGraph is a library designed to help build stateful multi-agent applications using language models. It provides tools for creating workflows and state machines to coordinate multiple AI agents or language model interactions. LangGraph is built on top of LangChain, leveraging its components while adding graph-based coordination capabilities. It's particularly useful for developing more complex, [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-6) LangGraph is a library designed for building stateful, multi-actor applications with Large Language Models (LLMs). It's particularly useful for creating agent and multi-agent workflows. [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-7) [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-21-8)2. Developer: [...] [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-19)LangGraph is likely a framework or library designed specifically for creating AI agents with advanced capabilities. Here are a few points to consider based on this recommendation: [](https://langchain-ai.github.io/langgraph/tutorials/introduction/#__codelineno-48-20)", "score": 0.9328032}]
================================== Ai Message ==================================
LangGraph is an open-source AI agent framework developed by LangChain, designed to build, deploy, and manage complex generative AI agent workflows. Here are some key points about LangGraph:
### Overview
- **Purpose**: LangGraph is aimed at creating, running, and optimizing large language models (LLMs) in a scalable and efficient manner.
- **Graph-Based Architecture**: It uses graph-based architectures to model and manage the intricate relationships between various components of an AI agent workflow.
### Features
- **Agent Systems**: LangGraph provides a framework for building agent-based systems, which can be used in applications such as robotics, autonomous vehicles, or video games.
- **LLM Applications**: Developers can build more sophisticated AI models that learn and improve over time. For example, Norwegian Cruise Line uses LangGraph to compile, construct, and refine guest-facing AI solutions, enhancing personalized guest experiences.
- **Scalability**: By using a graph-based architecture, LangGraph enables users to scale artificial intelligence workflows without sacrificing efficiency.
- **Enhanced Decision-Making**: LangGraph uses AI agents to analyze their past actions and feedback, a process referred to as "reflection" in the context of LLMs.
### Developer Resources
- **Quickstart Guide**: The LangGraph Quickstart guide on GitHub provides a detailed introduction to building stateful multi-agent applications using language models. It covers tools for creating workflows and state machines to coordinate multiple AI agents or language model interactions.
- **Built on LangChain**: LangGraph is built on top of LangChain, leveraging its components while adding graph-based coordination capabilities. This makes it particularly useful for developing more complex, stateful, multi-actor applications with LLMs.
### Further Reading
- **What is LangGraph? - IBM**: [Link](https://www.ibm.com/think/topics/langgraph)
- **LangGraph Quickstart - GitHub Pages**: [Link](https://langchain-ai.github.io/langgraph/tutorials/introduction/)
These resources should provide a solid foundation for understanding and getting started with LangGraph. If you have any specific questions or need further details, feel free to ask!

E agora a segunda chamada

	
< > Input
Python
user_input = (
"Ya that's helpful. Maybe I'll "
"build an autonomous agent with it!"
)
events = graph.stream(
{"messages": [{"role": "user","content": user_input},],},
config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Ya that's helpful. Maybe I'll build an autonomous agent with it!
================================== Ai Message ==================================
That sounds like an exciting project! Building an autonomous agent using LangGraph can be a rewarding experience. Here are some steps and tips to help you get started:
### 1. **Understand the Basics of LangGraph**
- **Read the Documentation**: Start with the official LangGraph documentation and quickstart guide. This will give you a solid understanding of the framework's capabilities and how to use its tools.
- **Quickstart Guide**: [LangGraph Quickstart - GitHub Pages](https://langchain-ai.github.io/langgraph/tutorials/introduction/)
### 2. **Set Up Your Development Environment**
- **Install LangChain and LangGraph**: Ensure you have the necessary dependencies installed. LangGraph is built on top of LangChain, so you'll need to set up both.
```bash
pip install langchain langgraph
```
### 3. **Define Your Agent's Objectives**
- **Identify the Use Case**: What specific tasks do you want your autonomous agent to perform? This could be anything from navigating a virtual environment, responding to user queries, or managing a robotic system.
- **Define the State and Actions**: Determine the states your agent can be in and the actions it can take. This will help you design the state machine and workflows.
### 4. **Design the Graph-Based Workflow**
- **Create Nodes and Edges**: In LangGraph, you'll define nodes (agents or components) and edges (interactions or transitions). Each node can represent a different part of your agent's functionality.
- **Define State Transitions**: Use the graph-based architecture to define how the agent transitions between different states based on actions and events.
### 5. **Implement the Agent**
- **Write the Code**: Start coding your agent using the LangGraph library. You can use the provided tools to create and manage the agent's workflows.
...
- **Deploy the Agent**: Once you are satisfied with the performance, you can deploy your agent in the real world or a production environment.
- **Monitor and Maintain**: Continuously monitor the agent's performance and make adjustments as needed. Use feedback loops to improve the agent over time.
### 8. **Community and Support**
- **Join the Community**: Engage with the LangChain and LangGraph community. You can find support, share ideas, and get feedback from other developers.
- **GitHub**: [LangGraph GitHub](https://github.com/langchain-ai/langgraph)
- **Forums and Discussion Boards**: Check out forums and discussion boards related to LangGraph and LangChain.
### Additional Resources
- **Tutorials and Examples**: Look for tutorials and example projects to get more hands-on experience.
- **Research Papers and Articles**: Read research papers and articles to deepen your understanding of AI agent design and graph-based architectures.
Good luck with your project! If you have any specific questions or need further guidance, feel free to ask.

Vemos o historial do estado

	
< > Input
Python
to_replay = None
for state in graph.get_state_history(config):
print(f"Num Messages: {len(state.values["messages"])}, Next: {state.next}, checkpoint id = {state.config["configurable"]['checkpoint_id']}")
print("-" * 80)
# Get state when first iteracction us done
if len(state.next) == 0:
to_replay = state
Copied
>_ Output
			
Num Messages: 8, Next: (), checkpoint id = 1f03263e-a96c-6446-8008-d2c11df0b6cb
--------------------------------------------------------------------------------
Num Messages: 7, Next: ('chatbot_node',), checkpoint id = 1f03263d-7a35-6660-8007-a37d4b584c88
--------------------------------------------------------------------------------
Num Messages: 6, Next: ('__start__',), checkpoint id = 1f03263d-7a32-624e-8006-6509bbf32ebe
--------------------------------------------------------------------------------
Num Messages: 6, Next: (), checkpoint id = 1f03263d-7a1a-6f36-8005-f10b5d83f22c
--------------------------------------------------------------------------------
Num Messages: 5, Next: ('chatbot_node',), checkpoint id = 1f03263c-c53f-6666-8004-c6d35868dd73
--------------------------------------------------------------------------------
Num Messages: 4, Next: ('tools',), checkpoint id = 1f03263c-b14b-68f8-8003-28558fa38dbc
--------------------------------------------------------------------------------
Num Messages: 3, Next: ('chatbot_node',), checkpoint id = 1f03263c-a66b-6276-8002-2dc89fca4d99
--------------------------------------------------------------------------------
Num Messages: 2, Next: ('tools',), checkpoint id = 1f03263c-8c7c-68ec-8001-fb8a9aa300b0
--------------------------------------------------------------------------------
Num Messages: 1, Next: ('chatbot_node',), checkpoint id = 1f03263c-6d06-68d2-8000-ced2e7b8538f
--------------------------------------------------------------------------------
Num Messages: 0, Next: ('__start__',), checkpoint id = 1f03263c-6cdb-63e4-bfff-c644b57cee28
--------------------------------------------------------------------------------
	
< > Input
Python
print(to_replay.config)
Copied
>_ Output
			
{'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f03263d-7a1a-6f36-8005-f10b5d83f22c'}}

Dando este checkpoint_id ao LangGraph, carrega o estado naquele momento do fluxo. Assim, criamos uma nova mensagem e a passamos ao grafo

	
< > Input
Python
user_input = (
"Thanks"
)
# The `checkpoint_id` in the `to_replay.config` corresponds to a state we've persisted to our checkpointer.
events = graph.stream({"messages": [{"role": "user","content": user_input},],},
to_replay.config,
stream_mode="values",
)
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()
Copied
>_ Output
			
================================ Human Message =================================
Thanks
================================== Ai Message ==================================
You're welcome! If you have any more questions about LangGraph or any other topic, feel free to reach out. Happy learning! 😊
	
< > Input
Python
for state in graph.get_state_history(config):
print(f"Num Messages: {len(state.values["messages"])}, Next: {state.next}, checkpoint id = {state.config["configurable"]['checkpoint_id']}")
print("-" * 80)
Copied
>_ Output
			
Num Messages: 8, Next: (), checkpoint id = 1f03263f-fcb9-63a0-8008-e8c4a3fb44f9
--------------------------------------------------------------------------------
Num Messages: 7, Next: ('chatbot_node',), checkpoint id = 1f03263f-eb3b-663c-8007-72da4d16bf64
--------------------------------------------------------------------------------
Num Messages: 6, Next: ('__start__',), checkpoint id = 1f03263f-eb36-6ac4-8006-a2333805d5d6
--------------------------------------------------------------------------------
Num Messages: 8, Next: (), checkpoint id = 1f03263e-a96c-6446-8008-d2c11df0b6cb
--------------------------------------------------------------------------------
Num Messages: 7, Next: ('chatbot_node',), checkpoint id = 1f03263d-7a35-6660-8007-a37d4b584c88
--------------------------------------------------------------------------------
Num Messages: 6, Next: ('__start__',), checkpoint id = 1f03263d-7a32-624e-8006-6509bbf32ebe
--------------------------------------------------------------------------------
Num Messages: 6, Next: (), checkpoint id = 1f03263d-7a1a-6f36-8005-f10b5d83f22c
--------------------------------------------------------------------------------
Num Messages: 5, Next: ('chatbot_node',), checkpoint id = 1f03263c-c53f-6666-8004-c6d35868dd73
--------------------------------------------------------------------------------
Num Messages: 4, Next: ('tools',), checkpoint id = 1f03263c-b14b-68f8-8003-28558fa38dbc
--------------------------------------------------------------------------------
Num Messages: 3, Next: ('chatbot_node',), checkpoint id = 1f03263c-a66b-6276-8002-2dc89fca4d99
--------------------------------------------------------------------------------
Num Messages: 2, Next: ('tools',), checkpoint id = 1f03263c-8c7c-68ec-8001-fb8a9aa300b0
--------------------------------------------------------------------------------
Num Messages: 1, Next: ('chatbot_node',), checkpoint id = 1f03263c-6d06-68d2-8000-ced2e7b8538f
--------------------------------------------------------------------------------
Num Messages: 0, Next: ('__start__',), checkpoint id = 1f03263c-6cdb-63e4-bfff-c644b57cee28
--------------------------------------------------------------------------------

---

🎉 **Você concluiu o _Guia completo de LangGraph_.** Revise os capítulos: Parte 1 · Parte 2 · Parte 3.

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Gymnasia

Gymnasia Gymnasia
React Native
Expo
TypeScript
FastAPI
Next.js
OpenAI
Anthropic

Aplicativo móvel de treino pessoal com assistente de IA, biblioteca de exercícios, acompanhamento de rotinas, dieta e medidas corporais

Horeca chatbot

Horeca chatbot Horeca chatbot
Python
LangChain
PostgreSQL
PGVector
React
Kubernetes
Docker
GitHub Actions

Chatbot conversacional para cozinheiros de hotéis e restaurantes. Um cozinheiro, gerente de cozinha ou serviço de quarto de um hotel ou restaurante pode falar com o chatbot para obter informações sobre receitas e menus. Mas também implementa agentes, com os quais pode editar ou criar novas receitas ou menus

Naviground

Naviground Naviground
Ver todos os projetos -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Quer assistir alguma palestra?

Últimas palestras -->

Quer melhorar com essas dicas?

Últimos tips -->

Use isso localmente

Os espaços do Hugging Face nos permitem executar modelos com demos muito simples, mas e se a demo quebrar? Ou se o usuário a deletar? Por isso, criei contêineres docker com alguns espaços interessantes, para poder usá-los localmente, aconteça o que acontecer. Na verdade, se você clicar em qualquer botão de visualização de projeto, ele pode levá-lo a um espaço que não funciona.

Flow edit

Flow edit Flow edit

Edite imagens com este modelo de Flow. Baseado em SD3 ou FLUX, você pode editar qualquer imagem e gerar novas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
Ver todos os contêineres -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Você quer treinar seu modelo com esses datasets?

short-jokes-dataset

HuggingFace

Dataset com piadas em inglês

Uso: Fine-tuning de modelos de geração de texto humorístico

231K linhas 2 colunas 45 MB
Ver no HuggingFace →

opus100

HuggingFace

Dataset com traduções de inglês para espanhol

Uso: Treinamento de modelos de tradução inglês-espanhol

1M linhas 2 colunas 210 MB
Ver no HuggingFace →

netflix_titles

HuggingFace

Dataset com filmes e séries da Netflix

Uso: Análise de catálogo Netflix e sistemas de recomendação

8.8K linhas 12 colunas 3.5 MB
Ver no HuggingFace →
Ver mais datasets -->