citefid 0.1.0: verificar la fidelidad de citas en wikis OKF con NLI (AUC 0.70 sobre código)
Los generadores de wikis OKF comprueban que la cita existe, no que su contenido respalde la afirmación. citefid cierra esa brecha: verifica fidelidad, no existencia.
El problema
Los wikis de conocimiento generados por LLM que siguen el estándar OKF (Open Knowledge Format) incluyen citas a fragmentos de código o documentación. El pipeline típico valida que el archivo citado exista y que el rango de líneas sea válido. Eso no dice nada sobre si el fragmento confirma lo que el texto afirma.
La literatura documenta el hueco: citas que apuntan a fuentes que no respaldan el claim (CiteCheck; "Cited but Not Verified"; grounding engañoso). Un lector que confía en la wiki hereda una afirmación sin verificar.
citefid no genera wikis. Toma un claim y su cita, y responde si el fragmento fuente lo confirma, contradice o es neutral.
Lo que no es
- No genera wikis OKF (eso lo hacen otras herramientas; citefid verifica después del build).
- No resuelve fuentes externas fueras del bundle citado (web/PDF ajenos).
- No hace verificación multi-hop ni razonamiento profundo (MVP: un pasaje por cita).
Cómo funciona
Pipeline determinista en tres pasos:
-
resolve— La cita se resuelve a su fragmento fuente. Código/CRD: URLblob/<commit>/<path>#Lx-Ly→ descarga el archivo en ese commit y recorta las líneas. Prosa:^[slug.md]→ resuelve por prefijo-hash (el archivo real lleva sufijo de hash), exigiendo coincidencia única. -
retrieve— Recupera el párrafo relevante antes de verificar. Híbrido: keyword primero (tokens distintivos del claim), embeddings (MiniLM) como tie-break. Salta frontmatter YAML. Este paso es obligatorio, no opcional. -
verify— NLI (cross-encoder/nli-deberta-v3-small, CPU, sin API key) sobre el pasaje recuperado, agregando sobre N evidencias (soporte = máx. entail − contra). Emite reporte CSV/JSON por-evidencia, determinista.
Por qué el retrieve es obligatorio (no decoración)
El fallo más caro del desarrollo fue creer que NLI sobre el documento entero bastaba. NLI sobre span[:1500] (truncado) daba un AUC engañoso de 0.92 en prosa: el hecho real estaba más allá del carácter 1500 y el modelo solo veía el frontmatter, "confirmando" por contexto temático. Sin recuperar el pasaje correcto, cualquier número de prosa es humo. De ahí que retrieve sea un paso duro del pipeline.
Resultados (con metodología, sin redondear)
Sobre el único terreno auditado sin fallos — código/CRD de un claim-ledger real (crossplane), 206 pares (128 fieles / 78 infieles), spans recortados a rango de líneas:
| Configuración | AUC (fiel vs. infiel) |
|---|---|
NLI sobre span[:1500]
|
0.7029 |
| NLI sobre pasaje recuperado | 0.7219 |
- AUC = P(soporte de par fiel > soporte de par infiel). El label NLI se resuelve por nombre del
id2labeldel modelo, no por índice hardcodeado (un bug de índice que cazamos en implementación daba entail 0.99 incluso a texto de tema ajeno). - Prosa larga: sin número fiable. Tres intentos de medir fueron invalidados por defectos de construcción del dataset. No se publica un AUC de prosa.
- El +0.019 del retrieve está en el orden del ruido sin intervalo de confianza; se justifica cualitativamente (no truncar, saltar frontmatter), no como número.
Reproducibilidad
El AUC citado es reproducible por cualquiera. El dataset (206 pares) y el script viven en evaluation/:
pip install -e ".[dev]"
python evaluation/evaluate.py
# AUC (NLI sobre pasaje recuperado) = 0.7219
Estado del proyecto
Fase 1 de 3 — MVP funcional y verificado. Lo que queda abierto, honestamente:
- Fase 2: capa LLM-as-judge para código/CRD y zona gris numérica. Sin validar todavía.
- Prosa larga sin AUC fiable (tres intentos invalidados por dataset defectuoso).
El ciclo de construcción siguió implementación → auditoría independiente en clone limpio → corrección. El bug crítico de label NLI lo encontró la auditoría, no el self-report, y quedó documentado con el dato crudo.
Stack
- Python ≥ 3.12, CPU-only, sin API key.
-
sentence-transformers(all-MiniLM-L6-v2, nli-deberta-v3-small),scikit-learn. - CI: ruff + pytest + bandit→SARIF + gitleaks + SonarCloud (condicional).
- Licencia: AGPL-3.0-or-later.
Links
- Repo: https://github.com/amurlaniakea/citefid
- RESEARCH.md: metodología completa y hallazgos del spike
Citefid ataca un problema muy específico (gap) que ha surgido con los sistemas de IA. No es un software de validación de datos genérico, sino una herramienta diseñada para dar respuesta a un cambio de paradigma tecnológico.
Este es el vacío técnico (gap) que viene a solucionar:
- El fin del "RAG tradicional" y el auge del estándar OKF.
Hasta ahora, para que una IA no alucinara, las empresas creaban sistemas RAG (Retrieval-Augmented Generation), fragmentando PDFs en una base de datos vectorial. Este enfoque probabilístico suele fallar con datos exactos como números, tablas o líneas de código.Google lanzó el estándar OKF (Open Knowledge Format), que propone cambiar el RAG por LLM-Wikis: directorios legibles donde los agentes de IA leen y escriben notas interconectadas en Markdown con metadatos estructurados en YAML. El problema (gap) es que no existían herramientas nativas para auditar que las citas generadas automáticamente dentro de este nuevo formato fueran verdaderas. Citefid es uno de los primeros validadores nacidos directamente para este estándar.
- El "gap" del recorte determinista vs. la ventana de contexto.
Cuando una IA cita una fuente como prueba de lo que dice, los validadores tradicionales suelen meter el documento entero de nuevo a un LLM para preguntarle si es correcto. Esto genera dos problemas: consumo masivo de tokens y pérdida de precisión (el LLM se "despista" en textos largos). Citefid solventa este gap mediante resolución exacta y determinista:Si la IA cita un fragmento de código de GitHub (usando una URL tipo #Lx-Ly), el script descarga el commit exacto y recorta las líneas rigurosamente antes de verificar nada. Si cita prosa, limpia la paja (como configuraciones de metadatos YAML) mediante expresiones regulares y búsquedas híbridas controladas.
- Verificación hiper-barata y local (CPU-only).
La gran mayoría de sistemas de alineación o "guardrails" actuales (LLM-as-judge) necesitan llamar a modelos gigantescos y costosos como GPT-4 o Claude por API para verificar datos.El repositorio cubre un gap de eficiencia usando Inferencia de Lenguaje Natural (NLI) con un modelo optimizado muy pequeño (deberta-v3-small). Consigue un AUC de 0.7029 (un 70% de precisión matemática discriminando citas verdaderas de falsas en código fuente de producción) corriendo exclusivamente local en una CPU, sin gastar un solo céntimo en APIs de terceros.
En resumen: Su novedad radica en que automatiza la auditoría de citas exactas para un estándar de IA moderno (OKF), aislando el fragmento exacto de la prueba para que un modelo diminuto local certifique si la IA está alucinando o no.
Licencia: AGPL-3.0-or-later — Copyright (C) 2026 Pedro Sordo Martínez amurlaniakea@gmail.com
Top comments (0)