Files
forja/ARCHITECTURE.md
2026-06-10 18:21:33 +02:00

3.8 KiB

Forja — Arquitectura técnica

Documento vivo con las decisiones técnicas.

Visión general

Forja es un único servicio FastAPI (:8000):

  • Todo el dominio de gobierno, runtime LangGraph, guardrails y persistencia.
  • UI embebida (HTMX) para uso humano + API REST completa bajo /api.

Diagrama

┌────────────────────────────────────────────────────────────┐
│                     forja-core :8000                        │
│  UI HTMX (humanos)  +  REST API (/api)  +  dominio completo │
│                                                             │
│   LLM (strategy)  │  Guardrails (strategy)  │  LangGraph    │
│                   │                         │  + checkpoints│
└────────────────────────────────────────────────────────────┘

Patrones aplicados

  • Strategy / Plugin: LLMProvider, GuardrailEngine, AgentRegistry, PolicyStore son Protocols con varias implementaciones intercambiables vía factory que lee Settings.
  • Configuration over code: agentes y políticas como YAML versionados; cambios sin redeploy.
  • Fail-closed por defecto: errores en validadores cuentan como bloqueo.
  • Trazabilidad obligatoria: trace_id UUID propagado por middleware → structlog → API → JSONL.

Persistencia

Capa Tecnología Por qué
Registries (agents/policies/datasets/models) YAML por versión + index.yaml Humano lo escribe; diff legible; hash SHA-256 normalizado. Base común en registry/yaml_store.py.
Logs de violaciones JSONL append-only Inmutable, auditable, fácil de shipear.
Logs de ejecuciones JSONL append-only Idem.
Checkpoints LangGraph SQLite Tool right; persistencia entre restarts (HITL).
Training runs / evaluaciones / promociones JSON por entidad bajo data/ Estado mutable consultable por id; los registros de promoción aprobada van además a JSONL append-only.

Ciclo MLOps (training → evaluación → promoción)

  1. POST /api/training/runs envía un job al backend configurado (TRAINING_BACKEND=mock|azure_ml) con dataset, modelo base y, opcionalmente, el agente y su versión candidata.
  2. POST /api/training/runs/{id}/evaluate ejecuta los escenarios canónicos (agents/<name>/examples/*.txt) contra la versión candidata por el runtime gobernado completo; pasa si no hay violaciones bloqueantes ni fallos.
  3. POST /api/promotions crea la petición; exige run succeeded, evaluación passed y que la evaluación cubra exactamente la versión a promocionar.
  4. Un operador aprueba/rechaza (UI /promotions); al aprobar, la versión pasa a active en el registry y queda un registro de auditoría append-only.

HITL — Patrón

Se usa la API dinámica interrupt(payload) de LangGraph ≥0.2 dentro del nodo approve_gate. Sólo pausa cuando hay acciones de alto riesgo (risk_score >= threshold o requires_approval=True). El cliente envía Command(resume={"approved_action_ids": [...]}) vía POST /api/executions/{trace_id}/approve.

Observabilidad

  • structlog con renderer JSON.
  • Middleware FastAPI inyecta X-Trace-Id y bind-ea contexto.
  • Cada nodo del grafo añade un step a decision_path con duration_ms.

Errores

  • Azure OpenAI / OpenAI: retry exponencial 1s/2s/4s; si LLM_FALLBACK_PROVIDER está configurado, FallbackLLMProvider delega en el secundario; luego status=failed.
  • Validador: fail_closed por defecto.
  • Schema mismatch en LLM output: 1 retry, luego failed.
  • Checkpoint corrupto: 500 explícito (sin auto-recovery).

Decisiones pospuestas

Ver docs/futuro.md.