Freedam
IngenieríaParte 1 de 7 · 28 min de lecturaActualizado el

Qué hace falta de verdad para construir una buena búsqueda de imágenes

En febrero de 2000, Jennifer Lopez llevó un vestido verde de Versace a los Grammy, y durante unas semanas fue lo más buscado en Google. Google solo podía devolver diez enlaces azules, algunos de los cuales llevaban a páginas que quizá contenían una fotografía. Eric Schmidt escribió más tarde que fue la consulta más popular que habían visto nunca y que por eso construyeron un buscador de imágenes. Google Imágenes se lanzó en julio de 2001 e indexaba unos 250 millones de imágenes.

El vestido, esa noche: Jennifer Lopez presentando el premio al mejor álbum de R&B en la 42.ª edición de los Grammy, el 23 de febrero de 2000. Video de la serie GRAMMY Rewind de la Recording Academy.

Me gusta esta historia por la parte que la gente omite: Google Imágenes no buscaba en los píxeles. Indexaba el nombre de archivo, el texto alternativo, el pie de foto y las palabras cercanas a una etiqueta <img>, y luego comparaba la consulta con ese texto. El vestido se podía encontrar porque miles de páginas habían escrito «Jennifer Lopez», «Versace» y «Grammys» a su lado.

Maqueta de una página de resultados de búsqueda de principios de 2000: diez enlaces azules y ninguna imagen BÚSQUEDA WEB, FEBRERO DE 2000 jennifer lopez green dress Buscar Grammy Awards 2000: red carpet arrivals Versace - Spring 2000 collection J.Lo fan page (under construction) E! Online: who wore what alt.fan.jennifer-lopez archive Green dress - GeoCities … 4 enlaces más ni una sola imagen en esta página la consulta más popular que Google había visto
Cómo era una búsqueda web del vestido a principios de 2000, reconstruida. La búsqueda de texto tenía las palabras y no podía mostrar la imagen.

Veinticinco años y varias generaciones de visión artificial después, la búsqueda de imágenes sigue empezando por crear algo que se pueda buscar a partir de la imagen o a su alrededor, lo que explica muchos de los problemas prácticos que siguen.

Dirijo freedam, un gestor de recursos digitales para las fotografías, los videos y los documentos que una empresa necesita volver a encontrar. Hemos dedicado más tiempo de ingeniería a la búsqueda que a cualquier otra parte, así que este artículo reúne lo que aprendimos, para quien esté construyendo una o quiera entender por qué la suya se deja cosas sin encontrar. También hay una versión más técnica con el SQL y los parámetros; esta se queda con la forma del problema.

Una imagen no tiene palabras

Una fila de una tabla de pedidos contiene el nombre de un cliente, un ticket de soporte contiene un cuerpo de texto y un PDF puede tener una capa de texto. Un JPEG tiene tres canales de color y algo de EXIF, pero ningún término con el que una consulta de texto pueda coincidir directamente.

Por eso una búsqueda de imágenes necesita un sustituto buscable de la imagen. En la práctica, esos sustitutos se agrupan en cuatro grandes familias, y cada una cubre consultas que las demás no cubren.

Cuatro puentes entre una consulta de texto y los píxeles de una imagen consulta «vestido verde» los píxeles sin términos dentro Palabras que alguien escribiónombre de archivo, pie de foto, el texto alrededor de la imagen. Google Imágenes, 2001 Palabras de un vocabularioetiquetas, categorías, una taxonomía. Precisas, filtrables, costosas, nunca terminadas Palabras que escribió una máquinaOCR, descripciones, transcripciones. Abundantes, con ruido, ciegas a tu negocio Ninguna palabrala imagen como 768 números. Significado sin palabras; no sabe deletrear un SKU
Toda búsqueda de imágenes cruza uno de cuatro puentes. Los sistemas que eligen un puente favorito fallan en las consultas que necesitan los otros tres.

Palabras que alguien escribió. Un nombre de archivo, un título, un pie de foto o el texto que rodea una imagen. Es con lo que se lanzó Google Imágenes, y con lo que se había lanzado Photo Finder de AltaVista tres años antes. Es barato y a menudo eficaz porque las personas son buenas poniendo nombres a las cosas, pero no sirve cuando una carpeta contiene solo archivos llamados DSC_0001 a DSC_4817.

Palabras de un vocabulario. Las etiquetas, las categorías y las taxonomías son precisas y filtrables, por lo que las usan las agencias de imágenes de stock y las bibliotecas corporativas. También son costosas de mantener, y el vocabulario tiende a alejarse del lenguaje que la gente usa para buscar.

Palabras que escribió una máquina. Esto incluye el OCR de la imagen, las descripciones de un modelo de visión y las transcripciones de video. El ESP Game de Luis von Ahn usó una versión humana en 2004: dos desconocidos veían la misma imagen, ganaban puntos cuando escribían la misma palabra y su coincidencia se convertía en una etiqueta. Google lo licenció como Google Image Labeler en 2006 y lo mantuvo cinco años. Hoy los modelos pueden producir estas etiquetas a escala, aunque el resultado tiene ruido y carece de contexto de negocio: un modelo puede reconocer una zapatilla sin saber que es el SKU 4471-RD.

Ninguna palabra. Una imagen se puede representar como números y compararse con otras representaciones numéricas. El QBIC de IBM lo hizo en 1995 permitiendo bosquejar una distribución de colores. TinEye en 2008 y la búsqueda por imagen de Google en 2011 popularizaron la forma inversa: aportar una imagen y encontrar copias de ella. CLIP puso después texto e imágenes en el mismo espacio numérico, de modo que una consulta como a dog on a skateboard podía encontrar una imagen que nadie había etiquetado con esas palabras. Es la base de la mayoría de las demos recientes de «búsqueda con IA».

Nada de esta lista reemplazó a lo anterior. Google Imágenes sigue usando el texto circundante y las agencias de imágenes siguen pagando a personas para etiquetar, porque cada representación responde preguntas que las otras no pueden. Nuestro primer error fue tratar una de ellas como la respuesta principal en lugar de combinarlas.

Lo que la investigación perseguía entretanto

La investigación que corría en paralelo a esos productos dedicó unos treinta años a una pregunta: cómo reducir la distancia entre las características visuales y el significado que expresa una consulta. Los modelos recientes avanzaron mucho, aunque el resultado es más acotado de lo que sugieren muchas demos.

Treinta años de búsqueda de imágenes: productos, investigación en visión artificial e infraestructura de recuperación 1992200020102020 PRODUCTOS INVESTIGACIÓN EN VISIÓN POR COMPUTADOR INFRAESTRUCTURA DE RECUPERACIÓN AltaVista Photo Finder1998 Google Imágenes2001 etiquetas de Flickr2004 Image Labeler2006 TinEye2008 Google, búsqueda por imagen2011 se acuña «CBIR»1992 IBM QBIC1995 la brecha semántica2000 Video Google2003 ImageNet2009 AlexNet2012 DeViSE2013 CLIP2021 BM251994 reciprocal rank fusion2009 multi-index hashing2012 HNSW2016
Los productos salieron al principio con texto mientras la investigación en visión trabajaba en la brecha semántica. Los métodos de recuperación necesarios para operar ambos a escala se desarrollaron en paralelo.

La expresión «recuperación de imágenes basada en el contenido» (content-based image retrieval, CBIR) se acuñó en 1992, por Toshikazu Kato en el Laboratorio Electrotécnico de Japón, para la idea de que se podían buscar imágenes por lo que había en ellas y no por lo que alguien había escrito sobre ellas. QBIC de IBM fue el primer sistema serio que lo intentó. Podía comparar histogramas de color, texturas y formas, y se consultaba dibujando un bosquejo. Photo Finder de AltaVista, en 1998, construido con una empresa llamada Virage, llegó a lanzar al público un botón de «visualmente similar», y el público, de forma abrumadora, escribió palabras en su lugar.

La razón recibió nombre en 2000, en un artículo de revisión de Smeulders y colaboradores que desde entonces cita todo investigador del campo: la brecha semántica. La distancia entre lo que un sistema informático puede extraer de los píxeles (esta región es verdosa, este borde es vertical) y lo que una persona quiere decir con una consulta (un vestido, una celebridad, una ceremonia de premios). Los histogramas de color viven a un lado de esa brecha. Todas las consultas que alguien escribe de verdad viven al otro. Durante los veinte años siguientes, el programa de investigación fue, en esencia, «cerrar la brecha».

Se cerró por etapas, y cada etapa acabó en un producto. Las características locales (SIFT, 1999) y el truco de «Video Google» de 2003, que trataba los parches visuales como palabras y los indexaba como texto, son los antecesores directos de TinEye y de la búsqueda inversa de imágenes de Google: coincidencia de la misma imagen a escala web, un problema distinto y más fácil que el del significado. ImageNet, en 2009, puso a disposición un millón de imágenes etiquetadas, y AlexNet, en 2012, mostró que una red neuronal entrenada con ellas producía características que superaban a todos los descriptores diseñados a mano. Luego, en 2013, un artículo de Google llamado DeViSE hizo algo que hoy parece obvio y entonces parecía extraño: entrenó las características de la imagen para que cayeran cerca de los vectores de palabras de sus etiquetas, de modo que la imagen de una cosa y el nombre de esa cosa quedaban juntos en un mismo espacio, y un modelo podía reconocer categorías para las que nunca había sido entrenado. CLIP, en 2021, fue esa idea llevada a 400 millones de pares imagen-texto extraídos de la web. La brecha que había sido el problema central del campo desde 1992 quedó, para las consultas descriptivas, en su mayor parte cerrada.

El matiz importante es descriptivas. CLIP puede encontrar a dog on a skateboard, pero no puede encontrar de forma fiable SS26-HERO-03, entender que la búsqueda actual está limitada a una colección, ni informar de que un límite de candidatos excluyó 953 resultados. Esos son problemas de producto y de recuperación, que se resuelven con otro conjunto de herramientas: BM25 para el ranking por palabras clave, reciprocal rank fusion para combinar listas de resultados y HNSW para la búsqueda rápida de vecinos más cercanos entre vectores. La recuperación semántica es útil, pero sigue siendo un componente del motor de búsqueda.

Lo que la gente espera de verdad

Antes de la arquitectura, quiero detenerme un poco en los usuarios, porque de sus expectativas salen la mayoría de las restricciones de diseño, y no son las que elegiría un ingeniero de búsqueda.

La mayoría de las personas aprendió la interacción con Google Imágenes, donde los resultados llegan rápido, la cuadrícula casi nunca termina y no existe una única respuesta correcta para sunset. Si una de las primeras imágenes sirve, la búsqueda ha cumplido.

La biblioteca de fotos de una empresa es otra cosa, y el modelo mental de Google resulta allí activamente perjudicial, de maneras que me costó años ver.

Lo que Google Imágenes enseñó a los usuarios, frente a lo que necesita una biblioteca de empresa LO QUE TE ENSEÑÓ GOOGLE IMÁGENES LO QUE NECESITA UNA BIBLIOTECA Estás explorandocualquier atardecer bonito sirve Buscas una cosa concretael atardecer de Lisboa, con el puente, del informe anual Las consultas son descripciones«vestido rojo», «playa de noche» Las consultas suelen ser identificadores4471-RD · SS26-HERO-03 · funda galaxy a52 El ámbito es toda la webno existe un «dentro» Se busca dentro de algoesta carpeta, esta sesión, esta campaña Nunca está vacíala cuadrícula siempre se llena y se desplaza sin fin «No» es una respuesta valiosanadie ha fotografiado Madrid aún, así que encárgalo Miras los tres primeros Actúas sobre los 1240
Todo usuario llega con la columna izquierda en la cabeza. El producto tiene que satisfacer la columna derecha sin que su uso resulte notablemente distinto.

En la biblioteca de una empresa, la respuesta suele ser más específica: el atardecer de la sesión de Lisboa, con el puente, usado en el informe anual del año pasado. Puede haber un resultado correcto o doce, así que una cuadrícula de 400 atardeceres plausibles no es especialmente útil.

Muchas consultas de una biblioteca no son descripciones en absoluto. Los registros contienen 4471-RD, SS26-HERO-03, números de factura y nombres de modelo, que son habituales en un DAM y poco adecuados para la búsqueda semántica, porque los vecinos más cercanos de un SKU suelen ser otros SKU.

La gente también busca dentro de una carpeta, una colección o una campaña. «Encuentra las fotos principales de esta sesión» es una petición común, y los límites de candidatos pueden hacer que este tipo de búsqueda quede incompleta sin que la página de resultados parezca rota.

«Sin resultados» también puede ser útil. Si nadie ha fotografiado la nueva tienda de Madrid, el usuario quizá necesite encargar el trabajo, mientras que llenar la cuadrícula con fotografías de Barcelona y Sevilla solo oculta esa información.

Por último, la gente actúa sobre conjuntos completos de resultados: «Selecciona los 1240 resultados y aplica esta fecha de caducidad de licencia». Eso solo es seguro cuando 1240 es realmente el conjunto completo.

Las personas tienden a juzgar una búsqueda por sus primeros resultados, así que las coincidencias que faltan son difíciles de notar. Una consulta puede perder dos tercios de sus recursos relevantes y aun así devolver una página plausible en noventa milisegundos. En una biblioteca que todos, nosotros incluidos, consideraban razonablemente buena, la medición encontró fallos totales en quince de sesenta consultas realistas, ninguno de los cuales se había reportado.

Para la biblioteca de una empresa, entonces, una buena búsqueda de imágenes necesita encontrar recursos específicos, manejar identificadores además de descripciones, funcionar dentro de un ámbito, devolver un resultado vacío honesto e informar de si los límites de candidatos pueden haber excluido coincidencias. El resto de este artículo explica cómo abordamos esos requisitos.

La indexación fija el límite

Al principio dedicamos demasiado tiempo al ranking porque es la parte visible de la búsqueda, pero muchos de nuestros problemas de exhaustividad empezaban en la indexación. Una consulta no puede recuperar un término que nunca se colocó en la representación buscable del recurso.

Por eso compilamos un documento de búsqueda almacenado para cada recurso e idioma, y lo reconstruimos cuando el recurso cambia. Incluye el título, el nombre de archivo, la descripción, el autor, el copyright, la ubicación, las palabras clave, las etiquetas y descripciones generadas, el OCR, los metadatos personalizados, los nombres de colecciones, los nombres confirmados de personas y los subtítulos de video. Los términos de vocabulario controlado incluyen además a sus ancestros, de modo que un recurso etiquetado como espresso machine se puede encontrar mediante small appliances o kitchen sin que el usuario conozca la taxonomía.

Cómo se compilan el documento de búsqueda y el embedding de un recurso FUENTES COMPILADO, POR RECURSO INDEXADO, DE DOS FORMAS título, nombre de archivo, descripción autor, copyright, ubicación palabras clave + etiquetas de IA, descripción texto de OCR, texto extraído valores de metadatos personalizados término de vocabulario + ancestros nombres de colecciones personas confirmadas (rostros) etiquetas de puntos de enfoque subtítulos / transcripción documento de búsqueda todo, ponderado peso = repetición literal ancestro 3 / padre 2 / hoja 1 una fila por idioma texto del embedding un subconjunto con presupuesto: título 300 / desc. 1500 meta 2000 / OCR 2000 8000 caracteres en total índice de palabras clave (BM25) ¿el documento contiene estas palabras? un índice por idioma, en PostgreSQL 20 stemmers, tolerancia a erratas con trigramas exacto. Encuentra 4471-RD. No encuentra «otoño» si el fotógrafo escribió «autumn» semántico (vectores) texto e imagen comparten un espacio de 768 d modelos nomic de texto y visión, autoalojados índice HNSW en pgvector, distancia coseno encuentra lo que nadie etiquetó. Siempre devuelve k vecinos, aunque nada coincida Toda fuente alimenta el documento de búsqueda; el texto del embedding toma una selección del mismo material con presupuesto de caracteres.
El mismo recurso se compila dos veces, en dos geometrías de recuperación distintas. Ambas viven en la misma fila de PostgreSQL, así que ambas ven la misma transacción.

Dos aspectos de este documento resultaron importar mucho más de lo que esperaba.

El primero es la ponderación. Un título debe contar más que una línea de OCR y, con un índice de palabras clave que no tiene noción de campos, representamos ese peso repitiendo el texto importante en el documento. Funciona, pero también cambia la longitud del documento. Como la puntuación por palabras clave normaliza por longitud, la repetición puede favorecer a los documentos más cortos en caso de empate. En una consulta por un nombre de lugar, once videos de producto superaron a las fotografías de producto: los documentos de los videos tenían entre 155 y 493 caracteres, mientras que los documentos más ricos de las imágenes tenían entre 746 y 1280.

El segundo es la tokenización, que decide dónde termina un término y empieza el siguiente. Encontramos un ejemplo pequeño pero útil en etiquetas de compatibilidad como Galaxy A52/A52S: PostgreSQL trataba el valor como un único token parecido a una ruta, así que una consulta con a52 no encontraba recursos que visiblemente llevaban esa etiqueta. Normalizar los separadores antes de indexar resolvió el caso. La lección general es sencillamente inspeccionar los términos que produce el analizador cuando el texto está presente pero la exhaustividad es inesperadamente baja, porque reconstruir los mismos tokens no cambiará el resultado.

Dos formas de buscar, una sola base de datos

Una vez que tienes el documento, hay dos formas útiles de buscar en él, y son buenas en cosas opuestas.

La primera es la búsqueda por palabras clave con BM25. El nombre no ayuda mucho (viene de «Best Match», y 25 es el número de versión que se quedó), pero la idea es simple: un documento puntúa más alto cuando un término de la consulta aparece más veces, cuando el término es raro en la biblioteca y cuando el documento es corto. La fórmula data de 1994 y sigue siendo eficaz para términos exactos como 4471-RD. Su debilidad es el vocabulario: cuando el fotógrafo escribió autumn y quien hace marketing busca fall, puede que no haya ningún término en común que ordenar.

La segunda es el enfoque estilo CLIP: convertir el documento y la imagen en puntos de un espacio de 768 dimensiones, poner la consulta en el mismo espacio y devolver los puntos cercanos. Esto puede encontrar team celebrating outdoors cuando nadie usó esas palabras, pero un índice vectorial siempre devuelve k vecinos, incluso cuando ninguno es una buena coincidencia. Por eso un umbral de distancia forma parte del diseño de la recuperación y no es un ajuste opcional del ranking.

Ejecutamos ambos dentro de PostgreSQL, en la misma instancia que los recursos: BM25 con pg_textsearch y los vectores con pgvector y un índice HNSW. Así se evita un servicio de búsqueda aparte y su pipeline de sincronización.

El compromiso es directo. Un recurso nuevo puede volverse buscable en la misma transacción que lo inserta, mientras que los permisos, los embargos y los derechos de uso siguen siendo cláusulas WHERE normales en lugar de un segundo modelo de autorización. Las instalaciones autoalojadas también tienen un servicio con estado menos que operar. A cambio, la forma de la consulta importa mucho: en un caso, referenciar dos veces la misma subconsulta convirtió una consulta de 6 ms en una de 7,3 segundos porque el planificador perdió el límite de filas necesario para un escaneo de índice top-k. Gran parte del trabajo consiste, por tanto, en revisar planes y mantener visibles para PostgreSQL los límites previstos.

Los embeddings provienen de modelos de texto y visión de nomic entrenados para compartir un espacio, y se ejecutan en un sidecar autoalojado para que las imágenes de los clientes no salgan de la instalación. Dos detalles operativos importaron. Primero, los modelos usan prefijos de tarea: los documentos se incorporan como search_document y las consultas como search_query, por lo que esas entradas necesitan cobertura de pruebas, ya que un prefijo incorrecto reduce la calidad sin producir ningún error. Segundo, guardamos en caché brevemente los intentos fallidos de embedding de consultas, para que la búsqueda recurra a la recuperación léxica en lugar de contactar con un sidecar no disponible en cada pulsación de tecla.

¿Cómo de cerca es suficientemente cerca?

El canal vectorial necesita un corte a partir del cual un vecino deja de considerarse coincidencia. Esperábamos un único umbral, pero el valor útil variaba con la longitud de la consulta y no era monótono.

Consulta Distancia coseno máx.
1 palabra 0,35
2 palabras 0,42
de 3 a 5 palabras 0,45
de 6 a 10 palabras 0,48
más de 10 palabras 0,40

Ambos extremos son estrictos, por razones opuestas. Una sola palabra como chair tiene un vecindario semántico gigantesco: con un umbral laxo coincide con todas las fotografías de interiores de la biblioteca, llena la página y parece fiable mientras es inútil. Una consulta muy larga, que en la práctica es alguien que pega un título de producto entero, produce un embedding vago y promediado que queda débilmente cerca de todo; si aflojas el umbral ahí, obtienes todo el corpus, en orden de confianza. La franja intermedia, donde la consulta es lo bastante específica como para significar algo y lo bastante corta como para seguir significándolo, es donde la búsqueda semántica se gana el sitio.

Las consultas de una sola palabra reciben una regla adicional: un resultado también debe tener una coincidencia léxica. Sin ella, los términos de nicho tienden a llenar la página con imágenes semánticamente cercanas, haciendo que un resultado vacío parezca uno grande. Con la regla, madrid puede no devolver resultados cuando la biblioteca no contiene texto coincidente.

Combinar dos rankings que no hablan el mismo idioma

Una puntuación BM25 y una distancia coseno no son directamente comparables. Normalizarlas a una escala común hace que la combinación dependa del corpus, del idioma y de los umbrales usados para producir ese conjunto de resultados.

Combinamos en cambio las posiciones. Cada canal produce una lista ordenada; un documento en la posición r aporta 1 / (60 + r), mientras que un documento ausente de una lista no aporta nada de ese canal. Reciprocal Rank Fusion es simple, no requiere calibrar las puntuaciones y permite que un documento bien clasificado en ambas listas supere a uno respaldado por un solo método de recuperación.

Reciprocal rank fusion de una lista BM25 y una lista vectorial POSICIONES BM25 se conservan los 1000 primeros (escaneo bruto 3000) 1 recurso 4471 2 recurso 9310 8 recurso 1180 40 recurso 7702 … sin coincidencia vectorial POSICIONES VECTORIALES los 200 primeros, con filtro de distancia 1 recurso 6025 3 recurso 7702 11 recurso 4471 62 recurso 1180 … sin coincidencia léxica FULL OUTER JOIN una fila puede estar en una lista o en ambas 1/(60+r₁) + 1/(60+r₂) posición ausente ⇒ 0,0, nunca una penalización FUSIONADO 4471 0,0305 7702 0,0259 1180 0,0229 6025 0,0164 9310 0,0161 7702 quedó 40.º en el léxico, 3.º en el semántico. Gana. después, por orden: impulso por frase (el título contiene la consulta literal = 2, el documento la contiene = 1) ▸ rrf_score ▸ id del recurso umbral adaptativo según el número de palabras ▸ las filas de una sola palabra deben tener posición léxica ▸ se admiten las bandas garantizadas
RRF no necesita calibrar puntuaciones: un documento ausente de una lista aporta simplemente cero desde ese canal. El full outer join es lo que permite que una coincidencia puramente semántica pueda competir.

Los límites de candidatos pueden ocultar coincidencias

Todo lo anterior trata de relevancia, pero los límites de candidatos determinan si los recursos relevantes son siquiera alcanzables.

Todo sistema de recuperación necesita un límite. En lugar de puntuar 200.000 documentos en cada pulsación de tecla, puede tomar los 1000 mejores candidatos léxicos y los 200 mejores candidatos vectoriales, y ordenar ese conjunto menor. Si la respuesta no informa del límite, la página y el paginador pueden parecer normales mientras faltan los recursos que quedan más allá del corte.

Por ejemplo, una colección contiene 400 recursos y 30 llevan el término de la consulta, pero la búsqueda devuelve cuatro. Los 1000 mejores candidatos se seleccionaron en toda la biblioteca antes de aplicar el filtro de la colección, así que los otros 26 quedaron fuera del conjunto de candidatos. Los recursos devueltos son relevantes; el problema es que la mayoría de las coincidencias elegibles nunca estuvieron disponibles para ordenarse.

El caso más general es el cap crowding (acaparamiento del tope): si 1953 documentos contienen todos los términos y solo se conservan 1000 candidatos, filas igual de relevantes pueden quedar excluidas por un criterio de desempate.

Nuestra solución es una segunda recuperación garantizada para las filas que deben seguir siendo alcanzables, como los miembros de la colección en la que se busca y los recursos cuyo título contiene literalmente el término. Estas filas entran después de las posiciones de escaneo ordenadas normalmente, y cada límite posterior las admite de forma explícita. La primera página mantiene el mismo orden, mientras que las filas adicionales siguen disponibles en las páginas posteriores y en el total.

Las bandas garantizadas sobreviven al tope de candidatos CANDIDATOS ORDENADOS pos. 1 … 998 pos. 999 pos. 1000 tope pos. 1001, descartada pos. 1002, descartada … 953 más, en silencio BANDA GARANTIZADA Filas que deben poder encontrarse sea cual sea su posición: • miembros de la colección en la que buscaste • (opcionalmente) todo recurso cuyo título lleve el término Entran en las posiciones rawLimit + n, más allá de toda posición real del escaneo, y MIN(best_pos) conserva la posición real de todo lo que ya estaba dentro del corte. Por qué el orden no se altera Las filas de la banda se ordenan después de toda fila ordenada, así que la primera página que ve el usuario es idéntica byte a byte al ranking sin bandas. Cada filtro posterior, el umbral de RRF y el LIMIT final, lleva un «…O esta fila está en una banda» explícito. La marca sube por la unión con BOOL_OR en lugar de un segundo join, para que el escaneo conserve su límite de filas.
Una banda cambia lo que es alcanzable, no lo que se ordena primero. Esa separación es lo que permite lanzar con seguridad una garantía de exhaustividad.

La recuperación garantizada cambia con el tamaño del ámbito. Para una colección de cuarenta recursos, puntuamos los cuarenta directamente, lo que es completo por construcción y cuesta aproximadamente medio milisegundo por miembro. Hasta un par de miles de miembros, añadimos una comparación vectorial exacta sobre el ámbito en lugar de usar el índice aproximado. Hasta cincuenta mil, escaneamos la lista ordenada con más profundidad, mientras que los ámbitos mayores se solapan lo suficiente con el conjunto normal de candidatos como para que el trabajo extra sea menos útil.

Estrategia de banda de ámbito según su tamaño 1 32 2000 50.000 ∞ TAMAÑO DEL ÁMBITO: MIEMBROS DE LA COLECCIÓN EN LA QUE BUSCAS puntuar a cada miembro sin escaneo: se ordena el documento de cada miembro completo por construcción ≈ 0,6 ms por miembro + escaneo vectorial exacto coseno por fuerza bruta sobre los miembros, sin pérdida de recall de ANN en el ámbito < 40 ms con 2000 escaneo ordenado profundo leer la lista ordenada hasta cubrir el ámbito, hasta 45.000 filas ≈ 2,7 µs/fila → ≈ 120 ms sin banda un ámbito tan grande ya se solapa mucho con el conjunto de candidatos de todo el tenant el trabajo extra no compensaría
Cuatro regímenes, elegidos por tamaño. El caso de ámbito pequeño no es una optimización: puntuar a cada miembro es la única variante demostrablemente completa con cualquier tamaño de corpus.

Informar de si los resultados están completos

Los límites de candidatos llevan a una pregunta práctica: ¿puede el sistema decirle al usuario si ha mostrado todas las coincidencias?

Esto importa mucho más allá de la comodidad del usuario. «Selecciona los 1240 y aplica esta política de derechos» solo es seguro si 1240 es demostrablemente el conjunto completo. Una búsqueda que se trunca en silencio en 1000 convierte una operación en lote en un incidente de integridad de datos que nadie nota durante meses.

Por eso cada búsqueda de freedam devuelve un veredicto junto con sus resultados: completo, truncado o desconocido. Se calcula con columnas de conteo adicionales en la misma consulta, que miden cuántas filas produjo realmente cada fuente de candidatos frente al tope con el que operaba esa fuente. Si una fuente alcanzó su límite, el resultado está truncado, la interfaz lo dice y las operaciones en lote sobre él te avisan. Puntuar a cada miembro de una colección pequeña es completo por construcción. Un escaneo profundo es completo solo si terminó antes de su límite de filas. Una fuente nueva de candidatos es desconocido por defecto hasta que alguien demuestre lo contrario. Y un resultado obtenido mediante un mecanismo de respaldo, una corrección de errata o una expansión por prefijo nunca hereda el veredicto que obtuvo la consulta original.

Los tres veredictos de exhaustividad y lo que permite cada uno COMPLETO toda fuente de candidatos terminó por debajo de su tope, o se puntuó de forma exhaustiva, miembro a miembro 1240 resultados «seleccionar todo» significa los 1240 TRUNCADO una fuente alcanzó su límite de filas; la sonda contó más filas de las que dejó pasar el tope 1000 de más de 1000 la interfaz lo dice; las acciones en lote avisan DESCONOCIDO el valor por defecto de toda fuente nueva hasta que alguien demuestre su límite, y de toda ruta de respaldo corrección de erratas, expansión por prefijo nunca hereda el veredicto del original Se calcula dentro de la misma consulta que produjo los resultados columnas COUNT adicionales por fuente, comparadas con el tope con el que se ejecutó esa fuente. Una sonda escrita aparte acabaría desajustándose respecto de la consulta real.
Una búsqueda que distingue estos tres puede autorizar con seguridad una operación en lote. Una que siempre informa de un total, no.

Esto también cambió cómo revisamos la monitorización y las pruebas. Teníamos un monitor que se quedaba en silencio cuando su tarea moría, una prueba de desempate que seguía en verde después de que el desempate desapareciera de la consulta, y una suite de calidad cuyas advertencias no podían cambiar el código de salida. Para cada comprobación, ahora nos preguntamos qué resultado daría si el comportamiento se rompiera. Si un fallo produce la misma salida que un éxito, la comprobación necesita otra aserción observable.

Las otras formas de preguntar

El texto es una entrada. Otras tres importan específicamente para las imágenes, y seré breve porque cada una tiene su propio artículo.

Puedes buscar con una imagen para saber si ya estaba licenciada o para encontrar el resto de una sesión. Esta ruta usa hashes perceptuales y una búsqueda multi-índice para generar candidatos, y después un embedding visual para verificarlos. El artículo sobre casi duplicados trata los estilos de catálogo que debilitan el algoritmo estándar.

Puedes buscar a una persona. Los rostros tienen su propio detector y su propio espacio de embeddings en un sidecar que no envía imágenes fuera de la instalación. Un rostro no tiene nombre hasta que una persona lo confirma, así que el sistema agrupa candidatos y escribe en el documento de búsqueda solo los nombres confirmados. Los detalles están en el artículo sobre búsqueda de personas.

También puedes buscar con una frase. Nuestro asistente no ordena recursos; compila la frase en el mismo árbol de filtros que produce la interfaz de búsqueda avanzada, con una intención explícita como replace, refine, add o remove. Ese árbol se ejecuta por la ruta de recuperación normal con los mismos permisos y el mismo informe de exhaustividad, de modo que el usuario puede inspeccionar y corregir la interpretación. El artículo sobre búsqueda conversacional trata esa frontera y sus compromisos.

Cómo sabemos que algo de esto funciona

Evaluamos estas decisiones con sesenta consultas realistas y una verdad de referencia acordada, ejecutadas por la ruta de búsqueda de producción sobre una réplica de la biblioteca de un cliente de unos 23.000 recursos. El instrumento informa de aprobado/suspenso estricto, exhaustividad (recall) y posición recíproca, y tiene acceso de solo lectura, de modo que no puede cambiar ajustes ni reconstruir un índice. El artículo sobre medición explica el método y sus limitaciones.

La primera ejecución seria encontró quince fallos totales en una búsqueda que todos habían descrito como razonablemente buena. Más tarde atribuimos cinco regresiones de exhaustividad a un cambio de tokenización, pero la medición mostró que cuatro consultas tenían exactamente la misma exhaustividad y posición hasta el decimal quince. La causa real fue la longitud del documento, como en el caso de videos frente a fotos de arriba. El instrumento fue útil porque separó una explicación plausible del cambio que afectó al resultado.

De vuelta al vestido

El vestido original de Versace de 2000, de gasa de seda verde con estampado de jungla, expuesto sobre un maniquí en una vitrina de The Museum at FIT, Nueva York
El vestido en persona, veinticinco años después: el traje Versace de 2000 expuesto en The Museum at FIT de Nueva York, en noviembre de 2025. Foto de Rhododendrites, Wikimedia Commons, CC BY-SA 4.0.

Google encontró el vestido en 2001 leyendo las palabras que rodeaban la imagen. Hoy nosotros encontramos la foto de un producto buscando en el texto ensamblado a su alrededor y en una representación vectorial producida a partir de la imagen y sus metadatos. Los modelos semánticos ayudan con las consultas descriptivas, mientras que el resto del sistema sigue teniendo que manejar identificadores, reglas de acceso, ámbitos, límites de candidatos y totales honestos.

Si estás empezando, dedica tiempo a la representación indexada, porque una consulta no puede recuperar términos que el tokenizador nunca emitió. Ejecuta juntas la recuperación léxica y la semántica, y fusiona sus posiciones en lugar de sus puntuaciones. Ajusta los umbrales vectoriales según la forma de la consulta, considera exigir respaldo léxico para las palabras sueltas y trata cada tope de candidatos como un posible problema de exhaustividad. Y, sobre todo, expón cuándo el sistema no puede demostrar que devolvió todas las coincidencias.

Si prefieres verlo antes que leerlo, hay una demo con una biblioteca de ejemplo. Lo interesante es buscar algo que nadie habría etiquetado y después buscar algo dentro de una carpeta y contar.

Para desarrolladores

Sigue leyendo