Dictámenes Contraloría
¿Cuál es el criterio aplicable, sigue vigente y qué línea jurisprudencial lo sostiene?
FastAPI · SQLite FTS5 · Grafo force-directed · 18.747 dictámenes · :8011
- Estado
- En vivo · buscador + grafo
- Fuente de datos
- Buscador CGR · API JSON interna
- Stack
- FastAPI · SQLite FTS5 · grafo force-directed
- Cobertura
- 18.747 dictámenes · 28.877 relaciones
- Período
- 2017–2026 (en ampliación)
- Infraestructura
- Raspberry Pi · $0 cloud
El problema
La Contraloría General de la República fija, vía dictámenes, gran parte del criterio administrativo del Estado chileno. Su buscador oficial resuelve la consulta puntual, pero no ayuda a lo que de verdad hace quien investiga un tema: encontrar el criterio aplicable, verificar si sigue vigente y rastrear la línea jurisprudencial —qué dictamen aplica, reconsidera o confirma a cuál—. Quise convertir ese corpus en una base de conocimiento navegable, no en una lista de resultados.
Qué construí
Prototipé un scraper que consume la API JSON interna del buscador de la CGR, normaliza la metadata de cada dictamen y la guarda en una base local con índice full-text. Encima, dos formas de explorar: un buscador con ranking y un grafo interactivo tipo Obsidian.
- check_circle Corpus de 18.747 dictámenes (2017–2026) con ~32 campos de metadata cada uno: materia, descriptores, fuentes legales, destinatarios y el texto completo.
- check_circle Búsqueda full-text con SQLite FTS5 y ranking BM25, insensible a acentos, sobre materia, descriptores, fuentes legales y cuerpo del dictamen.
- check_circle Un grafo de la línea jurisprudencial: parseé el campo de acciones (aplica, reconsidera, confirma…) a 28.877 relaciones navegables en ambos sentidos (qué cita un dictamen y por quién es citado).
- check_circle Dos vistas del grafo: por relaciones (citas) y por descriptores (los sectores temáticos del tesauro de la CGR). Se puede buscar un tema —"compras públicas"— y ver en qué sectores caen los dictámenes.
- check_circle Todo corre sobre una Raspberry Pi, $0 cloud, con FastAPI sirviendo la API y el dashboard.
Qué es real y qué es parcial
La honestidad es parte del prototipo: el corpus todavía no es completo y conviene decirlo.
- verified Real: cada dictamen, su metadata y su texto vienen directo de la fuente oficial de la CGR. Las relaciones se extraen del propio campo de acciones del documento.
- schedule Parcial: por ahora la base cubre 2017–2026. Muchas citas apuntan a dictámenes más antiguos aún no descargados — aparecen en el grafo como nodos "fuera del corpus" y se resolverán al ampliar el histórico.
- build En desarrollo: la detección automática de contradicciones (criterios opuestos sobre la misma materia) es el siguiente paso; hoy la línea jurisprudencial se navega a mano.
Cómo funciona
El backend es FastAPI + SQLite. El scraper consume la API del buscador con paginación y filtro por año, deduplica por identificador y es idempotente. La metadata va a una tabla principal con índice FTS5; las acciones se normalizan a una tabla de relaciones que alimenta el grafo. La API propia expone la búsqueda, la ficha de cada dictamen con su grafo local, y la red completa del corpus —por citas o por temas—. El grafo se dibuja con una librería force-directed, sin paso de build.
Decisiones técnicas
Modelar citas como grafo, no como lista
Parseé el campo de acciones (aplica, reconsidera, confirma…) a 28.877 relaciones navegables en ambos sentidos. Investigar jurisprudencia es seguir la línea, no leer resultados sueltos; el grafo modela exactamente eso.
FTS5 + BM25 local, sin LLM
Búsqueda full-text insensible a acentos sobre ~32 campos, con ranking BM25 y sin embeddings ni modelo. Es barato, reproducible y corre en una Pi — y para esta tarea el ranking léxico rinde de sobra.
Scraper idempotente por año
Consume la API del buscador paginando y deduplicando por identificador, así re-correr nunca duplica nada. Permite ampliar el histórico hacia atrás de forma incremental, año por año.
¿Quieres explorar la jurisprudencia?
El buscador y el grafo corren ahora mismo sobre la Pi.