Quien busca, encuentra
Albert Cervera i Areny
Hola,
me pasan las semanas que no me doy cuenta, pero no me olvido de que te prometí informarte mensualmente de los progresos que hacemos en el nuevo asistente virtual.
Hoy quiero explicarte que hemos avanzado mucho en un componente esencial para el éxito de este tipo de tecnologías: un motor de búsqueda de texto.
¿Qué es y por qué queremos un motor de búsqueda?
Un modelo de lenguaje es la tecnología de IA que está detrás del asistente virtual, y ha sido entrenado con muchísima información.
Sin embargo, no lo sabe todo, y aún menos lo que hay que saber para responder preguntas sobre Tryton o cómo interactuar con él.
Eso sí, suele ser capaz de pedir información cuando la necesita.
Para que pueda hacerlo, le facilitamos unas herramientas (tools) y le explicamos cuándo las puede utilizar.
Una de las que hemos creado se llama help y la puede utilizar para buscar entre los tutoriales de Tryton que hemos creado... Como quien busca en Google, pero entre nuestra propia documentación.
Este tipo de búsquedas de texto son esenciales para que el asistente sepa qué hacer o qué responder cuando los usuarios le hacen una petición.
Si un usuario dice: "¡Hola! ¿Cómo puedo crear una factura?" él hará uso de esta búsqueda, probablemente buscando "crear una factura", nuestra herramienta le devolverá los tutoriales que hablan de estos temas y él podrá responder al usuario a partir de lo que "lee" en estos tutoriales.
Es fácil entender que es esencial que esta herramienta de búsqueda devuelva los tutoriales adecuados y si no lo hace, por muy inteligente que sea la IA, nunca podrá dar la respuesta adecuada.
ERP y texto
No sé si te has fijado en alguna ocasión que en un ERP existe relativamente poco texto en comparación con la información que gestiona una persona en la vida en general y también el entorno de trabajo.
No suele haber textos largos: nombres de empresas, personas, nombres de productos...
Alguna descripción… pero poco más.
Pero desde NaN-tic estamos convencidos de que esto va a cambiar y la búsqueda sobre los tutoriales es sólo el primero de los usos que daremos al motor de búsqueda de texto que hemos creado.
Motores de búsqueda y bases de datos vectoriales
El actual auge de los modelos de lenguaje ha hecho aparecer un nuevo concepto que son las bases de datos vectoriales.
¡Tengo que alargarme un poco pero agárrate que esto es súper interesante!
Un motor de búsqueda hace esencialmente tres cosas:
- busca el texto que ha dado el usuario sobre un conjunto de documentos
- devuelve los documentos que contienen lo que busca el usuario en forma de ranking (el orden es esencial)
- muestra el fragmento de texto que contiene las palabras clave y normalmente las resalta en negrita
Para hacer esto bien, se utilizan muchísimos trucos. Te comento sólo 3:
- stemming, que es el proceso de obtener las raíces de las palabras y trabajar sólo sobre ellas. Así si el usuario busca "contabilización" el sistema encontrará también el documento donde hay escrito "contabilizar".
- weighting, que es la forma en que damos más peso al título del documento, que a un párrafo: si un documento lleva la palabra "contabilizar" en el título aparecerá antes en el ranking que una que la tiene en medio de un párrafo.
- Tener en cuenta la frecuencia de aparición de la palabra. Las palabras que menos aparecen en el conjunto de los documentos son las más relevantes a la hora de establecer el orden. En este sentido, el algoritmo BM25 creado en los años 70 es todavía hoy el rey de la búsqueda.
Pero los motores de búsqueda tienen un grave problema: no entienden nada.
Supongamos que sólo tenemos tres documentos: uno que habla de fútbol, uno de tenis y uno de baloncesto. Ninguno de ellos menciona a ningún jugador. Entonces, si vamos al motor de búsqueda y buscamos "Leo Messi", no nos devolverá ningún resultado.
Sin embargo, si a ti te pido que me digas cuál de los tres documentos me darías tienes claro que me darías el que habla de fútbol.
Aquí es donde entran las bases de datos vectoriales, los embeddings y donde la magia de la Inteligencia Artificial hace explotar la cabeza.
Resulta que existen muchos modelos de embeddings, que son básicamente una caja negra donde le pasas un texto y te devuelve una lista de números: unas coordenadas (o vector).
Puedes imaginarlo como un punto en un espacio de dos dimensiones X e Y. Lo único que debes tener en cuenta es que los embeddings tienen muchísimas dimensiones: normalmente varios cientos o unos pocos miles.
¿Y qué demonios representan estas coordenadas?
Pues resulta que tienen una propiedad: si calculas la distancia entre las coordenadas de "Leo Messi" y "fútbol" es menor que la distancia entre "Leo Messi" y "tenis". Si calculas la distancia entre "Leo Messi" y "NaN-tic" es mayor que entre "Leo Messi" y "Barcelona".
Es una maravilla: resulta que esta caja negra, creada a partir de un sistema de aprendizaje automático, ha sido capaz de entender el mundo. Al menos en parte.
Se han desarrollado aplicaciones muy interesantes con estos embeddings. Por ejemplo, se han realizado sistemas de traducción razonablemente buenos entre idiomas sin utilizar ninguna base de datos de traducción entre ellos. Simplemente creando el modelo de embeddings de un idioma y del otro por separado (a partir de millones de documentos de cada uno): ¡las coordenadas que ocupan las palabras que tienen el mismo significado en los dos idiomas es muy parecido hasta el punto que se pueden utilizar para hacer traducciones de documentos!
Pero volviendo a lo que nos ocupa, la gracia de estos embeddings es que nos permiten calcular distancias entre dos textos cualesquiera y podemos saber si tienen un significado cercano o no y sobre todo, sobre todo, es muy rápido buscarlo en una base de datos grande porque sólo tenemos que calcular distancias entre números.
Al mismo tiempo, estas bases de vectores no las podemos utilizar para reemplazar a los buscadores tradicionales. Tienen sus retos. Por ejemplo, ¿qué debemos hacer, calcular las coordenadas (el embedding) por todo el documento? ¿Por cada párrafo? ¿Por cada frase? ¿Por cada palabra? ¿Cómo ponderamos la combinación de todo esto?
Así pues, un sistema de búsqueda moderno debe combinar los dos sistemas: un motor de búsqueda tradicional y una base de datos de vectores.
¿Cómo NO lo hacemos entonces?
Dotarnos de un buen buscador para Tryton es fácil y complicado a la vez.
Es fácil porque ya existen bastantes soluciones en el mercado pero es complicado porque hay que elegir la más adecuada.
Para tomar una buena decisión no es suficiente saber qué hacen las diferentes alternativas que hay disponibles sino que hay que entender:
- ¿Cómo funcionan? esencialmente lo que te he contado en el apartado anterior.
- ¿Qué trayectoria tiene el producto a nivel de fiabilidad, volumen de gente utilizándolo realmente?
- ¿Qué implicará desplegarlo y ponerlo a disposición de todos nuestros clientes?
- ¿Qué consecuencias puede tener el mantenimiento a largo plazo?
- ¿Cuál es el valor real que aporta a nuestro caso concreto cada una de ellas?
- ¿Hasta qué punto es preferible construir nuestra propia solución?
Así nos hemos planteado distintas soluciones que hemos descartado:
-
Elasticsearch (y soluciones similares como Solr): aunque sería la opción más fácil de coger por muchos de los aspectos anteriores (tiene soporte para búsqueda de texto y vectorial, tiene una larga trayectoria y es ampliamente utilizada), también supone complicaciones a nivel de infraestructura (habría que hacer una instalación para cada base de datos Tryton, complicando además, los entornos de pruebas que actualmente montamos con muchísima facilidad), también generaría nuevos puntos potenciales de error (debido a que puede no estar en funcionamiento cuando lo necesitamos), y a nivel de sincronización de datos (la información quedaría fuera de la base de datos Tryton).
-
Whoosh: ésta es una solución 100% python que utilizamos con éxito en páginas web de clientes. Funciona correctamente para la búsqueda de texto no incorpora la parte vectorial. Podríamos integrarla nosotros pero los principales motivos para descartarla han sido que lleva casi 8 años sin recibir mantenimiento (aunque funciona perfectamente) y que los datos también quedan fuera de Tryton. Aunque tiene algunas ventajas respecto a Elasticsearch en este sentido, no es un escenario ideal.
-
Bases de datos vectoriales: las hemos descartado esencialmente por motivos parecidos a Elasticsearch y por problemas adicionales como la juventud de las herramientas y que suelen estar pensadas para volúmenes enormes de datos. A menudo son creadas por startups que buscan poder atraer a grandes empresas, que es donde encuentran el negocio. No se alinean nuestras necesidades con su modelo de negocio.
-
ParadeDB: ha sido una solución que hemos intentado utilizar pero la hemos acabado descartando. Tiene la ventaja de estar integrada en PostgreSQL (el motor de base de datos que ya utilizamos con Tryton) y también tiene la ventaja de implementar BM25, a priori el mejor algoritmo de búsqueda de texto. Pero tiene dos grandes desventajas: es muy nuevo (inmaduro) y es lento. Y es que el algoritmo BM25 tiene algunas particularidades técnicas que quizás no lo hacen ideal para nuestro escenario.
¿Cómo lo hemos hecho entonces?
Hemos optado por crear un pequeño módulo Tryton que combina dos tecnologías bastante maduras y que utilizan el mismo PostgreSQL para almacenar la información.
Para la búsqueda de texto utilizamos las posibilidades de Full Text Search que ya incorpora Postgres. Aunque no es el estado del arte en búsqueda de texto, creemos que es suficiente y las ventajas superan las desventajas.
Para la búsqueda vectorial utilizamos la extensión de Postgres pg_vector que nos ha funcionado perfectamente bien, pronto hará 4 años que nació, recibiendo actualizaciones de mejoras y correcciones con frecuencia, y parece que ha tenido buena acogida entre los usuarios.
El módulo que hemos creado son menos de 400 líneas de código y nos permite tener algo que entendemos en profundidad y prácticamente no debemos hacer nada a nivel de infraestructura para entornos de producción ni de pruebas. También es 100% compatible con las instalaciones que tenemos con copia de seguridad y replicación en tiempo real.
Además, eliminamos muchos problemas de inconsistencia de información que podríamos tener con otras soluciones y sobre todo es extremadamente sencillo: indexar una nueva tabla del ERP pueden ser menos de 10 líneas de código.
A partir de ahora
Desde esta semana los asistentes de todos los clientes que ya trabajan con la versión 7.2 (la mayoría) estarán utilizando este sistema para encontrar ayuda y otras funciones y ya se puede notar en la mejora en la interacción con el sistema.
También estamos empezando a utilizar el buscador para nuevas funcionalidades, pero esto ya será material para otro correo.
¡Salud y buena semana!