Saltar al contenido

LLM locales (Ollama, LM Studio)

El endpoint de generación con IA admite un proveedor especial, provider: "local", que dirige el motor a cualquier servidor de chat completions compatible con OpenAI que alojes tú. El servidor sigue haciendo todo el trabajo pesado (renderizado del QR, validación ISO 18004, garantía de escaneo); solo el modelo de lenguaje que propone el diseño vive en tu máquina.

Cuándo usarlo

  • Infraestructuras que priorizan la privacidad. Los prompts nunca salen de tu red camino del LLM. La Signet API solo ve la configuración JSON resultante, no la descripción en lenguaje natural que escribiste.
  • Control de costes. Ya usas Ollama o LM Studio para otras tareas y quieres aprovechar el modelo que has pagado o descargado.
  • Modelos ajustados a medida. Has hecho fine-tuning de un modelo abierto pequeño con prompts de diseño de QR y quieres que Signet lo use.

No encaja bien en estos casos:

  • Llamadas desde servicios SaaS que intentan llegar a localhost en el servidor de la API: la Signet API se ejecuta en Azure Functions y no puede alcanzar tu portátil directamente. Necesitas un túnel público (ver más abajo).
  • Nubes de Ollama alojadas que no controlas: para esas, usa el proveedor nativo correspondiente (openai, groq, etc.).

Configuración

1. Arranca tu servidor local

Ollama:

ollama serve
# in another shell, pull a model
ollama pull llama3.3

Ollama expone de serie una API compatible con OpenAI en http://localhost:11434/v1/chat/completions.

LM Studio:

Carga un modelo en la interfaz gráfica, abre la pestaña «Local Server» y pulsa «Start Server». El endpoint por defecto es http://localhost:1234/v1.

Servidor de vLLM / llama.cpp: ambos exponen /v1/chat/completions de forma nativa. Usa el host y el puerto con los que los hayas arrancado.

2. Haz que tu servidor sea accesible públicamente

Azure Functions no puede llegar a localhost en tu máquina, así que necesitas un túnel. Dos opciones sin configuración:

# ngrok
ngrok http 11434
# → https://your-tunnel.ngrok.io

# Cloudflare Tunnel
cloudflared tunnel --url http://localhost:11434
# → https://random-words.trycloudflare.com

Usa la URL HTTPS pública resultante como localEndpoint. La API rechaza las IP RFC1918 y de enlace local (10.x, 172.16-31.x, 192.168.x, 169.254.x) para evitar SSRF: solo acepta direcciones públicas o localhost (para el desarrollo local de la propia API).

3. Llama a la API

curl -X POST https://signetqr-core.azurewebsites.net/api/qr/ai/generate \
  -H "Content-Type: application/json" \
  -H "X-RapidAPI-Proxy-Secret: $RAPIDAPI_PROXY_SECRET" \
  -d '{
    "provider": "local",
    "localEndpoint": "https://your-tunnel.ngrok.io/v1",
    "model": "llama3.3",
    "apiKey": "ollama",
    "prompt": "Tech startup QR, neon cyan and magenta on near-black, hexagonal modules with subtle glow",
    "content": "https://example.com"
  }'

Notas:

  • El validador exige el campo apiKey, pero su valor da igual en la mayoría de los servidores locales. Ollama acepta cualquier cadena no vacía; por convención, pasa "ollama". LM Studio también lo ignora salvo que hayas configurado expresamente una clave de API.
  • model es obligatorio con el proveedor local: no hay valor por defecto en el servidor. Pasa exactamente el nombre de modelo que expone tu servidor (llama3.3, qwen2.5:14b, mistral, etc.).
  • localEndpoint puede ser la URL base (https://host/v1) o la ruta completa (https://host/v1/chat/completions): la API normaliza ambas.
  • El modo JSON (response_format: { type: "json_object" }) no se reenvía a los servidores locales. Algunos entornos no lo admiten y darían error. El prompt de sistema es lo bastante estricto como para que los modelos que lo cumplen sigan devolviendo JSON limpio. Si tu modelo envuelve el JSON en texto, baja creativity hacia 0.0 o elige un modelo mejor ajustado para seguir instrucciones.

Modos de fallo

SíntomaCausaSolución
400 localEndpoint must be a publicly reachable addressHas pasado una IP 10.x / 192.168.x / 127.0.0.1 desde internetUsa un túnel (ngrok, Cloudflare Tunnel) y pasa la URL pública
400 For provider='local' the 'llmModel' field is requiredSe te ha olvidado modelPon en model el nombre que exponga tu servidor local
500 AI generated an invalid configurationEl modelo local ha devuelto JSON mal formadoPrueba un modelo más potente (≥ 7B parámetros) o baja creativity
502 / connection refused del servicio de IAEl túnel se ha caído o el servidor no está en marchaReinicia ollama serve y vuelve a lanzar cloudflared tunnel

Notas de seguridad

  • La Signet API nunca registra el contenido de localEndpoint ni de apiKey. Sí registra el nombre del proveedor (local) y el identificador del modelo para la telemetría de facturación.
  • Trata la URL de tu túnel como un secreto del mismo nivel que una clave de API: cualquiera que la tenga puede usar tu modelo local en tu hardware.
  • En infraestructuras de producción donde la garantía de privacidad importa, prefiere Cloudflare Tunnel a ngrok: las URL de ngrok se pueden adivinar y el nivel gratuito no tiene autenticación.