🏗️ Retrieval — Arquitetura
RAG — Arquitetura de Ingestion e RetrievalApresentação
1. Arquitetura Geral — Arquitetura Ideal de Retrieval
Este documento descreve a arquitetura ideal de retrieval: como o sistema encontra e compõe a resposta a partir de múltiplas fontes (docs, SQL, graph). A ingestion (pasta ../ingestion/) prepara os dados; o retrieval consulta-os e sintetiza.
1. Visão Geral
Sistema com 5 blocos: Query Analyzer, Strategy Router, Execution (4 pipelines), Validação e Observabilidade. O Router escolhe uma única estratégia por consulta. A saída passa por um bloco de Validação (planeado) antes da resposta final. Fontes: docs (Chroma), SQL (Postgres), graph (Neo4j) — as três integradas no multi_backend.
Diagrama de Fluxo Real
O Router escolhe uma das 4 estratégias. A saída de cada pipeline passa por Validação antes da resposta final. Validação permite detectar retrieval fraco ou alucinação e escalar/recusar.
+----------------------+
| Consulta do Utilizador |
+----------+-----------+
|
v
+------------+-------------+
| Query Analyzer |
| (heurísticas + classifier|
| + normalizer) |
+------------+-------------+
|
v
+------------+-------------+
| Strategy Router |
| (escolhe UMA estratégia) |
+------------+-------------+
|
+------------------------+----+----+------------------------+
| | | |
v v v v
+----------------+ +----------------+ +----------------+ +------------------+
| direct_answer | | simple_rag | | enriched_rag | | multi_backend |
| só LLM | | retrieve→ctx | | decompose→ | | planner→tools |
| sem grounding | | →generate | | retrieve→merge | | (docs+sql+graph)→|
+--------+-------+ +-------+-------+ | →synthesize | | synthesize |
| | +-------+--------+ +---------+--------+
| | | |
+----------------+----------------------+--------------------+
|
v
+------------+-------------+
| Validação |
|--------------------------|
| • cobertura de citações |
| • qualidade do retrieval |
| • verificação de groundedness |
| • conflito entre fontes |
+------------+-------------+
|
+--------------------+--------------------+
| |
v (OK) v (falha)
+----------------------+ +----------------------+
| Resposta Final | | Escalar / Esclarecer |
| (citações, metadata) | | ou retry pipeline |
+----------------------+ +----------------------+
Estado da validação: Planeada (não implementada). Atualmente o fluxo vai diretamente de cada pipeline para a Resposta Final, sem gate de validação.
2. Bloco 1 — Query Analyzer
Cérebro de decisão inicial. Não responde; apenas interpreta a query.
Objetivos
Determinar:
- Se a pergunta precisa de grounding
- Se basta conhecimento do modelo
- Se é necessário retrieval
- Se a pergunta envolve uma ou várias fontes
- Sinais de complexidade
- Tipo de tarefa: factual, comparativa, analítica, procedural, exploratória
Inputs
- Texto da query
- Contexto da conversa (opcional)
- Perfil do utilizador (opcional)
latency_preference(rápido / normal / qualidade)
Outputs
Ver 08-CONTRACTS para o schema completo de QueryAnalysis.
Implementação em 3 Camadas ✅
| Camada | Descrição | Estado |
|---|---|---|
| A — Heurísticas | Regras baratas, keywords PT/EN em config/heuristics.yaml | ✅ Implementado |
| B — Classifier | LLM gpt-4o-mini, temp=0, saída estruturada JSON | ✅ Implementado |
| C — Normalização | Consolida heurísticas + classifier → QueryAnalysis | ✅ Implementado |
3. Bloco 2 — Strategy Router
Traduz a análise em pipeline de execução. Rule-based, determinístico.
Estratégias
| Estratégia | Descrição | Estado |
|---|---|---|
direct_answer | LLM only, sem grounding | ✅ Implementado |
simple_rag | Retrieve (Chroma) → context → generate | ✅ Implementado |
enriched_rag | Decomposition → multi-query retrieval → merge → synthesis | ✅ Implementado |
multi_backend_agent | Planner → tools (docs + SQL) → synthesis | ✅ Implementado |
clarify_first | Pedir esclarecimento | ❌ Planeado |
safe_decline | Recusar com mensagem controlada | ❌ Planeado |
Princípios do Router
- Explicável — decisão auditável (routing_reasoning)
- Observável — métricas de routing (parcial)
4. Bloco 3 — Execution Layer
Estratégia A — Direct Answer ✅
Quando: needs_grounding=false, complexity=low, risk_level=low.
Pipeline implementado:
Query → LLM (prompt direto) → answer
Ficheiro: src/pipelines/direct_answer.py
Estratégia B — Simple RAG ✅
Quando: query factual, fonte única, sem multi-source.
Pipeline implementado:
Query → retrieval (Chroma, cosine) → context packing → grounded generation
Nota: Sem reranker; usa score de similaridade do Chroma diretamente.
Ficheiro: src/pipelines/simple_rag.py
Estratégia C — Enriched RAG ✅
Quando: task_type comparative/analytical, ou complexity=high.
Pipeline implementado:
Query → decomposition (LLM, sub-queries) → multi-query retrieval → merge
→ dedupe by passage → context packing → synthesis
Nota: Sem hybrid search; sem verificação de cobertura de citações.
Ficheiro: src/pipelines/enriched_rag.py
Estratégia D — Multi-Backend Agent ✅
Quando: requires_multi_source ou requires_structured_data, ou risk_level=high com multi-source.
Pipeline implementado (LangGraph):
Query → planner (LLM: use_docs? use_sql? use_graph?) → tools
→ [DocStore.retrieve | SQLTool.query | Neo4jTool.query] (paralelo conceptual)
→ docs_context + sql_context + graph_context → synthesis (LLM)
Diagrama interno:
+----------+
| planner | JSON: {"use_docs": bool, "use_sql": bool, "use_graph": bool}
+-----+-----+
|
v
+----------+
| tools | • use_docs → Chroma retrieval
| | • use_sql → text-to-SQL → Postgres (SELECT only)
| | • use_graph → text-to-Cypher → Neo4j (MATCH only)
+-----+-----+
|
v
+------------+
| synthesize | Combina docs_context + sql_context + graph_context
+------------+
Fontes: docs (Chroma), SQL (Postgres NovaOps), graph (Neo4j) — as três integradas.
Ficheiro: src/pipelines/multi_backend_agent.py
5. Bloco 4 — Validação (planeado)
Gate entre a saída de cada pipeline e a resposta final. Permite detetar problemas e escalar ou recusar em vez de devolver resposta de má qualidade.
Verificações planeadas
| Verificação | Descrição | Quando aplicável |
|---|---|---|
| Cobertura de citações | A resposta cita os documentos retornados? | simple_rag, enriched_rag, multi_backend |
| Qualidade do retrieval | Score médio dos chunks > limiar? | RAG paths |
| Groundedness | A resposta está sustentada no contexto? (NLI, entailment) | RAG paths |
| Conflito entre fontes | Dados de docs vs SQL contradizem-se? | multi_backend |
Comportamento em falha
- Escalar: retry com estratégia mais pesada (ex.: simple_rag → enriched_rag)
- Esclarecer: pedir esclarecimento ao utilizador
- Declínio seguro: devolver mensagem controlada em vez de resposta arriscada
Estado: ❌ Não implementado. O fluxo atual não tem este gate.
6. Bloco 5 — Evaluation / Observability
Estado Atual
- ExecutionResult em cada resposta:
strategy_used,sources_used,documents_retrieved,latency_ms,cost_usd,fallback_triggered - Logs estruturados parciais
- Sem dashboard, métricas agregadas, feedback do utilizador, groundedness automática
Métricas Planeadas
| Categoria | Métricas |
|---|---|
| Sistema | latência total, custo por query, taxa de fallback |
| Retrieval | cobertura de citações, groundedness |
| Router | router accuracy, over/under-routing |
| Qualidade | user satisfaction, unresolved rate |
7. Uso de LangGraph
| Path | Em LangGraph? | Razão |
|---|---|---|
| Analyzer → Router → Execution | ❌ Não | GraphRunner custom (linear) |
| direct_answer | ❌ Não | Fluxo simples |
| simple_rag | ❌ Não | Fluxo linear |
| enriched_rag | ❌ Não | Fluxo linear |
| multi_backend_agent | ✅ Sim | planner → tools → synthesize com estado |
Ficheiro: src/pipelines/multi_backend_agent.py usa StateGraph do LangGraph.
8. O Que Falta (v1 → v2)
| Item | Descrição | Ver secção 9 |
|---|---|---|
| clarify_first | Estratégia para pedir esclarecimento | Roadmap |
| safe_decline | Recusar queries fora de âmbito | Roadmap |
| Fallback / Retry | Retry inteligente antes de escalate | 9.4 |
| Confidence Score | Score composto em vez de boolean | 9.1 |
| Query Rewriter | Entre Analyzer e Router | 9.2 |
| Cost & Latency | Budget no router | 9.3 |
| Bloco de Validação | Citation, groundedness, source conflict | 5, 9.1 |
| Reranker | Cross-encoder ou Cohere | — |
| Hybrid search | BM25 + vector | — |
| Neo4j no multi_backend | Graph como terceira tool | — |
| Data Freshness | requires_fresh_data, version filters | 9.5 |
| Observability | Metrics, tracing, logs | 9.6 |
| Feedback Loop | Learning de thumbs, reformulações | 9.7 |
9. Arquitetura v2 — Roadmap (produção)
Visão evoluída para passar de "bom" a "muito forte" em contexto real.
Diagrama v2
+----------------------+
| Consulta do Utilizador |
+----------+-----------+
|
v
+------------+-------------+
| Query Analyzer |
| (+ requires_fresh_data |
| + latency_budget_ms |
| + cost_budget) |
+------------+-------------+
|
v
+------------+-------------+
| Query Rewriter |
| (normalize, expand, |
| disambiguate) |
+------------+-------------+
|
v
+------------+-------------+
| Strategy Router |
| (complexity + cost + |
| latency budget aware) |
+------------+-------------+
|
+------------------------+------------------------+
| | |
v v v
direct_answer simple_rag enriched_rag multi_backend
| | |
+------------------------+------------------------+
|
v
+------------+-------------+
| Validation Layer |
+------------+-------------+
|
v
+------------+-------------+
| Confidence Scoring |
| (retrieval + citation + |
| groundedness + consist.)|
+------------+-------------+
|
+------------------------+------------------------+
| | |
v (conf > 0.8) v (0.4-0.8) v (conf < 0.4)
+----------------+ +---------------------+ +---------------------+
| Resposta Final | | Retry (rewrite, | | Escalar / Esclarecer|
+----------------+ | top_k, BM25+vector) | +---------------------+
| +---------------------+
| |
v v
+----------------+ (novo attempt)
| Observability |
| (metrics, |
| tracing, logs)|
+-------+--------+
|
v
+----------------+
| Feedback Loop |
| (thumbs, |
| reformulações,|
| cliques) → |
| Router tuning |
+----------------+
Melhorias detalhadas
1. Confidence Score explícito (substituir boolean)
Em vez de validação → ok / falha, usar score composto:
{
"retrieval_confidence": 0.82,
"citation_coverage": 0.75,
"groundedness": 0.9,
"answer_consistency": 0.85,
"final_confidence": 0.81
}
Fórmula: confidence = w1*retrieval + w2*reranker + w3*citation + w4*consistency
Decisão:
confidence >= 0.8→ aceitar0.4 <= confidence < 0.6→ retry melhoradoconfidence < 0.4→ escalar / esclarecer
2. Query Rewriter explícito
Entre Analyzer e Router — normalizar, expandir, desambiguar.
Exemplo: "policy despesas" → "expense policy reimbursement rules NovaOps"
Melhora retrieval sem alterar o restante da arquitetura.
3. Cost & Latency Awareness no Router
Além de complexidade e tipo, o router deve considerar:
{
"latency_budget_ms": 1500,
"cost_budget": "low"
}
Exemplo:
- consulta complexa + latência baixa → enriched_rag light
- consulta complexa + orçamento alto → multi_backend
4. Retry inteligente (antes de escalar)
Em vez de falha → escalar imediatamente:
- Query rewrite (reformular)
- Aumentar top_k
- Hybrid (BM25 + vector)
Só escalar para estratégia mais pesada se retry falhar. Reduz custo.
5. Data Freshness Awareness
No Analyzer: requires_fresh_data: true para queries sensíveis a tempo.
No Retrieval: filtros version=latest ou timestamp > X para evitar respostas desatualizadas.
6. Observabilidade explícita
Bloco dedicado com:
- metrics store — latência, custo, strategy, fallback rate, confidence
- tracing — por query, por etapa
- logs estruturados — para debugging e auditoria
7. Ciclo de Feedback (aprendizagem)
Resposta Final
|
v
Feedback do Utilizador / Sinais implícitos
(thumbs down, reformulação, clique em fonte)
|
v
Armazém de Avaliação
|
v
Router tuning / Retrieval tuning
Permite melhoria contínua de routing e retrieval com dados reais.
Prioridade sugerida
| Ordem | Melhoria | Impacto | Esforço |
|---|---|---|---|
| 1 | Confidence Score | Alto | Médio |
| 2 | Query Rewriter | Alto | Baixo |
| 3 | Cost & Latency no Router | Alto | Médio |
| 4 | Retry inteligente | Alto | Médio |
| 5 | Observability | Alto | Médio |
| 6 | Data Freshness | Médio | Médio |
| 7 | Feedback Loop | Muito alto | Alto |
10. Ligação com Ingestion
O retrieval consome a saída da ingestion:
| Fonte | Proveniente de | Metadados úteis |
|---|---|---|
| Vector store | Document Pipeline (chunks, embeddings) | doc_id, version, freshness_ts |
| Postgres | SQL Pipeline (tabelas, views, SCD2) | valid_from, valid_to |
| Neo4j | Graph Pipeline (nós, edges) | valid_from, valid_to, is_active |
Ver ../ingestion/07-RETRIEVAL.md e 07-FRESHNESS-METADATA para metadados freshness-aware.
11. Resposta para Entrevista Técnica
"Eu não desenharia um único pipeline de RAG para todas as queries. Em produção, as perguntas têm níveis diferentes de complexidade, criticidade e necessidade de grounding. Por isso, pensaria numa arquitetura adaptativa com quatro blocos: Query Analyzer, Strategy Router, Execution Layer com vários paths, e Evaluation/Observability. O objetivo seria usar fast paths para queries simples e low-latency, enriched retrieval para casos intermédios, e multi-backend orchestration com LangGraph apenas quando a pergunta exige várias fontes (docs + SQL + graph) ou reasoning mais complexo."
Zona de prática
Sem perguntas. Clica em Editar para adicionar.