Ir al contenido
angel.library

Jev: primitivas (Choice, Score, Noul) y API HTTP

TypeSafe expone tres primitivas de IA. Como las primitivas de un lenguaje, son modulares y componibles: cada una hace un tipo de pregunta y devuelve un tipo de respuesta. Las tres se pueden mezclar en la misma llamada.

PrimitivaObjetivoDevuelve
ChoiceElegir una opción de una listachoice, probabilities, confidence
ScorePuntuar el estado en una rúbrica ordenadascore, probabilities, confidence, legend
Noul¿Es cierta esta afirmación?noul (0–1)
POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <API_KEY>
Content-Type: application/json
Ventana de terminal
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Llevo 3 días intentando conectar Stripe y la integración falla. Estoy perdiendo ventas.",
"model": "jev-latest",
"questions": {
"urgency": { "type": "noul", "instructions": "Does this message express urgency?" }
}
}'
CampoTipoObligatorioQué es
statestring | object | arraySíEl contenido a evaluar
modelstringSíjev-latest, jev-preview o un ID versionado como jev-1.13.0
questionsmap<string, Question>SíPreguntas con la clave que tú elijas

La clave de cada pregunta (urgency, department…) no se envía al modelo ni influye en la inferencia: solo sirve para leer la respuesta.

FormatoÚtil paraEjemplo
StringUn mensaje o pasaje"Me cobraron dos veces."
ObjetoCampos con nombre, registros relacionados, estado de la app{"message": "...", "order_id": "A-104"}
ArraySecuencia de mensajes o registros["Hola", "Mi cliente es TS1337", "Me cobraron dos veces"]

Usa un objeto casi siempre: cada parte tiene nombre y las preguntas pueden referirse a ella. Pon junto todo lo que la decisión necesita comparar (conversación, pedido y política de reembolsos en un mismo estado). El estado lleva el contenido; las preguntas, los juicios.

Devuelve la probabilidad de que la respuesta sea sí.

CampoTipoObligatorio
type"noul"Sí
instructionsstring | object | arraySí
criteria{ "true"?: ..., "false"?: ... }No
{
"is_urgent": {
"type": "noul",
"instructions": "Does this convey urgency?",
"criteria": {
"true": "Explicitly time-sensitive",
"false": "No urgency expressed"
}
}
}
{ "is_urgent": { "type": "noul", "noul": 0.95 } }

Noul no trae confidence: la probabilidad ya es la señal. El umbral lo decides tú según el riesgo.

CampoTipoObligatorio
type"choice"Sí
instructionsstring | object | arraySí
criteriamap<opción, descripción | null>Sí — máximo 255 opciones
{
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"
}
}
}
{
"department": {
"type": "choice",
"choice": "billing",
"probabilities": { "billing": 0.88, "technical": 0.12, "sales": 0.0 },
"confidence": 0.81
}
}

choice es la opción más probable; probabilities suma 1. Usa null cuando la opción se explica sola por su nombre.

CampoTipoObligatorio
type"score"Sí
instructionsstring | object | arraySí
criteriaarray ordenado de nivelesSí — mínimo 2, la API acepta hasta 10
{
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}
}
{
"frustration": {
"type": "score",
"score": 1.05,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.0, "1": 0.95, "2": 0.05 },
"confidence": 0.92
}
}

score es la media ponderada por probabilidad y puede caer entre niveles (1,05). Los niveles empiezan en 0; legend los traduce a su descripción. Úsalo para comparar contra un umbral, no para calcular magnitudes exactas entre niveles.

{
"model": "jev-1.13.0",
"answers": {
"department": { "type": "choice", "choice": "technical", "confidence": 0.78,
"probabilities": { "technical": 0.85, "sales": 0.0, "billing": 0.15 } },
"frustration": { "type": "score", "score": 1.0, "confidence": 1.0,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.0, "1": 1.0, "2": 0.0 } },
"is_urgent": { "type": "noul", "noul": 1.0 }
},
"usage": { "input_tokens": 392, "output_tokens": 65 }
}

model informa el ID versionado que respondió aunque pidieras un alias: regístralo junto a cada decisión.

instructions, las opciones de Choice, los niveles de Score y los criterios de Noul aceptan JSON. Para una pregunta con datos de referencia, pon la pregunta en un campo y los datos en otros, y nómbralos entre comillas invertidas:

"instructions": {
"potential_duplicate": {
"name": "John Smith",
"location": "Oakland, California",
"last_employer": "Google"
},
"question": "Is the resume for the same person as `potential_duplicate`?"
}

Así la pregunta queda corta y el modelo sabe exactamente a qué parte del estado o de las instrucciones se refiere.

Todas las preguntas ven el mismo estado, se evalúan en paralelo y aisladas, y la respuesta llega en una sola respuesta. El estado se procesa una vez, así que agrupar preguntas abarata y acelera: en el cookbook de preguntas en paralelo de TypeSafe, 13 preguntas en una llamada fueron 12,2× más baratas y 10× más rápidas que por separado, con las mismas respuestas.

El presupuesto de contexto: 64k tokens para estado + todas las preguntas; 32k para estado + la pregunta más larga.

CódigoSignificado
401 UnauthorizedFalta la API key o es inválida
422 Unprocessable EntityEl cuerpo no pasa la validación (campo obligatorio ausente, pregunta mal formada); el cuerpo indica el campo
429 Too Many RequestsSuperaste el rate limit; reintenta con backoff y respeta retry-after si viene

Los SDK oficiales reintentan con backoff por defecto.

Ventana de terminal
curl https://api.typesafe.ai/v1/models -H "Authorization: Bearer $TYPESAFE_API_KEY"

Devuelve models[] con name, description y release_date. Hoy lista los alias; los IDs versionados se aceptan aunque no aparezcan.