typestrict.aidocs

Ejecútalo donde quieras

Tu modelo como un contenedor que responde como Jev, en Docker, Cloud Run, AWS Lambda, Firebase y Kubernetes.

Próximamente

El contenedor está en construcción; hoy un modelo se descarga como ONNX, pesos y paquete. Esta página es su especificación. El runtime de servicio es open source (Apache-2.0).

Cada modelo también se entrega como imagen de contenedor: el modelo, un runtime de CPU (ONNX Runtime) y un servidor HTTP, sin nada que configurar. Habla la misma API de decisión que Jev, así que pasar de Jev a tu propio modelo es cambiar una URL base.

EndpointQué hace
POST /v1/systemoneResponde preguntas sobre un texto, en el formato de solicitud y respuesta de Jev.
GET /v1/modelsEl modelo que contiene, por nombre.
GET /healthzok cuando está listo, para health checks.
VariablePor defectoQué hace
PORT8080El puerto en el que escucha (Cloud Run y Lambda lo definen).
TYPESTRICT_TOKENningunoSi está definida, cada solicitud debe llevar Authorization: Bearer <token>. Prefiere la autenticación propia de tu plataforma (Cloud Run IAM, Lambda IAM) cuando la tengas.

Sin GPU, sin acceso a internet y sin llamadas a nosotros: las solicitudes y los datos se quedan en tu infraestructura.

Docker

typestrict pull <model> --container          # o: docker load -i <model>.tar (enlace de descarga en la página del modelo)
docker run -p 8080:8080 typestrict/<model>
curl http://localhost:8080/v1/systemone -H "Content-Type: application/json" -d '{
  "model": "ticket-router",
  "state": "Me cobraron dos veces. Por favor, ayúdenme.",
  "questions": {
    "team": {
      "type": "choice",
      "instructions": "¿Qué equipo atiende el ticket?",
      "criteria": { "billing": "Pagos y facturas", "support": "Todo lo demás" }
    }
  }
}'
# una respuesta se ve así:
# { "model": "ticket-router", "answers": { "team": { "type": "choice", "choice": "billing", "confidence": 0.97,
#   "probabilities": { "billing": 0.97, "support": 0.03 } } }, "usage": { "input_tokens": 41, "output_tokens": 0 } }

Google Cloud Run

Cloud Run ejecuta imágenes de Artifact Registry. Copia la imagen allí y luego despliega:

typestrict pull <model> --to us-docker.pkg.dev/<project>/<repo>/ticket-router
gcloud run deploy ticket-router \
  --image us-docker.pkg.dev/<project>/<repo>/ticket-router \
  --region us-central1 --cpu 1 --memory 1Gi \
  --no-allow-unauthenticated

--no-allow-unauthenticated lo mantiene privado: quienes llaman necesitan un token de identidad de una cuenta de servicio con el rol roles/run.invoker. Define --min-instances 1 si la primera solicitud después de un periodo sin tráfico debe ser rápida.

AWS Lambda

La imagen incluye el AWS Lambda Web Adapter, así que la misma imagen corre en Lambda sin cambios. Lambda ejecuta imágenes de ECR en la misma cuenta y región:

typestrict pull <model> --to <account>.dkr.ecr.us-east-1.amazonaws.com/ticket-router
aws lambda create-function --function-name ticket-router \
  --package-type Image \
  --code ImageUri=<account>.dkr.ecr.us-east-1.amazonaws.com/ticket-router:latest \
  --role arn:aws:iam::<account>:role/<lambda-role> \
  --memory-size 2048 --timeout 30
aws lambda create-function-url-config --function-name ticket-router --auth-type AWS_IAM

En Lambda, la CPU crece con la memoria: 2 GB es un buen punto de partida. La primera solicitud después de un arranque en frío carga el modelo.

Firebase

Firebase Functions no ejecuta imágenes propias, así que el modelo corre en Cloud Run (arriba) y Firebase llega hasta él:

  • Hosting: dirige una ruta directo al servicio de Cloud Run con un rewrite en firebase.json:

    { "hosting": { "rewrites": [{ "source": "/api/decide", "run": { "serviceId": "ticket-router", "region": "us-central1" } }] } }
  • Functions: llama al servicio de Cloud Run desde tu función con un token de identidad, como a cualquier otra API HTTP.

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata: { name: ticket-router }
spec:
  replicas: 2
  selector: { matchLabels: { app: ticket-router } }
  template:
    metadata: { labels: { app: ticket-router } }
    spec:
      containers:
        - name: model
          image: <your-registry>/ticket-router
          ports: [{ containerPort: 8080 }]
          resources: { requests: { cpu: "1", memory: 1Gi }, limits: { memory: 2Gi } }
          readinessProbe: { httpGet: { path: /healthz, port: 8080 } }
          livenessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 30 }
---
apiVersion: v1
kind: Service
metadata: { name: ticket-router }
spec:
  selector: { app: ticket-router }
  ports: [{ port: 80, targetPort: 8080 }]

El modelo no guarda estado, así que escala horizontalmente con réplicas (o con un HorizontalPodAutoscaler por CPU).

En esta página