Skip to content

Capítulo 3 — ChromaDB, embeddings y el fallback inteligente

Commits: 24730c1, 5528ed4, 0f80855aifs (16 enero 2024)

¿Qué cambió?

Estas tres commits del mismo día son refinamientos rápidos: agregar .gitignore, ajustar versiones en pyproject.toml, y una pequeña pero importante adición: el manejo de errores de embedding.

El problema: numpy y embeddings frágiles

En el commit inicial, había esta línea:

python
import numpy as np

Y más adelante, el embed se usaba directamente sin protección:

python
embed = setup_embed()

El problema: si chromadb o sentence-transformers no están instalados correctamente (algo muy común en proyectos nuevos), todo explota. Y numpy en particular tenía problemas de compatibilidad con Python 3.8.

La solución: try/except alrededor de la importación

python
try:
    embed = setup_embed()
except:
    # This does set up a model that we don't strictly need.
    # If it fails, it's not worth breaking everything.
    pass

Este patrón es simple pero revela una filosofía: la herramienta no debe morir por una dependencia opcional. Si el embedding falla al cargar, el error aparecerá más tarde cuando se intente usar, pero al menos el módulo no explota al importarse.

¿Cómo funcionan los embeddings?

Un embedding es la representación numérica del significado de un texto. Imagínalo así:

Los tres textos tienen significados similares → sus vectores son cercanos en el espacio vectorial → cuando buscas uno, encuentras los otros.

El fallback de chunks

python
try:
    chunks = chunk_file(path)
    if chunks == []:
        raise Exception("Failed to chunk.")
    if MAX_CHUNKS and len(chunks) > MAX_CHUNKS:
        raise Exception("Too many chunks. Will just embed filename.")
except Exception as e:
    print(f"Couldn't read `{path}`. Continuing.")
    chunks = [f"There is a file at `{path}`."]

Si no se puede leer o fragmentar un archivo (binarios, PDFs corruptos, archivos muy grandes), en lugar de fallar, se indexa solo el nombre del archivo: "There is a file at '/ruta/al/archivo.bin'.".

Esto garantiza que el archivo aparezca en los resultados si se busca algo relacionado con su nombre, aunque no se pueda leer su contenido.

La constante MAX_CHUNKS

python
MAX_CHUNKS = 300

Un archivo con más de 300 fragmentos es probablemente gigante (un dataset, un archivo generado, logs). Embedear 300+ fragmentos es costoso en tiempo y memoria. La solución pragmática: si es demasiado grande, solo indexa el nombre.

Lección del capítulo

Los sistemas robustos no evitan los errores — los anticipan y degradan graciosamente. Un resultado parcial es mejor que un crash.


Siguiente: Cap 04 — Indexado inteligente de Python

Libro generado por El Profe 🧑‍🏫