Chatbot com Base de Conhecimento Própria
Tutorial guiado — Claude API + RAG (Retrieval-Augmented Generation)
Este tutorial não entrega o código pronto. Ele te guia por etapas, com perguntas para você pensar e
checkpoints para validar se está no caminho certo. O objetivo é que, no final, você entenda cada peça
do seu próprio chatbot — não apenas copiou algo que funcionou.
Nível: iniciante em IA · Pré-requisitos: Python básico (você já tem)
Visão geral do projeto
No final deste projeto, você terá um chatbot de linha de comando que responde perguntas usando
informações que você forneceu (ex: seus próprios documentos, anotações de aula, PDF de um
manual) — não apenas o conhecimento geral do modelo. Esse é o padrão conhecido como RAG.
O fluxo, em alto nível:
1 O usuário faz uma pergunta.
2 O sistema busca, na sua base de conhecimento, os trechos mais relevantes para essa pergunta.
3 Esses trechos são inseridos no prompt enviado ao Claude, junto da pergunta original.
4 O Claude responde com base no que foi recuperado — não apenas 'no escuro'.
Escopo sugerido (para não travar em perfeccionismo):
• Base de conhecimento: 3 a 5 arquivos de texto (.txt ou .md) sobre um tema que você escolher —
pode ser material da faculdade, documentação de uma matéria, ou até as ementas que você
recebeu esse período.
• Interface: linha de comando (terminal) é suficiente. Interface web fica como etapa bônus.
• Sem necessidade de fine-tuning, treinar modelo, ou infraestrutura complexa.
Estrutura de pastas sugerida
meu-chatbot/
■■■ .env # sua chave de API (nunca commitar no Git)
■■■ knowledge_base/ # seus arquivos .txt/.md
■■■ [Link]
■■■ [Link]
Antes de seguir: crie um repositório no seu GitHub para esse projeto agora, mesmo vazio. Você vai
commitando conforme avança — isso também vira histórico de commits, o que conta ponto na sua
vitrine.
Etapa 1 — Setup do ambiente
Objetivo: ter um ambiente Python isolado, com a SDK da Anthropic instalada e sua chave de API
funcionando, sem hardcodar a chave no código.
■ Pense antes de codar
• Por que usar um ambiente virtual (venv) em vez de instalar tudo global?
• Por que a chave de API não deve ir direto no código-fonte?
• O que precisa estar no seu .gitignore para não vazar a chave quando você fizer push pro GitHub?
O que fazer:
1 Crie e ative um ambiente virtual (venv).
2 Instale as bibliotecas que você vai precisar: SDK da Anthropic, um pacote para carregar
variáveis de ambiente, e o ChromaDB (você já estudou tudo isso na fase de pesquisa).
3 Gere sua API key no console da Anthropic e salve no arquivo .env.
4 Crie um .gitignore que exclua o .env e a pasta do venv.
■ Checkpoint: escreva um script mínimo que só importa a SDK, cria o client e imprime uma
mensagem de sucesso se a chave foi carregada. Se der erro de autenticação aqui, resolva antes
de seguir.
Etapa 2 — Primeira conversa com o Claude (sem base de
conhecimento ainda)
Objetivo: confirmar que você consegue mandar uma pergunta e receber uma resposta de texto, antes
de complicar com RAG.
■ Pense antes de codar
• Quais campos são obrigatórios numa chamada à Messages API? (dica: modelo, tokens máximos,
mensagens)
• O que muda entre usar um 'system prompt' e colocar tudo na mensagem do usuário?
• Onde, na resposta da API, está o texto que o modelo gerou? (a resposta não é só uma string
simples)
■ Checkpoint: seu script recebe uma pergunta digitada no terminal (input()) e imprime a resposta
do Claude. Teste com 2-3 perguntas diferentes antes de seguir.
Etapa 3 — Preparar a base de conhecimento
Objetivo: transformar seus documentos de texto em pedaços (chunks) pequenos o suficiente para
serem buscados individualmente.
■ Pense antes de codar
• Por que não dá pra jogar um documento inteiro de uma vez como 'conhecimento' — o que
acontece se o documento for muito grande?
• Se você cortar um texto em pedaços fixos de N caracteres, o que pode dar errado no meio de
uma frase ou parágrafo importante?
• Faz sentido dividir por parágrafo, por número de palavras, ou por seção? Depende do quê?
O que fazer:
1 Coloque de 3 a 5 arquivos .txt/.md na pasta knowledge_base/.
2 Escreva uma função que lê todos os arquivos da pasta.
3 Escreva uma função de 'chunking' que quebra cada texto em pedaços menores, com algum
overlap (sobreposição) entre eles para não perder contexto nas bordas.
■ Checkpoint: imprima quantos chunks foram gerados e o conteúdo dos 2 primeiros. Eles fazem
sentido como unidades de busca (nem muito curtos, nem muito longos)?
Etapa 4 — Gerar embeddings e indexar no ChromaDB
Objetivo: transformar cada chunk em um vetor numérico (embedding) e guardá-lo num banco vetorial,
para poder buscar por similaridade depois.
■ Pense antes de codar
• A Anthropic não oferece um modelo de embeddings próprio — qual biblioteca/modelo de
embeddings você vai usar? (pesquise 'embedding models' compatíveis com ChromaDB — há
opções que rodam localmente, sem custo)
• O que é uma 'collection' no ChromaDB e o que ela guarda além do vetor?
• Se você rodar o script duas vezes, seus documentos vão duplicar na base? Como evitar isso?
■ Checkpoint: depois de indexar, faça uma query manual simples direto no ChromaDB (fora do
fluxo do chatbot) e confirme que ele retorna chunks coerentes com a query.
Etapa 5 — Conectar busca + geração (o RAG de verdade)
Objetivo: dado uma pergunta do usuário, buscar os chunks mais relevantes e montar um prompt que dá
esse contexto ao Claude antes de pedir a resposta.
■ Pense antes de codar
• Quantos chunks você deve recuperar por pergunta? O que acontece se recuperar poucos ou
demais?
• Como estruturar o prompt para deixar claro pro modelo o que é 'contexto recuperado' e o que é a
'pergunta do usuário'? (isso normalmente vai dentro do system prompt ou da mensagem)
• O que o chatbot deve responder se a base de conhecimento não tiver nada relevante para a
pergunta? Você precisa instruir o modelo sobre isso explicitamente, ou ele já lida bem sozinho?
■ Checkpoint: faça 3 perguntas: uma claramente respondida pela sua base, uma parcialmente
relacionada, e uma totalmente fora do tema. Veja como o chatbot se comporta em cada caso —
isso revela se seu prompt está bem construído.
Etapa 6 — Loop de conversa no terminal
Objetivo: transformar isso num chatbot de verdade — um loop contínuo, não uma pergunta única por
execução.
■ Pense antes de codar
• Como o usuário vai sinalizar que quer encerrar a conversa?
• Você quer manter histórico da conversa (o chatbot lembra do que foi perguntado antes) ou cada
pergunta é independente? Qual a diferença de implementação entre as duas abordagens?
• Se for manter histórico: ele deve crescer para sempre, ou existe um limite razoável?
■ Checkpoint: converse com o chatbot por pelo menos 5 mensagens seguidas, incluindo uma
pergunta de acompanhamento (‘e sobre X que você mencionou?’) para testar se o histórico está
funcionando.
Etapa 7 — Melhorias (opcional, para elevar o nível do projeto)
Depois que o essencial estiver funcionando, essas melhorias aumentam bastante o valor do projeto
para quem for avaliar seu GitHub:
• Streaming de resposta: mostrar o texto sendo gerado aos poucos, como o [Link] faz.
• Citação de fonte: o chatbot indica de qual arquivo veio a informação usada na resposta.
• Interface web simples: usando Streamlit ou Flask, para sair do terminal.
• Tratamento de erros: o que acontece se a API falhar, ou o arquivo estiver vazio?
• Testes automatizados básicos: pelo menos testar a função de chunking e a de busca.
Checklist antes de subir para o GitHub
■ README explicando o que o projeto faz, como rodar, e um exemplo de pergunta/resposta.
■ [Link] atualizado (pip freeze > [Link]).
■ .env fora do repositório (confirme no .gitignore).
■ Pelo menos um exemplo de arquivo na knowledge_base/ incluído (ou instruções de como
adicionar o seu).
■ Commits com mensagens que contam a história do desenvolvimento (não um commit único
'projeto pronto').
Trave em algum ponto? Antes de pedir a resposta pronta, tente: (1) reler o erro com calma, (2) checar a
documentação oficial da parte específica que falhou, (3) isolar o problema num script minúsculo
separado. Se ainda travar, me chama — mas me conta o que você já tentou.