Menu iconMenu icon
OpenAI API Biblia Volumen 2

Capítulo 3: Embeddings y Búsqueda Semántica

3.1 Entendiendo los Embeddings de Texto

A lo largo de este libro, hemos profundizado en las fascinantes capacidades de GPT-4o, explorando su habilidad para procesar lenguaje natural, interpretar información visual y analizar señales de audio. Ahora, estamos a punto de descubrir otro aspecto crucial de los sistemas modernos de IA: la capacidad de entender y procesar contenido a escalas masivas de una manera que verdaderamente comprende el significado.

Aquí es donde entra en juego el poderoso concepto de los embeddings. Piensa en los embeddings como el puente entre el lenguaje humano y la comprensión de las máquinas.

En su esencia, los embeddings son representaciones matemáticas sofisticadas que transforman el texto en vectores numéricos. Pero estos no son solo números aleatorios: son huellas numéricas cuidadosamente elaboradas que capturan la esencia semántica del contenido. Esta representación matemática permite a las computadoras entender relaciones entre conceptos, medir la similitud entre ideas y procesar información de manera que refleja la comprensión humana. Cuando convertimos texto en embeddings, podemos comparar ideas, clasificar resultados de búsqueda, identificar patrones y analizar grandes cantidades de información utilizando la comprensión contextual, yendo mucho más allá de la simple coincidencia de palabras clave.

En este capítulo completo, exploraremos:

  • Una inmersión profunda en la creación y manipulación de embeddings de texto utilizando la API de vanguardia de OpenAI, incluyendo mejores prácticas y técnicas de optimización
  • Aplicaciones avanzadas de embeddings en sistemas de búsqueda semántica y mecanismos sofisticados de recuperación de documentos que comprenden el contexto y la intención del usuario
  • Implementación práctica de embeddings en aplicaciones del mundo real, enfocándose en motores de recomendaciónsistemas inteligentes de respuesta a preguntas y soluciones avanzadas de agrupamiento de datos
  • Una mirada exhaustiva a cómo los embeddings sirven como base para los sistemas modernos de IA, incluyendo arquitecturas RAG (Generación Aumentada por Recuperación), chatbots inteligentes, motores de búsqueda de próxima generación y bases de datos vectoriales sofisticadas

Comencemos nuestro viaje dominando los fundamentos: entendiendo qué hace que los embeddings sean tan poderosos y cómo implementarlos efectivamente en tus proyectos.

En esta sección, exploraremos los conceptos fundamentales detrás de los embeddings de texto, comenzando con su definición básica y avanzando a través de sus aplicaciones prácticas. Entender los embeddings de texto es crucial porque forman la columna vertebral de muchas aplicaciones modernas de IA, desde motores de búsqueda hasta sistemas de recomendación.

Desglosaremos conceptos técnicos complejos en explicaciones digeribles, complementadas con ejemplos prácticos que demuestran cómo los embeddings capturan y representan el significado. Ya seas un desarrollador que busca implementar búsqueda semántica o un entusiasta de la tecnología que desea entender cómo los sistemas de IA procesan el lenguaje, esta sección te proporcionará una base sólida.

3.1.1 ¿Qué Son los Embeddings?

En términos simples, los embeddings son representaciones numéricas sofisticadas de texto —como oraciones, párrafos o incluso documentos completos— que capturan su significado de una manera que las máquinas pueden entender y procesar. Piensa en ellos como la conversión de palabras en una serie de números que preservan la esencia y el contexto del texto original.

Lo que hace particularmente poderosos a los embeddings es su capacidad de ir más allá de la simple coincidencia de palabras. En lugar de comparar palabras carácter por carácter (como "perro" vs "perros"), los embeddings analizan las relaciones semánticas más profundas entre palabras y frases. Así es como funciona:

  • Cuando el texto se convierte en embeddings, los conceptos similares se posicionan más cerca entre sí en el espacio matemático. Por ejemplo, "¿Cómo hago panqueques?" y "Pasos para cocinar tortitas" pueden parecer completamente diferentes como texto, pero tienen embeddings muy similares porque expresan el mismo concepto subyacente.
  • El mismo principio se aplica a sinónimos, conceptos relacionados e incluso diferentes formas de expresar la misma idea. Por ejemplo, "mantenimiento de automóvil" y "reparación de coche" tendrían embeddings similares a pesar de usar palabras diferentes.
  • Esta comprensión semántica significa que el modelo puede reconocer relaciones entre conceptos incluso cuando no comparten palabras en común.

Los embeddings se han convertido en bloques fundamentales en las aplicaciones modernas de IA, sirviendo como base para:

  • Búsqueda semántica: Encontrar información relevante basada en el significado en lugar de solo palabras clave, permitiendo resultados de búsqueda más inteligentes
  • Agrupamiento de temas: Organizar automáticamente grandes colecciones de documentos en grupos significativos basados en su contenido
  • Sistemas de recomendación: Sugerir elementos relacionados mediante la comprensión de las conexiones más profundas entre diferentes piezas de contenido
  • Recuperación de contexto para asistentes de IA: Ayudar a los chatbots y sistemas de IA a encontrar y utilizar información relevante de grandes bases de conocimiento
  • Detección de anomalías y similitudes: Identificar patrones inusuales o encontrar elementos similares en grandes conjuntos de datos comparando sus representaciones semánticas

Estos casos de uso se explorarán en detalle en la sección 3.1.4.

3.1.2 ¿Cómo Funcionan los Embeddings?

Cada fragmento de texto se transforma en un vector —esencialmente una larga lista de números de punto flotante (por ejemplo, usando el modelo text-embedding-3-small de OpenAI se crea un vector de 1,536 dimensiones). Piensa en este vector como un punto preciso en un vasto espacio matemático. La parte fascinante es cómo estos vectores se relacionan entre sí: cuando dos fragmentos de texto tienen significados similares, sus vectores estarán posicionados más cerca en este espacio. Esta proximidad se mide utilizando técnicas matemáticas como la similitud del coseno.

Por ejemplo, las frases "Me encanta la pizza" y "La pizza es mi comida favorita" tendrían vectores mucho más cercanos entre sí que cualquiera de ellos lo estaría de "El clima está agradable hoy". Esta representación matemática del significado hace que los embeddings sean increíblemente poderosos para varias aplicaciones:

  • Buscar en una base de datos de documentos por significado - encontrando documentos relevantes incluso cuando usan diferentes palabras para expresar el mismo concepto. Por ejemplo, una búsqueda de "remedios naturales para dolores de cabeza" también encontraría documentos sobre "tratamientos holísticos para migrañas" u "opciones de alivio del dolor no farmacéuticas", porque los embeddings entienden que estos conceptos están relacionados.
  • Encontrar la coincidencia más cercana a la pregunta de un usuario - entendiendo la intención detrás de las consultas y relacionándolas con las respuestas más relevantes, incluso si la redacción difiere. Esto es particularmente poderoso en escenarios de atención al cliente, donde una pregunta como "¿Cómo restablezco mi contraseña?" podría coincidir con documentación titulada "Guía de Recuperación de Contraseña" o "Pasos para Restaurar el Acceso a la Cuenta". El modelo de embedding reconoce que estos están abordando la misma necesidad subyacente.
  • Agrupar correos electrónicos similares, tickets de soporte o descripciones de productos - organizando automáticamente el contenido basado en similitud semántica en lugar de solo coincidencias de palabras clave. Por ejemplo, todas las quejas de clientes sobre retrasos en los envíos podrían agruparse juntas, incluso si están redactadas de manera diferente. Esto permite una categorización poderosa como enrutar automáticamente correos electrónicos de "¿Dónde está mi pedido?", quejas de "La entrega está tardando demasiado" y tickets de "Paquete detenido en tránsito" a la misma cola de soporte, a pesar de sus diferentes redacciones. El sistema incluso puede identificar problemas relacionados como "el número de seguimiento no funciona" porque comparten similitud contextual con preocupaciones relacionadas con el envío.

3.1.3 Generemos Tu Primer Embedding

Usaremos el modelo text-embedding-3-small de OpenAI, que ofrece varias ventajas clave. Primero, es liviano, lo que significa que requiere recursos computacionales mínimos y puede procesar embeddings rápidamente. Segundo, es rentable, con un precio de $0.02 por millón de tokens (Nota: Siempre verifica la página de precios actual de OpenAI para las tarifas vigentes), haciéndolo accesible tanto para proyectos pequeños como para aplicaciones a gran escala.

Tercero, a pesar de su eficiencia, es sorprendentemente potente, capaz de generar embeddings de alta calidad de 1,536 dimensiones que capturan relaciones semánticas sutiles. Este modelo logra un excelente equilibrio entre rendimiento y utilización de recursos, convirtiéndolo en una opción ideal para desarrolladores que buscan implementar funcionalidad de embeddings en sus aplicaciones.

Generemos un embedding para una frase de ejemplo.

Ejemplo del Mundo Real: Comparando Dos Textos

Los embeddings nos permiten cuantificar la similitud semántica entre fragmentos de texto. Supongamos que quieres saber qué tan similares son estas dos frases en significado:

  • text_1 = "How to bake a chocolate cake?"
  • text_2 = "What are the steps for making chocolate dessert?"

Podemos generar embeddings para ambos y luego calcular la similitud del coseno entre sus vectores. La similitud del coseno mide el coseno del ángulo entre dos vectores no nulos; un valor más cercano a 1 indica mayor similitud, 0 indica ninguna similitud (ortogonalidad), y -1 indica significado opuesto (aunque menos común con este tipo de embeddings).

import os
from openai import OpenAI, OpenAIError
from dotenv import load_dotenv
import numpy as np # For cosine similarity calculation
import datetime

# --- Configuration ---
load_dotenv()

# Get the current date and location context
current_timestamp = "2025-03-12 15:07:00 CDT"
current_location = "Grapevine, Texas, United States"
print(f"Running Embeddings example at: {current_timestamp}")
print(f"Location Context: {current_location}")


# Initialize the OpenAI client
try:
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise ValueError("OPENAI_API_KEY not found in environment variables.")
    client = OpenAI(api_key=api_key)
    print("OpenAI client initialized.")
except ValueError as e:
    print(f"Configuration Error: {e}")
    exit()
except Exception as e:
    print(f"Error initializing OpenAI client: {e}")
    exit()

# Define the embedding model
EMBEDDING_MODEL = "text-embedding-3-small"

# --- Helper Function to Generate Embedding ---
def get_embedding(client, text, model=EMBEDDING_MODEL):
    """Generates an embedding for the given text using the specified model."""
    print(f"\nGenerating embedding for: \"{text}\"")
    try:
        # Use client.embeddings.create (updated syntax)
        response = client.embeddings.create(
            input=text,
            model=model
        )
        # Access embedding via attribute (updated syntax)
        embedding_vector = response.data[0].embedding
        print("Embedding generation successful.")
        return embedding_vector
    except OpenAIError as e:
        print(f"OpenAI API Error generating embedding: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred during embedding generation: {e}")
        return None

# --- Helper Function for Cosine Similarity ---
def cosine_similarity(vec_a, vec_b):
    """Calculates the cosine similarity between two vectors."""
    if vec_a is None or vec_b is None:
        print("Error: Cannot calculate similarity with None vectors.")
        return 0.0 # Or handle as appropriate

    # Ensure vectors are numpy arrays for calculation
    vec_a = np.array(vec_a)
    vec_b = np.array(vec_b)

    # Calculate dot product and norms
    dot_product = np.dot(vec_a, vec_b)
    norm_a = np.linalg.norm(vec_a)
    norm_b = np.linalg.norm(vec_b)

    # Calculate similarity (handle potential division by zero)
    if norm_a == 0 or norm_b == 0:
        print("Warning: One or both vectors have zero magnitude.")
        return 0.0
    else:
        similarity = dot_product / (norm_a * norm_b)
        return similarity

# --- Generate First Embedding ---
print("\n--- Section 3.1.3: Generating First Embedding ---")
text_to_embed = "Artificial intelligence can help improve healthcare outcomes."
embedding1 = get_embedding(client, text_to_embed)

if embedding1:
    print("✅ Embedding vector generated!")
    print(f"Vector size: {len(embedding1)}")
    # print("First few dimensions:", embedding1[:5]) # Optionally print part of the vector
else:
    print("Failed to generate the first embedding.")

# --- Comparing Two Texts ---
print("\n--- Section 3.1.4: Comparing Two Texts ---")
text_1 = "How to bake a chocolate cake?"
text_2 = "What are the steps for making chocolate dessert?"

# Get embeddings for both texts
embedding_comp1 = get_embedding(client, text_1)
embedding_comp2 = get_embedding(client, text_2)

# Compute and print cosine similarity if both embeddings were generated
if embedding_comp1 and embedding_comp2:
    similarity_score = cosine_similarity(embedding_comp1, embedding_comp2)
    print(f"\nSemantic similarity score between \"{text_1}\" and \"{text_2}\": {similarity_score:.3f}")
    print("(Score closer to 1.0 means higher semantic similarity)")
else:
    print("\nCould not calculate similarity because one or both embeddings failed.")

Explicación del Desglose del Código

Este script de Python demuestra cómo usar la API de OpenAI para generar embeddings de texto y luego calcular la similitud semántica entre dos fragmentos de texto.

  1. Prerrequisitos y Configuración:
    • Comentarios: El script comienza con comentarios que describen las bibliotecas necesarias (openaipython-dotenvnumpy) y la necesidad de un archivo .env que contenga el OPENAI_API_KEY.
    • Importaciones: Importa las bibliotecas requeridas:
      • os: Utilizado aquí para interactuar con variables de entorno.
      • openaiOpenAIError: La biblioteca principal para interactuar con la API de OpenAI y manejar sus errores específicos.
      • dotenv: Para cargar la clave API de forma segura desde un archivo .env.
      • numpy (como np): Una biblioteca fundamental para operaciones numéricas en Python, utilizada aquí específicamente para cálculos vectoriales (producto punto, norma) necesarios para la similitud del coseno.
      • datetime: Utilizado para obtener la marca de tiempo actual para el contexto de registro.
  2. Configuración:
    • load_dotenv(): Carga las variables de entorno desde el archivo .env.
    • Registro de Contexto: Imprime la marca de tiempo actual y la ubicación para el contexto de ejecución.
    • Inicialización del Cliente OpenAI:
      • Obtiene la clave API usando os.getenv("OPENAI_API_KEY").
      • Instancia el objeto cliente principal: client = OpenAI(api_key=api_key). Todas las llamadas a la API se realizarán a través de este objeto client. Esto utiliza la sintaxis moderna para la biblioteca openai (v1.0.0+).
      • Incluye bloques try...except para manejar posibles errores durante la inicialización (por ejemplo, clave API faltante).
    • EMBEDDING_MODEL: Define una constante que contiene el nombre del modelo de embedding de OpenAI a utilizar (text-embedding-3-small).
  3. Función Auxiliar: get_embedding:
    • Propósito: Encapsula la lógica para generar un embedding para un fragmento de texto individual.
    • Parámetros: Toma el objeto client, el text a embeber, y el nombre del model como entrada.
    • Llamada a la API: Realiza la llamada principal a la API usando client.embeddings.create(...).
      • input=text: La cadena de texto que se convertirá en un embedding.
      • model=model: El modelo específico de embedding a utilizar.
    • Manejo de Respuesta:
      • Accede al vector de embedding generado mediante acceso a atributos en el objeto de respuesta: response.data[0].embedding. Esta es la forma estándar de acceder a los resultados en las versiones más nuevas de la biblioteca.
      • Devuelve el vector de embedding numérico (una lista de números flotantes).
    • Manejo de Errores: Incluye bloques try...except para capturar OpenAIError y otras posibles excepciones durante la llamada a la API. Devuelve None si ocurre un error.
  4. Función Auxiliar: cosine_similarity:
    • Propósito: Calcula la similitud del coseno entre dos vectores numéricos (embeddings).
    • Parámetros: Toma dos vectores, vec_a y vec_b.
    • Validación de Entrada: Verifica si alguno de los vectores de entrada es None.
    • Conversión a Numpy: Convierte las listas/vectores de entrada en arreglos de numpy (np.array()) para operaciones matemáticas eficientes.
    • Cálculo:
      • np.dot(vec_a, vec_b): Calcula el producto punto de los dos vectores.
      • np.linalg.norm(vec_a) y np.linalg.norm(vec_b): Calculan la magnitud (norma euclidiana o norma L2) de cada vector.
      • Maneja la posible división por cero si algún vector tiene magnitud cero.
      • Calcula la similitud usando la fórmula: dot_product / (norm_a * norm_b).
    • Salida: Devuelve el puntaje de similitud del coseno, un número flotante típicamente entre -1 y 1 (aunque generalmente entre 0 y 1 para este tipo de embeddings).
  5. Generar Primer Embedding:
    • Imprime un encabezado de sección.
    • Define el texto de ejemplo text_to_embed.
    • Llama a la función auxiliar get_embedding para generar el embedding para este texto.
    • Si tiene éxito (if embedding1:), imprime un mensaje de confirmación y el tamaño (dimensionalidad) del vector generado usando len(embedding1).
  6. Comparación de Dos Textos:
    • Imprime un encabezado de sección.
    • Define dos cadenas de texto, text_1 y text_2, para ser comparadas.
    • Llama a get_embedding dos veces para obtener los vectores de embedding tanto para text_1 como para text_2.
    • Si ambos embeddings se generaron exitosamente (if embedding_comp1 and embedding_comp2:), procede a calcular la similitud.
    • Llama a la función auxiliar cosine_similarity con los dos vectores de embedding.
    • Imprime el similarity_score calculado, formateado a tres decimales, junto con una explicación del significado del puntaje.
  7. Guardia de Ejecución Principal (if __name__ == "__main__":):
    • Esta construcción estándar de Python asegura que el código dentro de este bloque (que incluye las llamadas para las secciones 3.1.3 y 3.1.4) solo se ejecute cuando el script se ejecuta directamente, no cuando se importa como un módulo en otro script.

Este ejemplo proporciona un ejemplo claro y funcional de cómo generar embeddings y usarlos para medir la similitud semántica entre textos utilizando los estándares actuales de la biblioteca Python de OpenAI.

3.1 Entendiendo los Embeddings de Texto

A lo largo de este libro, hemos profundizado en las fascinantes capacidades de GPT-4o, explorando su habilidad para procesar lenguaje natural, interpretar información visual y analizar señales de audio. Ahora, estamos a punto de descubrir otro aspecto crucial de los sistemas modernos de IA: la capacidad de entender y procesar contenido a escalas masivas de una manera que verdaderamente comprende el significado.

Aquí es donde entra en juego el poderoso concepto de los embeddings. Piensa en los embeddings como el puente entre el lenguaje humano y la comprensión de las máquinas.

En su esencia, los embeddings son representaciones matemáticas sofisticadas que transforman el texto en vectores numéricos. Pero estos no son solo números aleatorios: son huellas numéricas cuidadosamente elaboradas que capturan la esencia semántica del contenido. Esta representación matemática permite a las computadoras entender relaciones entre conceptos, medir la similitud entre ideas y procesar información de manera que refleja la comprensión humana. Cuando convertimos texto en embeddings, podemos comparar ideas, clasificar resultados de búsqueda, identificar patrones y analizar grandes cantidades de información utilizando la comprensión contextual, yendo mucho más allá de la simple coincidencia de palabras clave.

En este capítulo completo, exploraremos:

  • Una inmersión profunda en la creación y manipulación de embeddings de texto utilizando la API de vanguardia de OpenAI, incluyendo mejores prácticas y técnicas de optimización
  • Aplicaciones avanzadas de embeddings en sistemas de búsqueda semántica y mecanismos sofisticados de recuperación de documentos que comprenden el contexto y la intención del usuario
  • Implementación práctica de embeddings en aplicaciones del mundo real, enfocándose en motores de recomendaciónsistemas inteligentes de respuesta a preguntas y soluciones avanzadas de agrupamiento de datos
  • Una mirada exhaustiva a cómo los embeddings sirven como base para los sistemas modernos de IA, incluyendo arquitecturas RAG (Generación Aumentada por Recuperación), chatbots inteligentes, motores de búsqueda de próxima generación y bases de datos vectoriales sofisticadas

Comencemos nuestro viaje dominando los fundamentos: entendiendo qué hace que los embeddings sean tan poderosos y cómo implementarlos efectivamente en tus proyectos.

En esta sección, exploraremos los conceptos fundamentales detrás de los embeddings de texto, comenzando con su definición básica y avanzando a través de sus aplicaciones prácticas. Entender los embeddings de texto es crucial porque forman la columna vertebral de muchas aplicaciones modernas de IA, desde motores de búsqueda hasta sistemas de recomendación.

Desglosaremos conceptos técnicos complejos en explicaciones digeribles, complementadas con ejemplos prácticos que demuestran cómo los embeddings capturan y representan el significado. Ya seas un desarrollador que busca implementar búsqueda semántica o un entusiasta de la tecnología que desea entender cómo los sistemas de IA procesan el lenguaje, esta sección te proporcionará una base sólida.

3.1.1 ¿Qué Son los Embeddings?

En términos simples, los embeddings son representaciones numéricas sofisticadas de texto —como oraciones, párrafos o incluso documentos completos— que capturan su significado de una manera que las máquinas pueden entender y procesar. Piensa en ellos como la conversión de palabras en una serie de números que preservan la esencia y el contexto del texto original.

Lo que hace particularmente poderosos a los embeddings es su capacidad de ir más allá de la simple coincidencia de palabras. En lugar de comparar palabras carácter por carácter (como "perro" vs "perros"), los embeddings analizan las relaciones semánticas más profundas entre palabras y frases. Así es como funciona:

  • Cuando el texto se convierte en embeddings, los conceptos similares se posicionan más cerca entre sí en el espacio matemático. Por ejemplo, "¿Cómo hago panqueques?" y "Pasos para cocinar tortitas" pueden parecer completamente diferentes como texto, pero tienen embeddings muy similares porque expresan el mismo concepto subyacente.
  • El mismo principio se aplica a sinónimos, conceptos relacionados e incluso diferentes formas de expresar la misma idea. Por ejemplo, "mantenimiento de automóvil" y "reparación de coche" tendrían embeddings similares a pesar de usar palabras diferentes.
  • Esta comprensión semántica significa que el modelo puede reconocer relaciones entre conceptos incluso cuando no comparten palabras en común.

Los embeddings se han convertido en bloques fundamentales en las aplicaciones modernas de IA, sirviendo como base para:

  • Búsqueda semántica: Encontrar información relevante basada en el significado en lugar de solo palabras clave, permitiendo resultados de búsqueda más inteligentes
  • Agrupamiento de temas: Organizar automáticamente grandes colecciones de documentos en grupos significativos basados en su contenido
  • Sistemas de recomendación: Sugerir elementos relacionados mediante la comprensión de las conexiones más profundas entre diferentes piezas de contenido
  • Recuperación de contexto para asistentes de IA: Ayudar a los chatbots y sistemas de IA a encontrar y utilizar información relevante de grandes bases de conocimiento
  • Detección de anomalías y similitudes: Identificar patrones inusuales o encontrar elementos similares en grandes conjuntos de datos comparando sus representaciones semánticas

Estos casos de uso se explorarán en detalle en la sección 3.1.4.

3.1.2 ¿Cómo Funcionan los Embeddings?

Cada fragmento de texto se transforma en un vector —esencialmente una larga lista de números de punto flotante (por ejemplo, usando el modelo text-embedding-3-small de OpenAI se crea un vector de 1,536 dimensiones). Piensa en este vector como un punto preciso en un vasto espacio matemático. La parte fascinante es cómo estos vectores se relacionan entre sí: cuando dos fragmentos de texto tienen significados similares, sus vectores estarán posicionados más cerca en este espacio. Esta proximidad se mide utilizando técnicas matemáticas como la similitud del coseno.

Por ejemplo, las frases "Me encanta la pizza" y "La pizza es mi comida favorita" tendrían vectores mucho más cercanos entre sí que cualquiera de ellos lo estaría de "El clima está agradable hoy". Esta representación matemática del significado hace que los embeddings sean increíblemente poderosos para varias aplicaciones:

  • Buscar en una base de datos de documentos por significado - encontrando documentos relevantes incluso cuando usan diferentes palabras para expresar el mismo concepto. Por ejemplo, una búsqueda de "remedios naturales para dolores de cabeza" también encontraría documentos sobre "tratamientos holísticos para migrañas" u "opciones de alivio del dolor no farmacéuticas", porque los embeddings entienden que estos conceptos están relacionados.
  • Encontrar la coincidencia más cercana a la pregunta de un usuario - entendiendo la intención detrás de las consultas y relacionándolas con las respuestas más relevantes, incluso si la redacción difiere. Esto es particularmente poderoso en escenarios de atención al cliente, donde una pregunta como "¿Cómo restablezco mi contraseña?" podría coincidir con documentación titulada "Guía de Recuperación de Contraseña" o "Pasos para Restaurar el Acceso a la Cuenta". El modelo de embedding reconoce que estos están abordando la misma necesidad subyacente.
  • Agrupar correos electrónicos similares, tickets de soporte o descripciones de productos - organizando automáticamente el contenido basado en similitud semántica en lugar de solo coincidencias de palabras clave. Por ejemplo, todas las quejas de clientes sobre retrasos en los envíos podrían agruparse juntas, incluso si están redactadas de manera diferente. Esto permite una categorización poderosa como enrutar automáticamente correos electrónicos de "¿Dónde está mi pedido?", quejas de "La entrega está tardando demasiado" y tickets de "Paquete detenido en tránsito" a la misma cola de soporte, a pesar de sus diferentes redacciones. El sistema incluso puede identificar problemas relacionados como "el número de seguimiento no funciona" porque comparten similitud contextual con preocupaciones relacionadas con el envío.

3.1.3 Generemos Tu Primer Embedding

Usaremos el modelo text-embedding-3-small de OpenAI, que ofrece varias ventajas clave. Primero, es liviano, lo que significa que requiere recursos computacionales mínimos y puede procesar embeddings rápidamente. Segundo, es rentable, con un precio de $0.02 por millón de tokens (Nota: Siempre verifica la página de precios actual de OpenAI para las tarifas vigentes), haciéndolo accesible tanto para proyectos pequeños como para aplicaciones a gran escala.

Tercero, a pesar de su eficiencia, es sorprendentemente potente, capaz de generar embeddings de alta calidad de 1,536 dimensiones que capturan relaciones semánticas sutiles. Este modelo logra un excelente equilibrio entre rendimiento y utilización de recursos, convirtiéndolo en una opción ideal para desarrolladores que buscan implementar funcionalidad de embeddings en sus aplicaciones.

Generemos un embedding para una frase de ejemplo.

Ejemplo del Mundo Real: Comparando Dos Textos

Los embeddings nos permiten cuantificar la similitud semántica entre fragmentos de texto. Supongamos que quieres saber qué tan similares son estas dos frases en significado:

  • text_1 = "How to bake a chocolate cake?"
  • text_2 = "What are the steps for making chocolate dessert?"

Podemos generar embeddings para ambos y luego calcular la similitud del coseno entre sus vectores. La similitud del coseno mide el coseno del ángulo entre dos vectores no nulos; un valor más cercano a 1 indica mayor similitud, 0 indica ninguna similitud (ortogonalidad), y -1 indica significado opuesto (aunque menos común con este tipo de embeddings).

import os
from openai import OpenAI, OpenAIError
from dotenv import load_dotenv
import numpy as np # For cosine similarity calculation
import datetime

# --- Configuration ---
load_dotenv()

# Get the current date and location context
current_timestamp = "2025-03-12 15:07:00 CDT"
current_location = "Grapevine, Texas, United States"
print(f"Running Embeddings example at: {current_timestamp}")
print(f"Location Context: {current_location}")


# Initialize the OpenAI client
try:
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise ValueError("OPENAI_API_KEY not found in environment variables.")
    client = OpenAI(api_key=api_key)
    print("OpenAI client initialized.")
except ValueError as e:
    print(f"Configuration Error: {e}")
    exit()
except Exception as e:
    print(f"Error initializing OpenAI client: {e}")
    exit()

# Define the embedding model
EMBEDDING_MODEL = "text-embedding-3-small"

# --- Helper Function to Generate Embedding ---
def get_embedding(client, text, model=EMBEDDING_MODEL):
    """Generates an embedding for the given text using the specified model."""
    print(f"\nGenerating embedding for: \"{text}\"")
    try:
        # Use client.embeddings.create (updated syntax)
        response = client.embeddings.create(
            input=text,
            model=model
        )
        # Access embedding via attribute (updated syntax)
        embedding_vector = response.data[0].embedding
        print("Embedding generation successful.")
        return embedding_vector
    except OpenAIError as e:
        print(f"OpenAI API Error generating embedding: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred during embedding generation: {e}")
        return None

# --- Helper Function for Cosine Similarity ---
def cosine_similarity(vec_a, vec_b):
    """Calculates the cosine similarity between two vectors."""
    if vec_a is None or vec_b is None:
        print("Error: Cannot calculate similarity with None vectors.")
        return 0.0 # Or handle as appropriate

    # Ensure vectors are numpy arrays for calculation
    vec_a = np.array(vec_a)
    vec_b = np.array(vec_b)

    # Calculate dot product and norms
    dot_product = np.dot(vec_a, vec_b)
    norm_a = np.linalg.norm(vec_a)
    norm_b = np.linalg.norm(vec_b)

    # Calculate similarity (handle potential division by zero)
    if norm_a == 0 or norm_b == 0:
        print("Warning: One or both vectors have zero magnitude.")
        return 0.0
    else:
        similarity = dot_product / (norm_a * norm_b)
        return similarity

# --- Generate First Embedding ---
print("\n--- Section 3.1.3: Generating First Embedding ---")
text_to_embed = "Artificial intelligence can help improve healthcare outcomes."
embedding1 = get_embedding(client, text_to_embed)

if embedding1:
    print("✅ Embedding vector generated!")
    print(f"Vector size: {len(embedding1)}")
    # print("First few dimensions:", embedding1[:5]) # Optionally print part of the vector
else:
    print("Failed to generate the first embedding.")

# --- Comparing Two Texts ---
print("\n--- Section 3.1.4: Comparing Two Texts ---")
text_1 = "How to bake a chocolate cake?"
text_2 = "What are the steps for making chocolate dessert?"

# Get embeddings for both texts
embedding_comp1 = get_embedding(client, text_1)
embedding_comp2 = get_embedding(client, text_2)

# Compute and print cosine similarity if both embeddings were generated
if embedding_comp1 and embedding_comp2:
    similarity_score = cosine_similarity(embedding_comp1, embedding_comp2)
    print(f"\nSemantic similarity score between \"{text_1}\" and \"{text_2}\": {similarity_score:.3f}")
    print("(Score closer to 1.0 means higher semantic similarity)")
else:
    print("\nCould not calculate similarity because one or both embeddings failed.")

Explicación del Desglose del Código

Este script de Python demuestra cómo usar la API de OpenAI para generar embeddings de texto y luego calcular la similitud semántica entre dos fragmentos de texto.

  1. Prerrequisitos y Configuración:
    • Comentarios: El script comienza con comentarios que describen las bibliotecas necesarias (openaipython-dotenvnumpy) y la necesidad de un archivo .env que contenga el OPENAI_API_KEY.
    • Importaciones: Importa las bibliotecas requeridas:
      • os: Utilizado aquí para interactuar con variables de entorno.
      • openaiOpenAIError: La biblioteca principal para interactuar con la API de OpenAI y manejar sus errores específicos.
      • dotenv: Para cargar la clave API de forma segura desde un archivo .env.
      • numpy (como np): Una biblioteca fundamental para operaciones numéricas en Python, utilizada aquí específicamente para cálculos vectoriales (producto punto, norma) necesarios para la similitud del coseno.
      • datetime: Utilizado para obtener la marca de tiempo actual para el contexto de registro.
  2. Configuración:
    • load_dotenv(): Carga las variables de entorno desde el archivo .env.
    • Registro de Contexto: Imprime la marca de tiempo actual y la ubicación para el contexto de ejecución.
    • Inicialización del Cliente OpenAI:
      • Obtiene la clave API usando os.getenv("OPENAI_API_KEY").
      • Instancia el objeto cliente principal: client = OpenAI(api_key=api_key). Todas las llamadas a la API se realizarán a través de este objeto client. Esto utiliza la sintaxis moderna para la biblioteca openai (v1.0.0+).
      • Incluye bloques try...except para manejar posibles errores durante la inicialización (por ejemplo, clave API faltante).
    • EMBEDDING_MODEL: Define una constante que contiene el nombre del modelo de embedding de OpenAI a utilizar (text-embedding-3-small).
  3. Función Auxiliar: get_embedding:
    • Propósito: Encapsula la lógica para generar un embedding para un fragmento de texto individual.
    • Parámetros: Toma el objeto client, el text a embeber, y el nombre del model como entrada.
    • Llamada a la API: Realiza la llamada principal a la API usando client.embeddings.create(...).
      • input=text: La cadena de texto que se convertirá en un embedding.
      • model=model: El modelo específico de embedding a utilizar.
    • Manejo de Respuesta:
      • Accede al vector de embedding generado mediante acceso a atributos en el objeto de respuesta: response.data[0].embedding. Esta es la forma estándar de acceder a los resultados en las versiones más nuevas de la biblioteca.
      • Devuelve el vector de embedding numérico (una lista de números flotantes).
    • Manejo de Errores: Incluye bloques try...except para capturar OpenAIError y otras posibles excepciones durante la llamada a la API. Devuelve None si ocurre un error.
  4. Función Auxiliar: cosine_similarity:
    • Propósito: Calcula la similitud del coseno entre dos vectores numéricos (embeddings).
    • Parámetros: Toma dos vectores, vec_a y vec_b.
    • Validación de Entrada: Verifica si alguno de los vectores de entrada es None.
    • Conversión a Numpy: Convierte las listas/vectores de entrada en arreglos de numpy (np.array()) para operaciones matemáticas eficientes.
    • Cálculo:
      • np.dot(vec_a, vec_b): Calcula el producto punto de los dos vectores.
      • np.linalg.norm(vec_a) y np.linalg.norm(vec_b): Calculan la magnitud (norma euclidiana o norma L2) de cada vector.
      • Maneja la posible división por cero si algún vector tiene magnitud cero.
      • Calcula la similitud usando la fórmula: dot_product / (norm_a * norm_b).
    • Salida: Devuelve el puntaje de similitud del coseno, un número flotante típicamente entre -1 y 1 (aunque generalmente entre 0 y 1 para este tipo de embeddings).
  5. Generar Primer Embedding:
    • Imprime un encabezado de sección.
    • Define el texto de ejemplo text_to_embed.
    • Llama a la función auxiliar get_embedding para generar el embedding para este texto.
    • Si tiene éxito (if embedding1:), imprime un mensaje de confirmación y el tamaño (dimensionalidad) del vector generado usando len(embedding1).
  6. Comparación de Dos Textos:
    • Imprime un encabezado de sección.
    • Define dos cadenas de texto, text_1 y text_2, para ser comparadas.
    • Llama a get_embedding dos veces para obtener los vectores de embedding tanto para text_1 como para text_2.
    • Si ambos embeddings se generaron exitosamente (if embedding_comp1 and embedding_comp2:), procede a calcular la similitud.
    • Llama a la función auxiliar cosine_similarity con los dos vectores de embedding.
    • Imprime el similarity_score calculado, formateado a tres decimales, junto con una explicación del significado del puntaje.
  7. Guardia de Ejecución Principal (if __name__ == "__main__":):
    • Esta construcción estándar de Python asegura que el código dentro de este bloque (que incluye las llamadas para las secciones 3.1.3 y 3.1.4) solo se ejecute cuando el script se ejecuta directamente, no cuando se importa como un módulo en otro script.

Este ejemplo proporciona un ejemplo claro y funcional de cómo generar embeddings y usarlos para medir la similitud semántica entre textos utilizando los estándares actuales de la biblioteca Python de OpenAI.

3.1 Entendiendo los Embeddings de Texto

A lo largo de este libro, hemos profundizado en las fascinantes capacidades de GPT-4o, explorando su habilidad para procesar lenguaje natural, interpretar información visual y analizar señales de audio. Ahora, estamos a punto de descubrir otro aspecto crucial de los sistemas modernos de IA: la capacidad de entender y procesar contenido a escalas masivas de una manera que verdaderamente comprende el significado.

Aquí es donde entra en juego el poderoso concepto de los embeddings. Piensa en los embeddings como el puente entre el lenguaje humano y la comprensión de las máquinas.

En su esencia, los embeddings son representaciones matemáticas sofisticadas que transforman el texto en vectores numéricos. Pero estos no son solo números aleatorios: son huellas numéricas cuidadosamente elaboradas que capturan la esencia semántica del contenido. Esta representación matemática permite a las computadoras entender relaciones entre conceptos, medir la similitud entre ideas y procesar información de manera que refleja la comprensión humana. Cuando convertimos texto en embeddings, podemos comparar ideas, clasificar resultados de búsqueda, identificar patrones y analizar grandes cantidades de información utilizando la comprensión contextual, yendo mucho más allá de la simple coincidencia de palabras clave.

En este capítulo completo, exploraremos:

  • Una inmersión profunda en la creación y manipulación de embeddings de texto utilizando la API de vanguardia de OpenAI, incluyendo mejores prácticas y técnicas de optimización
  • Aplicaciones avanzadas de embeddings en sistemas de búsqueda semántica y mecanismos sofisticados de recuperación de documentos que comprenden el contexto y la intención del usuario
  • Implementación práctica de embeddings en aplicaciones del mundo real, enfocándose en motores de recomendaciónsistemas inteligentes de respuesta a preguntas y soluciones avanzadas de agrupamiento de datos
  • Una mirada exhaustiva a cómo los embeddings sirven como base para los sistemas modernos de IA, incluyendo arquitecturas RAG (Generación Aumentada por Recuperación), chatbots inteligentes, motores de búsqueda de próxima generación y bases de datos vectoriales sofisticadas

Comencemos nuestro viaje dominando los fundamentos: entendiendo qué hace que los embeddings sean tan poderosos y cómo implementarlos efectivamente en tus proyectos.

En esta sección, exploraremos los conceptos fundamentales detrás de los embeddings de texto, comenzando con su definición básica y avanzando a través de sus aplicaciones prácticas. Entender los embeddings de texto es crucial porque forman la columna vertebral de muchas aplicaciones modernas de IA, desde motores de búsqueda hasta sistemas de recomendación.

Desglosaremos conceptos técnicos complejos en explicaciones digeribles, complementadas con ejemplos prácticos que demuestran cómo los embeddings capturan y representan el significado. Ya seas un desarrollador que busca implementar búsqueda semántica o un entusiasta de la tecnología que desea entender cómo los sistemas de IA procesan el lenguaje, esta sección te proporcionará una base sólida.

3.1.1 ¿Qué Son los Embeddings?

En términos simples, los embeddings son representaciones numéricas sofisticadas de texto —como oraciones, párrafos o incluso documentos completos— que capturan su significado de una manera que las máquinas pueden entender y procesar. Piensa en ellos como la conversión de palabras en una serie de números que preservan la esencia y el contexto del texto original.

Lo que hace particularmente poderosos a los embeddings es su capacidad de ir más allá de la simple coincidencia de palabras. En lugar de comparar palabras carácter por carácter (como "perro" vs "perros"), los embeddings analizan las relaciones semánticas más profundas entre palabras y frases. Así es como funciona:

  • Cuando el texto se convierte en embeddings, los conceptos similares se posicionan más cerca entre sí en el espacio matemático. Por ejemplo, "¿Cómo hago panqueques?" y "Pasos para cocinar tortitas" pueden parecer completamente diferentes como texto, pero tienen embeddings muy similares porque expresan el mismo concepto subyacente.
  • El mismo principio se aplica a sinónimos, conceptos relacionados e incluso diferentes formas de expresar la misma idea. Por ejemplo, "mantenimiento de automóvil" y "reparación de coche" tendrían embeddings similares a pesar de usar palabras diferentes.
  • Esta comprensión semántica significa que el modelo puede reconocer relaciones entre conceptos incluso cuando no comparten palabras en común.

Los embeddings se han convertido en bloques fundamentales en las aplicaciones modernas de IA, sirviendo como base para:

  • Búsqueda semántica: Encontrar información relevante basada en el significado en lugar de solo palabras clave, permitiendo resultados de búsqueda más inteligentes
  • Agrupamiento de temas: Organizar automáticamente grandes colecciones de documentos en grupos significativos basados en su contenido
  • Sistemas de recomendación: Sugerir elementos relacionados mediante la comprensión de las conexiones más profundas entre diferentes piezas de contenido
  • Recuperación de contexto para asistentes de IA: Ayudar a los chatbots y sistemas de IA a encontrar y utilizar información relevante de grandes bases de conocimiento
  • Detección de anomalías y similitudes: Identificar patrones inusuales o encontrar elementos similares en grandes conjuntos de datos comparando sus representaciones semánticas

Estos casos de uso se explorarán en detalle en la sección 3.1.4.

3.1.2 ¿Cómo Funcionan los Embeddings?

Cada fragmento de texto se transforma en un vector —esencialmente una larga lista de números de punto flotante (por ejemplo, usando el modelo text-embedding-3-small de OpenAI se crea un vector de 1,536 dimensiones). Piensa en este vector como un punto preciso en un vasto espacio matemático. La parte fascinante es cómo estos vectores se relacionan entre sí: cuando dos fragmentos de texto tienen significados similares, sus vectores estarán posicionados más cerca en este espacio. Esta proximidad se mide utilizando técnicas matemáticas como la similitud del coseno.

Por ejemplo, las frases "Me encanta la pizza" y "La pizza es mi comida favorita" tendrían vectores mucho más cercanos entre sí que cualquiera de ellos lo estaría de "El clima está agradable hoy". Esta representación matemática del significado hace que los embeddings sean increíblemente poderosos para varias aplicaciones:

  • Buscar en una base de datos de documentos por significado - encontrando documentos relevantes incluso cuando usan diferentes palabras para expresar el mismo concepto. Por ejemplo, una búsqueda de "remedios naturales para dolores de cabeza" también encontraría documentos sobre "tratamientos holísticos para migrañas" u "opciones de alivio del dolor no farmacéuticas", porque los embeddings entienden que estos conceptos están relacionados.
  • Encontrar la coincidencia más cercana a la pregunta de un usuario - entendiendo la intención detrás de las consultas y relacionándolas con las respuestas más relevantes, incluso si la redacción difiere. Esto es particularmente poderoso en escenarios de atención al cliente, donde una pregunta como "¿Cómo restablezco mi contraseña?" podría coincidir con documentación titulada "Guía de Recuperación de Contraseña" o "Pasos para Restaurar el Acceso a la Cuenta". El modelo de embedding reconoce que estos están abordando la misma necesidad subyacente.
  • Agrupar correos electrónicos similares, tickets de soporte o descripciones de productos - organizando automáticamente el contenido basado en similitud semántica en lugar de solo coincidencias de palabras clave. Por ejemplo, todas las quejas de clientes sobre retrasos en los envíos podrían agruparse juntas, incluso si están redactadas de manera diferente. Esto permite una categorización poderosa como enrutar automáticamente correos electrónicos de "¿Dónde está mi pedido?", quejas de "La entrega está tardando demasiado" y tickets de "Paquete detenido en tránsito" a la misma cola de soporte, a pesar de sus diferentes redacciones. El sistema incluso puede identificar problemas relacionados como "el número de seguimiento no funciona" porque comparten similitud contextual con preocupaciones relacionadas con el envío.

3.1.3 Generemos Tu Primer Embedding

Usaremos el modelo text-embedding-3-small de OpenAI, que ofrece varias ventajas clave. Primero, es liviano, lo que significa que requiere recursos computacionales mínimos y puede procesar embeddings rápidamente. Segundo, es rentable, con un precio de $0.02 por millón de tokens (Nota: Siempre verifica la página de precios actual de OpenAI para las tarifas vigentes), haciéndolo accesible tanto para proyectos pequeños como para aplicaciones a gran escala.

Tercero, a pesar de su eficiencia, es sorprendentemente potente, capaz de generar embeddings de alta calidad de 1,536 dimensiones que capturan relaciones semánticas sutiles. Este modelo logra un excelente equilibrio entre rendimiento y utilización de recursos, convirtiéndolo en una opción ideal para desarrolladores que buscan implementar funcionalidad de embeddings en sus aplicaciones.

Generemos un embedding para una frase de ejemplo.

Ejemplo del Mundo Real: Comparando Dos Textos

Los embeddings nos permiten cuantificar la similitud semántica entre fragmentos de texto. Supongamos que quieres saber qué tan similares son estas dos frases en significado:

  • text_1 = "How to bake a chocolate cake?"
  • text_2 = "What are the steps for making chocolate dessert?"

Podemos generar embeddings para ambos y luego calcular la similitud del coseno entre sus vectores. La similitud del coseno mide el coseno del ángulo entre dos vectores no nulos; un valor más cercano a 1 indica mayor similitud, 0 indica ninguna similitud (ortogonalidad), y -1 indica significado opuesto (aunque menos común con este tipo de embeddings).

import os
from openai import OpenAI, OpenAIError
from dotenv import load_dotenv
import numpy as np # For cosine similarity calculation
import datetime

# --- Configuration ---
load_dotenv()

# Get the current date and location context
current_timestamp = "2025-03-12 15:07:00 CDT"
current_location = "Grapevine, Texas, United States"
print(f"Running Embeddings example at: {current_timestamp}")
print(f"Location Context: {current_location}")


# Initialize the OpenAI client
try:
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise ValueError("OPENAI_API_KEY not found in environment variables.")
    client = OpenAI(api_key=api_key)
    print("OpenAI client initialized.")
except ValueError as e:
    print(f"Configuration Error: {e}")
    exit()
except Exception as e:
    print(f"Error initializing OpenAI client: {e}")
    exit()

# Define the embedding model
EMBEDDING_MODEL = "text-embedding-3-small"

# --- Helper Function to Generate Embedding ---
def get_embedding(client, text, model=EMBEDDING_MODEL):
    """Generates an embedding for the given text using the specified model."""
    print(f"\nGenerating embedding for: \"{text}\"")
    try:
        # Use client.embeddings.create (updated syntax)
        response = client.embeddings.create(
            input=text,
            model=model
        )
        # Access embedding via attribute (updated syntax)
        embedding_vector = response.data[0].embedding
        print("Embedding generation successful.")
        return embedding_vector
    except OpenAIError as e:
        print(f"OpenAI API Error generating embedding: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred during embedding generation: {e}")
        return None

# --- Helper Function for Cosine Similarity ---
def cosine_similarity(vec_a, vec_b):
    """Calculates the cosine similarity between two vectors."""
    if vec_a is None or vec_b is None:
        print("Error: Cannot calculate similarity with None vectors.")
        return 0.0 # Or handle as appropriate

    # Ensure vectors are numpy arrays for calculation
    vec_a = np.array(vec_a)
    vec_b = np.array(vec_b)

    # Calculate dot product and norms
    dot_product = np.dot(vec_a, vec_b)
    norm_a = np.linalg.norm(vec_a)
    norm_b = np.linalg.norm(vec_b)

    # Calculate similarity (handle potential division by zero)
    if norm_a == 0 or norm_b == 0:
        print("Warning: One or both vectors have zero magnitude.")
        return 0.0
    else:
        similarity = dot_product / (norm_a * norm_b)
        return similarity

# --- Generate First Embedding ---
print("\n--- Section 3.1.3: Generating First Embedding ---")
text_to_embed = "Artificial intelligence can help improve healthcare outcomes."
embedding1 = get_embedding(client, text_to_embed)

if embedding1:
    print("✅ Embedding vector generated!")
    print(f"Vector size: {len(embedding1)}")
    # print("First few dimensions:", embedding1[:5]) # Optionally print part of the vector
else:
    print("Failed to generate the first embedding.")

# --- Comparing Two Texts ---
print("\n--- Section 3.1.4: Comparing Two Texts ---")
text_1 = "How to bake a chocolate cake?"
text_2 = "What are the steps for making chocolate dessert?"

# Get embeddings for both texts
embedding_comp1 = get_embedding(client, text_1)
embedding_comp2 = get_embedding(client, text_2)

# Compute and print cosine similarity if both embeddings were generated
if embedding_comp1 and embedding_comp2:
    similarity_score = cosine_similarity(embedding_comp1, embedding_comp2)
    print(f"\nSemantic similarity score between \"{text_1}\" and \"{text_2}\": {similarity_score:.3f}")
    print("(Score closer to 1.0 means higher semantic similarity)")
else:
    print("\nCould not calculate similarity because one or both embeddings failed.")

Explicación del Desglose del Código

Este script de Python demuestra cómo usar la API de OpenAI para generar embeddings de texto y luego calcular la similitud semántica entre dos fragmentos de texto.

  1. Prerrequisitos y Configuración:
    • Comentarios: El script comienza con comentarios que describen las bibliotecas necesarias (openaipython-dotenvnumpy) y la necesidad de un archivo .env que contenga el OPENAI_API_KEY.
    • Importaciones: Importa las bibliotecas requeridas:
      • os: Utilizado aquí para interactuar con variables de entorno.
      • openaiOpenAIError: La biblioteca principal para interactuar con la API de OpenAI y manejar sus errores específicos.
      • dotenv: Para cargar la clave API de forma segura desde un archivo .env.
      • numpy (como np): Una biblioteca fundamental para operaciones numéricas en Python, utilizada aquí específicamente para cálculos vectoriales (producto punto, norma) necesarios para la similitud del coseno.
      • datetime: Utilizado para obtener la marca de tiempo actual para el contexto de registro.
  2. Configuración:
    • load_dotenv(): Carga las variables de entorno desde el archivo .env.
    • Registro de Contexto: Imprime la marca de tiempo actual y la ubicación para el contexto de ejecución.
    • Inicialización del Cliente OpenAI:
      • Obtiene la clave API usando os.getenv("OPENAI_API_KEY").
      • Instancia el objeto cliente principal: client = OpenAI(api_key=api_key). Todas las llamadas a la API se realizarán a través de este objeto client. Esto utiliza la sintaxis moderna para la biblioteca openai (v1.0.0+).
      • Incluye bloques try...except para manejar posibles errores durante la inicialización (por ejemplo, clave API faltante).
    • EMBEDDING_MODEL: Define una constante que contiene el nombre del modelo de embedding de OpenAI a utilizar (text-embedding-3-small).
  3. Función Auxiliar: get_embedding:
    • Propósito: Encapsula la lógica para generar un embedding para un fragmento de texto individual.
    • Parámetros: Toma el objeto client, el text a embeber, y el nombre del model como entrada.
    • Llamada a la API: Realiza la llamada principal a la API usando client.embeddings.create(...).
      • input=text: La cadena de texto que se convertirá en un embedding.
      • model=model: El modelo específico de embedding a utilizar.
    • Manejo de Respuesta:
      • Accede al vector de embedding generado mediante acceso a atributos en el objeto de respuesta: response.data[0].embedding. Esta es la forma estándar de acceder a los resultados en las versiones más nuevas de la biblioteca.
      • Devuelve el vector de embedding numérico (una lista de números flotantes).
    • Manejo de Errores: Incluye bloques try...except para capturar OpenAIError y otras posibles excepciones durante la llamada a la API. Devuelve None si ocurre un error.
  4. Función Auxiliar: cosine_similarity:
    • Propósito: Calcula la similitud del coseno entre dos vectores numéricos (embeddings).
    • Parámetros: Toma dos vectores, vec_a y vec_b.
    • Validación de Entrada: Verifica si alguno de los vectores de entrada es None.
    • Conversión a Numpy: Convierte las listas/vectores de entrada en arreglos de numpy (np.array()) para operaciones matemáticas eficientes.
    • Cálculo:
      • np.dot(vec_a, vec_b): Calcula el producto punto de los dos vectores.
      • np.linalg.norm(vec_a) y np.linalg.norm(vec_b): Calculan la magnitud (norma euclidiana o norma L2) de cada vector.
      • Maneja la posible división por cero si algún vector tiene magnitud cero.
      • Calcula la similitud usando la fórmula: dot_product / (norm_a * norm_b).
    • Salida: Devuelve el puntaje de similitud del coseno, un número flotante típicamente entre -1 y 1 (aunque generalmente entre 0 y 1 para este tipo de embeddings).
  5. Generar Primer Embedding:
    • Imprime un encabezado de sección.
    • Define el texto de ejemplo text_to_embed.
    • Llama a la función auxiliar get_embedding para generar el embedding para este texto.
    • Si tiene éxito (if embedding1:), imprime un mensaje de confirmación y el tamaño (dimensionalidad) del vector generado usando len(embedding1).
  6. Comparación de Dos Textos:
    • Imprime un encabezado de sección.
    • Define dos cadenas de texto, text_1 y text_2, para ser comparadas.
    • Llama a get_embedding dos veces para obtener los vectores de embedding tanto para text_1 como para text_2.
    • Si ambos embeddings se generaron exitosamente (if embedding_comp1 and embedding_comp2:), procede a calcular la similitud.
    • Llama a la función auxiliar cosine_similarity con los dos vectores de embedding.
    • Imprime el similarity_score calculado, formateado a tres decimales, junto con una explicación del significado del puntaje.
  7. Guardia de Ejecución Principal (if __name__ == "__main__":):
    • Esta construcción estándar de Python asegura que el código dentro de este bloque (que incluye las llamadas para las secciones 3.1.3 y 3.1.4) solo se ejecute cuando el script se ejecuta directamente, no cuando se importa como un módulo en otro script.

Este ejemplo proporciona un ejemplo claro y funcional de cómo generar embeddings y usarlos para medir la similitud semántica entre textos utilizando los estándares actuales de la biblioteca Python de OpenAI.

3.1 Entendiendo los Embeddings de Texto

A lo largo de este libro, hemos profundizado en las fascinantes capacidades de GPT-4o, explorando su habilidad para procesar lenguaje natural, interpretar información visual y analizar señales de audio. Ahora, estamos a punto de descubrir otro aspecto crucial de los sistemas modernos de IA: la capacidad de entender y procesar contenido a escalas masivas de una manera que verdaderamente comprende el significado.

Aquí es donde entra en juego el poderoso concepto de los embeddings. Piensa en los embeddings como el puente entre el lenguaje humano y la comprensión de las máquinas.

En su esencia, los embeddings son representaciones matemáticas sofisticadas que transforman el texto en vectores numéricos. Pero estos no son solo números aleatorios: son huellas numéricas cuidadosamente elaboradas que capturan la esencia semántica del contenido. Esta representación matemática permite a las computadoras entender relaciones entre conceptos, medir la similitud entre ideas y procesar información de manera que refleja la comprensión humana. Cuando convertimos texto en embeddings, podemos comparar ideas, clasificar resultados de búsqueda, identificar patrones y analizar grandes cantidades de información utilizando la comprensión contextual, yendo mucho más allá de la simple coincidencia de palabras clave.

En este capítulo completo, exploraremos:

  • Una inmersión profunda en la creación y manipulación de embeddings de texto utilizando la API de vanguardia de OpenAI, incluyendo mejores prácticas y técnicas de optimización
  • Aplicaciones avanzadas de embeddings en sistemas de búsqueda semántica y mecanismos sofisticados de recuperación de documentos que comprenden el contexto y la intención del usuario
  • Implementación práctica de embeddings en aplicaciones del mundo real, enfocándose en motores de recomendaciónsistemas inteligentes de respuesta a preguntas y soluciones avanzadas de agrupamiento de datos
  • Una mirada exhaustiva a cómo los embeddings sirven como base para los sistemas modernos de IA, incluyendo arquitecturas RAG (Generación Aumentada por Recuperación), chatbots inteligentes, motores de búsqueda de próxima generación y bases de datos vectoriales sofisticadas

Comencemos nuestro viaje dominando los fundamentos: entendiendo qué hace que los embeddings sean tan poderosos y cómo implementarlos efectivamente en tus proyectos.

En esta sección, exploraremos los conceptos fundamentales detrás de los embeddings de texto, comenzando con su definición básica y avanzando a través de sus aplicaciones prácticas. Entender los embeddings de texto es crucial porque forman la columna vertebral de muchas aplicaciones modernas de IA, desde motores de búsqueda hasta sistemas de recomendación.

Desglosaremos conceptos técnicos complejos en explicaciones digeribles, complementadas con ejemplos prácticos que demuestran cómo los embeddings capturan y representan el significado. Ya seas un desarrollador que busca implementar búsqueda semántica o un entusiasta de la tecnología que desea entender cómo los sistemas de IA procesan el lenguaje, esta sección te proporcionará una base sólida.

3.1.1 ¿Qué Son los Embeddings?

En términos simples, los embeddings son representaciones numéricas sofisticadas de texto —como oraciones, párrafos o incluso documentos completos— que capturan su significado de una manera que las máquinas pueden entender y procesar. Piensa en ellos como la conversión de palabras en una serie de números que preservan la esencia y el contexto del texto original.

Lo que hace particularmente poderosos a los embeddings es su capacidad de ir más allá de la simple coincidencia de palabras. En lugar de comparar palabras carácter por carácter (como "perro" vs "perros"), los embeddings analizan las relaciones semánticas más profundas entre palabras y frases. Así es como funciona:

  • Cuando el texto se convierte en embeddings, los conceptos similares se posicionan más cerca entre sí en el espacio matemático. Por ejemplo, "¿Cómo hago panqueques?" y "Pasos para cocinar tortitas" pueden parecer completamente diferentes como texto, pero tienen embeddings muy similares porque expresan el mismo concepto subyacente.
  • El mismo principio se aplica a sinónimos, conceptos relacionados e incluso diferentes formas de expresar la misma idea. Por ejemplo, "mantenimiento de automóvil" y "reparación de coche" tendrían embeddings similares a pesar de usar palabras diferentes.
  • Esta comprensión semántica significa que el modelo puede reconocer relaciones entre conceptos incluso cuando no comparten palabras en común.

Los embeddings se han convertido en bloques fundamentales en las aplicaciones modernas de IA, sirviendo como base para:

  • Búsqueda semántica: Encontrar información relevante basada en el significado en lugar de solo palabras clave, permitiendo resultados de búsqueda más inteligentes
  • Agrupamiento de temas: Organizar automáticamente grandes colecciones de documentos en grupos significativos basados en su contenido
  • Sistemas de recomendación: Sugerir elementos relacionados mediante la comprensión de las conexiones más profundas entre diferentes piezas de contenido
  • Recuperación de contexto para asistentes de IA: Ayudar a los chatbots y sistemas de IA a encontrar y utilizar información relevante de grandes bases de conocimiento
  • Detección de anomalías y similitudes: Identificar patrones inusuales o encontrar elementos similares en grandes conjuntos de datos comparando sus representaciones semánticas

Estos casos de uso se explorarán en detalle en la sección 3.1.4.

3.1.2 ¿Cómo Funcionan los Embeddings?

Cada fragmento de texto se transforma en un vector —esencialmente una larga lista de números de punto flotante (por ejemplo, usando el modelo text-embedding-3-small de OpenAI se crea un vector de 1,536 dimensiones). Piensa en este vector como un punto preciso en un vasto espacio matemático. La parte fascinante es cómo estos vectores se relacionan entre sí: cuando dos fragmentos de texto tienen significados similares, sus vectores estarán posicionados más cerca en este espacio. Esta proximidad se mide utilizando técnicas matemáticas como la similitud del coseno.

Por ejemplo, las frases "Me encanta la pizza" y "La pizza es mi comida favorita" tendrían vectores mucho más cercanos entre sí que cualquiera de ellos lo estaría de "El clima está agradable hoy". Esta representación matemática del significado hace que los embeddings sean increíblemente poderosos para varias aplicaciones:

  • Buscar en una base de datos de documentos por significado - encontrando documentos relevantes incluso cuando usan diferentes palabras para expresar el mismo concepto. Por ejemplo, una búsqueda de "remedios naturales para dolores de cabeza" también encontraría documentos sobre "tratamientos holísticos para migrañas" u "opciones de alivio del dolor no farmacéuticas", porque los embeddings entienden que estos conceptos están relacionados.
  • Encontrar la coincidencia más cercana a la pregunta de un usuario - entendiendo la intención detrás de las consultas y relacionándolas con las respuestas más relevantes, incluso si la redacción difiere. Esto es particularmente poderoso en escenarios de atención al cliente, donde una pregunta como "¿Cómo restablezco mi contraseña?" podría coincidir con documentación titulada "Guía de Recuperación de Contraseña" o "Pasos para Restaurar el Acceso a la Cuenta". El modelo de embedding reconoce que estos están abordando la misma necesidad subyacente.
  • Agrupar correos electrónicos similares, tickets de soporte o descripciones de productos - organizando automáticamente el contenido basado en similitud semántica en lugar de solo coincidencias de palabras clave. Por ejemplo, todas las quejas de clientes sobre retrasos en los envíos podrían agruparse juntas, incluso si están redactadas de manera diferente. Esto permite una categorización poderosa como enrutar automáticamente correos electrónicos de "¿Dónde está mi pedido?", quejas de "La entrega está tardando demasiado" y tickets de "Paquete detenido en tránsito" a la misma cola de soporte, a pesar de sus diferentes redacciones. El sistema incluso puede identificar problemas relacionados como "el número de seguimiento no funciona" porque comparten similitud contextual con preocupaciones relacionadas con el envío.

3.1.3 Generemos Tu Primer Embedding

Usaremos el modelo text-embedding-3-small de OpenAI, que ofrece varias ventajas clave. Primero, es liviano, lo que significa que requiere recursos computacionales mínimos y puede procesar embeddings rápidamente. Segundo, es rentable, con un precio de $0.02 por millón de tokens (Nota: Siempre verifica la página de precios actual de OpenAI para las tarifas vigentes), haciéndolo accesible tanto para proyectos pequeños como para aplicaciones a gran escala.

Tercero, a pesar de su eficiencia, es sorprendentemente potente, capaz de generar embeddings de alta calidad de 1,536 dimensiones que capturan relaciones semánticas sutiles. Este modelo logra un excelente equilibrio entre rendimiento y utilización de recursos, convirtiéndolo en una opción ideal para desarrolladores que buscan implementar funcionalidad de embeddings en sus aplicaciones.

Generemos un embedding para una frase de ejemplo.

Ejemplo del Mundo Real: Comparando Dos Textos

Los embeddings nos permiten cuantificar la similitud semántica entre fragmentos de texto. Supongamos que quieres saber qué tan similares son estas dos frases en significado:

  • text_1 = "How to bake a chocolate cake?"
  • text_2 = "What are the steps for making chocolate dessert?"

Podemos generar embeddings para ambos y luego calcular la similitud del coseno entre sus vectores. La similitud del coseno mide el coseno del ángulo entre dos vectores no nulos; un valor más cercano a 1 indica mayor similitud, 0 indica ninguna similitud (ortogonalidad), y -1 indica significado opuesto (aunque menos común con este tipo de embeddings).

import os
from openai import OpenAI, OpenAIError
from dotenv import load_dotenv
import numpy as np # For cosine similarity calculation
import datetime

# --- Configuration ---
load_dotenv()

# Get the current date and location context
current_timestamp = "2025-03-12 15:07:00 CDT"
current_location = "Grapevine, Texas, United States"
print(f"Running Embeddings example at: {current_timestamp}")
print(f"Location Context: {current_location}")


# Initialize the OpenAI client
try:
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise ValueError("OPENAI_API_KEY not found in environment variables.")
    client = OpenAI(api_key=api_key)
    print("OpenAI client initialized.")
except ValueError as e:
    print(f"Configuration Error: {e}")
    exit()
except Exception as e:
    print(f"Error initializing OpenAI client: {e}")
    exit()

# Define the embedding model
EMBEDDING_MODEL = "text-embedding-3-small"

# --- Helper Function to Generate Embedding ---
def get_embedding(client, text, model=EMBEDDING_MODEL):
    """Generates an embedding for the given text using the specified model."""
    print(f"\nGenerating embedding for: \"{text}\"")
    try:
        # Use client.embeddings.create (updated syntax)
        response = client.embeddings.create(
            input=text,
            model=model
        )
        # Access embedding via attribute (updated syntax)
        embedding_vector = response.data[0].embedding
        print("Embedding generation successful.")
        return embedding_vector
    except OpenAIError as e:
        print(f"OpenAI API Error generating embedding: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred during embedding generation: {e}")
        return None

# --- Helper Function for Cosine Similarity ---
def cosine_similarity(vec_a, vec_b):
    """Calculates the cosine similarity between two vectors."""
    if vec_a is None or vec_b is None:
        print("Error: Cannot calculate similarity with None vectors.")
        return 0.0 # Or handle as appropriate

    # Ensure vectors are numpy arrays for calculation
    vec_a = np.array(vec_a)
    vec_b = np.array(vec_b)

    # Calculate dot product and norms
    dot_product = np.dot(vec_a, vec_b)
    norm_a = np.linalg.norm(vec_a)
    norm_b = np.linalg.norm(vec_b)

    # Calculate similarity (handle potential division by zero)
    if norm_a == 0 or norm_b == 0:
        print("Warning: One or both vectors have zero magnitude.")
        return 0.0
    else:
        similarity = dot_product / (norm_a * norm_b)
        return similarity

# --- Generate First Embedding ---
print("\n--- Section 3.1.3: Generating First Embedding ---")
text_to_embed = "Artificial intelligence can help improve healthcare outcomes."
embedding1 = get_embedding(client, text_to_embed)

if embedding1:
    print("✅ Embedding vector generated!")
    print(f"Vector size: {len(embedding1)}")
    # print("First few dimensions:", embedding1[:5]) # Optionally print part of the vector
else:
    print("Failed to generate the first embedding.")

# --- Comparing Two Texts ---
print("\n--- Section 3.1.4: Comparing Two Texts ---")
text_1 = "How to bake a chocolate cake?"
text_2 = "What are the steps for making chocolate dessert?"

# Get embeddings for both texts
embedding_comp1 = get_embedding(client, text_1)
embedding_comp2 = get_embedding(client, text_2)

# Compute and print cosine similarity if both embeddings were generated
if embedding_comp1 and embedding_comp2:
    similarity_score = cosine_similarity(embedding_comp1, embedding_comp2)
    print(f"\nSemantic similarity score between \"{text_1}\" and \"{text_2}\": {similarity_score:.3f}")
    print("(Score closer to 1.0 means higher semantic similarity)")
else:
    print("\nCould not calculate similarity because one or both embeddings failed.")

Explicación del Desglose del Código

Este script de Python demuestra cómo usar la API de OpenAI para generar embeddings de texto y luego calcular la similitud semántica entre dos fragmentos de texto.

  1. Prerrequisitos y Configuración:
    • Comentarios: El script comienza con comentarios que describen las bibliotecas necesarias (openaipython-dotenvnumpy) y la necesidad de un archivo .env que contenga el OPENAI_API_KEY.
    • Importaciones: Importa las bibliotecas requeridas:
      • os: Utilizado aquí para interactuar con variables de entorno.
      • openaiOpenAIError: La biblioteca principal para interactuar con la API de OpenAI y manejar sus errores específicos.
      • dotenv: Para cargar la clave API de forma segura desde un archivo .env.
      • numpy (como np): Una biblioteca fundamental para operaciones numéricas en Python, utilizada aquí específicamente para cálculos vectoriales (producto punto, norma) necesarios para la similitud del coseno.
      • datetime: Utilizado para obtener la marca de tiempo actual para el contexto de registro.
  2. Configuración:
    • load_dotenv(): Carga las variables de entorno desde el archivo .env.
    • Registro de Contexto: Imprime la marca de tiempo actual y la ubicación para el contexto de ejecución.
    • Inicialización del Cliente OpenAI:
      • Obtiene la clave API usando os.getenv("OPENAI_API_KEY").
      • Instancia el objeto cliente principal: client = OpenAI(api_key=api_key). Todas las llamadas a la API se realizarán a través de este objeto client. Esto utiliza la sintaxis moderna para la biblioteca openai (v1.0.0+).
      • Incluye bloques try...except para manejar posibles errores durante la inicialización (por ejemplo, clave API faltante).
    • EMBEDDING_MODEL: Define una constante que contiene el nombre del modelo de embedding de OpenAI a utilizar (text-embedding-3-small).
  3. Función Auxiliar: get_embedding:
    • Propósito: Encapsula la lógica para generar un embedding para un fragmento de texto individual.
    • Parámetros: Toma el objeto client, el text a embeber, y el nombre del model como entrada.
    • Llamada a la API: Realiza la llamada principal a la API usando client.embeddings.create(...).
      • input=text: La cadena de texto que se convertirá en un embedding.
      • model=model: El modelo específico de embedding a utilizar.
    • Manejo de Respuesta:
      • Accede al vector de embedding generado mediante acceso a atributos en el objeto de respuesta: response.data[0].embedding. Esta es la forma estándar de acceder a los resultados en las versiones más nuevas de la biblioteca.
      • Devuelve el vector de embedding numérico (una lista de números flotantes).
    • Manejo de Errores: Incluye bloques try...except para capturar OpenAIError y otras posibles excepciones durante la llamada a la API. Devuelve None si ocurre un error.
  4. Función Auxiliar: cosine_similarity:
    • Propósito: Calcula la similitud del coseno entre dos vectores numéricos (embeddings).
    • Parámetros: Toma dos vectores, vec_a y vec_b.
    • Validación de Entrada: Verifica si alguno de los vectores de entrada es None.
    • Conversión a Numpy: Convierte las listas/vectores de entrada en arreglos de numpy (np.array()) para operaciones matemáticas eficientes.
    • Cálculo:
      • np.dot(vec_a, vec_b): Calcula el producto punto de los dos vectores.
      • np.linalg.norm(vec_a) y np.linalg.norm(vec_b): Calculan la magnitud (norma euclidiana o norma L2) de cada vector.
      • Maneja la posible división por cero si algún vector tiene magnitud cero.
      • Calcula la similitud usando la fórmula: dot_product / (norm_a * norm_b).
    • Salida: Devuelve el puntaje de similitud del coseno, un número flotante típicamente entre -1 y 1 (aunque generalmente entre 0 y 1 para este tipo de embeddings).
  5. Generar Primer Embedding:
    • Imprime un encabezado de sección.
    • Define el texto de ejemplo text_to_embed.
    • Llama a la función auxiliar get_embedding para generar el embedding para este texto.
    • Si tiene éxito (if embedding1:), imprime un mensaje de confirmación y el tamaño (dimensionalidad) del vector generado usando len(embedding1).
  6. Comparación de Dos Textos:
    • Imprime un encabezado de sección.
    • Define dos cadenas de texto, text_1 y text_2, para ser comparadas.
    • Llama a get_embedding dos veces para obtener los vectores de embedding tanto para text_1 como para text_2.
    • Si ambos embeddings se generaron exitosamente (if embedding_comp1 and embedding_comp2:), procede a calcular la similitud.
    • Llama a la función auxiliar cosine_similarity con los dos vectores de embedding.
    • Imprime el similarity_score calculado, formateado a tres decimales, junto con una explicación del significado del puntaje.
  7. Guardia de Ejecución Principal (if __name__ == "__main__":):
    • Esta construcción estándar de Python asegura que el código dentro de este bloque (que incluye las llamadas para las secciones 3.1.3 y 3.1.4) solo se ejecute cuando el script se ejecuta directamente, no cuando se importa como un módulo en otro script.

Este ejemplo proporciona un ejemplo claro y funcional de cómo generar embeddings y usarlos para medir la similitud semántica entre textos utilizando los estándares actuales de la biblioteca Python de OpenAI.