IMPLEMENTAÇÃO
1️ Instalações Necessárias
pip install langchain
pip install langchain-community
pip install langchain-openai
pip install langchain-huggingface
pip install faiss-cpu
pip install pypdf
pip install tiktoken
pip install python-dotenv
Ollama:
Baixar modelos:
ollama pull bge-m3
ollama pull gemma:4b
2️ Criar Caderno do Zero
Abra Jupyter:
jupyter notebook
Chorar:RAG_Local_Integrado.ipynb
3️ Carregar PDFs do Diretório
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
loader = DirectoryLoader(
"./pdfs",
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
documents = loader.load()
print(len(documents))
Agora você tem apenas PDFs.
4️ Chunking com Token Splitter (Hugging Face)
from langchain_text_splitters import TokenTextSplitter
splitter = TokenTextSplitter(
chunk_size=512,
chunk_overlap=100
)
chunks = splitter.split_documents(documents)
print(len(chunks))
chunk_size 512 → equilíbrio
overlap 100 → mantém contexto
5️ Incorporações locais (BGE-M3 via Ollama)
from langchain_community.embeddings import OllamaEmbeddings
embeddings = OllamaEmbeddings(
model="bge-m3"
)
Sem API externa. 100% local.
6️ Vector Store Local (FAISS)
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(
chunks,
embeddings
)
vectorstore.save_local("faiss_index")
Agora persistido em arquivo.
7️ Criar Retriever
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
8️ Testar LLM Local (Gemma)
from langchain_community.chat_models import ChatOllama
llm = ChatOllama(
model="gemma:4b",
temperature=0
)
response = llm.invoke("Explique o princípio da legalidade.")
print(response.content)
9️ Criar Corrente RAG Básica
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("""
Responda com base apenas no contexto:
{context}
Pergunta:
{question}
""")
rag_chain = (
{
"context": retriever,
"question": RunnablePassthrough()
}
| prompt
| llm
| StrOutputParser()
)
Teste:
rag_chain.invoke("Qual o prazo de vigência do contrato?")
10 Reescrita de consulta (Modelo Menor)
Objetivo: melhorar consultas mal formuladas.
rewrite_prompt = ChatPromptTemplate.from_template("""
Reescreva a pergunta de forma mais clara e específica:
Pergunta: {question}
""")
rewriter_chain = rewrite_prompt | llm | StrOutputParser()
query = "prazo contrato?"
new_query = rewriter_chain.invoke({"question": query})
print(new_query)
Agora usamos uma consulta refinada no retriever.
Recuperador de consultas múltiplas
from langchain.retrievers.multi_query import MultiQueryRetriever
multi_retriever = MultiQueryRetriever.from_llm(
retriever=retriever,
llm=llm
)
docs = multi_retriever.get_relevant_documents(
"Qual a responsabilidade da contratada?"
)
print(len(docs))
Ele gera diversas variações automaticamente.
Técnica HyDE (Ocultar)
HyDE cria um documento hipotético antes de pesquisar.
hyde_prompt = ChatPromptTemplate.from_template("""
Escreva um parágrafo hipotético que responderia:
{question}
""")
hyde_chain = hyde_prompt | llm | StrOutputParser()
hypothetical_doc = hyde_chain.invoke(
{"question": "Qual a penalidade por inadimplemento?"}
)
docs = vectorstore.similarity_search(hypothetical_doc, k=4)