Pergunte ao Claude sobre sua empresa, suas anotações ou seus arquivos, e ele fica em branco. Ele nunca os viu. Ele só sabe o que aprendeu no treinamento, e suas coisas não faziam parte disso.
Um sistema RAG resolve isso. Em vez de responder de memória, o Claude primeiro consulta seus documentos, pega as partes relevantes e responde com base no que realmente encontrou. Seus dados, a fonte dele, sem adivinhação.
Por que é melhor do que simplesmente colar arquivos no chat:
Escalável. Sua base de conhecimento inteira não cabe em um único chat. O RAG armazena tudo e puxa apenas o que cada pergunta precisa.
Mais barato. Colar um arquivo faz o Claude reler o documento inteiro a cada pergunta. O RAG lê uma vez, depois busca apenas a parte relevante. Em vez de enviar um manual de 10.000 tokens toda vez, ele pode enviar 500 tokens da seção exata que você precisa. Configurações reais reduzem o uso de tokens em 80% ou mais.
Mais preciso. Alimente um modelo com um muro de texto e ele perde detalhes no meio. Entregue alguns trechos precisos e as respostas ficam mais exatas.
Sempre atualizado. Atualize seus arquivos uma vez e o sistema usa a versão nova. Sem precisar colar de novo.
Ao final deste guia, você terá um sistema funcionando com seus próprios arquivos, passo a passo, sem precisar de um PhD.
O que você vai precisar
Antes de tocarmos em qualquer código, aqui está a lista completa. Boa notícia: esta versão precisa de apenas uma chave de API, e todo o resto roda gratuitamente na sua própria máquina.
1. Python 3.9 ou superior. Para verificar se você tem, abra seu terminal (Terminal no Mac, Prompt de Comando no Windows) e digite python --version. Se aparecer algo como 3.11, está ok. Caso contrário, baixe do python.org e execute o instalador. No Windows, marque a opção "Adicionar Python ao PATH" durante a instalação, senão os comandos abaixo não funcionarão.
2. Uma chave de API do Claude, mais um pequeno saldo de créditos. Esta é a única chave e o único dinheiro que o guia inteiro vai precisar. Aqui está o caminho exato, clique a clique:
Acesse platform.claude.com, faça login (ou cadastre-se) lá.
A API precisa de um saldo positivo para funcionar, então adicione fundos primeiro. Quando solicitado, escolha se os créditos são para você ou para uma empresa, e então você cai na tela de pagamento. Escolha a opção $5 "Iniciando". É mais que suficiente: todo o resto deste guia é gratuito e local, então o Claude é a única coisa que custa dinheiro, e cada pergunta custa uma fração de centavo. Os créditos expiram um ano após a compra.
Após o pagamento, você estará no painel do Console. Você deve ver seu saldo (por exemplo, $5,00) no canto superior esquerdo, em "Créditos da organização".
Agora pegue a chave. Clique em Obter chave de API (canto superior direito), depois em Criar chave. Dê a ela qualquer nome que você queira (por exemplo, minha-chave-rag) e deixe o espaço de trabalho como Padrão. Clique em criar, e copie a string que aparece. Ela começa com sk-ant- e você só a vê uma vez, então cole em algum lugar seguro por um minuto.
Essa é toda a configuração.
Passo 1: Adicione sua chave e carregue seus arquivos
1. Crie a pasta do projeto. Crie uma nova pasta na sua Área de Trabalho e nomeie-a como rag-project. Tudo vai aqui.
2. Abra seu terminal. No Mac: Cmd+Espaço, digite Terminal, Enter. No Windows: Botão Iniciar, digite cmd, Enter.
3. Aponte o terminal para sua pasta. Digite cd e um espaço, depois arraste a pasta rag-project para a janela do terminal e pressione Enter. Todos os comandos abaixo são executados de dentro desta pasta.
1cd Desktop/rag-project
4. Instale as ferramentas. Cole isto no terminal e pressione Enter (a primeira execução pode levar um minuto):
1pip install anthropic chromadb sentence-transformers pypdf python-dotenv
Se você receber pip: command not found, use pip3 no lugar de pip. Quando o terminal mostrar uma linha nova sem erros em vermelho, está pronto.
5. Crie seu arquivo de código. Dentro de rag-project, crie um arquivo vazio com o nome exato rag.py. Abra-o em qualquer editor de texto.
6. Crie seu arquivo de chave. Na mesma pasta, crie um arquivo com o nome exato .env (começa com um ponto, sem nome antes). Cole isto dentro, com a chave real que você criou durante a configuração depois do =, sem espaços, sem aspas:
1ANTHROPIC_API_KEY=sk-ant-cole-sua-chave-real-aqui
Manter a chave no .env em vez de no código significa que ela não vazará se você compartilhar o script ou colocá-lo no GitHub.
7. Carregue a chave. Coloque isto no topo do rag.py:
1import os2from dotenv import load_dotenv34load_dotenv() # lê seu arquivo .env5api_key = os.getenv("ANTHROPIC_API_KEY")
8. Crie sua base de conhecimento. Dentro de rag-project, crie uma pasta chamada documents. Coloque quaisquer arquivos .txt, .md ou .pdf lá: suas anotações, um documento de produto, resumos de reunião, qualquer coisa.
8.1. Se você ainda não tem arquivos, use este arquivo de teste. Crie notes.txt dentro da pasta documents e cole isto:
Projeto Northstar é nossa ferramenta interna para acompanhar feedback de clientes. Foi lançado em março de 2026 e é mantido pela equipe de plataforma. A engenheira líder é Dana Reyes. O feedback é revisado toda sexta-feira. O Northstar substituiu o antigo sistema de planilhas que usávamos até 2025.
No final, você perguntará ao Claude sobre o Northstar e verá ele responder a partir deste arquivo exato.
9. Adicione o código que lê seus arquivos. Abaixo do código do passo 7, no rag.py:
1from pathlib import Path2from pypdf import PdfReader34def load_documents(folder="documents"):5 docs = []6 for file in Path(folder).iterdir():7 if file.suffix in [".txt", ".md"]:8 text = file.read_text(encoding="utf-8")9 docs.append({"source": file.name, "text": text})10 elif file.suffix == ".pdf":11 reader = PdfReader(str(file))12 text = "\n".join(page.extract_text() or "" for page in reader.pages)13 docs.append({"source": file.name, "text": text})14 return docs1516documents = load_documents()17print(f"Carregado(s) {len(documents)} documento(s).")
10. Execute. Salve o rag.py, então no terminal:
1python rag.py
Você deve ver:
Carregado(s) 1 documento(s).
Se aparecer Carregado(s) 0 documento(s), a pasta documents está vazia ou no lugar errado. Ela deve estar diretamente dentro de rag-project, ao lado do rag.py.
Passo 2: Divida seus arquivos em chunks
Agora cada arquivo é um grande bloco de texto. Antes de podermos pesquisar, precisamos cortá-lo em pedaços menores chamados chunks. Eis o porquê: quando alguém faz uma pergunta, o sistema encontra os chunks que correspondem e envia apenas esses para o Claude. Se seus chunks forem documentos inteiros de 50 páginas, você envia demais. Se forem frases isoladas, perdem contexto. Pequenos parágrafos são o ponto ideal.
1. Adicione o código de chunking. Abaixo do código do passo 10, no rag.py:
1def chunk_text(text, chunk_size=500, overlap=100):2 words = text.split()3 chunks = []4 start = 05 while start < len(words):6 end = start + chunk_size7 chunk = " ".join(words[start:end])8 chunks.append(chunk)9 start = end - overlap # recua um pouco para que os chunks se sobreponham10 return chunks
Dois números para entender aqui, em termos simples:
- chunk_size=500 significa que cada chunk tem cerca de 500 palavras. Grande o suficiente para conter uma ideia completa, pequeno o suficiente para ser preciso.
- overlap=100 significa que cada chunk repete as últimas 100 palavras do anterior. Isso importa porque uma resposta pode ficar exatamente na linha onde dois chunks se encontram. Sem sobreposição, uma frase cortada ao meio pode se perder. A sobreposição garante que nenhuma ideia caia na fenda.
2. Transforme todo documento em chunks. Adicione isto abaixo:
1all_chunks = []2for doc in documents:3 for chunk in chunk_text(doc["text"]):4 all_chunks.append({"source": doc["source"], "text": chunk})56print(f"Criado(s) {len(all_chunks)} chunk(s) a partir de {len(documents)} documento(s).")
Observe que cada chunk carrega sua source (o nome do arquivo de onde veio). Mantemos isso anexado durante todo o caminho, para que quando o Claude responder mais tarde, ele possa dizer de qual arquivo veio a resposta.
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
Você deve ver algo como:
Carregado(s) 1 documento(s).
Criado(s) 1 chunk(s) a partir de 1 documento(s).
O pequeno arquivo de teste se torna apenas um chunk porque é curto. Documentos reais produzirão muitos. Se você colocar um PDF longo na pasta, pode ver dezenas ou centenas de chunks, que é exatamente o que você quer.
Passo 3: Transforme seus chunks em embeddings
Este é o passo que permite ao computador pesquisar por significado em vez de palavras exatas. Cada chunk é convertido em uma lista de números (um embedding) que captura o assunto dele. Chunks com significado semelhante terminam com números semelhantes. Mais tarde, quando uma pergunta chegar, transformamos a pergunta em números também e encontramos as correspondências mais próximas.
O modelo que faz isso roda localmente na sua máquina. Ele baixa uma vez, depois funciona offline e gratuitamente, e seus arquivos nunca saem do seu computador.
1. Carregue o modelo de embedding. Abaixo do código do passo 2, no rag.py:
1from sentence_transformers import SentenceTransformer23print("Carregando o modelo de embedding (primeira execução baixa, cerca de 90 MB)...")4embedder = SentenceTransformer("all-MiniLM-L6-v2")
Na primeira vez que você executar, ele baixa o modelo, então aguarde um momento. Todas as execuções seguintes são instantâneas porque ele já está na sua máquina.
2. Transforme cada chunk em um embedding. Adicione isto abaixo:
1chunk_texts = [chunk["text"] for chunk in all_chunks]2embeddings = embedder.encode(chunk_texts)34print(f"Criado(s) {len(embeddings)} embedding(s).")5print(f"Cada embedding é uma lista de {len(embeddings[0])} números.")
embedder.encode(...) pega sua lista de textos dos chunks e devolve um embedding por chunk. É só isso.
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
A primeira execução pausa enquanto o modelo baixa, então você deve ver algo como:
Carregado(s) 1 documento(s).
Criado(s) 1 chunk(s) a partir de 1 documento(s).
Carregando o modelo de embedding (primeira execução baixa, cerca de 90 MB)...
Criado(s) 1 embedding(s).
Cada embedding é uma lista de 384 números.
Essa linha "384 números" é a ideia toda tornada visível: seu texto agora é uma linha de números que o computador pode comparar. Você não precisa ler ou entender esses números. O banco de dados no próximo passo lida com toda a comparação para você.
Se o download falhar com um erro de conexão, apenas execute o comando novamente. Ele retoma de onde parou.
Passo 4: Armazene tudo no seu banco de dados vetorial
Agora colocamos os chunks e seus embeddings no Chroma, seu banco de dados local. É isso que torna a pesquisa rápida: em vez de comparar sua pergunta contra cada chunk manualmente a cada vez, o Chroma os armazena prontos e faz a correspondência para você. Ele salva em uma pasta na sua máquina, então você só constrói uma vez.
1. Configure o banco de dados. Abaixo do código do passo 3, no rag.py:
1import chromadb23client = chromadb.PersistentClient(path="chroma_db")4collection = client.get_or_create_collection("my_documents")
PersistentClient(path="chroma_db") diz ao Chroma para salvar em uma pasta chamada chroma_db (ele a cria automaticamente, bem ao lado do seu script). Como é salvo em disco, seus dados sobrevivem após o script terminar. Uma collection é apenas a caixa nomeada onde seus chunks vivem.
2. Adicione seus chunks ao banco de dados. Adicione isto abaixo:
1collection.add(2 ids=[str(i) for i in range(len(all_chunks))],3 embeddings=[emb.tolist() for emb in embeddings],4 documents=[chunk["text"] for chunk in all_chunks],5 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],6)78print(f"Armazenado(s) {collection.count()} chunk(s) no banco de dados.")
Aqui está o que cada linha entrega ao Chroma, em termos simples: ids dá a cada chunk um rótulo único (0, 1, 2...), embeddings são os números do passo 3, documents é o texto real do chunk, e metadatas carrega o nome do arquivo junto para que possamos mostrar a fonte depois. O Chroma mantém todos os quatro interligados.
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
Você deve ver:
Armazenado(s) 1 chunk(s) no banco de dados.
Uma coisa para saber mais tarde. Toda vez que você executa o script agora, ele adiciona os chunks novamente, então as contagens podem subir (1, depois 2, depois 3...) em execuções repetidas. Isso é ok enquanto estamos construindo. Para começar do zero, exclua a pasta chroma_db e execute uma vez mais. Na versão final, lidaremos com isso adequadamente para que não duplique.
Passo 5: Pesquise seus documentos
Esta é a parte de "recuperação" do RAG, o R no nome. Pegamos uma pergunta, transformamos em um embedding da mesma forma que fizemos com os chunks, e pedimos ao Chroma pelos chunks cujo significado é mais próximo. Esses chunks correspondentes são o que entregaremos ao Claude no próximo passo.
1. Adicione a função de busca. Abaixo do código do passo 4, no rag.py:
1def search(question, n_results=3):2 question_embedding = embedder.encode([question])[0]3 results = collection.query(4 query_embeddings=[question_embedding.tolist()],5 n_results=n_results,6 )7 return results
O que isso faz, linha por linha em termos simples: transforma a pergunta em números com o mesmo modelo que você usou nos seus chunks (isso é importante, ambos têm que falar a mesma "linguagem numérica"), depois pede ao Chroma pelas correspondências mais próximas. n_results=3 significa "me dê os 3 chunks mais relevantes". Três é um bom padrão: contexto suficiente, não tanto que você desperdice tokens.
2. Teste uma busca. Adicione isto abaixo para testar:
1question = "Quem dirige o Northstar e quando o feedback é revisado?"2results = search(question)34for i, doc in enumerate(results["documents"][0]):5 source = results["metadatas"][0][i]["source"]6 print(f"\n--- Correspondência {i+1} (de {source}) ---")7 print(doc)
Isso executa uma pergunta real contra seu banco de dados e imprime os chunks encontrados, cada um com o nome do arquivo de origem.
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
Com o arquivo de teste Northstar, você deve ver ele puxar de volta o chunk correspondente, algo como:
--- Correspondência 1 (de notes.txt) ---
Projeto Northstar é nossa ferramenta interna para acompanhar feedback de clientes. Foi lançado em março de 2026 e é mantido pela equipe de plataforma. A engenheira líder é Dana Reyes. O feedback é revisado toda sexta-feira. O Northstar substituiu o antigo sistema de planilhas que usávamos até 2025.
Observe o que acabou de acontecer: sua pergunta usou as palavras "quem dirige" e "revisado", mas o arquivo diz "engenheira líder" e "revisado toda sexta-feira". Mesmo assim, houve correspondência, porque a busca funciona por significado, não por palavras exatas. Esse é o objetivo dos embeddings, e é por isso que isso supera uma busca simples por palavra-chave (Ctrl+F) nos seus arquivos.
Se você tiver mais arquivos, verá os 3 principais chunks de todos eles, ordenados por quão próximos correspondem.
Passo 6: Faça o Claude responder com base no que encontrou
Esta é a parte de "geração", o G em RAG. Pegamos os chunks do passo 5, entregamos ao Claude Opus 4.8 junto com a pergunta, e dizemos a ele para responder usando apenas aquele contexto. Isso é o que impede que ele adivinhe: o Claude responde a partir dos seus arquivos, não da própria memória, e diz qual arquivo usou.
1. Adicione a função de resposta. Abaixo do código do passo 5, no rag.py:
1import anthropic23claude = anthropic.Anthropic(api_key=api_key)45def answer(question):6 results = search(question)7 chunks = results["documents"][0]8 sources = [m["source"] for m in results["metadatas"][0]]910 context = ""11 for i, chunk in enumerate(chunks):12 context += f"[De {sources[i]}]\n{chunk}\n\n"1314 message = claude.messages.create(15 model="claude-opus-4-8",16 max_tokens=1024,17 system=(18 "Você responde perguntas usando apenas o contexto fornecido. "19 "Se a resposta não estiver no contexto, diga que não sabe. "20 "Sempre mencione de qual arquivo sua resposta veio."21 ),22 messages=[23 {24 "role": "user",25 "content": f"Contexto:\n{context}\nPergunta: {question}",26 }27 ],28 )29 return message.content[0].text
O que está acontecendo aqui, em termos simples: buscamos os chunks relevantes, os juntamos em um bloco de contexto (cada um rotulado com seu nome de arquivo), depois enviamos esse bloco mais a pergunta para o Claude. A instrução system é a parte chave. Ela diz três coisas ao Claude: responda apenas a partir do contexto, admita quando a resposta não estiver lá, e nomeie o arquivo de origem. Essas três regras são o que torna as respostas confiáveis em vez de inventadas.
model="claude-opus-4-8" é o nome exato do modelo (hífens, não pontos). max_tokens=1024 limita o tamanho da resposta.
2. Faça uma pergunta. Adicione isto abaixo:
1question = "Quem dirige o Northstar e quando o feedback é revisado?"2print(answer(question))
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
Você deve obter uma resposta real construída a partir do seu arquivo, algo como:
Dana Reyes é a engenheira líder que dirige o Projeto Northstar, e o feedback é revisado toda sexta-feira. (Fonte: notes.txt)
Isso é um sistema RAG completo funcionando. O Claude nunca viu este arquivo durante o treinamento, não pode saber quem é Dana Reyes, mas respondeu corretamente e disse exatamente de onde veio a resposta. Pergunte algo que não está nos seus arquivos e ele dirá que não sabe, em vez de inventar uma resposta. Esse "não sei" é uma característica, não uma falha: é a diferença entre uma ferramenta confiável e uma que adivinha.
Passo 7: Transforme isso em algo que você possa realmente usar
Agora você precisa editar o código e executar o script inteiro novamente toda vez que quiser perguntar algo. Pior ainda, cada execução relê seus arquivos e os readiciona ao banco de dados, então os chunks se acumulam. Vamos corrigir ambos: construir o banco de dados apenas uma vez, depois permitir que você faça perguntas em um loop, digitando-as diretamente no terminal.
1. Corrija a duplicação. Encontre o bloco do passo 4 que adiciona chunks (a parte collection.add(...)) e substitua por esta versão, que só constrói o banco de dados se ele estiver vazio:
1if collection.count() == 0:2 collection.add(3 ids=[str(i) for i in range(len(all_chunks))],4 embeddings=[emb.tolist() for emb in embeddings],5 documents=[chunk["text"] for chunk in all_chunks],6 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],7 )8 print(f"Armazenado(s) {collection.count()} chunk(s) no banco de dados.")9else:10 print(f"Banco de dados já tem {collection.count()} chunk(s), pulando reconstrução.")
Agora o trabalho pesado (ler arquivos, criar embeddings, preencher o banco) acontece apenas na primeira vez. Execuções posteriores pulam direto para a resposta.
2. Adicione o loop de perguntas. No final do rag.py, substitua a pergunta de teste única do passo 6 por isto:
1print("\nFaça uma pergunta sobre seus documentos (ou digite 'sair' para encerrar).\n")23while True:4 question = input("Você: ")5 if question.lower() in ["sair", "quit", "exit"]:6 break7 print("\nClaude: " + answer(question) + "\n")
input("Você: ") espera você digitar uma pergunta e pressionar Enter. while True mantém o loop para que você possa perguntar quantas vezes quiser. Digitar "sair" interrompe.
3. Execute. Salve o rag.py, então no terminal:
1python rag.py
Agora você pode simplesmente conversar com seus arquivos:
Faça uma pergunta sobre seus documentos (ou digite 'sair' para encerrar).
Você: quem é a engenheira líder do Northstar?
Claude: A engenheira líder do Projeto Northstar é Dana Reyes. (Fonte: notes.txt)
Você: o que ele substituiu?
Claude: O Northstar substituiu o antigo sistema de planilhas usado até 2025. (Fonte: notes.txt)
Você: sair
Esse é o seu sistema RAG finalizado. Ele lê seus arquivos uma vez, lembra deles e responde perguntas sobre eles sob demanda, sempre com a fonte.
Uma coisa para saber quando você adicionar novos arquivos. Como o banco de dados agora só é construído uma vez, colocar novos arquivos em documents não aparecerá automaticamente. Para carregar novos arquivos, exclua a pasta chroma_db e execute o script uma vez. Ele reconstrói do zero com tudo que está na pasta.
Opcional: dê a ele uma janela de chat no seu navegador
O terminal funciona, mas se você quiser uma janela de chat de verdade, o Streamlit adiciona uma em cerca de 20 linhas.
1. Instale. No terminal:
1pip install streamlit
2. Crie o app.py na mesma pasta e cole isto. Ele reutiliza a função answer do seu rag.py:
1import streamlit as st2from rag import answer34st.title("Converse com seus documentos")56if "history" not in st.session_state:7 st.session_state.history = []89question = st.chat_input("Pergunte sobre seus arquivos...")1011if question:12 reply = answer(question)13 st.session_state.history.append((question, reply))1415for q, a in st.session_state.history:16 st.chat_message("user").write(q)17 st.chat_message("assistant").write(a)
3. Execute. No terminal (nota: streamlit run, não python):
1streamlit run app.py
Ele abre uma janela de chat no seu navegador automaticamente. Digite uma pergunta, obtenha uma resposta com sua fonte, igual ao terminal, mas mais bonito de ver.
Uma nota: para isso funcionar, o loop de perguntas do passo 7 precisa não ser executado na importação. Envolva esse loop no final do rag.py em if __name__ == "__main__": para que ele só dispare quando você executar o rag.py diretamente, não quando o app.py o importar.
Deixando ele responder perguntas gerais também
Se você quiser que ele responda também perguntas gerais. Agora o sistema só responde a partir dos seus arquivos, então uma pergunta como "qual é a capital da Venezuela?" recebe "isso não está nos documentos", mesmo que o Claude saiba a resposta. Se você quiser que ele recorra ao próprio conhecimento, abra o rag.py, encontre o bloco system=(...) no passo 6 e troque esta linha:
1"Se a resposta não estiver no contexto, diga que você não sabe."
para este:
1"Se a resposta não estiver no contexto, responda com seu próprio conhecimento geral, mas avise que está fazendo isso."
Salve e execute novamente. Agora ele responde primeiro a partir dos seus arquivos e, quando eles não cobrem o assunto, recorre ao conhecimento geral, informando qual foi usado.
Concluindo
Você acabou de construir um sistema RAG funcional. Ele lê seus próprios arquivos, encontra as partes relevantes e faz o Claude responder a partir delas, sempre com a fonte exata. A mesma estrutura escala de algumas anotações para toda a sua base de conhecimento.
A partir daqui, você pode apontá-lo para onde quiser: seu cofre do Obsidian, seus documentos de trabalho, suas pesquisas salvas. Coloque os arquivos, reconstrua uma vez e comece a perguntar. Tudo que você aprendeu aqui — os chunks, os embeddings, a busca, a resposta — é a mesma base por trás de toda ferramenta de "converse com seus documentos" que você já viu.
Se isso foi útil, vá até meu perfil e siga. Escrevo sobre tecnologia, IA e sistemas que realmente funcionam.
Ciao,
[@undefinedKi**](https://x.com/@undefinedKi





