Búsqueda por significado, no por metadatos: filtrado semántico de imágenes con 4D.Vector

Sus usuarios no piensan en términos de nombres de archivo o jerarquías de carpetas. Piensan en ideas.

  • «Un robot pintado en acuarela».
  • «Una playa soleada llena de color».
  • «Algo parecido a la Mona Lisa… pero del futuro».

No importa si esa idea proviene de una imagen, de un pedido de un cliente, de un correo electrónico o de un documento 4D Write Pro, el reto es el mismo: ¿cómo ofrecer resultados que coincidan con la intención, no sólo con las palabras clave?

Con 4D.Vector y 4D AI Kit, su aplicación puede finalmente dar sentido al significado. En este post, lo ilustraremos con la búsqueda semántica por similitud de imágenes. Y aquí está la clave: en realidad no estamos trabajando con imágenes en bruto,  estamos trabajando con sus descripciones. El mismo enfoque funciona para cualquier tipo de datos de texto en su aplicación.

DEMO_AI_Vector_ImageSearch

Porqué los vectores y la IA lo cambian todo

La búsqueda tradicional tiene un único objetivo: encontrar términos exactos. Pero sus usuarios no siempre saben qué término exacto utilizar. Describen cosas. Expresan intenciones. Piensan en un lenguaje desordenado, hermoso y humano.

Para que la búsqueda funcione como piensan los usuarios, se necesita algo más que la concordancia de cadenas. Se necesita comprensión, y ahí es donde entran en juego las incrustaciones vectoriales.

¿Qué es exactamente una incrustación?

Una incrustación es la forma de convertir una entrada desordenada y desestructurada, una frase, una pregunta o una imagen, en un vector estructurado de números. No es sólo una lista de símbolos o palabras clave. Es una instantánea matemática del significado.

Cuando se envía la frase «un robot pintado en acuarela» al modelo text-embedding-ada-002 de OpenAI, éste devuelve unos cientos de valores en coma flotante. Cada uno de ellos capta algo: el tema, el estado de ánimo, el estilo, las relaciones semánticas incorporadas a la frase. Las frases similares producen vectores similares. ¿Las que no lo son? Se separan más.

Es como situar el significado en un mapa. Cuanto más cerca estén dos frases en ese espacio de alta dimensión, más parecidas serán, independientemente de la redacción. Esta es la base para crear búsquedas, recomendaciones, agrupaciones y categorizaciones basadas en el significado.

Un caso de uso real: búsqueda de imágenes por significado

En nuestra página de demostración, puede permitir a los usuarios realizar búsquedas semánticas. Escriben una pregunta o eligen una de una lista, y su aplicación devuelve imágenes clasificadas según su grado de coincidencia con la idea.

La interfaz de usuario es voluntariamente mínima:

  • Un campo de texto para los prompts personalizados
  • Un menú desplegable de prompts predefinidos
  • Una matriz que muestra las imágenes, ordenadas por similitud con el prompt.

Aquí está la clave: no vectorizamos las imágenes en bruto. En su lugar, cada imagen es analizada por OpenAIVision de AIKit , que genera una leyenda y una descripción en lenguaje natural. Esa descripción es la que se integra en un 4D.Vector y se almacena.

De esta forma, todo se compara a nivel de significado, no de píxeles.

Nota: este ejemplo utiliza 4D Qodly Pro, pero la misma lógica se aplica perfectamente también a los formularios 4D estándar. De hecho, todo el código se ejecuta dentro de los métodos y funciones de 4D. La única diferencia es cómo usted elige mostrar los resultados, en un formulario 4D clásico o en una página Qodly.

Cómo generaR el vector

Cuando alguien escribe un prompt y hace clic en «Use Custom Prompt«, 4D ejecuta la función calculate() de la clase VectorManagement:

exposed shared Function calculate($prompt : Text) : cs.PicturesSelection

Esto se inicia con la obtención de su clave API OpenAI en memoria (Storage.OpenAI.key), que debe ser presentada desde el primer campo de entrada en la pestaña Info. Si ha omitido este campo y ha hecho clic en «Use Custom Prompt«, aparecerá una ventana modal pidiéndole que introduzca su clave antes de continuar:

If (Storage.OpenAI.key#"")
	$apiKey:=Storage.OpenAI.key
Else 
	$apiModal:=Web Form.setApiKeyModal
	$apiModal.show()
End if 

Nota: este ejemplo utiliza OpenAI para las operaciones de IA, pero puede utilizar cualquier proveedor compatible con OpenAI, incluso un modelo local con Ollama. Aquí utilizamos OpenAI porque es fácil de configurar y no requiere instalación local. Si quiere seguirnos, solicite una clave OpenAI aquí.

A continuación, llame a la función generateVector() dentro de la clase AIManagement:

var $vector := cs.AIManagement.new($apiKey).generateVector($prompt)

¿Qué está pasando aquí?

Está utilizando el modelo text-embedding-ada-002 de OpenAI, optimizado para textos cortos, para convertir el prompt en un vector de alta dimensión. Utilizando el método .create() para enviar el prompt y el modelo text-embedding-ada-002 como una petición a OpenAI y devuelve una estructura JSON que contiene el vector. Ese vector es entonces envuelto en un objeto 4D.Vector, dándonos algo que podemos comparar y ordenar nativamente en 4D.

property clientAI : Object

Class constructor($openAIKey : Text)
  This.clientAI := cs.AIKit.OpenAI.new($openAIKey)

Function generateVector($text : Text) : 4D.Vector
  var $model := "text-embedding-ada-002"
  var $result := This.clientAI.embeddings.create($text; $model)
  return $result.vector

En este punto, se ha traducido el prompt del usuario a un formato estructurado que 4D puede utilizar para la comparación semántica.

Del PROMPT a los resultados ordenados

Con su vector en la mano, ahora lo compara con todos sus vectores de descripción de imagen almacenados en la base de datos:

var $pictureList := This._calculateVectors($vector)

Y dentro de _calculateVectors, esto es lo que ocurre:

For each ($picture; $pictureList)
  $picture.cosineSimilarity := $vector.cosineSimilarity($picture.vector)
  $picture.dotSimilarity := $vector.dotSimilarity($picture.vector)
  $picture.euclideanDistance := $vector.euclideanDistance($picture.vector)
  $picture.save()
End for each 

Cada medida de similitud le ofrece un objetivo diferente:

  • La similitud del coseno mide la proximidad de dos vectores que apuntan en la misma dirección. Ideal para clasificar la similitud semántica.
  • El producto de puntos tiene en cuenta tanto la dirección como la magnitud. Es útil cuando se quiere tener en cuenta la «fuerza» con la que se alinean dos vectores.
  • La distancia euclidiana es la distancia bruta entre dos puntos en el espacio. Cuanto menor es la distancia, más parecidos son.

Si usted es nuevo en las matemáticas vectoriales en 4D, la primera entrada del blog en esta serie cubre cómo crear y comparar vectores utilizando estos métodos y cuándo utilizar cada uno.

Una vez que todas las puntuaciones de similitud son calculadas y almacenadas en las entidades de imagen, se ordenan por similitud coseno y se devuelven los resultados:

return $pictureList.orderBy("cosineSimilarity desc")

Esto significa que las imágenes conceptualmente más relevantes aparecen en primer lugar, independientemente de su nombre de archivo, descripción o metadatos.

¿Qué ocurre si el usuario elige una pregunta predefinida?

Si alguien elige una pregunta del menú desplegable y hace clic en Utilizar el prompt seleccionado, se omite por completo el paso de integración:

exposed shared Function calculateWithSelectedPrompt($prompt : cs.PromptsEntity) : cs.PicturesSelection
  var $pictureList:=This._calculateVectors($prompt.Vector)
  return $pictureList.orderBy("cosineSimilarity desc")

No se necesita una llamada adicional a OpenAI – el vector de la pregunta ya está guardado en la base de datos. Usted simplemente reutiliza el 4D.Vector almacenado en la clase de datos Prompts cuando el prompt fue creado por primera vez.

Al igual que las descripciones de imágenes, cada prompt es vectorizado una vez, y luego almacenado para su reutilización. Esto le da:

  • Sin llamada a la API → Resultados instantáneos, sin demora de red.

  • Sin coste de token → Más económico, especialmente a escala.

  • Funciona sin conexión → Todo se ejecuta localmente, sin dependencia de un servicio externo

DE LA SUBIDA DE IMÁGENES A LA DESCRIPCIÓN VECTORIZADA

Cuando alguien sube una imagen, no integra los píxeles. En su lugar, describe la imagen con OpenAI Vision, e integra esa descripción.

En la función vectorizeImageDescription, se definen dos preguntas: una para una breve leyenda y otra para una descripción más completa. Ambas están diseñadas para devolver frases sencillas y fluidas optimizadas para incrustaciones:

// --- Prompts (single, fluent, embedding-friendly) ---
$captionPrompt:="You are a precise visual captioner. "+\
	"Write one short, clear English sentence (12–20 words) that summarizes the main subject of the image. "+\
	"Keep it straightforward and descriptive, not poetic. Output only the sentence."

$descriptionPrompt:="You are a detailed scene describer. "+\
	"Write a longer English paragraph (80–150 words) that expands on the caption. "+\
	"Include context, secondary elements (icons, arrows, checklists, text, logos), and atmosphere so nothing important is missed. "+\
	"Avoid repeating the caption verbatim. Output only the description."

Con estas instrucciones, OpenAI Vision analiza la imagen. Esto ocurre en dos pasos:

  • .create() crea una instancia de VisionHelper vinculada a la imagen cargada.
  • .prompt() envía una instrucción en lenguaje natural junto con la imagen a la API OpenAI Chat, devolviendo un pie de foto o una descripción.
// --- Get caption ---
$caption:=$client.chat.vision.create($imageData).prompt($captionPrompt).choice.message.text
	
// --- Get description ---
$description:=$client.chat.vision.create($imageData).prompt($descriptionPrompt).choice.message.text

En este punto, dispone de una legenda y de una descripción. Éstas se guardan junto con la propia imagen y, lo que es más importante, la descripción se vectoriza para la búsqueda semántica:

// --- Save entity ---
$pictureEntity:=ds.Pictures.new()
$pictureEntity.picture:=$imageToUpload.picture
$pictureEntity.prompt:=$caption
$pictureEntity.description:=$description
$pictureEntity.vector:=cs.AIManagement.new($apiKey).generateVector($description+$caption)
$status:=$pictureEntity.save()

Lo que se ve en la interfaz usuario

Una vez realizada la comparación, la matriz se actualiza al instante. Las imágenes se clasifican en función de la puntuación de similitud.

  • Usted busca: «una pintura en acuarela de un robot»  y ve imágenes con texturas suaves y formas robóticas:

Visual results of a semantic AI image search using the prompt 'a watercolor painting of a robot,' showing six top-matching artworks with cosine similarity scores in a futuristic 4D interface.

  • Cambia a: «una escena de playa vibrante y soleada con elementos coloridos» y obtiene un conjunto de resultados totalmente diferente, pero igualmente relevante:

Semantic image search results for the prompt 'a vibrant and sunny beach scene with colorful elements,' ranked by AI using vector comparisons in a real-time 4D interface.

Tanto si escribe como si sube archivos, siempre está comparando ideas, no píxeles ni nombres de archivos.

Lo que obtiene como desarrollador

El uso de vectores con IA desbloquea un valor real e inmediato en sus aplicaciones 4D:

  • Búsqueda más inteligente: permite a los usuarios buscar por significado, no por palabras clave. Sin etiquetas ni filtros, sólo resultados relevantes.

  • Lógica nativa: todo se ejecuta dentro de 4D. No hay necesidad de motores de búsqueda externos o herramientas de terceros.

  • Patrón reutilizable: funciona para imágenes, documentos, productos, tickets, cualquier cosa que quiera comparar por concepto.

  • Baja configuración, alto impacto: unas pocas líneas de código le dan ranking, filtrado y recomendaciones impulsadas por IA.

  • Más barato y más rápido: integre una vez, almacene el vector y reutilícelo para siempre. Sin repetidas llamadas a la API ni costes de token.

  • Base preparada para la IA: no sólo está añadiendo búsqueda, está sentando las bases para chatbots, recomendaciones y flujos de trabajo más inteligentes.

Con 4D.Vector y 4D AI Kit, usted no necesita construir inteligencia, usted la conecta.

Reflexiones finales

No está atornillando IA a su aplicación, está integrando inteligencia en su lógica central.

Con 4D.Vector y 4D AI Kit, le da a su aplicación la capacidad de entender la intención, no sólo la entrada. Para sacar a la superficie el significado, no sólo las coincidencias.

Las herramientas están listas. El código es ligero. El valor es real. Todo lo que necesita ahora… es un prompt.

Avatar
Product Marketing Manager – Basma se unió a 4D en 2019 y fue creciendo en su rol actual tras haber trabajado en desarrollo, documentación y estrategia de contenido. Colabora estrechamente con los equipos de producto, ingeniería, marketing, soporte y gestión para dar forma al “por qué”, “cómo” y “qué” detrás de cada funcionalidad y lanzamiento. Su experiencia transversal le permite hoy construir mensajes claros y desarrollar contenido técnico en profundidad — incluidos artículos especializados — para el blog y la web de 4D. Con un máster en Ingeniería de Software, Basma combina fluidez técnica con una fuerte voz editorial. Su trayectoria en áreas como desarrollo, migraciones, auditorías, webinars y formación le aporta una ventaja única en marketing de producto, ayudándola a traducir la complejidad en claridad y crear contenido que realmente conecte con los desarrolladores.