Ato 2: A Construção
"Você aprendeu a falar com a IA. Agora, você vai dar a ela mãos para agir e uma mente para lembrar. Este é o momento em que passamos de meros conversadores a verdadeiros construtores de aplicações. Com LangChain, você não está mais limitado a uma única interação; você está construindo sistemas inteligentes e persistentes."
Bem-vindo à oficina do Engenheiro de Agentes. Se os LLMs são o motor e os prompts são o volante, LangChain é o chassi, o sistema de transmissão e todo o conjunto que transforma um motor potente em um veículo funcional.
Este framework de código aberto nos dá os blocos de construção para criar aplicações de IA que vão muito além de um simples chatbot. Vamos aprender a:
- Dar memória aos nossos agentes
- Conectá-los a fontes de dados externas
- Criar cadeias de raciocínio complexas
- Orquestrar múltiplos modelos e ferramentas
Capítulo 3.1: A Arquitetura LangChain
O Problema que LangChain Resolve
Imagine que você precisa construir um assistente de IA que:
- Responde perguntas sobre documentos da sua empresa
- Lembra conversas anteriores
- Pode buscar informações na web quando necessário
- Consulta um banco de dados SQL
- Envia emails automaticamente
Sem um framework, você teria que:
- Escrever código personalizado para cada integração
- Gerenciar manualmente o estado e a memória
- Implementar lógica complexa de orquestração
- Lidar com diferentes formatos de API
- Debugar fluxos de dados entre componentes
Filosofia de Design
LangChain segue princípios fundamentais:
- Modularidade: Cada componente é independente e intercambiável
- Composabilidade: Componentes simples se combinam para criar sistemas complexos
- Abstração: Interfaces unificadas para diferentes provedores e serviços
- Extensibilidade: Fácil criar componentes customizados
Os 6 Pilares da Arquitetura LangChain
1. Models (Modelos)
Interface unificada para diferentes LLMs:
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_community.llms import Ollama
# Todos usam a mesma interface!
llm_openai = ChatOpenAI(model="gpt-4")
llm_claude = ChatAnthropic(model="claude-3-sonnet")
llm_local = Ollama(model="llama3")
# Trocar de modelo = trocar 1 linha de código
Tipos de modelos suportados:
- Chat Models: Conversacional (ChatGPT, Claude, etc.)
- LLMs: Completion-style (GPT-3, etc.)
- Text Embedding Models: Para criar vetores
- Multimodal Models: Visão + Texto
2. Prompts
Gerenciamento avançado de prompts:
from langchain.prompts import PromptTemplate, ChatPromptTemplate
# Template simples
template = PromptTemplate(
input_variables=["produto", "publico"],
template="""
Crie um slogan de marketing para {produto}
direcionado a {publico}.
"""
)
# Chat template (com papéis)
chat_template = ChatPromptTemplate.from_messages([
("system", "Você é um especialista em {dominio}"),
("human", "{pergunta}"),
("ai", "{resposta_parcial}"),
("human", "Continue...")
])
Recursos avançados:
- Few-shot example selectors
- Conditional prompting
- Prompt composition
- Versioning e A/B testing
3. Chains
Sequências de operações:
from langchain.chains import LLMChain
chain = LLMChain(
llm=llm,
prompt=template
)
resultado = chain.run(
produto="Tênis de corrida",
publico="atletas profissionais"
)
Tipos de Chains:
LLMChain: Chain básica (LLM + Prompt)SequentialChain: Encadeia múltiplas chainsTransformChain: Transforma dados entre chainsRouterChain: Direciona para chains específicasMapReduceChain: Processa documentos em paralelo
4. Agents
LLM como motor de decisão:
from langchain.agents import create_react_agent, AgentExecutor
from langchain.tools import Tool
tools = [
Tool(
name="Calculator",
func=calculator_function,
description="Útil para cálculos matemáticos"
),
Tool(
name="Search",
func=search_function,
description="Busca informações na web"
)
]
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
executor.invoke({"input": "Qual é a raiz quadrada de 144?"})
5. Memory
Memória conversacional:
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
# Armazena automaticamente histórico
memory.save_context(
{"input": "Oi, meu nome é João"},
{"output": "Olá João! Como posso ajudar?"}
)
# Recupera contexto
memory.load_memory_variables({})
# {'history': 'Human: Oi, meu nome é João\nAI: Olá João!...'}
Tipos de Memory:
ConversationBufferMemory: Guarda tudoConversationBufferWindowMemory: Últimas N mensagensConversationSummaryMemory: Resume conversas longasConversationKGMemory: Extrai knowledge graph
6. Tools
Conexão com o mundo externo:
from langchain.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
wikipedia = WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper()
)
resultado = wikipedia.run("Inteligência Artificial")
Categorias de Tools:
- Search: Google, Bing, DuckDuckGo
- APIs: Weather, News, Finance
- Databases: SQL, MongoDB, Redis
- Files: PDF, CSV, JSON
- Custom: Suas próprias funções
Capítulo 3.2: Chains - Construindo Pipelines Inteligentes
LLMChain: A Fundação
A LLMChain é o building block mais básico:
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
# 1. Definir o modelo
llm = ChatOpenAI(temperature=0.7)
# 2. Criar template de prompt
prompt = PromptTemplate(
input_variables=["tema", "tom"],
template="""
Escreva um parágrafo sobre {tema}.
Tom: {tom}
"""
)
# 3. Criar a chain
chain = LLMChain(llm=llm, prompt=prompt)
# 4. Executar
resultado = chain.invoke({
"tema": "inteligência artificial",
"tom": "inspirador"
})
print(resultado['text'])
SequentialChain: Workflows Multi-Etapa
Crie pipelines complexos onde a saída de uma chain alimenta a próxima:
from langchain.chains import SequentialChain
# Chain 1: Gerar ideia de produto
chain_ideia = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["categoria"],
template="Sugira um nome criativo para um produto na categoria: {categoria}"
),
output_key="nome_produto"
)
# Chain 2: Criar descrição
chain_descricao = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["nome_produto"],
template="Escreva uma descrição de marketing para: {nome_produto}"
),
output_key="descricao"
)
# Chain 3: Gerar slogan
chain_slogan = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["nome_produto", "descricao"],
template="""
Baseado no produto {nome_produto} e sua descrição:
{descricao}
Crie um slogan memorável (máximo 7 palavras).
"""
),
output_key="slogan"
)
# Combinar em sequência
pipeline_marketing = SequentialChain(
chains=[chain_ideia, chain_descricao, chain_slogan],
input_variables=["categoria"],
output_variables=["nome_produto", "descricao", "slogan"],
verbose=True
)
# Executar pipeline completo
resultado = pipeline_marketing.invoke({"categoria": "fitness wearables"})
print(f"Produto: {resultado['nome_produto']}")
print(f"Descrição: {resultado['descricao']}")
print(f"Slogan: {resultado['slogan']}")
Produto: FitPulse Pro
Descrição: O FitPulse Pro é o smartwatch definitivo para atletas...
Slogan: Seu batimento, sua vitória
RouterChain: Decisões Dinâmicas
Direcione para chains diferentes baseado no input:
from langchain.chains.router import MultiPromptChain
# Definir chains especializadas
chains = {
"matematica": LLMChain(...),
"codigo": LLMChain(...),
"geral": LLMChain(...)
}
# Descrições para o router decidir
chain_descriptions = [
{
"name": "matematica",
"description": "Bom para resolver problemas matemáticos e cálculos"
},
{
"name": "codigo",
"description": "Bom para explicar código e conceitos de programação"
}
]
# Criar router
router_chain = MultiPromptChain.from_prompts(
llm=llm,
destination_chains=chains,
destinations=chain_descriptions,
default_chain=chains["geral"]
)
# Teste
print(router_chain.run("Qual é 25 * 17?")) # → matematica
print(router_chain.run("def factorial(n): ...")) # → codigo
TransformChain: Processamento de Dados
Transforme dados entre chains:
from langchain.chains import TransformChain
def extrair_palavras_chave(inputs: dict) -> dict:
texto = inputs["texto"]
# Lógica customizada
palavras = texto.lower().split()
freq = {}
for palavra in palavras:
if len(palavra) > 4:
freq[palavra] = freq.get(palavra, 0) + 1
top_palavras = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:5]
return {"palavras_chave": [p[0] for p in top_palavras]}
transform_chain = TransformChain(
input_variables=["texto"],
output_variables=["palavras_chave"],
transform=extrair_palavras_chave
)
Capítulo 3.3: RAG (Retrieval-Augmented Generation)
O Problema do Conhecimento Limitado
LLMs têm três limitações fundamentais:
- Conhecimento Datado: Treinados até uma data de corte
- Sem Dados Privados: Não conhecem seus documentos internos
- Alucinações: Podem inventar informações
Arquitetura RAG Completa
Implementação Completa: ChatPDF
Passo 1: Document Loading
from langchain_community.document_loaders import PyPDFLoader, TextLoader, WebBaseLoader
# Carregar PDF
loader_pdf = PyPDFLoader("manual_produto.pdf")
documentos_pdf = loader_pdf.load()
# Carregar de URL
loader_web = WebBaseLoader("https://docs.empresa.com")
documentos_web = loader_web.load()
# Carregar múltiplos arquivos
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader(
"docs/",
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
todos_docs = loader.load()
print(f"Carregados {len(todos_docs)} documentos")
Passo 2: Text Splitting
Documentos precisam ser divididos em chunks para:
- Caber no contexto do LLM
- Melhorar precisão da busca semântica
- Otimizar performance
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # Tamanho de cada chunk
chunk_overlap=200, # Overlap entre chunks (continuidade)
length_function=len,
separators=["\n\n", "\n", " ", ""] # Tenta quebrar em parágrafos primeiro
)
chunks = text_splitter.split_documents(todos_docs)
print(f"Documentos divididos em {len(chunks)} chunks")
print(f"Exemplo de chunk:\n{chunks[0].page_content[:200]}...")
Passo 3: Embeddings
from langchain_openai import OpenAIEmbeddings
from langchain_community.embeddings import HuggingFaceEmbeddings
# Opção 1: OpenAI (pago, alta qualidade)
embeddings_openai = OpenAIEmbeddings(
model="text-embedding-3-small"
)
# Opção 2: Open-source (gratuito)
embeddings_hf = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
# Testar embedding
vetor = embeddings_openai.embed_query("Qual é a garantia?")
print(f"Dimensões do vetor: {len(vetor)}")
print(f"Primeiros valores: {vetor[:5]}")
Passo 4: Vector Store
from langchain_community.vectorstores import FAISS, Chroma
# Opção 1: FAISS (local, rápido, sem dependências)
vectorstore_faiss = FAISS.from_documents(
documents=chunks,
embedding=embeddings_openai
)
# Salvar para uso posterior
vectorstore_faiss.save_local("vectorstore_local")
# Carregar
vectorstore_carregado = FAISS.load_local(
"vectorstore_local",
embeddings_openai,
allow_dangerous_deserialization=True
)
# Opção 2: Chroma (persistent, com metadados)
vectorstore_chroma = Chroma.from_documents(
documents=chunks,
embedding=embeddings_openai,
persist_directory="./chroma_db"
)
Passo 5: Retrieval
# Busca simples por similaridade
query = "Qual é a política de devolução?"
docs_relevantes = vectorstore_faiss.similarity_search(
query,
k=4 # Top 4 resultados mais relevantes
)
for i, doc in enumerate(docs_relevantes):
print(f"\n--- Documento {i+1} ---")
print(doc.page_content[:200])
print(f"Metadados: {doc.metadata}")
# Busca com score de similaridade
docs_com_score = vectorstore_faiss.similarity_search_with_score(
query,
k=4
)
for doc, score in docs_com_score:
print(f"Score: {score:.4f} | {doc.page_content[:100]}...")
Passo 6: Geração com Contexto
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Criar chain RAG completa
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # Como combinar documentos
retriever=vectorstore_faiss.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True, # Retornar fontes
verbose=True
)
# Fazer pergunta
pergunta = "Qual é o período de garantia do produto X?"
resultado = qa_chain.invoke({"query": pergunta})
print(f"Pergunta: {pergunta}")
print(f"\nResposta: {resultado['result']}")
print(f"\nFontes utilizadas:")
for doc in resultado['source_documents']:
print(f"- {doc.metadata['source']}, página {doc.metadata.get('page', 'N/A')}")
1. "stuff" - Coloca tudo em um prompt (melhor para poucos docs)
2. "map_reduce" - Processa docs em paralelo, depois combina
3. "refine" - Processa docs sequencialmente, refinando resposta
4. "map_rerank" - Pontua cada doc, escolhe melhor resposta
RAG Conversacional (com memória)
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
# Criar memória
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)
# Chain conversacional
conversational_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectorstore_faiss.as_retriever(),
memory=memory,
return_source_documents=True
)
# Conversa multi-turn
perguntas = [
"Qual é a garantia do produto?",
"E se eu quiser estender ela?", # Usa contexto anterior
"Quanto custa?" # Ainda referencia "garantia estendida"
]
for pergunta in perguntas:
resultado = conversational_chain.invoke({"question": pergunta})
print(f"\nQ: {pergunta}")
print(f"A: {resultado['answer']}")
Capítulo 3.4: Agentes LangChain - Inteligência Autônoma
Do Scripted ao Autônomo
Chains são como seguir uma receita:
- Passo 1: Faça X
- Passo 2: Faça Y
- Passo 3: Faça Z
Agents são como ter um chef que decide:
- Qual receita seguir
- Que ingredientes usar
- Quando improvisar
O Padrão ReAct (Reason + Act)
Criando Seu Primeiro Agente
Passo 1: Definir Tools
from langchain.tools import Tool
from langchain_community.utilities import WikipediaAPIWrapper
import requests
# Tool 1: Wikipedia
wikipedia = WikipediaAPIWrapper()
tool_wikipedia = Tool(
name="Wikipedia",
func=wikipedia.run,
description="""
Útil para buscar informações factuais sobre pessoas, lugares,
eventos históricos, etc. Input deve ser uma pergunta ou termo
de busca em português.
"""
)
# Tool 2: Calculadora
def calculadora(expression: str) -> str:
"""Avalia expressões matemáticas"""
try:
return str(eval(expression))
except Exception as e:
return f"Erro: {str(e)}"
tool_calc = Tool(
name="Calculadora",
func=calculadora,
description="""
Útil para fazer cálculos matemáticos. Input deve ser uma
expressão matemática válida em Python (ex: '2 + 2', '10 ** 3').
"""
)
# Tool 3: Busca na Web (exemplo com DuckDuckGo)
from langchain_community.tools import DuckDuckGoSearchRun
search = DuckDuckGoSearchRun()
tool_search = Tool(
name="WebSearch",
func=search.run,
description="""
Útil para buscar informações atualizadas na internet.
Use quando precisar de notícias recentes, dados atuais,
ou informações que não estão na Wikipedia.
"""
)
tools = [tool_wikipedia, tool_calc, tool_search]
Passo 2: Criar o Agente
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Prompt do agente ReAct
react_prompt = PromptTemplate.from_template("""
Responda à seguinte pergunta o melhor que puder. Você tem acesso às seguintes ferramentas:
{tools}
Use o seguinte formato:
Question: a pergunta de entrada que você deve responder
Thought: você deve sempre pensar sobre o que fazer
Action: a ação a tomar, deve ser uma de [{tool_names}]
Action Input: a entrada para a ação
Observation: o resultado da ação
... (este Thought/Action/Action Input/Observation pode se repetir N vezes)
Thought: Agora eu sei a resposta final
Final Answer: a resposta final para a pergunta original
Comece!
Question: {input}
Thought: {agent_scratchpad}
""")
# Criar agente
agent = create_react_agent(
llm=llm,
tools=tools,
prompt=react_prompt
)
# Executor (gerencia execução)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # Mostra raciocínio
max_iterations=10, # Limite de segurança
handle_parsing_errors=True
)
Passo 3: Executar o Agente
# Teste 1: Requer Wikipedia
resposta1 = agent_executor.invoke({
"input": "Quem foi Albert Einstein e em que ano nasceu?"
})
print(resposta1['output'])
# Teste 2: Requer Calculadora
resposta2 = agent_executor.invoke({
"input": "Qual é a raiz quadrada de 12345?"
})
print(resposta2['output'])
# Teste 3: Requer múltiplas tools
resposta3 = agent_executor.invoke({
"input": """
O PIB do Brasil em 2023 foi de 10.9 trilhões de reais.
Se dividirmos isso pela população de 215 milhões,
quanto é o PIB per capita em reais?
"""
})
print(resposta3['output'])
# Agente vai: buscar confirmação do PIB → calcular divisão → responder
> Entering new AgentExecutor chain... Question: Qual é a raiz quadrada de 12345? Thought: Preciso calcular a raiz quadrada de um número. Action: Calculadora Action Input: 12345 ** 0.5 Observation: 111.1081249402829 Thought: Agora eu sei a resposta final. Final Answer: A raiz quadrada de 12345 é aproximadamente 111.11. > Finished chain.
Tipos de Agentes no LangChain
1. Zero-Shot ReAct Agent
from langchain.agents import create_react_agent
# Decide ferramentas baseado apenas em descrições
agent_zero_shot = create_react_agent(
llm=llm,
tools=tools,
prompt=react_prompt
)
2. Conversational Agent (com memória)
from langchain.agents import create_conversational_agent
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
conversational_agent = create_conversational_agent(
llm=llm,
tools=tools,
memory=memory,
verbose=True
)
# Agora mantém contexto entre perguntas
executor = AgentExecutor(agent=conversational_agent, tools=tools)
executor.invoke({"input": "Pesquise sobre Python"})
executor.invoke({"input": "E quanto a performance?"}) # Lembra que é sobre Python
3. OpenAI Functions Agent
from langchain.agents import create_openai_functions_agent
# Usa function calling nativo do GPT-4
functions_agent = create_openai_functions_agent(
llm=llm,
tools=tools,
prompt=react_prompt
)
# Mais confiável e menos propenso a erros de parsing
Criando Tools Customizadas
Tool Simples (função)
@tool
def consultar_estoque(produto: str) -> str:
"""
Consulta estoque de um produto no sistema.
Args:
produto: Nome do produto a consultar
"""
# Simular consulta ao banco
estoque_db = {
"notebook": 15,
"mouse": 50,
"teclado": 30
}
quantidade = estoque_db.get(produto.lower(), 0)
return f"Estoque de {produto}: {quantidade} unidades"
tools.append(consultar_estoque)
Tool com API Externa
from langchain.tools import tool
import requests
@tool
def buscar_cep(cep: str) -> str:
"""
Busca endereço a partir do CEP brasileiro.
Args:
cep: CEP no formato 12345-678 ou 12345678
"""
cep_limpo = cep.replace("-", "")
response = requests.get(f"https://viacep.com.br/ws/{cep_limpo}/json/")
if response.status_code == 200:
data = response.json()
if "erro" not in data:
return f"""
Endereço:
{data['logradouro']}, {data['bairro']}
{data['localidade']} - {data['uf']}
"""
return "CEP não encontrado"
Capítulo 3.5: Memory - Dando Memória aos Agentes
Por Que Memória é Crucial
LLMs são stateless por padrão - cada chamada é independente. Memória permite:
- Conversas naturais multi-turn
- Personalização baseada em histórico
- Contexto acumulado
- Aprendizado de preferências
Tipos de Memory no LangChain
1. ConversationBufferMemory (Memória Completa)
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
# Salvar interações
memory.save_context(
{"input": "Olá! Meu nome é Ana"},
{"output": "Olá Ana! Como posso ajudar?"}
)
memory.save_context(
{"input": "Preciso de ajuda com Python"},
{"output": "Claro! Qual sua dúvida sobre Python?"}
)
# Recuperar histórico completo
print(memory.load_memory_variables({}))
{
'history': 'Human: Olá! Meu nome é Ana\nAI: Olá Ana! Como posso ajudar?\nHuman: Preciso de ajuda com Python\nAI: Claro! Qual sua dúvida sobre Python?'
}
Usar com Chain:
from langchain.chains import ConversationChain
conversation = ConversationChain(
llm=llm,
memory=ConversationBufferMemory(),
verbose=True
)
conversation.predict(input="Oi, sou João")
conversation.predict(input="Qual é meu nome?") # Vai lembrar: João
2. ConversationBufferWindowMemory (Janela Deslizante)
from langchain.memory import ConversationBufferWindowMemory
# Mantém apenas últimas K interações
memory_window = ConversationBufferWindowMemory(k=3)
# Depois de 10 interações, só lembra as 3 últimas
Quando usar:
- Conversas longas
- Limitar custos de tokens
- Focar em contexto recente
3. ConversationSummaryMemory (Resumo Inteligente)
from langchain.memory import ConversationSummaryMemory
# Resume conversas longas
memory_summary = ConversationSummaryMemory(llm=llm)
memory_summary.save_context(
{"input": "Quero comprar um notebook para programação"},
{"output": "Recomendo um com pelo menos 16GB RAM e SSD"}
)
memory_summary.save_context(
{"input": "Qual processador você recomenda?"},
{"output": "Intel i7 ou AMD Ryzen 7 são ótimas opções"}
)
# Em vez de guardar tudo, cria resumo
print(memory_summary.load_memory_variables({}))
{
'history': 'O usuário está interessado em comprar um notebook para programação. Recomendei especificações mínimas de 16GB RAM, SSD, e processadores Intel i7 ou AMD Ryzen 7.'
}
4. ConversationSummaryBufferMemory (Híbrido)
from langchain.memory import ConversationSummaryBufferMemory
# Resume antigas, mantém recentes completas
memory_hybrid = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=500 # Limite antes de resumir
)
5. ConversationKGMemory (Knowledge Graph)
from langchain.memory import ConversationKGMemory
# Extrai relações entre entidades
memory_kg = ConversationKGMemory(llm=llm)
memory_kg.save_context(
{"input": "João mora em São Paulo"},
{"output": "Entendi"}
)
memory_kg.save_context(
{"input": "Ele trabalha na Google"},
{"output": "Anotado"}
)
# Cria grafo: João --mora_em--> São Paulo
# João --trabalha_em--> Google
Memory Persistente (Banco de Dados)
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import RedisChatMessageHistory
# Salvar em Redis
message_history = RedisChatMessageHistory(
url="redis://localhost:6379/0",
session_id="user_123"
)
memory_redis = ConversationBufferMemory(
chat_memory=message_history
)
# Ou SQLite
from langchain.memory.chat_message_histories import SQLChatMessageHistory
sql_history = SQLChatMessageHistory(
session_id="user_123",
connection_string="sqlite:///chat_history.db"
)
memory_sql = ConversationBufferMemory(chat_memory=sql_history)
Memory com Agentes
from langchain.agents import initialize_agent, AgentType
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
agent_with_memory = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=memory,
verbose=True
)
# Conversa com contexto
agent_with_memory.invoke({"input": "Meu nome é Carlos e gosto de futebol"})
agent_with_memory.invoke({"input": "Qual meu esporte favorito?"}) # Lembra!
agent_with_memory.invoke({"input": "E meu nome?"}) # Também lembra!
Capítulo 3.6: Integrações e Ecosystem
Document Loaders (60+ tipos)
# PDFs
from langchain_community.document_loaders import PyPDFLoader, PDFMinerLoader
# Web
from langchain_community.document_loaders import WebBaseLoader, SeleniumURLLoader
# Office
from langchain_community.document_loaders import UnstructuredWordDocumentLoader, UnstructuredExcelLoader
# Código
from langchain_community.document_loaders import GitLoader, NotebookLoader
# Databases
from langchain_community.document_loaders import DataFrameLoader, SQLDatabaseLoader
# APIs
from langchain_community.document_loaders import GoogleDriveLoader, NotionDBLoader
Vector Stores (50+ opções)
# Local
from langchain_community.vectorstores import FAISS, Chroma, DocArrayInMemorySearch
# Cloud
from langchain_community.vectorstores import Pinecone, Weaviate, Qdrant
# Databases
from langchain_community.vectorstores import PGVector, Redis, ElasticsearchStore
LLM Providers
# Proprietários
from langchain_openai import ChatOpenAI, OpenAI
from langchain_anthropic import ChatAnthropic
from langchain_google_genai import ChatGoogleGenerativeAI
# Open-source
from langchain_community.llms import Ollama, HuggingFaceHub, LlamaCpp
# Self-hosted
from langchain_community.llms import HuggingFacePipeline
📝 Resumo Gráfico do Módulo 3
Conceitos-Chave
LangChain = Framework de Orquestração
- Modularidade + Composabilidade
- Abstração de complexidade
- Ecosystem rico
6 Pilares:
- Models (LLMs)
- Prompts (Templates)
- Chains (Pipelines)
- Agents (Autonomia)
- Memory (Contexto)
- Tools (Conexões externas)
RAG (Retrieval-Augmented Generation):
- Indexação → Embedding → VectorDB
- Retrieval → Busca semântica
- Generation → LLM com contexto
Agents:
- ReAct (Reason + Act)
- Tools customizadas
- Decisões autônomas
🚀 Projeto Prático do Módulo 3
Desafio: ChatPDF Completo com Interface Web
Objetivo: Construir uma aplicação completa de RAG que permite:
- Upload de múltiplos PDFs
- Processamento e indexação automática
- Chat conversacional com memória
- Citação de fontes
- Interface web intuitiva
Especificações Técnicas
Stack:
- LangChain para RAG
- OpenAI para embeddings e LLM
- FAISS para vector store (local)
- Streamlit para interface web
- Python 3.10+
Veja o arquivo completo do projeto ChatPDF (200+ linhas) no conteúdo markdown do módulo, incluindo:
• Interface Streamlit completa
• Sistema de upload e processamento de PDFs
• RAG conversacional com memória
• Citação de fontes com metadados
• requirements.txt e instruções de setup
Como Executar
# 1. Criar ambiente virtual
python -m venv venv
source venv/bin/activate # Linux/Mac
# ou
venv\Scripts\activate # Windows
# 2. Instalar dependências
pip install -r requirements.txt
# 3. Executar aplicação
streamlit run chatpdf_app.py
💡 Dicas de Otimização e Debugging
1. Debugging de Chains
# Ativar verbose
chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
# Callbacks customizados
from langchain.callbacks import StdOutCallbackHandler
handler = StdOutCallbackHandler()
chain.run(input="...", callbacks=[handler])
# LangSmith (plataforma oficial)
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "..."
2. Otimizando RAG
# Cache de embeddings
from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import LocalFileStore
store = LocalFileStore("./cache/")
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(
underlying_embeddings,
store,
namespace="openai_embeddings"
)
# Compressão de contexto
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=retriever
)
3. Gerenciamento de Custos
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
result = chain.run(input="...")
print(f"Tokens: {cb.total_tokens}")
print(f"Custo: ${cb.total_cost}")
🎯 Próximos Passos
Você dominou LangChain! Agora sabe como:
- ✓ Criar chains complexas
- ✓ Implementar RAG completo
- ✓ Construir agentes autônomos
- ✓ Gerenciar memória conversacional
- ✓ Integrar ferramentas externas
- ✓ Deploy de aplicações reais