Construindo um RAG com LangChain e Llama 3
Tutorial passo a passo para criar um sistema de perguntas e respostas sobre seus próprios documentos usando Retrieval-Augmented Generation.
RAG (Retrieval-Augmented Generation) é uma das técnicas mais poderosas para fazer LLMs responderem com base nos seus documentos — sem fine-tuning, sem vazar dados para APIs externas. Neste tutorial, criamos um RAG completo com LangChain e Llama 3 rodando localmente via Ollama.
O que é RAG?
Em vez de depender apenas do conhecimento pré-treinado do modelo, o RAG:
- Indexa seus documentos em um banco vetorial
- Recupera os trechos mais relevantes para a pergunta
- Aumenta o prompt com esse contexto
- Gera uma resposta fundamentada nos seus dados
O resultado é um modelo que fala sobre seus PDFs, relatórios, bases de conhecimento internas — com menos alucinações.
Setup
# Instalar Ollama e baixar o modelo
ollama pull llama3
# Instalar dependências Python
pip install langchain langchain-community chromadb pypdf sentence-transformers
Indexando Documentos
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
# Carregando PDFs
loader = PyPDFLoader("relatorio_seguranca.pdf")
docs = loader.load()
# Dividindo em chunks
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.split_documents(docs)
# Criando embeddings e salvando no banco vetorial
embeddings = OllamaEmbeddings(model="llama3")
vectorstore = Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")
Pipeline de Perguntas e Respostas
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
llm = Ollama(model="llama3", temperature=0)
template = """Use o contexto abaixo para responder à pergunta.
Se não souber a resposta, diga que não encontrou nos documentos.
Contexto: {context}
Pergunta: {question}
Resposta:"""
prompt = PromptTemplate(template=template, input_variables=["context", "question"])
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
chain_type_kwargs={"prompt": prompt},
)
resposta = qa_chain.invoke("Quais foram as principais ameaças identificadas?")
print(resposta["result"])
Avaliando a Qualidade
Métricas importantes para RAG:
| Métrica | O que mede |
|---|---|
| Context Precision | Os chunks recuperados são relevantes? |
| Context Recall | Todos os chunks necessários foram recuperados? |
| Answer Faithfulness | A resposta é fiel ao contexto? |
| Answer Relevance | A resposta responde à pergunta? |
Use o framework RAGAS para automatizar essa avaliação.
Dicas de Produção
- Chunk size: comece com 512-1024 tokens; ajuste conforme o tipo de documento
- Overlap: 10-20% do chunk size previne quebra de contexto nas bordas
- Reranking: use um modelo de reranking (ex:
cross-encoder/ms-marco-MiniLM-L-6-v2) para melhorar a precisão da recuperação - Hybrid search: combine busca semântica + BM25 para resultados mais robustos
- Privacidade: com Ollama, tudo roda localmente — ideal para dados sensíveis
Este setup é um excelente ponto de partida. Para casos de uso em produção, considere também o LlamaIndex como alternativa ao LangChain — mais focado em RAG avançado.