1
resposta

[Projeto] persistência e streaming

Instalação e Atualização das Dependências

pip install -U langgraph langchain langchain-google-genai tavily-python python-dotenv
2️ Configurando Persistência com SQLiteSaver

O SQLiteSaver permite que o estado do agente seja salvo no banco SQLite, garantindo memória persistente entre execuções.

import os from dotenv import load_dotenv from langgraph.checkpoint.sqlite import SqliteSaver load_dotenv ( ) # Banco persistente memory = SqliteSaver.from_conn_string ( " sqlite:///memoria_agente.db " )

Agora o agente pode salvar e recuperar o contexto automaticamente.

3️ Criando o Estado do Agente
from typing import Annotated , TypedDict from langgraph.graph import add_messages class AgentState ( TypedDict ) : messages : Annotated [ list , add_messages ]​

Esse estado será persistido no SQLite.

4️ Configurando o LLM (Gêmeos)
from langchain_google_genai import ChatGoogleGenerativeAI llm = ChatGoogleGenerativeAI ( model = "gemini-1.5-flash" , temperature = 0 )

5️ Integração com Tavily Search
from tavily import TavilyClient from langchain.tools import tool TAVILY_API_KEY = os.getenv ( "TAVILY_API_KEY" ) tavily = TavilyClient ( api_key = TAVILY_API_KEY ) @tool def tavily_search ( query : str ) -> str : " " " Realiza busca na internet usando Tavily""" response = tavily.search ( query = query , search_depth = " basic" , max_results = 3 ) return str ( response [ "results" ] )

6️ Estruturando o Gráfico
from langgraph.graph import StateGraph , END from langgraph.prebuilt import ToolNode from langgraph.prebuilt import create_react_agent tools = [ tavily_search ] # Criando agente ReAct agent = create_react_agent ( model = llm , tools = tools ) builder = StateGraph ( AgentState ) builder.add_node ( " agent " , agent ) builder.add_node ( " tools " , ToolNode ( tools ) ) builder.set_entry_point ( " agent " )

7️ Arestas Condicionais
def route_tools ( state ): last_message = state [ " messages" ][ - 1 ] if getattr ( last_message , "tool_calls" , None ): return " tools" return END builder.add_conditional_edges ( "agent" , route_tools , { "tools" : "tools" , END : END } ) builder.add_edge ( "tools" , "agent" )

8️ Compilando com Persistência

Aqui está o ponto principal da aula:

gráfico = construtor.compilar ( ponto de verificação = memória )

Agora o estado fica salvo no SQLite.

9️ Implementando Streaming

O streaming permite acompanhar o julgamento passo a passo.

config = { "configurable" : { "thread_id" : "usuario_1" }} para evento no gráfico . stream( { "messages" : [( "user" , "Qual a previsão do tempo em Recife hoje?" )]}, config = config , ): print ( event )

Mantendo Contexto com Threads

O segredo está no thread_id.

config = {"configurable": {"thread_id": "usuario_1"}}

Primeira pergunta

graph.invoke(
{"messages": [("user", "Quem é o presidente do Brasil?")]},
config=config
)

Segunda pergunta mantendo contexto

response = graph.invoke(
{"messages": [("user", "Qual a idade dele?")]},
config=config
)

print(response["messages"][-1].content)

Mesmo sendo outra chamada, o agente lembra do contexto anterior porque:

O estado foi salvo no SQLite
O mesmo thread_id foi utilizado

Streaming interrupted. Waiting for the complete message...

1 resposta

Olá, Moacir! Tudo bem?

Parabéns pela conclusão da atividade e por compartilhar esse super resumo com a comunidade! A forma como você dividiu o processo em 9 passos transformou a sua resolução em um verdadeiro tutorial. Você capturou perfeitamente a essência do LangGraph: usar o checkpointer (neste caso, o SQLiteSaver) atrelado a um thread_id para garantir que o agente não sofra de "amnésia" entre as interações.

A lógica da sua montagem do grafo, definição de estado e uso das arestas condicionais (ToolNode) está impecável!

GBons estudos!

Sucesso

Imagem da comunidade