Pipeline completo
Section titled “Pipeline completo”Prometheus API ─┐LM Studio API ─┤ ├── SensorFusionEngine ──→ RuntimeSensorFusionSnapshotGateway state ─┘ │ ┌─────┴──────┐ │ │ observed derived data state │ │ └─────┬──────┘ │ domain_confidence │ evidence_catalog │ OperationalSummary │ OBSERVED_RUNTIME (≤16KB) │ LLM (qwen2.5-14b) │ Evidence Guard (post-hoc) │ Response al clienteEtapa 1: Adquisición
Section titled “Etapa 1: Adquisición”PrometheusQueryClient
Section titled “PrometheusQueryClient”class PrometheusQueryClient: def query_instant(self, query: str) -> float | None def get_target_up(self, job: str) -> dict def query_gpu_metrics(self, host: str) -> dict def get_freshness(self, source: str) -> float- Timeout: 2s por query
- Cache: TTL 5s por source
- Fallback: None (nunca lanza excepción)
- GPU detection: dinámica desde target labels
LM Studio API
Section titled “LM Studio API”class LmStudioClient: def get_models(self) -> list[dict]- Endpoint:
GET /v1/models - Timeout: 3s
- Fallback: lista vacía + freshness label
Etapa 2: Fusión
Section titled “Etapa 2: Fusión”SensorFusionEngine
Section titled “SensorFusionEngine”class SensorFusionEngine: def collect(self) -> RuntimeSensorFusionSnapshotEl método collect():
- Consulta Prometheus para cada uno de los 13 dominios
- Clasifica targets UP/DOWN
- Descubre métricas GPU dinámicamente
- Obtiene modelos de LM Studio
- Separa observed_data de derived_state
- Calcula domain_confidence per-domain
- Clasifica topología
- Construye evidence_catalog
RuntimeSensorFusionSnapshot
Section titled “RuntimeSensorFusionSnapshot”@dataclassclass RuntimeSensorFusionSnapshot: observed_data: dict # Datos crudos por dominio derived_state: dict # Inferencias del runtime domain_confidence: dict # Confidence por dominio topology: RuntimeTopologyState # Topología derivada evidence_catalog: dict # Catálogo de evidencia observed_sources: list[str] # Fuentes observadas missing_sources: list[str] # Fuentes no disponibles expected_offline_targets: list[dict] # Targets offline esperados unexpected_down_targets: list[dict] # Targets caídos inesperados last_scrape_seconds_ago: dict[str, float] # Freshness labelsEtapa 3: Resumen
Section titled “Etapa 3: Resumen”OperationalSummaryBuilder
Section titled “OperationalSummaryBuilder”Construye resúmenes route-family-aware. Cada ruta recibe solo la información que necesita:
| Ruta | GPU | Routing | SLO | Storage | Identity |
|---|---|---|---|---|---|
| minimal | ✅ | ❌ | ❌ | ❌ | ❌ |
| report | ✅ | ✅ | ✅ | ✅ | ✅ |
| cognitive | ✅ | ✅ | ✅ | ❌ | ✅ |
Ejemplo de summary para ruta report:
=== GPU ===RX9070: 16GB VRAM, 0% load, 32°C, 49W, fan 950RPMRX7900XT: 20GB VRAM, offline (inventory)
=== ROUTING ===Mode: stream-aware sanitizedDefault: qwen2.5-coder-14b-instructGreeting fastpath: llama-3.1-8b-instructRoute tightening: active (29.3.1)
=== SLO ===State: GREEN, Degradation: NORMALTTFB p50: 804ms, Success: 99.2%
=== STORAGE ===Snapshots: /opt/ai-lab/runtime/state/
=== IDENTITY ===Runtime: ai-lab-openai-gatewayHost: ubuntu-ialab (192.168.1.30)Prometheus: 192.168.1.40:9090Inference: 192.168.1.50:1234Etapa 4: Inyección
Section titled “Etapa 4: Inyección”OBSERVED_RUNTIME
Section titled “OBSERVED_RUNTIME”El snapshot se inyecta en el system prompt del LLM como JSON. Límite: 16 KB.
{ "observed_data": { "...": "..." }, "derived_state": { "...": "..." }, "domain_confidence": { "...": "..." }, "runtime_topology": { "...": "..." }, "evidence_catalog": { "...": "..." }, "operational_summary": { "...": "..." }}Etapa 5: Sanitización
Section titled “Etapa 5: Sanitización”Evidence Guard (FASE 30H)
Section titled “Evidence Guard (FASE 30H)”Post-hoc scanning de la respuesta del LLM contra el evidence_catalog:
- Detecta afirmaciones no verificadas
- Compara contra denylists (PROHIBITED_MODELS, UNOBSERVED_GPUS, etc.)
- Calcula hallucination_risk score
- Añade [EVIDENCE GUARD] section si es necesario
Métricas del pipeline
Section titled “Métricas del pipeline”flowchart LR
subgraph Métricas
ST[ailab_sensor_fusion_total]
SD[ailab_sensor_fusion_duration_ms]
SM[ailab_sensor_fusion_missing_source_total]
OS[ailab_observed_runtime_context_size_bytes]
EG[ailab_report_evidence_guard_total]
EU[ailab_report_unverified_claim_total]
ES[ailab_report_evidence_score]
EH[ailab_report_hallucination_suppressed_total]
end
SF[SensorFusion] --> ST
SF --> SD
SF --> SM
SF --> OS
EG[Evidence Guard] --> EG
EG --> EU
EG --> ES
EG --> EH