🧠 O problema da amnésia
Memória curta (buffer) existe dentro de uma sessão. Quando a sessão termina, o agente esquece tudo. Para um agente de suporte ao cliente, isso significa perguntar o mesmo problema toda vez. Para um agente de pesquisa, significa refazer o trabalho já feito. Memória longo prazo resolve isso.
📚
Memória Episódica
O que aconteceu em interações passadas. "Semana passada o usuário reportou bug X e foi resolvido assim..."
🗂️
Memória Semântica
Conhecimento geral e especializado. "A documentação da API diz que o endpoint /orders aceita estes parâmetros..."
⚙️
Memória Procedural
Como fazer coisas. "O processo de onboarding segue estes 7 passos na ordem correta..."
RAG vs. Fine-tuning: quando usar cada um
Use RAG quando:
- •Dados mudam frequentemente (documentos, preços, casos)
- •Você precisa citar a fonte da informação
- •Volume de dados é grande (GB de documentos)
Use Fine-tuning quando:
- •Você quer mudar o estilo/tom do LLM
- •Conhecimento é estável e não muda
- •Você tem milhares de exemplos de Q&A curados
🗃️ Bancos vetoriais: FAISS e Chroma
Bancos vetoriais são especializados em armazenar e buscar vetores de alta dimensão (embeddings). Em vez de busca por palavra-chave exata, eles encontram documentos semanticamente similares à sua query em milissegundos.
FAISS (Meta)
- +Extremamente rápido (busca em milhões de vetores em ms)
- +Roda localmente, sem servidor, sem custo de API
- +Suporta GPU para escala enorme
- -Sem metadata filtering nativo
- -Interface de baixo nível — mais código para usar
Melhor para: prototipagem local, datasets grandes, sem dependência de servidor
Chroma
- +API simples e pythônica — menor curva de aprendizado
- +Metadata filtering nativo — busque por data, categoria, etc.
- +Persistência automática em SQLite
- -Mais lento que FAISS em datasets muito grandes
- -Escalabilidade limitada sem Chroma Cloud
Melhor para: projetos menores/médios, necessidade de filtering por metadata, início de projeto
💻 Criando um vectorstore com Chroma (5 linhas)
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma(
persist_directory="./meu_banco",
embedding_function=embeddings
)
# Adicionar documentos
vectorstore.add_texts(texts=["doc1...", "doc2..."])
# Buscar similaridade
resultados = vectorstore.similarity_search("minha query", k=3)
🔢 Embeddings na prática
Embeddings transformam texto em vetores numéricos onde textos com significado similar ficam próximos no espaço. "Cachorro" e "cão" ficam perto; "cachorro" e "avião" ficam distantes. Não é magia — é geometria aplicada ao significado.
🗺️ Intuição sem matemática
Imagine um mapa onde cada palavra/frase tem uma posição (coordenadas). O modelo de embedding aprendeu a colocar textos similares perto uns dos outros:
Região "Finanças"
ação, dividendo, bolsa, investimento, rendimento
Região "Animais"
cachorro, gato, cão, felino, canino
Região "Código"
função, loop, variável, debugar, compilar
Modelos de embedding em 2026
- text-embedding-3-small — 1536 dims, $0.02/1M tokens, ótimo custo-benefício
- text-embedding-3-large — 3072 dims, $0.13/1M tokens, mais preciso
- voyage-3 (Anthropic) — excelente para código e documentação técnica
- nomic-embed — open-source, self-hosted, gratuito
Parâmetros críticos de chunking
- chunk_size: tamanho de cada pedaço de texto (256-1024 tokens)
- chunk_overlap: sobreposição entre chunks (10-20% do chunk_size)
- separators: onde cortar — parágrafo, frase ou palavra
- Regra: chunk menor = mais preciso, chunk maior = mais contexto
🔄 Pipeline RAG completo
RAG (Retrieval-Augmented Generation) é a técnica de dar ao LLM acesso a uma base de conhecimento externa no momento da geração. O pipeline tem 4 fases distintas: indexar, recuperar, injetar e gerar.
Indexação (feita uma vez)
Carrega documentos → divide em chunks → gera embedding de cada chunk → armazena no vector database. Pago uma vez, benefício permanente até os documentos mudarem.
Recuperação (a cada query)
Recebe a pergunta do usuário → gera embedding da pergunta → busca os K chunks mais similares no vector database por similaridade cosseno.
Injeção de contexto
Os chunks recuperados são adicionados ao prompt como contexto: "Com base nos seguintes documentos: [chunks]. Responda: [pergunta do usuário]".
Geração
O LLM responde usando o contexto injetado. Ele pode citar fontes, ser mais preciso e não "alucinar" sobre informações que estão explicitamente nos documentos.
💻 RAG completo em LangChain (código funcional)
from langchain.chains import RetrievalQA
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
# 1. Indexação
loader = TextLoader("documentacao.txt")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=50)
chunks = splitter.split_documents(docs)
vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings())
# 2-4. Recuperação + Injeção + Geração
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o-mini"),
retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
)
resposta = qa.invoke("O que é a política de devolução?")
🐛 Debug de retrieval ruim
"O RAG não funciona" é o bug mais comum em projetos com LLM. Mas qual parte falhou? Pode ser chunk muito pequeno, top-k insuficiente, threshold errado, ou embedding de baixa qualidade para o domínio. Cada causa tem solução específica.
🟡 Problema: chunks muito pequenos (256 tokens)
Sintoma: O chunk contém a palavra-chave mas falta contexto para ser útil ao LLM.
Solução: Aumente para 512-1024 tokens. Use chunk_overlap de 10-20% para não perder frases no corte.
🔴 Problema: top-k muito baixo (k=1 ou k=2)
Sintoma: O chunk com a resposta existe mas não está entre os primeiros retornados.
Solução: Aumente para k=5 ou k=10. Use MMR (Maximal Marginal Relevance) para diversidade.
🔵 Problema: embedding ruim para o domínio
Sintoma: Documentos semanticamente relacionados não aparecem como similares.
Solução: Use modelos de embedding especializados (voyage-3 para código, multilingual-e5 para PT-BR).
💡 Avaliando RAG com RAGAS
RAGAS é uma framework open-source que avalia seu pipeline RAG em 4 métricas: Faithfulness (resposta está nos chunks?), Answer Relevancy (resposta é relevante à pergunta?), Context Recall (chunks relevantes foram recuperados?) e Context Precision (chunks recuperados são todos relevantes?). Use antes de ir para produção.
💸 Custo de memória vetorial
Um sistema RAG tem dois custos distintos: indexação (embedding de todos os documentos — pago uma vez) e busca (embedding da query a cada interação — pago sempre). Em escala, a diferença importa.
📊 Exemplo de custo real
Base de conhecimento: 1.000 documentos (500 tokens médios cada) = 500.000 tokens
O custo real do RAG é dominado pelo custo do LLM para gerar a resposta, não pelos embeddings.
Self-hosted (FAISS/Chroma local)
- ✓Custo zero de armazenamento vetorial
- ✓Dados ficam na sua infraestrutura
- ✗Você gerencia backup e disponibilidade
- ✗Escalabilidade limitada por memória RAM
Hosted (Pinecone, Weaviate Cloud)
- ✓Escalabilidade automática sem limite
- ✓SLA de disponibilidade garantido
- ✗Custo: Pinecone Serverless ~$0.033/1M reads
- ✗Dados na nuvem do provider
✅ Resumo do Módulo 2.3
Próximo Módulo:
2.4 — Tools e Function Calling: como dar ao agente a capacidade de agir no mundo real com JSON Schema, Pydantic e segurança de tools.