# Framework de IA Haystack

Haystack es el framework de orquestación de IA de código abierto de deepset para construir aplicaciones LLM de grado de producción. Con más de 18K estrellas en GitHub, ofrece una arquitectura flexible **basada en pipelines** que conecta almacenes de documentos, recuperadores, lectores, generadores y agentes — todo en Python limpio y componible. Ya sea que necesites RAG sobre documentos privados, búsqueda semántica o flujos de trabajo de agentes multi-paso, Haystack maneja la plomería para que puedas enfocarte en la lógica de la aplicación.

En Clore.ai, Haystack destaca cuando necesitas una GPU para inferencia de modelos local vía Hugging Face Transformers o sentence-transformers. Si dependes únicamente de APIs externas (OpenAI, Anthropic), puedes ejecutarlo en instancias solo con CPU — pero para la generación de embeddings y LLMs locales, una GPU reduce la latencia dramáticamente.

{% hint style="success" %}
Todos los ejemplos se ejecutan en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
Esta guía cubre **Haystack v2.x** (`paquete haystack-ai` ). La API v2 difiere significativamente de la v1 (`farm-haystack`). Si tienes pipelines existentes en v1, consulta la [guía de migración](https://docs.haystack.deepset.ai/docs/migration).
{% endhint %}

## Resumen

| Propiedad                 | Detalles                                                                          |
| ------------------------- | --------------------------------------------------------------------------------- |
| **Proyecto**              | [deepset-ai/haystack](https://github.com/deepset-ai/haystack)                     |
| **Licencia**              | Apache 2.0                                                                        |
| **Estrellas en GitHub**   | 18K+                                                                              |
| **Versión**               | v2.x (`paquete haystack-ai`)                                                      |
| **Caso de uso principal** | RAG, búsqueda semántica, QA de documentos, flujos de trabajo de agentes           |
| **Soporte GPU**           | Opcional — requerido para embeddings locales / LLMs locales                       |
| **Dificultad**            | Medio                                                                             |
| **Servir API**            | Hayhooks (basado en FastAPI, REST)                                                |
| **Integraciones clave**   | Ollama, OpenAI, Anthropic, HuggingFace, Elasticsearch, Pinecone, Weaviate, Qdrant |

### Qué puedes construir

* **Pipelines RAG** — ingerir documentos, generar embeddings, recuperar contexto, responder preguntas
* **Búsqueda semántica** — consultar documentos por significado, no por palabras clave
* **Procesamiento de documentos** — analizar PDFs, HTML, documentos Word; dividir, limpiar e indexar contenido
* **Flujos de trabajo de agentes** — razonamiento multi-paso con uso de herramientas (búsqueda web, calculadoras, APIs)
* **Servicios REST API** — exponer cualquier pipeline de Haystack como un endpoint vía Hayhooks

## Requisitos

### Requisitos de hardware

| Caso de uso                                    | GPU                | VRAM  | RAM   | Disco  | Precio de Clore.ai |
| ---------------------------------------------- | ------------------ | ----- | ----- | ------ | ------------------ |
| **Solo modo API** (OpenAI/Anthropic)           | Ninguno / Solo CPU | —     | 4 GB  | 20 GB  | \~$0.01–0.05/hr    |
| **Embeddings locales** (sentence-transformers) | RTX 3060           | 8 GB  | 16 GB | 30 GB  | \~$0.10–0.15/hr    |
| **Embeddings locales + LLM pequeño** (7B)      | RTX 3090           | 24 GB | 16 GB | 50 GB  | \~$0.20–0.25/hr    |
| **LLM local** (13B–34B)                        | RTX 4090           | 24 GB | 32 GB | 80 GB  | \~$0.35–0.50/hr    |
| **LLM local grande** (70B, cuantizado)         | A100 80GB          | 80 GB | 64 GB | 150 GB | \~$1.10–1.50/hr    |

{% hint style="info" %}
Para la mayoría de los casos de RAG, un **RTX 3090** a \~ $0.20/hr es el punto óptimo — 24 GB de VRAM manejan embeddings de sentence-transformer + un LLM local de 7B–13B simultáneamente.
{% endhint %}

### Requisitos de software

* Docker (preinstalado en los servidores de Clore.ai)
* Controladores NVIDIA + CUDA (preinstalados en servidores GPU de Clore.ai)
* Python 3.10+ (dentro del contenedor)
* CUDA 11.8 o 12.x

## Inicio rápido

### 1. Alquila un servidor Clore.ai

En el [Clore.ai Marketplace](https://clore.ai/marketplace), filtra por:

* **VRAM**: ≥ 8 GB para cargas de embeddings, ≥ 24 GB para LLMs locales
* **Docker**: Habilitado (predeterminado en la mayoría de listados)
* **Imagen**: `nvidia/cuda:12.1-devel-ubuntu22.04` o `pytorch/pytorch:2.2.0-cuda12.1-cudnn8-runtime`

Toma nota de la IP pública del servidor y el puerto SSH desde **Mis Pedidos**.

### 2. Conectar y verificar GPU

```bash
ssh root@<clore-server-ip> -p <port>

# Verificar que la GPU esté disponible
nvidia-smi

# La salida esperada muestra tu GPU, versión del driver, versión de CUDA
```

### 3. Construir la imagen Docker de Haystack

Haystack v2 recomienda la instalación con pip. Crea un Dockerfile personalizado:

```bash
mkdir -p /workspace/haystack-app && cd /workspace/haystack-app

cat > Dockerfile << 'EOF'
FROM nvidia/cuda:12.1-devel-ubuntu22.04

# Evitar indicaciones interactivas
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1

# Instalar Python y dependencias del sistema
RUN apt-get update && apt-get install -y \
    python3.11 \
    python3-pip \
    python3.11-dev \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Establecer python3.11 como predeterminado
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
RUN update-alternatives --install /usr/bin/python python python3.11 1

# Instalar Haystack v2 y dependencias principales
RUN pip install --no-cache-dir \
    haystack-ai \
    hayhooks \
    sentence-transformers \
    transformers \
    torch \
    accelerate \
    fastapi \
    uvicorn

# Instalar integraciones opcionales
RUN pip install --no-cache-dir \
    ollama-haystack \
    haystack-experimental

WORKDIR /app

# Puerto predeterminado para Hayhooks
EXPOSE 1416

CMD ["hayhooks", "run", "--host", "0.0.0.0", "--port", "1416"]
EOF

# Construir la imagen
docker build -t haystack-clore:latest .
```

### 4. Ejecutar Haystack con Hayhooks

[Hayhooks](https://github.com/deepset-ai/hayhooks) convierte cualquier pipeline de Haystack en una API REST automáticamente:

```bash
# Crear un directorio para tus pipelines
mkdir -p /workspace/haystack-pipelines

# Ejecutar Hayhooks con acceso a GPU
docker run -d \
  --name haystack \
  --gpus all \
  -p 1416:1416 \
  -v /workspace/haystack-pipelines:/app/pipelines \
  -e OPENAI_API_KEY=${OPENAI_API_KEY:-""} \
  -e HF_TOKEN=${HF_TOKEN:-""} \
  haystack-clore:latest

# Verificar que esté en ejecución
curl http://localhost:1416/status
```

Respuesta esperada:

```json
{"status": "ok", "pipelines": []}
```

### 5. Crea tu primer pipeline RAG

Escribe un YAML de pipeline que Hayhooks servirá como endpoint:

```bash
cat > /workspace/haystack-pipelines/rag_pipeline.yml << 'EOF'
# Pipeline RAG usando Ollama para LLM + embeddings locales para recuperación
componentes:
  embedder:
    type: haystack.components.embedders.SentenceTransformersTextEmbedder
    init_parameters:
      model: BAAI/bge-small-en-v1.5

  retriever:
    type: haystack.components.retrievers.in_memory.InMemoryEmbeddingRetriever
    init_parameters:
      document_store:
        type: haystack_integrations.document_stores.in_memory.InMemoryDocumentStore

  prompt_builder:
    type: haystack.components.builders.PromptBuilder
    init_parameters:
      template: |
        Responde la pregunta basada en el contexto abajo.
        Contexto: {% for doc in documents %}{{ doc.content }}{% endfor %}
        Pregunta: {{ question }}

  llm:
    type: haystack_integrations.components.generators.ollama.OllamaGenerator
    init_parameters:
      model: llama3
      url: http://host.docker.internal:11434

conexiones:
  - sender: embedder.embedding
    receiver: retriever.query_embedding
  - sender: retriever.documents
    receiver: prompt_builder.documents
  - sender: prompt_builder.prompt
    receiver: llm.prompt

entradas:
  query:
    - embedder.text
    - prompt_builder.question

salidas:
  answer: llm.replies
EOF
```

Hayhooks descubre y sirve automáticamente este pipeline. Pruébalo:

```bash
# Listar pipelines desplegados
curl http://localhost:1416/pipelines

# Consultar el pipeline RAG
curl -X POST http://localhost:1416/rag_pipeline/run \
  -H "Content-Type: application/json" \
  -d '{"query": "What is Haystack?"}'
```

## Configuración

### Variables de entorno

| Variable                     | Descripción                                     | Ejemplo               |
| ---------------------------- | ----------------------------------------------- | --------------------- |
| `OPENAI_API_KEY`             | Clave API de OpenAI para modelos GPT            | `sk-...`              |
| `ANTHROPIC_API_KEY`          | Clave API de Anthropic para Claude              | `sk-ant-...`          |
| `HF_TOKEN`                   | Token de Hugging Face para modelos restringidos | `hf_...`              |
| `HAYSTACK_TELEMETRY_ENABLED` | Deshabilitar telemetría de uso                  | `false`               |
| `CUDA_VISIBLE_DEVICES`       | Seleccionar GPU específica                      | `0`                   |
| `TRANSFORMERS_CACHE`         | Ruta de caché para modelos HF                   | `/workspace/hf-cache` |

### Ejecutar con configuración completa

```bash
docker run -d \
  --name haystack \
  --gpus '"device=0"' \
  -p 1416:1416 \
  -v /workspace/haystack-pipelines:/app/pipelines \
  -v /workspace/hf-cache:/root/.cache/huggingface \
  -e OPENAI_API_KEY="tu-clave-aqui" \
  -e HF_TOKEN="tu-token-hf" \
  -e HAYSTACK_TELEMETRY_ENABLED=false \
  -e CUDA_VISIBLE_DEVICES=0 \
  --restart unless-stopped \
  haystack-clore:latest
```

### Pipeline de ingestión de documentos

Construye un pipeline de indexación separado para ingerir documentos:

```bash
cat > /workspace/index_documents.py << 'EOF'
import haystack
from haystack import Pipeline
from haystack.components.converters import PyPDFToDocument, TextFileToDocument
from haystack.components.preprocessors import DocumentSplitter, DocumentCleaner
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack.components.writers import DocumentWriter
from haystack.document_stores.in_memory import InMemoryDocumentStore

# Inicializar el almacén de documentos
document_store = InMemoryDocumentStore()

# Construir pipeline de indexación
indexing_pipeline = Pipeline()
indexing_pipeline.add_component("converter", PyPDFToDocument())
indexing_pipeline.add_component("cleaner", DocumentCleaner())
indexing_pipeline.add_component("splitter", DocumentSplitter(
    split_by="word",
    split_length=200,
    split_overlap=20
))
indexing_pipeline.add_component("embedder", SentenceTransformersDocumentEmbedder(
    model="BAAI/bge-small-en-v1.5"
))
indexing_pipeline.add_component("writer", DocumentWriter(document_store=document_store))

# Conectar componentes
indexing_pipeline.connect("converter", "cleaner")
indexing_pipeline.connect("cleaner", "splitter")
indexing_pipeline.connect("splitter", "embedder")
indexing_pipeline.connect("embedder", "writer")

# Ejecutar indexación
from pathlib import Path
indexing_pipeline.run({"converter": {"sources": list(Path("/data/documents").glob("*.pdf"))}})

print(f"Indexed {document_store.count_documents()} document chunks")
EOF

docker run --rm \
  --gpus all \
  -v /workspace:/workspace \
  -v /your/documents:/data/documents \
  -v /workspace/hf-cache:/root/.cache/huggingface \
  haystack-clore:latest \
  python3 /workspace/index_documents.py
```

### Usando bases de datos vectoriales (Producción)

Para cargas de producción, reemplaza el almacén en memoria por una base de datos vectorial persistente:

```bash
# Lanzar Qdrant junto a Haystack
docker network create haystack-net

docker run -d \
  --name qdrant \
  --network haystack-net \
  -p 6333:6333 \
  -v /workspace/qdrant-data:/qdrant/storage \
  qdrant/qdrant

# Instalar integración de Qdrant en el contenedor Haystack
# Añadir al Dockerfile:  RUN pip install qdrant-haystack
# Luego usar QdrantDocumentStore en lugar de InMemoryDocumentStore
```

## Aceleración por GPU

Haystack usa aceleración por GPU en dos escenarios principales:

### 1. Generación de embeddings (Sentence Transformers)

La GPU es muy beneficiosa para generar embeddings de grandes colecciones de documentos:

```bash
cat > /workspace/benchmark_embeddings.py << 'EOF'
import time
import torch
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack import Document

# Comprobar disponibilidad de GPU
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using device: {device}")
if device == "cuda":
    print(f"GPU: {torch.cuda.get_device_name(0)}")
    print(f"VRAM: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")

# Crear embedder
embedder = SentenceTransformersDocumentEmbedder(
    model="BAAI/bge-base-en-v1.5"
)
embedder.warm_up()

# Benchmark
docs = [Document(content=f"Sample document {i} with some text content.") for i in range(100)]

start = time.time()
result = embedder.run(documents=docs)
elapsed = time.time() - start

print(f"Embedded 100 documents in {elapsed:.2f}s ({100/elapsed:.0f} docs/sec)")
EOF

docker run --rm --gpus all \
  -v /workspace:/workspace \
  haystack-clore:latest \
  python3 /workspace/benchmark_embeddings.py
```

### 2. Inferencia de LLM local (Hugging Face Transformers)

Para ejecutar LLMs directamente en Haystack sin Ollama:

```bash
cat > /workspace/local_llm_pipeline.py << 'EOF'
from haystack import Pipeline
from haystack.components.builders import PromptBuilder
from haystack.components.generators.hugging_face import HuggingFaceLocalGenerator

# Usa GPU automáticamente cuando esté disponible
generator = HuggingFaceLocalGenerator(
    model="mistralai/Mistral-7B-Instruct-v0.2",
    task="text-generation",
    generation_kwargs={
        "max_new_tokens": 512,
        "temperature": 0.7,
        "do_sample": True,
    }
)

prompt_builder = PromptBuilder(template="Answer this question: {{ question }}")

pipeline = Pipeline()
pipeline.add_component("prompt_builder", prompt_builder)
pipeline.add_component("llm", generator)
pipeline.connect("prompt_builder.prompt", "llm.prompt")

result = pipeline.run({"prompt_builder": {"question": "What is RAG?"}})
print(result["llm"]["replies"][0])
EOF

docker run --rm --gpus all \
  -v /workspace:/workspace \
  -e HF_TOKEN="tu-token-hf" \
  haystack-clore:latest \
  python3 /workspace/local_llm_pipeline.py
```

### 3. Combinar con Ollama (Enfoque recomendado)

Para la mejor combinación de facilidad y rendimiento, ejecuta Ollama para la inferencia de LLM y Haystack para la orquestación:

```bash
# Paso 1: Iniciar Ollama (ver guía de Ollama)
docker run -d \
  --name ollama \
  --gpus all \
  -p 11434:11434 \
  -v /workspace/ollama:/root/.ollama \
  ollama/ollama

# Paso 2: Descargar un modelo de coding/chat
docker exec ollama ollama pull llama3
docker exec ollama ollama pull nomic-embed-text  # Para embeddings vía Ollama

# Paso 3: Iniciar Haystack apuntando a Ollama
docker run -d \
  --name haystack \
  --gpus '"device=0"' \
  -p 1416:1416 \
  --add-host=host.docker.internal:host-gateway \
  -v /workspace/haystack-pipelines:/app/pipelines \
  haystack-clore:latest
```

Monitorea el uso de GPU entre ambos contenedores:

```bash
watch -n 2 nvidia-smi
```

## Consejos y mejores prácticas

### Elige el modelo de embedding adecuado

| Modelo                         | VRAM     | Velocidad     | Calidad   | Mejor para                     |
| ------------------------------ | -------- | ------------- | --------- | ------------------------------ |
| `BAAI/bge-small-en-v1.5`       | \~0.5 GB | El más rápido | Bueno     | Indexación de alto rendimiento |
| `BAAI/bge-base-en-v1.5`        | \~1 GB   | Rápido        | Mejor     | RAG general                    |
| `BAAI/bge-large-en-v1.5`       | \~2 GB   | Medio         | Mejor     | Mayor precisión                |
| `nomic-ai/nomic-embed-text-v1` | \~1.5 GB | Rápido        | Excelente | Documentos largos              |

### Consejos de diseño de pipeline

* **Divide los documentos sabiamente** — fragmentos de 200–400 palabras con 10–15% de solapamiento funcionan bien para la mayoría de casos de RAG
* **Cachea embeddings** — persiste tu almacén de documentos en disco; volver a generar embeddings es costoso
* **Usa `warm_up()`** — llama a `component.warm_up()` antes del uso en producción para cargar modelos en la memoria GPU
* **Indexación por lotes** — procesa documentos en lotes de 32–64 para una utilización óptima de la GPU
* **Filtra con metadata** — usa el filtrado por metadata de Haystack para acotar la recuperación (p. ej., por fecha, fuente, categoría)

### Optimización de costos

```bash
# Usa precios estilo spot en Clore.ai — elige servidores con menor $/hr
# Para desarrollo/pruebas: RTX 3060 (~$0.10/hr) es suficiente para embedding
# Para embedding en producción: RTX 3090 (~$0.20/hr) — 24 GB maneja grandes lotes
# Para LLM local + embedding: A100 40GB (~$0.60/hr) — margen para usuarios concurrentes

# Monitorea el uso de recursos
docker stats haystack
nvidia-smi dmon -s u -d 5  # Utilización de GPU cada 5 segundos
```

### Asegurar Hayhooks para acceso externo

```bash
# Opción 1: túnel SSH (más simple, para uso personal)
# Desde tu máquina local:
ssh -L 1416:localhost:1416 root@<clore-ip> -p <clore-ssh-port>
# Luego accede a http://localhost:1416 localmente

# Opción 2: Añadir autenticación básica vía proxy inverso nginx
docker run -d \
  --name nginx-proxy \
  -p 80:80 \
  -v /workspace/nginx.conf:/etc/nginx/conf.d/default.conf \
  nginx:alpine
```

## Solución de problemas

| Problema                              | Causa probable                       | Solución                                                                                                   |
| ------------------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `ModuleNotFoundError: haystack`       | Paquete no instalado                 | Reconstruye la imagen Docker; comprueba `pip install haystack-ai` sucedió                                  |
| `CUDA fuera de memoria`               | Modelo de embedding demasiado grande | Usa `bge-small-en-v1.5` o reduce el tamaño del batch                                                       |
| Hayhooks devuelve 404 en pipeline     | Archivo YAML no encontrado           | Comprueba el montaje del volumen; el archivo de pipeline debe estar en `/app/pipelines/`                   |
| Embeddings lentos en CPU              | GPU no detectada                     | Verifica `--gpus all` bandera; comprueba `torch.cuda.is_available()`                                       |
| Conexión a Ollama rehusada            | Nombre de host incorrecto            | Usa `--add-host=host.docker.internal:host-gateway`; establece la URL a `http://host.docker.internal:11434` |
| Descarga de HuggingFace falla         | Falta token o límite de tasa         | Establecer `HF_TOKEN` var de entorno; asegúrate de que el modelo no esté restringido                       |
| Error de parseo YAML del pipeline     | Sintaxis inválida                    | Valida el YAML; usa `python3 -c "import yaml; yaml.safe_load(open('pipeline.yml'))"`                       |
| El contenedor sale inmediatamente     | Error de inicio                      | Verifique `docker logs haystack`; asegúrate de que el CMD en el Dockerfile sea correcto                    |
| Puerto 1416 no accesible externamente | Cortafuegos / reenvío de puertos     | Expón el puerto en la configuración de pedido de Clore.ai; comprueba los puertos abiertos del servidor     |

### Comandos de depuración

```bash
# Comprobar logs del contenedor
docker logs haystack --tail 50 -f

# Probar la API de Hayhooks
curl http://localhost:1416/status
curl http://localhost:1416/pipelines

# Sesión interactiva de depuración en Python
docker exec -it haystack python3

# Comprobar GPU dentro del contenedor
docker exec haystack python3 -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"

# Comprobar paquetes instalados
docker exec haystack pip show haystack-ai hayhooks
```

## Lecturas adicionales

* [Documentación de Haystack](https://docs.haystack.deepset.ai/) — docs oficiales v2
* [Hayhooks en GitHub](https://github.com/deepset-ai/hayhooks) — servir pipelines vía API REST
* [Haystack Cookbook](https://haystack.deepset.ai/cookbook) — tutoriales de extremo a extremo (RAG, agentes, búsqueda)
* [deepset-ai/haystack en GitHub](https://github.com/deepset-ai/haystack) — código fuente, issues, releases
* [Integraciones de Haystack](https://haystack.deepset.ai/integrations) — lista completa de stores vectoriales, LLMs y herramientas soportadas
* [Ollama en Clore.ai](/guides/guides_v2-es/modelos-de-lenguaje/ollama.md) — empareja Haystack con Ollama para inferencia de LLM local
* [vLLM en Clore.ai](/guides/guides_v2-es/modelos-de-lenguaje/vllm.md) — backend de serving de LLMs de alto rendimiento para Haystack
* [Guía de comparación de GPU](/guides/guides_v2-es/primeros-pasos/gpu-comparison.md) — elige la GPU correcta de Clore.ai para tu carga de trabajo
* [CLORE.AI Marketplace](https://clore.ai/marketplace) — alquila servidores GPU


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-es/plataformas-y-agentes-de-ia/haystack.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
