El problema
El RAG corporativo tiene un fallo silencioso: el recuperador trae un fragmento que el usuario nunca tuvo permiso para leer, y el modelo resume diligentemente el secreto. La mayoría de sistemas lo "arreglan" depurando la respuesta después — demasiado tarde, el dato ya llegó al modelo. Strata aplica el control de acceso dentro de la recuperación.
Enfoque y compromisos
El nivel de acceso del usuario es un techo:
public < internal < confidential < restricted. Esa ACL se aplica como filtro
dentro de la búsqueda vectorial de Qdrant y de la cláusula WHERE del grafo
en Neo4j, antes de que ningún contexto llegue al generador — así que un dato de
mayor nivel ni siquiera puede recuperarse, mucho menos filtrarse.
Sobre esa frontera está la ingeniería de recuperación:
- Recuperación híbrida — densa (BGE-M3) + dispersa BM25, fusionadas por RRF en Qdrant — seguida de expansión por grafo en Neo4j alrededor de las semillas vectoriales, fusión y reranking con un cross-encoder BGE.
- Un bucle agéntico en LangGraph (reescribir → recuperar → generar → crítico), acotado por un límite de iteraciones y un presupuesto duro de tiempo de reloj, con una mitigación que omite la reescritura si se excede.
- Totalmente local / OSS — Qwen3, BGE-M3, reranker BGE, Qdrant, Neo4j. Sin API de modelo en la nube.
Resultados
- Seguridad de ACL: 100% en los casos de denegación — el secreto se filtra en Qdrant y en Neo4j, así que nunca llega al modelo ni siquiera cuando el agente agota todo su presupuesto de reintentos.
- Un fallo de recuperación medido, diagnosticado y corregido: la búsqueda solo densa no lograba fijar IDs exactos de CVE entre 150 registros casi idénticos (recall 0.79); un híbrido denso + BM25 llevó el recall a 1.00.
- Un juez LLM estricto añadido junto a la métrica laxa de subcadena bajó un 100% saturado a 71% — la cifra que discrimina, y una lección sobre diseño de métricas.
Lo que señalaría
Los conjuntos dorados son pequeños (10–20 ítems, una sola ejecución, en una GPU local de 8 GB), así que las diferencias entre paso único y agente están dentro del ruido — y por eso cada informe de evaluación guarda las respuestas en bruto. Así detecté un bug en el comparador de rechazos que era culpa de la métrica, no del modelo.