AHG
Portada abstracta: documentos comprimidos en una rejilla de pequeñas celdas de colores
Laboratorio de IA local

RAG privado en tu propia máquina con turbovec

Busca en 177K fragmentos del BOE en local — sin nube, sin claves de API

  • rag
  • turbovec
  • embeddings
  • ollama
  • boe

También en: EnglishFrançais

Las demos de “chatea con tus documentos” suelen acabar con una base de datos vectorial en la nube y una clave de API. Esta no: el modelo de embeddings, el índice y el modelo de lenguaje corren en tu propia máquina. Como corpus de prueba usé algo real y exigente — 2.000 documentos del BOE, el Boletín Oficial del Estado, convertidos a Markdown. La pieza interesante es el índice, turbovec, que comprime los vectores a 4 bits por dimensión y aun así busca más rápido que FAISS.

Por qué turbovec

  • Sin fase de entrenamiento. La mayoría de los índices comprimidos (como los de FAISS) tienen que aprender de tus datos primero. TurboQuant deriva su compresión analíticamente: los vectores son buscables en cuanto se añaden.
  • Diminuto. Todo el corpus de abajo —177K fragmentos— vive en un índice de 94 MB. Los mismos vectores sin comprimir ocuparían 727 MB.
  • Búsqueda acotada. Puedes restringir una consulta a una carpeta o proyecto dentro del propio índice, así que los permisos no necesitan un índice aparte.
  • Offline de verdad. Sin servicio ni telemetría. Con un modelo local de embeddings, nada sale del portátil.

La pila

Capa Elección Por qué
Documentos Corpus del BOE → Markdown 2.000 leyes y normas; el español legal denso es una prueba de estrés real
Fragmentos Pasajes de ~800 tokens Suficiente contexto sin perder relevancia
Vectores Qwen3-Embedding-0.6B vía Ollama Pequeño, multilingüe, corre en CPU
Índice turbovec, 4 bits Ver arriba
Respuestas Gemma 4 12B o Qwen3.8-27B vía Ollama Los dos modelos del experimento anterior

Cómo está montado

El pegamento son unas cien líneas de Python y el flujo son tres pasos:

Paso 1 — Indexar una vez. Trocear cada Markdown en pasajes de ~800 tokens, vectorizarlos y añadirlos a un índice de 4 bits. El sync hace la escritura incremental y tolerante a fallos — la ingesta de 177K fragmentos tardó unas horas y pudo reanudarse tras interrupciones.

index = turbovec.IdMapIndex(dim=1024, bit_width=4)
index.add_with_ids(vectors, chunk_ids)   # vectors salen del modelo de embeddings
index.sync("boe.tvec")                   # incremental, a prueba de fallos

Paso 2 — Buscar. Vectorizar la pregunta y recuperar los seis pasajes más cercanos.

scores, ids = index.search(question_vector, k=6)

Paso 3 — Responder con citas. El modelo de chat solo ve los pasajes recuperados y tiene la orden de citarlos. Es la parte que lo mantiene honesto.

answer = chat(f"Responde usando solo estos pasajes, citando [n]:\n{passages}\n\nP: {question}")

Medido sobre este corpus

Valor
Corpus 2.000 documentos del BOE · 445 MB de Markdown
Fragmentos indexados 177.580 vectores (1024 dimensiones)
Índice en disco 94,2 MB a 4 bits — ~7,7× más pequeño que los 727 MB en float32
Carga del índice 0,08 s
Búsqueda mediana, k = 6 1,35 ms en consultas sintéticas · ~27 ms de extremo a extremo en la batería real (incluye vectorizar la pregunta)
Tiempo de respuesta completa mediana ~18 s con Gemma 4 12B en el Mac de 16 GB

Después pasé una batería de 11 preguntas legales reales —duración de alquileres, obligaciones de protección de datos, puntos del carnet— por todo el pipeline. Todas las respuestas volvieron con citas a entradas reales del BOE, y la recuperación fue anecdótica: ~25 ms para encontrar los pasajes frente a segundos del modelo redactando. Mi resultado favorito es la prueba negativa: ante “¿qué dice la legislación española sobre la colonización de Marte?”, el sistema respondió sin más que los pasajes no lo cubren — en lugar de inventarse un artículo. Esa negativa es justo lo que quieres de un pipeline de recuperación.

Para poner las cifras en contexto: buscar en medio millón de palabras de español jurídico tarda más o menos lo mismo que renderizar un solo fotograma de un videojuego. La recuperación dejó de ser el cuello de botella hace tiempo — los segundos se van en el LLM leyendo los pasajes, que es justo por lo que importa combinarlo con un modelo local rápido.

Lo que me llevo

  • El texto legal es un gran benchmark de RAG. Denso, formulaico, lleno de referencias cruzadas: si la recuperación funciona aquí, funcionará en corpus más amables.
  • La parte difícil nunca es el índice. Trocear bien y escribir un prompt que obligue a citar importan mucho más que la base de datos que elijas.
  • Las citas son la funcionalidad. Obligar al modelo a citar pasajes [n] convierte las alucinaciones de invisibles en obvias — y te deja saltar a la ley real.

Experiencias relacionadas

← Volver a experiencias