Volver a la wiki

OpenRouter Driver — servicio de análisis de planos vía LLM

Descripción

blueprints/services/openrouter_driver.py es el driver que conecta el pipeline Auto-Plan con la API de OpenRouter para analizar imágenes de planos de sala mediante modelos LLM multimodales (por defecto google/gemma-4-26b-a4b-it vía Vertex AI).

Expone una función pública:

def analyze_blueprint(api_key: str, file_path: str, prompt: str) -> dict[str, Any]

Esta función es invocada por AutoPlanService como backend LLM cuando el proveedor configurado es OpenRouter (en contraposición a Ollama o DeepSeek self-hosted).


Flujo de ejecución

analyze_blueprint(api_key, file_path, prompt)
  │
  ├─ Carga imagen → base64 JPEG
  ├─ Lee configuración de env (MODEL, SEED, PROVIDER_ORDER, ALLOW_FALLBACKS, …)
  ├─ Construye create_kwargs (max_tokens=16384, response_format=json_object)
  │
  └─ Bucle de retries (max 2 por JSONDecodeError):
       ├─ effective_seed = base_seed + json_attempt
       ├─ client.chat.completions.create(**create_kwargs)
       ├─ Log diagnóstico (provider, model, seed, tokens, cost, finish_reason)
       ├─ AutoPlanService._clean_llm_json_basic(text_response)
       │    └─ json.loads → OK → return
       └─ AutoPlanService._clean_llm_json_aggressive(cleaned_basic)
            └─ json.loads → OK → return
                   └─ JSONDecodeError → continue (retry) / raise (último intento)

Configuración (variables de entorno)

VariableDefaultDescripción
OPENROUTER_API_KEY—API key de OpenRouter (obligatorio)
OPENROUTER_MODELgoogle/gemma-4-26b-a4b-itModelo a usar
OPENROUTER_PROVIDER_ORDER—Lista de providers separada por comas (Vertex AI,Fireworks)
OPENROUTER_SEED—Semilla base para reproducibilidad. Preservada entre retries desde PR#19
OPENROUTER_IMAGE_DETAILautoNivel de detalle de imagen (auto, high, low)
OPENROUTER_ALLOW_FALLBACKSfalseSi true, OpenRouter puede redirigir a otro provider silenciosamente

⚠️ OPENROUTER_ALLOW_FALLBACKS es false por defecto desde PR#19 (s49 audit C2). Cambiar a true solo si el provider primario tiene saturación frecuente y se acepta la pérdida de reproducibilidad.


Parámetros OpenRouter extras

Desde PR#19, el extra_body enviado a la API incluye:

{
    "top_k": 64,
    "provider": {
        "order": provider_order,         # lista de providers preferidos
        "allow_fallbacks": allow_fallbacks,  # False por defecto
        "require_parameters": True,      # rechaza providers sin soporte seed/top_k
    }
}

require_parameters: True garantiza que si el provider seleccionado no soporta seed o top_k, OpenRouter devuelve error explícito en lugar de ignorarlos silenciosamente.


Manejo de retries y seeds (PR#19 — s49 C1)

json_attempt=0: effective_seed = base_seed + 0 = base_seed
json_attempt=1: effective_seed = base_seed + 1
json_attempt=2: effective_seed = base_seed + 2

El base_seed nunca se modifica. Si no hay seed configurado, effective_seed = None y la clave seed se elimina de create_kwargs para no enviar null.


Log diagnóstico

Cada llamada loggea a nivel INFO:

[AutoPlan] OpenRouter served by <provider> (retry N) | model=<model> | seed=<N> |
tokens: <P>p+<C>c (cached=<K>) | cost=$<X.XXXXXX> | finish=<reason> | response=<N> chars

Si finish_reason == "length", se emite un WARNING adicional indicando truncamiento por max_tokens.

El bloque de log está envuelto en try/except Exception para no enmascarar errores de parsing si la respuesta tiene formato inesperado.


Relación con AutoPlanService

ResponsabilidadMódulo
Llamada a API OpenRouteropenrouter_driver.py
Cleanup JSON (basic/aggressive)autoplan.py → AutoPlanService
Coordinación de retriesopenrouter_driver.py
Coordinación de providers (Ollama, DeepSeek)autoplan.py → AutoPlanService

Historial de cambios relevantes

PRDescripción
PR#19 (s49 C1)base_seed preservado; effective_seed = base_seed + attempt explícito; seed en log siempre
PR#19 (s49 C2)allow_fallbacks=False por defecto; require_parameters=True; log defensivo; lectura provider robusta
PR#19 (s49 C3)Cleanup en cascada: _clean_llm_json_basic → _clean_llm_json_aggressive desde el driver
s46Primera detección de glitches JSON en outputs Gemma 4 >70 elementos (plano 70)

Véase también

Subir