← Voltar a RAG — Arquitetura de Ingestion e Retrieval
🔍 Core do Retrieval
RAG — Arquitetura de Ingestion e RetrievalApresentação
2. Núcleo do Retrieval — Como Encontro e Componho a Resposta
Este documento responde à pergunta central: "Como é que encontro e componho a resposta?"
1.1 Visão Conceitual
O retrieval em sistemas RAG tem duas funções:
- Encontrar — localizar evidência relevante em fontes (vector store, SQL, graph)
- Compor — combinar evidência, sintetizar e devolver resposta com citações
Query → [Encontrar] → Chunks / Rows / Graph results
→ [Compor] → Contexto packed
→ LLM synthesis → Resposta + Citações
1.2 DocStore — Vector Retrieval
Implementação Atual
| Componente | Valor |
|---|---|
| Backend | Chroma (persistent, local) |
| Embedding model | sentence-transformers (all-MiniLM-L6-v2) |
| Similarity | Cosseno (hnsw:space=cosine) |
| Chunking | Recursive, chunk_size=600, overlap=100 |
| Coleção | "docs" |
Fluxo de Indexação
Markdown files (.md)
→ chunk_text() (quebrar em frase/nova linha)
→ SentenceTransformer.encode()
→ Chroma.upsert(ids, documents, embeddings, metadatas)
Script: ingest-rag/scripts/ingest_docs.py
Fluxo de Retrieval
Query (string)
→ model.encode([query])
→ collection.query(query_embeddings, n_results=top_k, include=["documents","metadatas","distances"])
→ Converter distance → score: 1 - (dist/2) para cosseno
→ Retornar [(doc_id, passage, score), ...]
Metadados nos Chunks
| Campo | Exemplo | Uso |
|---|---|---|
doc_id | expense_policy | Identificar fonte na citação |
Futuro (ver ingestion): version, freshness_ts, is_active, valid_from, valid_to
Limitações Atuais
- Sem reranker (usa score do Chroma diretamente)
- Sem hybrid search (BM25 + vector)
- Sem filtros por metadata (ex.: document_type)
- Chunking fixo (sem semantic chunking por documento)
1.3 Chunking — Teoria e Prática
Estratégia Atual
- Tipo: RecursiveCharacterTextSplitter-style (break em
\n,.,;) - chunk_size: 600 caracteres
- chunk_overlap: 100 caracteres
- Objetivo: Balanço entre contexto suficiente e granularidade
Teoria Alternativa (não implementada)
| Estratégia | Descrição | Quando usar |
|---|---|---|
| Semantic chunking | Dividir por secções/headers, parágrafos lógicos | Docs estruturados (MD com ##) |
| Sentence-based | Quebrar por frases completas | Texto corrido |
| Overlap variável | Mais overlap em zonas críticas | Políticas, procedimentos |
| Chunk plan por documento | chunk_plan.json por tipo de doc | Dados NovaOps (document_manifest) |
Versioning de Chunking
Quando muda a estratégia de chunking (ex.: 600→800), deve-se:
- Criar nova
chunking_versionno registry - Reprocessar documentos ativos
- Não misturar chunks de versões diferentes na mesma coleção
1.4 Embedding — Modelo e Similaridade
Modelo Atual
- ID:
all-MiniLM-L6-v2 - Dimensão: 384
- Vantagens: Rápido, local, sem API
- Limitações: Menos preciso que modelos maiores (e5-large, multilingual-e5)
Teoria: Escolha de Modelo
| Critério | Consideração |
|---|---|
| Idioma | PT/EN misto → multilingual-e5 ou paraphrase-multilingual |
| Domínio | Técnico → fine-tune ou modelo especializado |
| Latência | Local vs API (OpenAI embeddings) |
| Custo | sentence-transformers livre, API paga |
Versioning de Embedding
Regra: Não misturar embeddings de modelos diferentes na mesma coleção.
Quando mudar modelo:
- Nova coleção ou
embedding_versionno metadata - Re-embed total ou progressivo
- Registry com
embedding_versionpor asset
1.5 Top-K e Ranking
Atual
- simple_rag: top_k=5 (configurável)
- enriched_rag: top_k_per_query=4, merge, dedupe, total ~ retrieval_top_k*2
- multi_backend: top_k=retrieval_top_k*2 para docs
Teoria: Reranker
Após retrieval inicial (top_k=20 ou 50):
- Cross-encoder (ex.: Cohere rerank, cross-encoder/ms-marco) reordena
- Top 5–10 passam para synthesis
- Melhora precisão sem aumentar custo de embedding
Estado: Planeado, não implementado.
1.6 Composição da Resposta
Packing de Contexto
Contextos das fontes são formatados para o LLM:
[Source: expense_policy]
Passage 1...
---
[Source: security_policy]
Passage 2...
Synthesis
O LLM recebe:
- System prompt (instruções)
- Prompt do utilizador: Contexto + Consulta
- Deve responder baseado no contexto e citar fontes
Citações
Cada resposta inclui citations: lista de {doc_id, passage, score} para os chunks usados.
1.7 Configuração Relevante
| Variável | Default | Descrição |
|---|---|---|
embedding_model | all-MiniLM-L6-v2 | Modelo de embedding |
retrieval_top_k | 5 | Chunks por query (simple_rag) |
chunk_size | 600 | Caracteres por chunk |
chunk_overlap | 100 | Overlap entre chunks |
chroma_db_path | data/chroma_db | Path Chroma persistente |
enriched_max_subqueries | 4 | Sub-queries na decomposição |
enriched_top_k_per_query | 4 | Chunks por sub-query |
1.8 Resumo do Fluxo Completo
Consulta do Utilizador
|
v
Query Analyzer → QueryAnalysis (needs_grounding, sources, complexity, ...)
|
v
Strategy Router → strategy (direct_answer | simple_rag | enriched_rag | multi_backend_agent)
|
v
Pipeline:
• direct_answer: nenhum retrieval
• simple_rag: DocStore.retrieve(query, top_k) → pack → LLM
• enriched_rag: decompose → multi-retrieve → merge → pack → LLM
• multi_backend: planner → [DocStore | SQLTool | Neo4jTool] → pack → LLM
|
v
Resposta + Citações + ExecutionResult
Zona de prática
Sem perguntas. Clica em Editar para adicionar.