rag-assertivo
Allows using OpenAI models such as gpt-4o-mini as the answer generator when configured with OPENAI_API_KEY and RAG_GEN_MODEL, enabling cited answer generation within the RAG pipeline.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
rag-assertivo
Fail-closed RAG for PT-BR. Hybrid retrieve (dense + BM25) → cross-encoder rerank → answer with a literal citation per sentence, checked by code. Unverified text never leaves.
Senior-AI-engineer proof in ten seconds: the reranker is optional, the proof is not. A tempting “split pools” change was measured, rejected, and documented.
flowchart LR
Q["question"] --> R["hybrid retrieve<br/>e5-large + BM25"]
R --> RK["rerank<br/>jina-reranker-v2"]
RK --> G["generate JSON<br/>sentence + literal quote"]
G --> P["code proof<br/>citation_found + numbers"]
P -->|fail| X["cut / fail-closed"]
P -->|pass| V["optional LLM verifier"]
V --> OUT["answer + proofs"]LangGraph runs that chain (rag/graph.py). Tracing: docs/TRACING.md (Langfuse or LangSmith, both optional).
Why this is not a toy RAG
layer | what ships | what does not ship |
retrieve |
| a single dense ANN and a prayer |
rerank |
| trusting HNSW order |
synthetic | ementa/resumo/qa is not citable ( | quoting an LLM summary as if it were the statute |
answer | JSON sentences + literal | “the model usually cites well” |
eval | golden + traps + funnel (where the right chunk dies) + release gate with McNemar | a vibes demo notebook |
corpus | official Brazilian law (Planalto), vendored, reproducible ingest | paid courses, member-area scrapes, private transcripts |
Phrase proof is the product. Measured on a private production corpus (anonymized below): a relevance-score cutoff added zero extra trap catches on the test split — the citation contract already refused what the cutoff would have refused. So MIN_RELEVANCE stayed off.
Related MCP server: Legal MCP Server
Eval: baseline vs rerank vs pools
Numbers below are from a private PT-BR production corpus (calibration split, evidence threshold L = 0.6, hybrid e5-large + BM25 + Jina v2). They are not measurements of the public golden set in eval/golden.jsonl. Collection names, hosts, and questions are withheld; the funnel code in eval/ is the same.
Each question dies in at most one step. viva = the right chunk reached top-k.
Deaths by step (both paths summed)
corpus | variant | 1 chunk | 2 miss | 3 rerank drop | 4 MCP k-cut | viva | dominant |
A (large, mixed primary + synthetic) | hybrid + rerank (shipped) | 53 | 90 | 2 | 14 | 121 | 2 first search |
A | + split pools + synthetic penalty 0.5 | 53 | 88 | 1 | 6 | 132 | 2 (almost unchanged) |
B (smaller, multi-facet questions) | hybrid + rerank | 20 | 3 | 1 | 4 | 18 | 1 chunking |
B | + split pools + penalty 0.5 | 20 | 2 | 0 | 3 | 21 | 1 |
Latency (interleaved A/B, same pass, HNSW)
corpus | path | off p50 / p95 (s) | pools on p50 / p95 | ratio |
B | CLI k=15 | 4.93 / 5.83 | 6.01 / 6.90 | 1.22 / 1.19 |
B | MCP k=6 | 3.06 / 3.43 | 3.47 / 3.88 | 1.14 / 1.13 |
A | CLI k=15 | 5.33 / 6.56 | 6.16 / 7.92 | 1.16 / 1.21 |
A | MCP k=6 | 3.13 / 4.07 | 3.51 / 4.93 | 1.12 / 1.21 |
Decision: pools not merged. CLI gain was +2 questions (need ≥ 3, McNemar). Latency +12–22%. The hypothesis (“synthetic crowding causes step-2 deaths”) failed: 41 of 45 step-2 CLI misses were nenhum — neither dense-only nor sparse-only retrieved the evidence. Split pools mostly helped step 4 (MCP k=6 cutting a CLI hit). That is a k-policy problem, not a fusion problem.
Rerank itself is cheap in failure terms: step 3 is 1–2 deaths. Turning rerank off is not a baseline this eval uses in production; the shipped system is hybrid with Jina. The public harness (python -m eval.run_funnel --backend fake) lets you A/B RAG_RERANK=0 against 1 on the legislative golden set.
Release gate (answer rate / facet coverage / fail-closed) on the same private calibration:
corpus | variant | answer rate | facet-in-answer | p50 / p95 (s) |
B | base | 1.00 | 0.672 | 32.9 / 83.8 |
B | pools | 1.00 | 0.688 | 30.2 / 70.0 |
A | base | 1.00 | n/a | 28.3 / 46.5 |
A | pools | 1.00 | n/a | 27.4 / 40.7 |
Reproduce the public gate (lexical backend, no keys):
pip install -r requirements-dev.txt
python -m eval.run_gate run --tag demo --backend fake
python -m eval.run_funnel --backend fake --tag demo
pytest -qdocker compose up
cp .env.example .env
docker compose up -d qdrant rag
docker compose run --rm ingest # first run downloads e5-large + BM25 (~minutes)Qdrant: http://localhost:6333
MCP HTTP: http://localhost:8000/mcp
Health:
curl -fsS http://localhost:8000/healthz
Ingest reads only corpus/texts/*.md (official Planalto excerpts). No scrapers.
Without Docker (stdio MCP, after a local ingest):
python -m ingest.ingest # needs Qdrant + models
python -m rag.mcp_server # MCP_TRANSPORT=stdioThe extractive generator is the default (RAG_GEN_MODEL=extractive). Set OPENAI_API_KEY / ANTHROPIC_API_KEY and RAG_GEN_MODEL=gpt-4o-mini (or claude-haiku-4-5) for a real model. Tests never need those keys.
Talk to the MCP
Cursor / Claude Desktop — stdio (no Docker):
{
"mcpServers": {
"rag-assertivo": {
"command": "python",
"args": ["-m", "rag.mcp_server"],
"env": {
"QDRANT_URL": "http://localhost:6333",
"COLLECTION_NAME": "publico_br"
}
}
}
}HTTP (after docker compose up):
{
"mcpServers": {
"rag-assertivo": {
"url": "http://localhost:8000/mcp"
}
}
}If MCP_AUTH_TOKEN is set (≥16 chars), send Authorization: Bearer <token>.
Tools:
tool | does |
| hybrid + rerank. Each hit has |
| LangGraph retrieve → rerank → generate → code-check. |
| collection up? point count? |
| the public Planalto documents |
Contract: cite numbers and claims only from citavel=true. Ementas are a map, not a source.
CLI: python -m rag search "o que é dado pessoal" · python -m rag answer "prazo de vício no CDC"
Layout
rag/ retrieve, proof, answer, LangGraph, MCP
ingest/ chunk + secret scan + upsert (public files only)
corpus/texts/ CF/88, LGPD, CDC, LAI, Marco Civil (excerpts)
eval/ golden, traps, judge, run_gate, funnel
tests/ mocks; `pytest -q` on a clean checkoutSanitization checklist: docs/LEFT_OUT.md. Tracing: docs/TRACING.md. Eval details: eval/README.md.
Resumo PT-BR
RAG que não inventa. Busca híbrida (e5-large + BM25 no Qdrant), rerank Jina v2, resposta com citação literal por frase conferida por código (rag.proof + guarda de números). Texto sem prova não sai. Eval com golden, armadilhas, juiz, portão de release e funil (em que degrau o trecho certo morre). Corpus só de legislação pública brasileira. Pools separados foram medidos em produção e reprovados (ganho insuficiente, latência +12–22%). Orquestração LangGraph; tracing Langfuse/LangSmith opcional. docker compose up + MCP em stdio ou HTTP.
MIT. Public legislative excerpts: official texts, vendored from planalto.gov.br for reproducible ingest.
Related MCP Connectors
Resolve, search and verify legal citations against the official sources, with provenance.
Search Brazilian case law, súmulas and federal/state legislation with official source links.
Acervo jurídico brasileiro: busca, Markdown, grafo de normas e precedentes, citação verificável.
Busca e verifica jurisprudência brasileira real (+400 mil julgados) — anti-alucinação para IA.
Related MCP Servers
- AlicenseAqualityBmaintenanceServes legal retrieval-augmented generation over Brazilian federal legislation, returning exact statutory text with URN-LEX and Planalto URLs to prevent hallucination, running locally with optional GPU acceleration.5MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants and agents to search a legal document collection via hybrid BM25+dense retrieval, read articles with context, and generate full or short citations. It also exposes whole acts as Markdown resources, provides a citation-answering prompt, and supports stdio and streamable HTTP transports.MIT
- AlicenseNot gradedqualityBmaintenanceEnables Brazilian legal practitioners to search and verify case law, súmulas, and federal legislation against official sources, and to audit entire draft documents citation by citation with source provenance, collection dates, and verification status. Every response carries its own verification flag so a failed source lookup never silently becomes "no results", and citations blocked by anti-bot protections are returned as pending manual review with an official search link.MIT
- AlicenseAqualityBmaintenanceEnables verified retrieval of Brazilian primary legal sources — legislation, CVM and CMN/BCB norms, and case law — with reproducible evidence, checking whether a provision exists, whether a quoted passage is literal, which wording was in force on a given date, and whether the citations in a document resolve. Each result carries official URLs, capture timestamps and hashes, and the server abstains rather than asserting nonexistence when an official source cannot be reached.13AGPL 3.0