GalaxIA - Documentación Técnica v3.0

Stable Enterprise v3.0.0

GalaxIA es una plataforma de IA Agentic de nivel empresarial que adopta una arquitectura Hexagonal (Ports & Adapters) implementada sobre un Monolito Modular.

🎯 Características Principales

  • Arquitectura Hexagonal con puertos y adaptadores
  • Multi-LLM Gateway con soporte para GPT-4o, Claude 3.5, Llama 3
  • Protocolo MCP para estandarización de herramientas
  • Motor RAG avanzado con Qdrant
  • Orchestrator Agentic con ReAct + Chain of Thought
  • Security Layer de grado empresarial

Quick Start

Instalación con Docker

# Clonar el repositorio
git clone https://github.com/symcarper/galaxia.git
cd galaxia

# Configurar variables de entorno
cp .env.example .env

# Construir y ejecutar con Docker Compose
docker-compose up -d

# Verificar que los servicios están corriendo
docker-compose ps

Primer Uso

from galaxia.core import AgenticOrchestrator
from galaxia.llm import MultiLLMGateway

# Inicializar orchestrator
orchestrator = AgenticOrchestrator(
    llm_gateway=MultiLLMGateway(
        primary="gpt-4o",
        fallback=["claude-3.5-sonnet"]
    )
)

# Ejecutar tarea
result = await orchestrator.execute(
    task="Analizar logs del sistema",
    context={"timeframe": "last_24h"}
)

Arquitectura Hexagonal

GalaxIA adopta el patrón arquitectónico Hexagonal (también conocido como Ports & Adapters), que permite aislar la lógica de negocio de las dependencias externas.

Capa Externa

Interfaces de usuario, APIs, CLI

Puertos (Interfaces)

Contratos de entrada/salida

Núcleo (Domain)

Lógica de negocio pura

Adaptadores

Implementaciones concretas

Infraestructura

Base de datos, APIs externas, MCP

Justificación de FastAPI

⚡ Por qué FastAPI

Utilizamos FastAPI como núcleo debido a su soporte nativo para concurrencia asíncrona (asyncio), tipado estático (Pydantic) y alto rendimiento (Starlette), crucial para manejar múltiples conexiones WebSocket y streaming de LLMs en tiempo real sin bloquear el hilo principal.

Backend & Asincronía

🐍

Python 3.11+

Lenguaje principal con soporte completo de tipado estático y async/await.

FastAPI

Framework web moderno con validación automática y documentación OpenAPI.

📋

Celery

Task queue distribuido para operaciones de larga duración.

🔴

Redis

Cache in-memory y message broker para Celery.

Ejemplo de Endpoint Asíncrono

from fastapi import FastAPI, WebSocket
from galaxia.orchestrator import AgenticOrchestrator

app = FastAPI()
orchestrator = AgenticOrchestrator()

@app.websocket("/ws/agent")
async def websocket_agent(websocket: WebSocket):
    await websocket.accept()
    
    while True:
        # Recibir mensaje del cliente
        data = await websocket.receive_json()
        
        # Procesar con el orchestrator (streaming)
        async for chunk in orchestrator.stream(data["task"]):
            await websocket.send_json({
                "type": "token",
                "content": chunk
            })
        
        # Enviar señal de finalización
        await websocket.send_json({"type": "done"})

Capa de IA - Multi-LLM Gateway

Para cumplir la promesa de agnosticismo de modelo, GalaxIA implementa una capa de abstracción utilizando LiteLLM que permite cambiar el "cerebro" del agente dinámicamente mediante configuración.

Model Router

Tipo de Tarea Modelo Primario Fallback Uso
Code Generation GPT-4o Claude 3.5 Sonnet Tareas complejas
Chat / Resumen GPT-4o-mini Llama 3 (Groq) Latencia ultra-baja
Análisis de Código Claude 3.5 Sonnet GPT-4o Comprensión profunda

Estrategia de Fallback

from galaxia.llm import MultiLLMGateway

gateway = MultiLLMGateway(
    models=[
        {
            "name": "gpt-4o",
            "provider": "openai",
            "priority": 1,
            "max_retries": 2
        },
        {
            "name": "claude-3.5-sonnet",
            "provider": "anthropic",
            "priority": 2,
            "max_retries": 2
        },
        {
            "name": "llama-3-70b",
            "provider": "groq",
            "priority": 3,
            "max_retries": 1
        }
    ],
    fallback_strategy="cascade"  # o "load_balance"
)

# El gateway automáticamente intentará los modelos en orden
response = await gateway.complete(
    prompt="Analizar este código...",
    temperature=0.7
)

Motor Vectorial RAG

GalaxIA utiliza Qdrant como base de datos vectorial por su rendimiento excepcional en filtrado híbrido (vector + metadata) y por estar escrito en Rust.

Comparación de Vector DBs

Característica Qdrant Pinecone pgvector
Performance Excelente Muy buena Buena
Filtrado Híbrido ✓ Nativo ✓ Soportado ✓ Limitado
Self-Hosted ✓ Sí ✗ No ✓ Sí
Escalabilidad Horizontal Managed Vertical

Configuración de Qdrant

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams

# Inicializar cliente
client = QdrantClient(host="localhost", port=6333)

# Crear colección
client.create_collection(
    collection_name="galaxia_knowledge",
    vectors_config=VectorParams(
        size=1536,  # OpenAI text-embedding-3-small
        distance=Distance.COSINE
    )
)

# Insertar vectores con metadata
client.upsert(
    collection_name="galaxia_knowledge",
    points=[
        {
            "id": "doc_1",
            "vector": embedding,
            "payload": {
                "text": "Contenido del documento...",
                "source": "api_docs",
                "timestamp": "2025-01-02",
                "category": "technical"
            }
        }
    ]
)

Protocolo MCP (Model Context Protocol)

GalaxIA implementa el estándar MCP para estandarizar las herramientas. En lugar de escribir funciones Python "hardcoded" para cada integración, GalaxIA expone un Servidor MCP.

📦 Ventajas del Protocolo MCP

  • Estandarización: Todas las herramientas siguen la misma interfaz
  • Extensibilidad: Desarrolla plugins sin tocar el núcleo
  • Descubrimiento: Los agentes pueden descubrir herramientas dinámicamente
  • Validación: Schemas automáticos para inputs/outputs

Estructura de un Adaptador MCP

from galaxia.mcp import MCPAdapter, Tool

class JiraAdapter(MCPAdapter):
    """Adaptador MCP para Jira"""
    
    def list_tools(self) -> List[Tool]:
        return [
            Tool(
                name="create_issue",
                description="Crea un issue en Jira",
                parameters={
                    "project": {"type": "string", "required": True},
                    "title": {"type": "string", "required": True},
                    "description": {"type": "string"},
                    "priority": {"type": "string", "enum": ["low", "medium", "high"]}
                }
            ),
            Tool(
                name="search_issues",
                description="Busca issues en Jira usando JQL",
                parameters={
                    "jql": {"type": "string", "required": True},
                    "max_results": {"type": "integer", "default": 50}
                }
            )
        ]
    
    async def call_tool(self, tool_name: str, parameters: dict):
        if tool_name == "create_issue":
            return await self._create_issue(**parameters)
        elif tool_name == "search_issues":
            return await self._search_issues(**parameters)
    
    async def _create_issue(self, project, title, description=None, priority="medium"):
        # Implementación real de creación de issue
        pass

Containerización con Docker

GalaxIA utiliza Multi-stage Builds para minimizar el tamaño de la imagen final y mejorar la seguridad.

Dockerfile Optimizado

# Stage 1: Builder
FROM python:3.11-slim as builder

WORKDIR /app

# Instalar dependencias de compilación
RUN apt-get update && apt-get install -y \
    gcc \
    g++ \
    && rm -rf /var/lib/apt/lists/*

# Copiar requirements y crear wheels
COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels \
    -r requirements.txt

# Stage 2: Runtime
FROM python:3.11-slim

WORKDIR /app

# Instalar dependencias de runtime
RUN apt-get update && apt-get install -y \
    libpq5 \
    && rm -rf /var/lib/apt/lists/*

# Copiar wheels desde builder
COPY --from=builder /app/wheels /wheels
RUN pip install --no-cache /wheels/*

# Copiar código fuente
COPY . .

# Crear usuario no root
RUN useradd -m -u 1000 appuser && \
    chown -R appuser:appuser /app

USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

# Comando de inicio
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Docker Compose

version: '3.8'

services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - REDIS_URL=redis://redis:6379
      - QDRANT_URL=http://qdrant:6333
      - OPENAI_API_KEY=${OPENAI_API_KEY}
    depends_on:
      - redis
      - qdrant
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  worker:
    build: .
    command: celery -A app.tasks worker --loglevel=info
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  qdrant:
    image: qdrant/qdrant:latest
    ports:
      - "6333:6333"
    volumes:
      - qdrant_data:/qdrant/storage

volumes:
  redis_data:
  qdrant_data:

Security Layer - RBAC

GalaxIA implementa un sistema de RBAC (Role-Based Access Control) granular con middleware en FastAPI que intercepta cada request.

Definición de Roles y Permisos

from galaxia.security import Role, Permission

# Definir permisos
PERMISSIONS = {
    "read:users": Permission("read:users", "Ver usuarios"),
    "write:users": Permission("write:users", "Modificar usuarios"),
    "exec:pipeline": Permission("exec:pipeline", "Ejecutar pipelines"),
    "admin:system": Permission("admin:system", "Administración total"),
}

# Definir roles
ROLES = {
    "viewer": Role("viewer", [PERMISSIONS["read:users"]]),
    "developer": Role("developer", [
        PERMISSIONS["read:users"],
        PERMISSIONS["exec:pipeline"],
    ]),
    "admin": Role("admin", list(PERMISSIONS.values())),
}

# Middleware de autorización
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer

security = HTTPBearer()

async def require_permission(required_permission: str):
    def permission_checker(token: str = Depends(security)):
        # Decodificar JWT
        payload = decode_jwt(token.credentials)
        
        # Obtener rol del usuario
        user_role = ROLES[payload["role"]]
        
        # Verificar permiso
        if not user_role.has_permission(required_permission):
            raise HTTPException(status_code=403, detail="Insufficient permissions")
        
        return payload
    
    return permission_checker

# Uso en endpoints
@app.post("/api/pipeline/execute")
async def execute_pipeline(
    user = Depends(require_permission("exec:pipeline"))
):
    # Lógica del endpoint
    pass