Skip to content

Arthurss123/rag-chatbot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RAG Chatbot — Q&A sobre documentos PDF

Chatbot que responde perguntas sobre documentos PDF usando RAG (Retrieval-Augmented Generation). O sistema busca os trechos mais relevantes nos documentos e usa um LLM para gerar a resposta com base nesse contexto, citando a fonte (arquivo e página) de onde a informação foi extraída.

Arquitetura

O pipeline funciona em duas fases:

Indexação (executada uma vez, ou sempre que os documentos mudam)

PDFs → carregamento → chunking com overlap → embeddings → índice FAISS salvo em disco

Consulta (executada a cada pergunta)

Pergunta → embedding da pergunta → busca por similaridade no FAISS
         → top-k chunks mais relevantes → prompt com contexto → LLM → resposta + fontes

Stack

Componente Tecnologia Motivo
API FastAPI validação automática, documentação interativa, async nativo
Orquestração LangChain (LCEL) composição declarativa do pipeline RAG
LLM Groq (Llama 3.3 70B) gratuito, alta velocidade de inferência
Embeddings HuggingFace all-MiniLM-L6-v2 roda localmente, sem custo, sem enviar dados para fora
Vector Store FAISS busca por similaridade local, sem infraestrutura externa
Validação Pydantic / pydantic-settings schemas tipados e configuração via .env
Containerização Docker / Docker Compose ambiente reproduzível

Estrutura do projeto

rag-chatbot/
├── app/
│   ├── __init__.py
│   ├── config.py        # configurações centralizadas (lidas do .env)
│   ├── ingest.py         # pipeline de indexação: PDF → chunks → embeddings → FAISS
│   ├── retriever.py       # carrega o índice FAISS e expõe a busca por similaridade
│   ├── chain.py          # monta o pipeline RAG: prompt + LLM + formatação de contexto
│   ├── schemas.py         # modelos Pydantic de request/response da API
│   └── main.py            # endpoints FastAPI: /chat, /ingest, /health
├── tests/
│   ├── conftest.py
│   └── test_rag.py        # testes unitários, de integração e de API
├── data/                  # PDFs a serem indexados (não versionados)
├── vectorstore/            # índice FAISS gerado (não versionado)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example

Como rodar

Pré-requisitos

  • Python 3.11+
  • Conta gratuita no Groq Console para obter uma API key

1. Clonar e instalar dependências

git clone https://github.com/Arthurss123/rag-chatbot.git
cd rag-chatbot

python -m venv venv
source venv/bin/activate      # Linux/Mac
venv\Scripts\activate         # Windows

pip install -r requirements.txt

2. Configurar variáveis de ambiente

cp .env.example .env

Edite o .env e preencha sua chave do Groq:

GROQ_API_KEY=chave_aqui
LLM_MODEL=llama-3.3-70b-versatile

3. Adicionar documentos

Coloque os arquivos PDF que deseja indexar dentro da pasta data/.

4. Indexar os documentos

python -m app.ingest

Esse comando carrega os PDFs, divide o texto em chunks, gera os embeddings e salva o índice FAISS em vectorstore/. Na primeira execução, o modelo de embedding (~90MB) é baixado e fica em cache local.

5. Subir a API

uvicorn app.main:app --reload

A API fica disponível em http://localhost:8000, com documentação interativa (Swagger) em http://localhost:8000/docs.

Rodando com Docker

docker-compose up --build

As pastas data/ e vectorstore/ são montadas como volumes, então é possível adicionar PDFs e reindexar sem reconstruir a imagem.

Endpoints da API

GET /health

Verifica se a API está no ar e se o índice FAISS está carregado.

POST /ingest

Reprocessa todos os PDFs da pasta data/ e reconstrói o índice FAISS. Use sempre que adicionar, remover ou atualizar documentos.

POST /chat

Recebe uma pergunta e retorna uma resposta baseada nos documentos indexados, com a lista de fontes (arquivo e página) usadas para gerar a resposta.

Request:

{
  "question": "Quais são as boas práticas em RAG?",
  "history": []
}

Response:

{
  "answer": "As boas práticas em RAG incluem usar chunk overlap para preservar contexto, limitar o top-k a 3-5 chunks, citar sempre a fonte dos trechos recuperados, separar o prompt template do código e monitorar a qualidade com métricas como faithfulness e relevancy.",
  "sources": [
    { "file": "manual.pdf", "page": 6 }
  ],
  "model": "llama-3.3-70b-versatile"
}

O campo history aceita uma lista de mensagens anteriores (role: user ou assistant, content: texto), permitindo perguntas de follow-up que dependem do contexto da conversa. A API é stateless: o histórico é enviado pelo cliente a cada requisição, o servidor não mantém estado entre chamadas.

Decisões de design e boas práticas aplicadas

Chunking com overlap. Os documentos são divididos em chunks de ~500 caracteres com 150 caracteres de sobreposição entre chunks consecutivos. O overlap evita que uma informação fique cortada exatamente na borda entre dois chunks, perdendo contexto.

Top-k limitado a 4 chunks. Passar muitos chunks para o LLM não melhora a resposta — degrada. Contextos muito longos fazem o modelo perder atenção em informações no meio do prompt. Entre 3 e 5 chunks é o equilíbrio entre contexto suficiente e foco.

Prompt template com fallback explícito. O prompt instrui o modelo a responder apenas com base no contexto fornecido e a admitir explicitamente quando a informação não está disponível, em vez de inventar uma resposta. Isso reduz significativamente a taxa de alucinação.

Citação de fontes. Toda resposta inclui o arquivo e a página de onde a informação foi extraída, permitindo verificação e auditoria.

Modelo de embedding local. A vetorização roda na CPU via HuggingFace, sem custo por requisição e sem enviar o conteúdo dos documentos para serviços externos.

Temperatura zero no LLM. Para tarefas de Q&A sobre documentos, respostas determinísticas e factuais são preferíveis a respostas criativas.

Singletons para modelo de embedding e índice FAISS. Carregados uma única vez na inicialização da API e reutilizados em todas as requisições, evitando recarregar ~90MB a cada chamada.

Testes

O projeto inclui testes unitários, de integração e de API:

pytest tests/ -v
  • Unitários: funções de formatação de contexto, histórico e extração de fontes, testadas isoladamente.
  • Integração: o pipeline RAG completo (ask()), com o LLM e o índice FAISS mockados.
  • API: endpoints testados via TestClient do FastAPI, incluindo validação de schemas e tratamento de erros.

Possíveis evoluções

  • Substituir FAISS por um vector store com servidor dedicado (Qdrant, Weaviate) para cenários de maior escala.
  • Adicionar uma etapa de reranking após o retrieval para refinar a seleção dos chunks.
  • Implementar streaming de resposta via StreamingResponse.
  • Avaliação automática da qualidade das respostas com métricas de faithfulness e relevancy (RAGAS).

About

Chatbot RAG que responde perguntas sobre PDFs usando LangChain, FAISS e Groq (Llama 3.3)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

No contributors

Languages