Convertir documentos en vectores numéricos es el paso que conecta tu información cruda con un sistema capaz de responder preguntas. Aquí aprenderás a generar embeddings con OpenAI, almacenarlos en una base de datos vectorial Chroma usando LangChain y manejar su recreación o carga según convenga. Esta guía es para quienes construyen aplicaciones de búsqueda semántica o asistentes conversacionales con documentación propia.
¿Cómo configurar la API de OpenAI antes de generar embeddings?
Antes de tocar una sola línea de embeddings, necesitas validar que tu llave de OpenAI esté disponible como variable de ambiente. Sin esto, nada corre.
Desde el módulo utils se importa la función get_openai_api_key, que revisa si tienes configurada la variable OPENAI_API_KEY. Si no la tienes, el script falla y te avisa. La solución es simple: copia tu llave desde el panel de desarrolladores de OpenAI y expórtala en tu terminal antes de ejecutar.
¿Qué es un embedding? Es la representación numérica de un texto en forma de vector. Permite que un modelo compare significados entre fragmentos calculando distancia entre vectores en lugar de comparar palabras literales.
¿Cómo generar embeddings con OpenAI y LangChain?
La instancia de embeddings es el motor que traduce tus documentos a números. Aquí defines qué modelo usar y cómo inicializarlo [1:15].
Desde langchain.embeddings importas OpenAIEmbeddings y creas una instancia indicando el modelo. En este caso se usa text-embedding-ada-002, un modelo de OpenAI diseñado específicamente para generar embeddings de alta calidad [1:30].
python
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
Al correr el script con Poetry, los embeddings se inicializan correctamente y quedan listos para alimentar la base vectorial.
¿Cómo guardar embeddings en una base de datos Chroma?
Una vez tienes los embeddings y los documentos partidos, toca unirlos en Chroma, una base de datos vectorial open source que se integra de forma nativa con LangChain [2:45].
La lógica se encapsula en una función llamada get_chroma_db que recibe tres argumentos clave:
- Los embeddings que vas a usar para vectorizar.
- Los documentos de LangChain ya fragmentados.
- Un path donde persistir la base de datos.
¿Por qué usar una variable recreate_chroma_db?
No siempre quieres regenerar todo desde cero. Procesar cientos de documentos toma tiempo y consume llamadas a la API de OpenAI, lo que cuesta dinero.
Por eso se introduce la variable booleana recreate_chroma_db. Si está en True, el sistema recrea la base de datos desde cero usando Chroma.from_documents, vectoriza todo y guarda en persist_directory. Si está en False, simplemente carga la base existente desde el path indicado, reutilizando los embeddings ya calculados [4:50].
python
from langchain.vectorstores import Chroma
from rich.console import Console
console = Console()
def get_chroma_db(embeddings, documents, path):
if recreate_chroma_db:
console.print("Recreando Chroma DB")
return Chroma.from_documents(
documents=documents,
embedding=embeddings,
persist_directory=path
)
else:
console.print("Cargando Chroma existente")
return Chroma(
persist_directory=path,
embedding_function=embeddings
)
¿Cómo mejorar la salida en la terminal con rich?
La librería rich permite imprimir mensajes con colores y formato en la consola. Importas Console desde rich.console, instancias el objeto y usas console.print para mostrar mensajes en verde u otros estilos [5:30].
Esto no es decorativo nada más: en proyectos largos te ayuda a distinguir rápido entre logs de creación, carga y errores.
¿Cuántos fragmentos se cargan en la base vectorial Chroma?
Al ejecutar el script con recreate_chroma_db = True, el sistema procesa toda la documentación de Hugging Face fragmentada y la convierte en vectores [7:10].
El resultado: 1807 fragmentos cargados como embeddings en la base de datos Chroma. Cada uno representa una porción de texto convertida en un vector numérico, lista para búsquedas semánticas.
¿Qué hace persist_directory en Chroma? Define la carpeta local donde se guardan los vectores. Permite que la base de datos sobreviva entre ejecuciones, evitando recalcular embeddings cada vez que corres el script.
Después de la primera carga, en el directorio del proyecto aparece la carpeta chroma-docs, que contiene la base persistida. A partir de ese momento, cambias recreate_chroma_db a False y la próxima ejecución solo carga lo que ya existe.
Conceptos y herramientas clave usados en el flujo
Estos son los elementos técnicos que aparecen en el desarrollo y conviene tener claros:
- OpenAIEmbeddings: clase de LangChain que conecta con la API de OpenAI para generar vectores [1:20].
- text-embedding-ada-002: modelo de embeddings de OpenAI optimizado para semántica [1:35].
- Chroma: base de datos vectorial que almacena embeddings y permite búsquedas por similitud [3:00].
- from_documents: método que recibe documentos y embeddings para crear la base desde cero [5:15].
- persist_directory: parámetro que define dónde se guarda físicamente la base vectorial [5:45].
- rich.console: librería para imprimir logs estéticos en terminal [5:25].
Con la base vectorial lista, el siguiente paso es hacerle preguntas en lenguaje natural y recuperar los fragmentos más relevantes. ¿Ya configuraste tu primera base Chroma? Cuéntame en los comentarios qué documentación estás vectorizando.