stratumiops/docs/es/architecture/adrs/002-stratum-llm.md
Jesús Pérez 0ae853c2fa
Some checks failed
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
chore: create stratum-embeddings and stratum-llm crates, docs
2026-01-24 02:03:12 +00:00

10 KiB
Raw Permalink Blame History

ADR-002: Stratum-LLM - Biblioteca Unificada de Providers LLM

Estado

Propuesto

Contexto

Estado Actual: Conexiones LLM Fragmentadas

El ecosistema stratumiops tiene 4 proyectos con funcionalidad IA, cada uno con su propia implementación:

Proyecto Implementación Providers Duplicación
Vapora typedialog-ai (path dep) Claude, OpenAI, Ollama Base compartida
TypeDialog typedialog-ai (local) Claude, OpenAI, Ollama Define la abstracción
Provisioning Custom LlmClient Claude, OpenAI 100% duplicado
Kogral rig-core Solo embeddings Diferente stack

Problemas Identificados

1. Duplicación de Código

Provisioning reimplementa lo que TypeDialog ya tiene:

  • reqwest HTTP client
  • Headers: x-api-key, anthropic-version
  • JSON body formatting
  • Response parsing
  • Error handling

Impacto: ~500 líneas duplicadas, bugs arreglados en un lugar no se propagan.

2. Solo API Keys, No CLI Detection

Ningún proyecto detecta credenciales de CLIs oficiales:

Claude CLI:  ~/.config/claude/credentials.json
OpenAI CLI:  ~/.config/openai/credentials.json

Impacto: Usuarios con Claude Pro/Max ($20-100/mes) pagan API tokens cuando podrían usar su suscripción.

3. Sin Fallback Automático

Cuando un provider falla (rate limit, timeout), la request falla completamente:

Actual:   Request → Claude API → Rate Limit → ERROR
Deseado:  Request → Claude API → Rate Limit → OpenAI → Success

4. Sin Circuit Breaker

Si Claude API está caído, cada request intenta conectar, falla, y propaga el error:

Request 1 → Claude → Timeout (30s) → Error
Request 2 → Claude → Timeout (30s) → Error
Request 3 → Claude → Timeout (30s) → Error

Impacto: Latencia acumulada, UX degradado.

5. Sin Caching

Requests idénticas van siempre a la API:

"Explain this Rust error" → Claude → $0.003
"Explain this Rust error" → Claude → $0.003 (mismo resultado)

Impacto: Costos innecesarios, especialmente en desarrollo/testing.

6. Kogral No Integrado

Kogral tiene guidelines y patterns que podrían enriquecer el contexto de LLM, pero no hay integración.

Decisión

Crear stratum-llm como crate unificado que:

  1. Consolide las implementaciones existentes de typedialog-ai y provisioning
  2. Detecte credenciales CLI y subscripciones antes de usar API keys
  3. Implemente fallback automático con circuit breaker
  4. Añada caching de requests para reducir costos
  5. Integre Kogral para enriquecer contexto
  6. Sea usado por todos los proyectos del ecosistema

Arquitectura

┌─────────────────────────────────────────────────────────┐
│                      stratum-llm                         │
├─────────────────────────────────────────────────────────┤
│  CredentialDetector                                      │
│  ├─ Claude CLI → ~/.config/claude/ (subscription)       │
│  ├─ OpenAI CLI → ~/.config/openai/                      │
│  ├─ Env vars → *_API_KEY                                │
│  └─ Ollama → localhost:11434 (free)                     │
│                          │                               │
│                          ▼                               │
│  ProviderChain (ordered by priority)                     │
│  [CLI/Sub] → [API] → [DeepSeek] → [Ollama]              │
│      │          │         │           │                  │
│      └──────────┴─────────┴───────────┘                  │
│                          │                               │
│                  CircuitBreaker per provider             │
│                          │                               │
│                    RequestCache                          │
│                          │                               │
│                  KogralIntegration                       │
│                          │                               │
│                    UnifiedClient                         │
│                                                          │
└─────────────────────────────────────────────────────────┘

Justificación

Por Qué No Usar Otra Crate Externa

Alternativa Por Qué No
kaccy-ai Orientada a blockchain/fraud detection
llm (crate) Muy básica, sin circuit breaker ni caching
langchain-rust Port de Python, no idiomático Rust
rig-core Solo embeddings/RAG, no chat completion

Mejor opción: Construir sobre typedialog-ai y añadir features faltantes.

Por Qué CLI Detection es Importante

Análisis de costos para usuario típico:

Escenario Costo Mensual
Solo API (actual) ~$840
Claude Pro + API overflow ~$20 + ~$200 = $220
Claude Max + API overflow ~$100 + ~$50 = $150

Ahorro potencial: 70-80% detectando y usando subscripciones primero.

Por Qué Circuit Breaker

Sin circuit breaker, un provider caído causa:

  • N requests × 30s timeout = N×30s de latencia total
  • Todos los recursos ocupados esperando timeouts

Con circuit breaker:

  • Primera falla abre circuito
  • Siguientes requests fallan inmediatamente (fast fail)
  • Fallback a otro provider sin esperar
  • Circuito se resetea después de cooldown

Por Qué Caching

Para desarrollo típico:

  • Mismas preguntas repetidas mientras se itera
  • Testing ejecuta mismos prompts múltiples veces

Cache hit rate estimado: 15-30% en desarrollo activo.

Por Qué Kogral Integration

Kogral tiene guidelines por lenguaje, patterns por dominio, y ADRs. Sin integración el LLM genera código genérico; con integración genera código que sigue convenciones del proyecto.

Consecuencias

Positivas

  1. Single source of truth para lógica de LLM
  2. CLI detection reduce costos 70-80%
  3. Circuit breaker + fallback = alta disponibilidad
  4. 15-30% menos requests en desarrollo (caching)
  5. Kogral mejora calidad de generación
  6. Feature-gated: cada feature es opcional

Negativas

  1. Migration effort: Refactorizar Vapora, TypeDialog, Provisioning
  2. New dependency: Proyectos dependen de stratumiops
  3. CLI auth complexity: Diferentes formatos de credenciales por versión
  4. Cache invalidation: Respuestas obsoletas si no se gestiona bien

Mitigaciones

Negativo Mitigación
Migration effort Re-export API compatible desde typedialog-ai
New dependency Path dependency local, no crates.io
CLI auth complexity Version detection, fallback a API si falla
Cache invalidation TTL configurable, opción de bypass

Métricas de Éxito

Métrica Actual Objetivo
Líneas de código duplicadas ~500 0
CLI credential detection 0% 100%
Fallback success rate 0% >90%
Cache hit rate 0% 15-30%
Latency (provider down) 30s+ <1s (fast fail)

Análisis de Impacto en Costos

Basado en datos reales de uso ($840/mes):

Escenario Ahorro
CLI detection (Claude Max) ~$700/mes
Caching (15% hit rate) ~$50/mes
DeepSeek fallback para código ~$100/mes
Total potencial $500-700/mes

Estrategia de Migración

Fases de Migración

  1. Crear stratum-llm con API compatible con typedialog-ai
  2. typedialog-ai re-exporta stratum-llm (backward compatible)
  3. Vapora migra a stratum-llm directamente
  4. Provisioning migra su LlmClient a stratum-llm
  5. Deprecar typedialog-ai, consolidar en stratum-llm

Adopción de Features

Feature Adopción
Basic providers Inmediata (reemplazo directo)
CLI detection Opcional, feature flag
Circuit breaker Default on
Caching Default on, configurable TTL
Kogral Feature flag, requiere Kogral instalado

Alternativas Consideradas

Alternativa 1: Mejorar typedialog-ai In-Place

Pros: No requiere nuevo crate

Cons: TypeDialog es proyecto específico, no infraestructura compartida

Decisión: stratum-llm en stratumiops es mejor ubicación para infraestructura cross-project.

Alternativa 2: Usar LiteLLM (Python) como Proxy

Pros: Muy completo, 100+ providers

Cons: Dependencia Python, latencia de proxy, no Rust-native

Decisión: Mantener stack Rust puro.

Alternativa 3: Cada Proyecto Mantiene su Implementación

Pros: Independencia

Cons: Duplicación, inconsistencia, bugs no compartidos

Decisión: Consolidar es mejor a largo plazo.

Referencias

Implementaciones Existentes:

  • TypeDialog: typedialog/crates/typedialog-ai/
  • Vapora: vapora/crates/vapora-llm-router/
  • Provisioning: provisioning/platform/crates/rag/

Kogral: kogral/

Ubicación Objetivo: stratumiops/crates/stratum-llm/