# ChromaDB

ChromaDB es el **principal base de datos de vectores de código abierto** diseñada específicamente para aplicaciones de IA. Proporciona una API simple e intuitiva para almacenar, consultar y gestionar embeddings de alta dimensión: la columna vertebral de los sistemas RAG modernos, la búsqueda semántica, los motores de recomendación y la memoria de los LLM.

ChromaDB abstrae la complejidad de la búsqueda por similitud de vectores, permitiéndote centrarte en construir aplicaciones de IA. Admite tanto el modo en memoria para desarrollo como un modo servidor persistente para despliegues en producción, con soporte para Docker para un despliegue sencillo en servidores GPU de Clore.ai.

Características clave:

* 🚀 **API simple para Python/JavaScript** — empieza en minutos
* 💾 **Almacenamiento persistente** — los datos sobreviven a reinicios del contenedor
* 🔍 **Métricas de distancia múltiples** — coseno, L2, producto interno
* 📦 **Embeddings integrados** — soporte incorporado para OpenAI, Cohere, sentence-transformers
* 🏗️ **Multiinquilino** — colecciones para organizar diferentes conjuntos de datos
* 🔌 **API REST** — interfaz HTTP independiente del lenguaje
* ⚡ **Rápido** — índice HNSW para búsqueda aproximada de vecinos más cercanos
* 🔗 **Nativo con LangChain/LlamaIndex** — integración de primera clase

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

***

## Requisitos del servidor

| Parámetro | Mínimo                          | Recomendado                                  |
| --------- | ------------------------------- | -------------------------------------------- |
| GPU       | Cualquier GPU NVIDIA (opcional) | NVIDIA RTX 3080+ (para embeddings)           |
| VRAM      | No es obligatorio para ChromaDB | 8–16 GB (para modelos de embeddings locales) |
| RAM       | 4 GB                            | 16–32 GB                                     |
| CPU       | 2 núcleos                       | 8 núcleos                                    |
| Disco     | 10 GB                           | 50–200 GB (para conjuntos de datos grandes)  |
| SO        | Ubuntu 20.04+                   | Ubuntu 22.04                                 |
| Docker    | Requerido                       | Docker + Docker Compose                      |
| Puertos   | 22, 8000                        | 22, 8000                                     |

{% hint style="info" %}
ChromaDB en sí no requiere GPU: funciona de manera eficiente en CPU. Sin embargo, **generar embeddings** (convertir texto en vectores) se beneficia enormemente de la aceleración por GPU. Si planeas usar modelos de embeddings locales (sentence-transformers, etc.), elige un servidor con GPU.
{% endhint %}

***

## Despliegue rápido en CLORE.AI

### 1. Encuentra un servidor adecuado

Ve a [CLORE.AI Marketplace](https://clore.ai/marketplace) y elige:

* **Solo CPU** para el servidor ChromaDB + API (almacenar embeddings precomputados)
* **servidor GPU** si también quieres generar embeddings localmente

### 2. Configura tu despliegue

**Imagen Docker:**

```
chromadb/chroma:latest
```

**Mapeo de puertos:**

```
22   → acceso SSH
8000 → API HTTP de ChromaDB
```

**Variables de entorno:**

```
IS_PERSISTENT=TRUE
ANONYMIZED_TELEMETRY=FALSE
CHROMA_SERVER_AUTH_CREDENTIALS_FILE=/chroma/auth.txt
```

**Comando de inicio:**

```bash
uvicorn chromadb.app:app --host 0.0.0.0 --port 8000
```

### 3. Probar el despliegue

```bash
curl http://<server-ip>:8000/api/v1/heartbeat
# Esperado: {"nanosecond heartbeat": <timestamp>}
```

***

## Configuración paso a paso

### Paso 1: Conéctate por SSH a tu servidor

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

### Paso 2: Crear directorio de datos

```bash
mkdir -p /workspace/chromadb/data
mkdir -p /workspace/chromadb/config
```

### Paso 3: Ejecutar el contenedor de ChromaDB

```bash
docker run -d \
  --name chromadb \
  -p 8000:8000 \
  -v /workspace/chromadb/data:/chroma/chroma \
  -e IS_PERSISTENT=TRUE \
  -e ANONYMIZED_TELEMETRY=FALSE \
  -e CHROMA_SERVER_LOG_LEVEL=INFO \
  chromadb/chroma:latest
```

### Paso 4: Verificar que se está ejecutando

```bash
# Comprobar estado de salud
curl http://localhost:8000/api/v1/heartbeat

# Comprobar versión
curl http://localhost:8000/api/v1/version

# Listar colecciones
curl http://localhost:8000/api/v1/collections
```

### Paso 5: Instalar el cliente de Python

```bash
pip install chromadb
pip install sentence-transformers  # Para embeddings locales con GPU
pip install openai                  # Para embeddings de OpenAI
```

### Paso 6: Probar la conectividad desde Python

```python
import chromadb

client = chromadb.HttpClient(host="<server-ip>", port=8000)
print(f"Versión de ChromaDB: {client.get_version()}")
print(f"Heartbeat: {client.heartbeat()}")
```

### Paso 7: (Opcional) Habilitar autenticación

```bash
# Crear credenciales de auth
echo "admin:$2y$12$$(openssl rand -hex 16)" > /workspace/chromadb/auth.txt

# Ejecutar con auth habilitada
docker run -d \
  --name chromadb-auth \
  -p 8000:8000 \
  -v /workspace/chromadb/data:/chroma/chroma \
  -v /workspace/chromadb/auth.txt:/chroma/auth.txt \
  -e IS_PERSISTENT=TRUE \
  -e CHROMA_SERVER_AUTH_CREDENTIALS_FILE=/chroma/auth.txt \
  -e CHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER=chromadb.auth.providers.HtpasswdFileServerAuthCredentialsProvider \
  -e CHROMA_SERVER_AUTH_PROVIDER=chromadb.auth.basic.BasicAuthServerProvider \
  chromadb/chroma:latest
```

***

## Ejemplos de uso

### Ejemplo 1: Operaciones básicas de almacenamiento vectorial

```python
import chromadb
from chromadb.utils import embedding_functions

# Conectar a ChromaDB en servidor Clore.ai
client = chromadb.HttpClient(
    host="<your-clore-server-ip>",
    port=8000
)

# Usar sentence-transformers para embeddings (se ejecuta en GPU si está disponible)
embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction(
    model_name="all-MiniLM-L6-v2"
)

# Crear una colección
collection = client.get_or_create_collection(
    name="clore_ai_docs",
    embedding_function=embedding_fn,
    metadata={"hnsw:space": "cosine"}  # Métrica de distancia
)

# Añadir documentos
documents = [
    "Clore.ai es un mercado de nube GPU descentralizado para cargas de trabajo de IA.",
    "Puedes alquilar GPUs NVIDIA RTX 4090, A100 y H100 en Clore.ai.",
    "Clore.ai admite despliegues basados en Docker para cualquier framework de IA.",
    "Los precios en Clore.ai son competitivos en comparación con AWS y GCP.",
    "El marketplace de Clore.ai tiene miles de servidores GPU en todo el mundo.",
    "Puedes desplegar PyTorch, TensorFlow, JAX y otros frameworks de ML.",
    "Clore.ai ofrece precios spot para computación GPU rentable.",
]

ids = [f"doc_{i}" for i in range(len(documents))]

collection.add(
    documents=documents,
    ids=ids,
    metadatas=[{"source": "docs", "index": i} for i in range(len(documents))]
)

print(f"Añadidos {len(documents)} documentos a la colección")
print(f"Tamaño de la colección: {collection.count()} documentos")
```

***

### Ejemplo 2: Búsqueda semántica

```python
import chromadb
from chromadb.utils import embedding_functions

client = chromadb.HttpClient(host="<server-ip>", port=8000)
embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction(
    model_name="all-MiniLM-L6-v2"
)

collection = client.get_collection(
    name="clore_ai_docs",
    embedding_function=embedding_fn
)

# Consultas de búsqueda semántica
queries = [
    "¿Cuánto cuesta alquilar una GPU?",
    "¿Qué herramientas de aprendizaje automático están disponibles?",
    "Háblame sobre las opciones de hardware GPU",
]

for query in queries:
    results = collection.query(
        query_texts=[query],
        n_results=3,
        include=["documents", "distances", "metadatas"]
    )

    print(f"\n🔍 Consulta: {query}")
    for i, (doc, dist) in enumerate(zip(
        results["documents"][0],
        results["distances"][0]
    )):
        similarity = 1 - dist  # Convertir distancia a similitud
        print(f"  {i+1}. [{similarity:.3f}] {doc[:100]}...")
```

***

### Ejemplo 3: Canal RAG con ChromaDB + OpenAI

```python
import chromadb
from chromadb.utils import embedding_functions
from openai import OpenAI

# Inicializar clientes
chroma_client = chromadb.HttpClient(host="<server-ip>", port=8000)
openai_client = OpenAI(api_key="tu-clave-openai")

# Usar embeddings de OpenAI
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key="your-openai-api-key",
    model_name="text-embedding-3-small"
)

# Obtener colección
collection = chroma_client.get_or_create_collection(
    name="knowledge_base",
    embedding_function=openai_ef
)

def add_to_knowledge_base(texts, ids=None, metadatas=None):
    """Añadir documentos a la base de conocimientos de ChromaDB."""
    if ids is None:
        ids = [f"doc_{i}" for i in range(len(texts))]
    collection.add(documents=texts, ids=ids, metadatas=metadatas or [{}]*len(texts))
    print(f"✓ Añadidos {len(texts)} documentos. Total: {collection.count()}")

def rag_query(question, n_context=5):
    """Recuperar contexto relevante y generar respuesta con GPT-4."""
    # 1. Recuperar documentos relevantes
    results = collection.query(
        query_texts=[question],
        n_results=n_context,
        include=["documents", "distances"]
    )

    context_docs = results["documents"][0]
    distances = results["distances"][0]

    # 2. Construir cadena de contexto
    context = "\n\n".join([
        f"[Fuente {i+1} (relevancia: {1-d:.2f})]: {doc}"
        for i, (doc, d) in enumerate(zip(context_docs, distances))
    ])

    # 3. Generar respuesta con LLM
    messages = [
        {
            "role": "system",
            "content": "Eres un asistente servicial. Responde las preguntas basándote en el contexto proporcionado. Si la respuesta no está en el contexto, dilo."
        },
        {
            "role": "user",
            "content": f"Contexto:\n{context}\n\nPregunta: {question}"
        }
    ]

    response = openai_client.chat.completions.create(
        model="gpt-4-turbo",
        messages=messages,
        temperature=0.1
    )

    answer = response.choices[0].message.content

    return {
        "question": question,
        "answer": answer,
        "sources": context_docs,
        "relevance_scores": [1 - d for d in distances]
    }

# Ejemplo de uso
knowledge = [
    "Clore.ai es un marketplace de nube GPU con más de 45.000 usuarios.",
    "Clore.ai admite el despliegue de cargas de trabajo basadas en Docker.",
    "Los servidores GPU en Clore.ai van desde GTX 1080 hasta H100.",
    "Puedes desplegar aplicaciones de IA con acceso SSH y puertos personalizados.",
]
add_to_knowledge_base(knowledge)

result = rag_query("¿Cuántos usuarios tiene Clore.ai?")
print(f"P: {result['question']}")
print(f"R: {result['answer']}")
```

***

### Ejemplo 4: Gestión de documentos con múltiples colecciones

```python
import chromadb
from chromadb.utils import embedding_functions

client = chromadb.HttpClient(host="<server-ip>", port=8000)
embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction(
    model_name="all-mpnet-base-v2"  # Embeddings de mayor calidad
)

# Crear colecciones separadas para diferentes tipos de documentos
collections = {
    "technical_docs": client.get_or_create_collection("technical_docs", embedding_function=embedding_fn),
    "faq": client.get_or_create_collection("faq", embedding_function=embedding_fn),
    "blog_posts": client.get_or_create_collection("blog_posts", embedding_function=embedding_fn),
}

# Añadir documentos a las colecciones respectivas
collections["technical_docs"].add(
    documents=["Guía de despliegue con Docker para Clore.ai", "Configuración SSH para servidores GPU"],
    ids=["tech_001", "tech_002"],
    metadatas=[{"type": "guide", "version": "v2"}, {"type": "config"}]
)

collections["faq"].add(
    documents=["P: ¿Cómo pago? R: Vía criptomonedas.", "P: ¿Qué GPUs? R: De RTX a H100."],
    ids=["faq_001", "faq_002"],
    metadatas=[{"category": "payment"}, {"category": "hardware"}]
)

# Buscar en todas las colecciones
def search_all_collections(query, n_results=2):
    all_results = []
    for name, col in collections.items():
        results = col.query(query_texts=[query], n_results=n_results)
        for doc, dist in zip(results["documents"][0], results["distances"][0]):
            all_results.append({
                "collection": name,
                "document": doc,
                "similarity": 1 - dist
            })

    # Ordenar por relevancia
    all_results.sort(key=lambda x: x["similarity"], reverse=True)
    return all_results[:n_results * 2]

results = search_all_collections("¿Cómo despliego con Docker?")
for r in results:
    print(f"[{r['collection']}] ({r['similarity']:.3f}) {r['document'][:80]}...")
```

***

### Ejemplo 5: Filtrado y consultas por metadatos

```python
import chromadb

client = chromadb.HttpClient(host="<server-ip>", port=8000)
collection = client.get_collection("technical_docs")

# Añadir documentos con metadatos ricos
collection.add(
    documents=[
        "Guía: Ejecutar PyTorch en clústeres GPU NVIDIA A100",
        "Guía: Entrenamiento distribuido con TensorFlow en RTX 4090",
        "Tutorial: Fine-tuning de LLM con LoRA en GPU",
        "Referencia: matriz de compatibilidad de CUDA 12.1",
        "Guía: Redes Docker para configuraciones multi-GPU",
    ],
    ids=["d1", "d2", "d3", "d4", "d5"],
    metadatas=[
        {"type": "guide", "gpu": "A100", "framework": "pytorch", "year": 2024},
        {"type": "guide", "gpu": "RTX4090", "framework": "tensorflow", "year": 2024},
        {"type": "tutorial", "gpu": "any", "framework": "transformers", "year": 2024},
        {"type": "reference", "gpu": "any", "framework": "cuda", "year": 2023},
        {"type": "guide", "gpu": "multi", "framework": "docker", "year": 2024},
    ]
)

# Consulta con filtro de metadatos
results = collection.query(
    query_texts=["Guía de entrenamiento en GPU"],
    n_results=3,
    where={"type": "guide"},  # Solo devolver guías
    include=["documents", "metadatas", "distances"]
)

print("Resultados filtrados (type=guide):")
for doc, meta, dist in zip(
    results["documents"][0],
    results["metadatas"][0],
    results["distances"][0]
):
    print(f"  [{1-dist:.3f}] {doc}")
    print(f"    Metadatos: {meta}")
```

***

## Configuración

### Docker Compose (Producción)

```yaml
version: '3.8'

services:
  chromadb:
    image: chromadb/chroma:latest
    container_name: chromadb
    ports:
      - "8000:8000"
    volumes:
      - chromadb_data:/chroma/chroma
    environment:
      - IS_PERSISTENT=TRUE
      - ANONYMIZED_TELEMETRY=FALSE
      - CHROMA_SERVER_LOG_LEVEL=INFO
      - ALLOW_RESET=FALSE
      - CHROMA_SEGMENT_CACHE_POLICY=LRU
      - CHROMA_MEMORY_LIMIT_BYTES=2147483648  # Caché de 2 GB
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat"]
      intervalo: 30s
      tiempo de espera: 10s
      reintentos: 3

volumes:
  chromadb_data:
    controlador: local
```

### Referencia de variables de entorno

| Variable                      | Por defecto | Descripción                                  |
| ----------------------------- | ----------- | -------------------------------------------- |
| `IS_PERSISTENT`               | `FALSE`     | Habilitar almacenamiento persistente         |
| `ANONYMIZED_TELEMETRY`        | `TRUE`      | Desactivar el seguimiento de uso             |
| `CHROMA_SERVER_LOG_LEVEL`     | `INFO`      | Verbosity de registro                        |
| `CHROMA_MEMORY_LIMIT_BYTES`   | Ninguna     | Memoria máxima para la caché de segmentos    |
| `ALLOW_RESET`                 | `FALSE`     | Permitir restablecer todos los datos vía API |
| `CHROMA_SERVER_AUTH_PROVIDER` | Ninguna     | Clase proveedor de autenticación             |

***

## Consejos de rendimiento

### 1. Elegir el modelo de embeddings adecuado

| Modelo                   | Dimensiones | Velocidad | Calidad   | GPU requerida |
| ------------------------ | ----------- | --------- | --------- | ------------- |
| `all-MiniLM-L6-v2`       | 384         | Rápido    | Bueno     | No            |
| `all-mpnet-base-v2`      | 768         | Medio     | Mejor     | Opcional      |
| `text-embedding-3-small` | 1536        | Rápido    | Excelente | Solo API      |
| `BAAI/bge-large-en-v1.5` | 1024        | Medio     | Mejor     | Sí            |

### 2. Inserciones por lotes para velocidad

```python
# Añadir en lotes de 100-1000 para un mejor rendimiento
BATCH_SIZE = 500

for i in range(0, len(all_documents), BATCH_SIZE):
    batch = all_documents[i:i+BATCH_SIZE]
    collection.add(
        documents=[d["text"] for d in batch],
        ids=[d["id"] for d in batch],
        metadatas=[d["meta"] for d in batch]
    )
    print(f"Lote {i//BATCH_SIZE + 1} completado")
```

### 3. Ajuste del índice HNSW

```python
collection = client.create_collection(
    name="optimized",
    metadata={
        "hnsw:space": "cosine",
        "hnsw:construction_ef": 200,  # Más alto = mejor calidad de índice (construcción más lenta)
        "hnsw:search_ef": 100,        # Más alto = mejor recall (búsqueda más lenta)
        "hnsw:M": 32,                 # Más alto = mejor recall (más memoria)
    }
)
```

### 4. Cliente persistente para uso local

```python
# Para desarrollo directamente en el servidor Clore.ai
import chromadb

client = chromadb.PersistentClient(path="/workspace/chromadb/data")
# No se necesita servidor, más rápido para uso en un solo proceso
```

***

## Solución de problemas

### Problema: No se puede conectar a ChromaDB

```bash
# Comprobar que el contenedor está en ejecución
docker ps | grep chromadb

# Comprobar logs
docker logs chromadb --tail 20

# Probar desde dentro del contenedor
docker exec chromadb curl http://localhost:8000/api/v1/heartbeat
```

### Problema: Datos perdidos al reiniciar el contenedor

```bash
# Asegurarse de que el volumen está montado
docker inspect chromadb | grep Mounts -A 10

# Volver a ejecutar con volumen explícito
docker run -d -p 8000:8000 \
  -v /workspace/chromadb/data:/chroma/chroma \
  -e IS_PERSISTENT=TRUE \
  chromadb/chroma:latest
```

### Problema: Errores por falta de memoria

```bash
# Limitar caché de memoria
docker run -d -p 8000:8000 \
  -e CHROMA_MEMORY_LIMIT_BYTES=1073741824 \
  -v /workspace/chromadb/data:/chroma/chroma \
  chromadb/chroma:latest
```

### Problema: Generación de embeddings lenta

```bash
# Verificar que la GPU se está usando para embeddings
python3 -c "
import torch
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2', device='cuda')
print(f'Modelo de embeddings en: {model.device}')
"
```

### Problema: Colección no encontrada después del reinicio

```bash
# Verificar que la persistencia está habilitada
curl http://localhost:8000/api/v1/collections
# Si está vacío, IS_PERSISTENT no se estableció o el volumen no se montó
```

***

## Enlaces

* **GitHub**: <https://github.com/chroma-core/chroma>
* **Documentación oficial**: <https://docs.trychroma.com>
* **Docker Hub**: <https://hub.docker.com/r/chromadb/chroma>
* **PyPI**: <https://pypi.org/project/chromadb>
* **Discord**: <https://discord.gg/MMeYNTmh3x>
* **CLORE.AI Marketplace**: <https://clore.ai/marketplace>

***

## Recomendaciones de GPU en Clore.ai

| Caso de uso                    | GPU recomendada | Coste estimado en Clore.ai |
| ------------------------------ | --------------- | -------------------------- |
| Desarrollo/Pruebas             | RTX 3090 (24GB) | \~$0.12/gpu/hr             |
| RAG en producción              | RTX 3090 (24GB) | \~$0.12/gpu/hr             |
| Embeddings de alto rendimiento | RTX 4090 (24GB) | \~$0.70/gpu/hr             |

> 💡 Todos los ejemplos en esta guía pueden desplegarse en [Clore.ai](https://clore.ai/marketplace) servidores GPU. Navega las GPUs disponibles y alquila por hora — sin compromisos, acceso root completo.


---

# 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/rag-y-bases-de-datos-vectoriales/chromadb.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.
