Haystack: Construyendo Aplicaciones de IA con Componentes Modulares

Jaime Hernández
3 min readAug 28, 2024

--

Haystack es un marco de trabajo de código abierto para construir aplicaciones de inteligencia artificial (IA) en Python. Este marco permite combinar diferentes componentes para crear pipelines que ejecutan tareas específicas en aplicaciones de IA. En este blog, exploraremos cómo utilizar Haystack para crear una aplicación básica de búsqueda de documentos, partiendo desde la inicialización de los componentes hasta la ejecución de la pipeline.

Componentes: La Base de Todo

Los componentes son las unidades fundamentales en Haystack. Cada componente realiza una tarea específica, como procesar texto, generar incrustaciones (embeddings) o escribir documentos en un almacén. A continuación, se muestra un ejemplo de cómo inicializar un componente de incrustación de documentos utilizando el modelo text-embedding-3-small de OpenAI.

pythonfrom haystack.components.embedders import OpenAIDocumentEmbedder
embedder = OpenAIDocumentEmbedder(model="text-embedding-3-small")

Este componente tomará documentos como entrada y generará sus respectivas representaciones embebidas.

Pipelines: Conectando Componentes

Una pipeline en Haystack es simplemente una cadena de componentes conectados entre sí. Estas pipelines permiten realizar tareas complejas al pasar los datos de un componente a otro de manera secuencial.

Para construir una pipeline de indexación de documentos, primero necesitamos inicializar un almacén de documentos. En este caso, utilizaremos InMemoryDocumentStore, un almacén simple que no requiere configuración adicional.

from haystack.document_stores.in_memory import InMemoryDocumentStore
document_store = InMemoryDocumentStore()

Creando una Pipeline de Indexación

Nuestra pipeline de indexación tomará archivos de texto, los convertirá en documentos, los dividirá en fragmentos manejables, generará incrustaciones para cada fragmento y finalmente los almacenará en nuestro almacén de documentos.

from haystack import Pipeline
from haystack.components.converters.txt import TextFileToDocument
from haystack.components.preprocessors.document_splitter import DocumentSplitter
from haystack.components.writers import DocumentWriter
converter = TextFileToDocument()
splitter = DocumentSplitter()
embedder = OpenAIDocumentEmbedder()
writer = DocumentWriter(document_store=document_store)
indexing_pipeline = Pipeline()
indexing_pipeline.add_component("converter", converter)
indexing_pipeline.add_component("splitter", splitter)
indexing_pipeline.add_component("embedder", embedder)
indexing_pipeline.add_component("writer", writer)

Una vez que los componentes están añadidos, es necesario conectarlos para que los datos fluyan entre ellos:

indexing_pipeline.connect("converter", "splitter")
indexing_pipeline.connect("splitter", "embedder")
indexing_pipeline.connect("embedder", "writer")

Finalmente, ejecutamos la pipeline para indexar nuestros documentos:

indexing_pipeline.run({"converter": {"sources": ['data/davinci.txt']}})

Creando una Pipeline de Búsqueda de Documentos

Una vez que los documentos están indexados, podemos crear una pipeline para buscar información relevante en ellos. Al igual que la pipeline de indexación, necesitamos varios componentes, como un incrustador de consultas y un recuperador de documentos basado en incrustaciones.

rom haystack.components.embedders import OpenAITextEmbedder
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
query_embedder = OpenAITextEmbedder()
retriever = InMemoryEmbeddingRetriever(document_store=document_store)
document_search = Pipeline()
document_search.add_component("query_embedder", query_embedder)
document_search.add_component("retriever", retriever)
document_search.connect("query_embedder.embedding", "retriever.query_embedding")

Ejecución de la Búsqueda

Para buscar en los documentos, formulamos una pregunta y ejecutamos la pipeline de búsqueda.

question = "How old was Davinci when he died?"
results = document_search.run({"query_embedder": {"text": question}})

Los resultados devueltos incluirán los documentos que mejor respondan a la pregunta.

for i, document in enumerate(results["retriever"]["documents"]):
print(f"DOCUMENT {i}")
print(document.content)

Exploración de Nuevas Preguntas y Ajustes

Puedes ajustar los parámetros de búsqueda, como el número de resultados (top_k) o probar con diferentes preguntas.

question = "Where was Davinci born?"
results = document_search.run({"query_embedder": {"text": question}, "retriever": {"top_k": 3}})

Esta flexibilidad permite personalizar la pipeline según las necesidades de la aplicación.

Conclusión

Haystack ofrece un enfoque modular para construir aplicaciones de IA al permitir la combinación de componentes en pipelines. Este enfoque hace que sea fácil experimentar y escalar las aplicaciones de IA, desde la indexación de documentos hasta la búsqueda avanzada.

Para los desarrolladores interesados en construir aplicaciones de búsqueda, generación de respuestas o análisis de documentos, Haystack proporciona las herramientas necesarias para combinar componentes y lograr resultados precisos y eficientes.

Si deseas explorar más sobre Haystack y sus capacidades, visita su documentación oficial. https://docs.haystack.deepset.ai/docs/intro

--

--