GalaxIA - Documentación Técnica v3.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