DEV Community

Higor Silva
Higor Silva

Posted on

Uma Análise Técnica da Arquitetura RAG da "Juci"

A criação de assistentes de conversação que operam sobre domínios de conhecimento específicos representa um desafio significativo de engenharia. A simples utilização de um Large Language Model (LLM) pré-treinado é insuficiente quando a precisão e a fidelidade a uma base de fatos controlada são requisitos primordiais. Este artigo apresenta um estudo de caso técnico da "Juci", uma assistente virtual desenvolvida pela equipe de IA da Residência Tecnológica para o Tribunal de Justiça do Amapá (TJAP), detalhando sua arquitetura baseada no padrão Retrieval-Augmented Generation (RAG). Analisaremos os componentes de seu stack tecnológico, o fluxo de ingestão e gerenciamento de dados e o pipeline de execução em tempo de execução.

Componentes da Arquitetura e Stack Tecnológico

A fundação do sistema reside em um stack de componentes de código aberto, orquestrados em Python. O núcleo generativo é o Llama 3.1 8B, um LLM servido localmente através do Ollama. Essa escolha estratégica garante a soberania dos dados e a total customização do ambiente, eliminando a dependência de APIs de terceiros e mantendo as interações dentro da infraestrutura local. Para a transformação do conhecimento textual em representações numéricas, utilizamos o modelo de embeddings mixedbread-ai/mxbai-embed-2d-large-v1, acessado via Hugging Face. Este modelo é responsável por gerar os vetores de alta dimensão que capturam a semântica do conteúdo.

O armazenamento e a recuperação desses vetores são gerenciados pelo Qdrant, um banco de dados vetorial de alta performance. O Qdrant indexa os vetores de embedding para permitir buscas por similaridade de cosseno em latência extremamente baixa, que é a operação central da fase de Retrieval. Para unir todos esses componentes, o framework LangChain atua como a principal camada de orquestração. Ele abstrai a complexidade do pipeline, gerenciando o carregamento de documentos com DataFrameLoader e DirectoryLoader, a fragmentação de texto através do RecursiveCharacterTextSplitter (configurado com chunk_size de 500 e chunk_overlap de 100 caracteres) e a integração entre o cliente Qdrant e o LLM Ollama.

Fluxograma completo da Juci
Ingestão e Manutenção Incremental da Base de Conhecimento

Uma característica crucial de um sistema RAG robusto é sua capacidade de manter a base de conhecimento atualizada de forma eficiente. Na arquitetura da Juci, implementamos uma separação lógica de dados em duas coleções distintas no Qdrant: chatbot, contendo um dataset de perguntas e respostas comuns (FAQs), e blog, com notícias e conteúdo institucional do TJAP. O script de inicialização permite, através de argumentos de linha de comando (argparse), a recriação completa das coleções ou a sua reutilização.

Fluxograma de inicialização do servidor

O destaque do design é a função inserirNovosArquivos, projetada para a atualização incremental da coleção blog. Em vez de reprocessar todo o diretório de documentos a cada atualização, esta função primeiro lista os arquivos de origem e, em seguida, itera sobre eles, consultando o Qdrant para verificar a existência de cada um através de um filtro em seus metadados (metadata.source). Apenas os documentos não encontrados no banco de dados são carregados, divididos em chunks, vetorizados e, por fim, inseridos na coleção. Essa abordagem reduz drasticamente o custo computacional e o tempo necessário para sincronizar a base de conhecimento com novas informações.

Fluxograma de alimentação da base de dados para uso de RAG

O Pipeline RAG em Execução

A interação do usuário é gerenciada por um servidor TCP implementado com o módulo socket do Python. Ao receber uma query, o sistema não a envia diretamente ao LLM. Primeiramente, a fase de Retrieval é acionada pela função custom_prompt. Esta função executa duas buscas de similaridade paralelas no Qdrant: uma na coleção chatbot (com k=5) e outra na coleção blog (com k=15), recuperando os chunks de texto mais relevantes de cada fonte.

Os resultados de ambas as buscas são então concatenados para formar um bloco de contexto unificado. Este contexto é injetado em um prompt template estruturado, que serve a um duplo propósito. Além de fornecer ao LLM os dados factuais para formular a resposta, o template também realiza a engenharia de persona, instruindo o modelo sobre sua identidade, tom de voz e regras de comportamento (guardrails), como a proibição de responder a tópicos fora do escopo do TJAP. Somente após essa fase de Augmentation, o prompt completo é enviado ao Llama 3.1 para a geração final da resposta, que é então retornada ao usuário.

Guardrails e processamento da resposta final

Concluímos então, que este design modular e eficiente exemplifica como a combinação de LLMs locais, bancos de dados vetoriais e uma lógica de orquestração cuidadosa pode produzir assistentes de IA especializados, seguros e altamente confiáveis.

Top comments (0)