Documentación

Score

Un Score es un tipo de pregunta de System One para puntuar contenido según niveles ordenados y descriptivos. La respuesta incluye una puntuación, una probabilidad para cada nivel y la confianza.

Usa un Score cuando la respuesta sea una posición en un espectro que puedas describir por pasos. Por ejemplo, cuán grave es un error, cuán contento está un cliente o cuánta experiencia tiene un candidato con Python. Si la respuesta es una de un conjunto fijo de opciones sin orden entre ellas, usa un Choice. Si es un sí o un no, usa un Noul. Elige un tipo de pregunta compara los tres.

Una respuesta de Score es una posición a lo largo de tus niveles en score, que puede caer entre dos niveles. El modelo también devuelve una probabilidad para cada nivel en probabilities y un valor de confidence para la respuesta.

Ejemplo de pregunta score

How severe is the reported issue?

0 Cosmetic; no impact to functionality
1 Broken or degraded feature, but workaround exists
2 Blocking issue; no workaround exists

Estado (el material a evaluar)

The export button crashes the settings page in Safari. It works in Chrome, but a few of our customers only use Safari.

Respuesta

Probabilidad de cada nivel

Confianza

0.35

Puntuación: 1.43

Cómo se calculan la puntuación y la confianza

Puntuación:

Multiplica el número de cada nivel por su probabilidad y suma:

0 × 0 + 1 × 0.57 + 2 × 0.43 ≈ 1.43

Confianza

TypeSafe la calcula a partir de cuán repartida está la probabilidad entre los niveles. Si todo se concentra en uno, es 1.0; cuanto más uniforme sea, más baja.

How formal is this outfit based on the description?

0 gym clothes
1 casual
2 business casual
3 formal
4 black tie

Estado (el material a evaluar)

A navy blazer over a plain white T-shirt, dark jeans, and clean leather loafers. No tie.

Respuesta

Probabilidad de cada nivel

Confianza

0.89

Puntuación: 1.86

Cómo se calculan la puntuación y la confianza

Puntuación:

Multiplica el número de cada nivel por su probabilidad y suma:

0 × 0 + 1 × 0.14 + 2 × 0.86 + 3 × 0 + 4 × 0 ≈ 1.86

Confianza

TypeSafe la calcula a partir de cuán repartida está la probabilidad entre los niveles. Si todo se concentra en uno, es 1.0; cuanto más uniforme sea, más baja.

How relevant is this candidate's experience to the job posting?

0 completely unrelated
1 adjacent field
2 some direct experience
3 deep, direct experience

Estado (el material a evaluar)

Job posting: Senior backend engineer building Python APIs and PostgreSQL services. Candidate: Three years building Django REST APIs with PostgreSQL, preceded by two years in frontend JavaScript. Has owned small services but has not led a backend team.

Respuesta

Probabilidad de cada nivel

Confianza

0.52

Puntuación: 2.52

Cómo se calculan la puntuación y la confianza

Puntuación:

Multiplica el número de cada nivel por su probabilidad y suma:

0 × 0 + 1 × 0 + 2 × 0.48 + 3 × 0.52 ≈ 2.52

Confianza

TypeSafe la calcula a partir de cuán repartida está la probabilidad entre los niveles. Si todo se concentra en uno, es 1.0; cuanto más uniforme sea, más baja.

How frustrated is the customer?

0 Calm, just stating facts
1 Frustrated but civil
2 Very angry, strong language or threatening to leave

Estado (el material a evaluar)

Export to PDF fails with a spinner that never finishes. Some of our team say CSV export still works for them, others say it fails too. This is the third time I'm writing in and honestly I'm done. Steps: open any report, click Export, choose PDF. Chrome 128 on macOS.

Respuesta

Probabilidad de cada nivel

Confianza

0.61

Puntuación: 1.26

Cómo se calculan la puntuación y la confianza

Puntuación:

Multiplica el número de cada nivel por su probabilidad y suma:

0 × 0 + 1 × 0.74 + 2 × 0.26 ≈ 1.26

Confianza

TypeSafe la calcula a partir de cuán repartida está la probabilidad entre los niveles. Si todo se concentra en uno, es 1.0; cuanto más uniforme sea, más baja.

How much does the report give an engineer to work with?

0 No detail; just says something is broken
1 Names the feature but no steps or environment
2 Steps to reproduce or environment, but not both
3 Steps to reproduce and environment

Estado (el material a evaluar)

Export to PDF fails with a spinner that never finishes. Some of our team say CSV export still works for them, others say it fails too. This is the third time I'm writing in and honestly I'm done. Steps: open any report, click Export, choose PDF. Chrome 128 on macOS.

Respuesta

Probabilidad de cada nivel

Confianza

1.00

Puntuación: 3.00

Cómo se calculan la puntuación y la confianza

Puntuación:

Multiplica el número de cada nivel por su probabilidad y suma:

0 × 0 + 1 × 0 + 2 × 0 + 3 × 1 ≈ 3.00

Confianza

TypeSafe la calcula a partir de cuán repartida está la probabilidad entre los niveles. Si todo se concentra en uno, es 1.0; cuanto más uniforme sea, más baja.

Los números delante de cada paso son posiciones, explicadas en Niveles.

Estructura de la solicitud

El cuerpo de la solicitud POST a la API de TypeSafe tiene los mismos tres campos de nivel superior que cualquier otro tipo de pregunta: state, que es el contenido que se evalúa; model; y questions. Cada pregunta Score tiene los siguientes campos:

  • type: Siempre "score".
  • instructions: La pregunta que responde el modelo. Lo que se está puntuando.
  • criteria: Un array ordenado de descripciones de nivel, del extremo bajo de la escala al alto. Debe tener al menos dos niveles; la API acepta hasta 10.

Abajo hay una solicitud en la que el estado es un informe de error y la pregunta es cuán grave es el error:

request
{
  "state": "The export button crashes the settings page in Safari. It works in Chrome, but a few of our customers only use Safari.",
  "questions": {
    "bug_severity": {
      "type": "score",
      "instructions": "How severe is the reported issue?",
      "criteria": [
        "Cosmetic; no impact to functionality",
        "Broken or degraded feature, but workaround exists",
        "Blocking issue; no workaround exists"
      ]
    }
  }
}

Tú eliges el id de la pregunta, bug_severity en este caso. Este id no se envía al modelo. La respuesta se devuelve bajo el mismo id.

Niveles

Cada entrada de criteria es un nivel: un punto del espectro de respuestas posibles, descrito con palabras. El número de un nivel es su posición en el array criteria, empezando por 0, así que las tres entradas de arriba son los niveles 0, 1 y 2. El orden del array es la numeración.

El modelo recibe las descripciones y nada más, y cada nivel se juzga por sí solo contra el estado.

El score de la respuesta es una posición en el espectro de niveles. Para una escala de tres niveles va de 0 a 2, y puede caer entre dos niveles.

Nuestros SDK de cliente ofrecen preguntas con tipo. En Python, la misma pregunta es un Score:

from typesafe_sdk import Score, TypeSafeClient

with TypeSafeClient() as client:
    response = client.system_one(
        state="The export button crashes the settings page in Safari. It works in Chrome, but a few of our customers only use Safari.",
        questions={
            "bug_severity": Score(
                instructions="How severe is the reported issue?",
                criteria=[
                    "Cosmetic; no impact to functionality",
                    "Broken or degraded feature, but workaround exists",
                    "Blocking issue; no workaround exists",
                ],
            ),
        },
    )

    print(response.answers["bug_severity"].score)

Usa el método system_one o el endpoint https://api.typesafe.ai/v1/systemone para llamar a un modelo System One. El campo model selecciona qué modelo gestiona la solicitud. Cómo construir con TypeSafe explica en qué parte de tu código llamarlo.

Usa uno de nuestros SDK de cliente o llama directamente a la API de TypeSafe. Si un agente de programación está escribiendo la integración por ti, instala primero la habilidad de agente de TypeSafe para que conozca las formas de la solicitud y la respuesta.

Estructura de la respuesta

La respuesta tiene una entrada en answers por cada pregunta, bajo los id de la solicitud. Esta es la respuesta a la solicitud de ejemplo de arriba:

{
  "model": "jev-1.13.0",
  "answers": {
    "bug_severity": {
      "type": "score",
      "score": 1.43,
      "confidence": 0.35,
      "legend": {
        "0": "Cosmetic; no impact to functionality",
        "1": "Broken or degraded feature, but workaround exists",
        "2": "Blocking issue; no workaround exists"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.57,
        "2": 0.43
      }
    }
  },
  "usage": {
    "input_tokens": 332,
    "output_tokens": 18
  }
}

Cada respuesta de Score tiene cinco valores:

  • type: El tipo de pregunta de TypeSafe.
  • probabilities: La probabilidad de cada nivel, con el número de nivel como clave en forma de cadena. La suma de todos los valores es 1.
  • score: La posición en la recta numérica de los niveles, de 0 al número del nivel más alto, que aquí es 2. Es cada número de nivel multiplicado por su probabilidad, sumado: 0 x 0.0 + 1 x 0.57 + 2 x 0.43 = 1.43.
  • legend: Cada número de nivel asignado de nuevo a su descripción.
  • confidence: Un número de 0 a 1 calculado a partir de cómo se reparte probabilities. Un único pico en un nivel significa confianza alta. La probabilidad repartida entre varios niveles significa confianza baja.

Una puntuación de 1.43 significa que el modelo se reparte entre los niveles 1 y 2, inclinándose por el nivel 1. Eso encaja con el informe: la exportación está rota, y pasarse a Chrome es una solución alternativa para la mayoría de los clientes, pero no para los que solo usan Safari. El modelo pone 0.57 en «existe una solución alternativa» y 0.43 en «no hay solución alternativa», y la confianza es 0.35 porque está repartida.

Con el SDK de Python, ScoreAnswer tiene score, confidence, probabilities y legend como campos con tipo. El SDK indexa probabilities y legend por nivel entero en lugar de por cadena.

Leer un Score

Veamos cómo cambia la puntuación con distintas entradas. Por ejemplo, usando la pregunta y sus niveles de la solicitud de arriba:

"How severe is the reported issue?"
  → 0: Cosmetic; no impact to functionality
  → 1: Broken or degraded feature, but workaround exists
  → 2: Blocking issue; no workaround exists

Podemos ver cómo distintos informes de error cambian la puntuación:

probabilities
EstadoscoreconfidenceNivel 0Nivel 1Nivel 2
El botón de exportar está desalineado unos pocos píxeles en la página de ajustes.0.01.01.00.00.0
El botón de exportar a PDF no hace nada al hacer clic. Aún puedo exportar a CSV y convertirlo yo, pero eso tarda muchísimo.1.01.00.01.00.0
La exportación a PDF falla con un indicador de carga que nunca termina. Algunos de nuestro equipo dicen que la exportación a CSV todavía les funciona, otros dicen que también falla.1.110.840.00.890.11
El botón de exportar bloquea la página de ajustes en Safari. Funciona en Chrome, pero unos pocos clientes nuestros solo usan Safari.1.430.350.00.570.43
Nadie de nuestro equipo puede iniciar sesión desde esta mañana. Recibimos un error 500 en cada intento.2.01.00.00.01.0

En estos ejemplos, una confianza de 1.0 significa que la distribución devuelta pone toda su probabilidad en un nivel. Esto describe la respuesta del modelo, no garantiza que la respuesta sea correcta.

La puntuación es una media ponderada por probabilidad de los números de nivel. En el tercer y el cuarto ejemplo, la probabilidad se reparte entre los niveles 1 y 2. Más peso en el nivel 2 eleva la puntuación. No mide la fracción de clientes sin solución alternativa.

Distintas distribuciones pueden producir la misma puntuación. Una puntuación de 1.0 puede significar que toda la probabilidad está en el nivel 1, o que la mitad está en el nivel 0 y la otra mitad en el 2. Lee probabilities y confidence junto con la puntuación para distinguir estos casos.

Una puntuación fraccionaria es una posición. Puedes usarla para ordenar informes por gravedad, o redondearla al nivel más cercano cuando tu código necesite un único resultado. Nuestro cookbook de alineación de entidades muestra un ejemplo de redondeo al nivel más cercano para tomar una decisión.

Una confianza baja en un Score suele significar una de tres cosas. Los niveles se solapan para este estado, la pregunta mide más de una cosa, o el estado no dice lo suficiente para situarlo. Nuestra documentación de Confianza cubre cómo usarla en tu código.

Escribir buenos niveles

Describe situaciones, no grados. «Función rota o degradada, pero existe una solución alternativa» le da al modelo algo con lo que cotejar el estado. «Moderadamente grave» no. Las descripciones concretas pueden ayudar al modelo a distinguir los niveles. Comprueba las respuestas contra ejemplos conocidos; una confianza más alta por sí sola no demuestra que una descripción sea mejor.

Cada nivel se evalúa por separado. El modelo no ve el número de un nivel ni sus vecinos, así que «peor que el nivel anterior» no significa nada para él, y los números en las descripciones o en las instrucciones no ayudan. Esto es lo que ocurre cuando los niveles son solo números, con el informe del botón desalineado de la tabla de arriba:

instructions: "Rate severity from 0 to 2, where 2 is worst"
criteria: ["0", "1", "2"]
→ score 0.55, confidence 0.33, probabilities 0: 0.45, 1: 0.55, 2: 0.0

El mismo informe con los tres niveles descriptivos puntúa 0.0 con una confianza de 1.0. Con solo números, el modelo no tiene nada con lo que cotejar y reparte la probabilidad entre 0 y 1.

Usa tantos niveles como puedas describir de forma distinta, hasta 10. Tres está bien. No añadas niveles que no puedas describir de forma distinta.

Mantén cada pregunta Score en una sola dimensión. Si una descripción dice «puntual, inteligente y con experiencia», la pregunta está midiendo tres cosas, y una entrada que es alta en una y baja en otra no se puede situar. La confianza baja y la puntuación significa menos. Divídela en una pregunta Score por cosa y combínalas en el código, como muestra la siguiente sección.

Si lo más alto de tu escala tiene un caso extremo poco frecuente sobre el que necesites actuar de forma distinta, dale su propio nivel. Una escala de sentimiento que termina en «muy furioso» puede añadir «abusivo o amenazante». Sin ese nivel, ambos mensajes pueden recibir una puntuación cerca de lo más alto. La puntuación por sí sola puede no distinguirlos.

Si no hay nada intermedio en absoluto, y la respuesta es una de unas pocas categorías discretas, usa un Choice en su lugar, o divide la pregunta en varias preguntas Noul. Es importante probar tus niveles con tus propios datos. Dos redacciones de la misma escala pueden comportarse de forma distinta con tus datos.

Dividir un juicio complejo en varias preguntas Score

Un juicio complejo, uno que depende de varias cosas, es mejor dividirlo en una pregunta Score por cosa. Luego puedes combinar en tu código los Scores que devuelve TypeSafe para hacer el juicio. Puede que algunas preguntas Score importen más que otras, así que dale a cada pregunta Score un peso según su importancia relativa. Los pesos son tuyos. Cuando el resultado combinado no coincida con lo que decidiría tu equipo, cámbialos en el código y vuelve a ejecutar. Envía las preguntas Score en una sola solicitud. Se evalúan en paralelo. Añadir preguntas apenas cambia el tiempo de respuesta y cuesta unos pocos tokens de pregunta extra; consulta Haz varias preguntas a la vez.

La solicitud de abajo es el ticket del indicador de carga de la tabla de arriba con algo más de contexto. Hace tres preguntas Score: cuán grave es el error, cuán frustrado está el cliente y cuánta información da el informe a un ingeniero.

request
{
  "state": "Export to PDF fails with a spinner that never finishes. Some of our team say CSV export still works for them, others say it fails too. This is the third time I'm writing in and honestly I'm done. Steps: open any report, click Export, choose PDF. Chrome 128 on macOS.",
  "questions": {
    "severity": {
      "type": "score",
      "instructions": "How severe is the reported issue?",
      "criteria": [
        "Cosmetic; no impact to functionality",
        "Broken or degraded feature, but workaround exists",
        "Blocking issue; no workaround exists"
      ]
    },
    "frustration": {
      "type": "score",
      "instructions": "How frustrated is the customer?",
      "criteria": [
        "Calm, just stating facts",
        "Frustrated but civil",
        "Very angry, strong language or threatening to leave"
      ]
    },
    "report_quality": {
      "type": "score",
      "instructions": "How much does the report give an engineer to work with?",
      "criteria": [
        "No detail; just says something is broken",
        "Names the feature but no steps or environment",
        "Steps to reproduce or environment, but not both",
        "Steps to reproduce and environment"
      ]
    }
  }
}

La respuesta de TypeSafe:

{
  "model": "jev-1.13.0",
  "answers": {
    "severity": {
      "type": "score",
      "score": 1.24,
      "confidence": 0.64,
      "legend": {
        "0": "Cosmetic; no impact to functionality",
        "1": "Broken or degraded feature, but workaround exists",
        "2": "Blocking issue; no workaround exists"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.76,
        "2": 0.24
      }
    },
    "frustration": {
      "type": "score",
      "score": 1.28,
      "confidence": 0.58,
      "legend": {
        "0": "Calm, just stating facts",
        "1": "Frustrated but civil",
        "2": "Very angry, strong language or threatening to leave"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.72,
        "2": 0.28
      }
    },
    "report_quality": {
      "type": "score",
      "score": 3.0,
      "confidence": 1.0,
      "legend": {
        "0": "No detail; just says something is broken",
        "1": "Names the feature but no steps or environment",
        "2": "Steps to reproduce or environment, but not both",
        "3": "Steps to reproduce and environment"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.0,
        "2": 0.0,
        "3": 1.0
      }
    }
  },
  "usage": {
    "input_tokens": 468,
    "output_tokens": 43
  }
}

Cada pregunta se responde por sí sola contra el ticket y recibe una puntuación:

  • severity es 1.24 con una confianza de 0.64. La misma lectura que el ejemplo inicial: la exportación está rota y algunos tienen una solución alternativa.
  • frustration es 1.28 con una confianza de 0.58. Las palabras son cordiales, pero «tercera vez» y «ya está» desplazan parte de la puntuación hacia el nivel más alto, así que el modelo reparte 0.72 y 0.28 entre «frustrado pero cordial» y «muy furioso». Para este ticket los dos niveles se solapan, y por eso la confianza es moderada.
  • report_quality es 3.0 con una confianza de 1.0. Se indican tanto los pasos como la versión del navegador.

Las tres escalas tienen longitudes distintas, así que antes de combinarlas, normaliza cada puntuación. Una escala de cuatro niveles devuelve de 0 a 3 y una de tres niveles devuelve de 0 a 2, así que la puntuación máxima en una es mayor que en la otra. Divide cada puntuación por el número de su nivel más alto, len(criteria) - 1, para poner todas las puntuaciones entre 0 y 1. Entonces los pesos significan lo que dicen: 0.6 en severity y 0.3 en frustration hacen que severity cuente el doble.

El código del SDK de Python de TypeSafe de abajo hace las tres preguntas, normaliza cada puntuación y las combina usando un cálculo de prioridad de ejemplo:

from typesafe_sdk import Score, TypeSafeClient

TRIAGE_QUESTIONS = {
    "severity": Score(
        instructions="How severe is the reported issue?",
        criteria=[
            "Cosmetic; no impact to functionality",
            "Broken or degraded feature, but workaround exists",
            "Blocking issue; no workaround exists",
        ],
    ),
    "frustration": Score(
        instructions="How frustrated is the customer?",
        criteria=[
            "Calm, just stating facts",
            "Frustrated but civil",
            "Very angry, strong language or threatening to leave",
        ],
    ),
    "report_quality": Score(
        instructions="How much does the report give an engineer to work with?",
        criteria=[
            "No detail; just says something is broken",
            "Names the feature but no steps or environment",
            "Steps to reproduce or environment, but not both",
            "Steps to reproduce and environment",
        ],
    ),
}

def normalized(answers, question_id: str) -> float:
    """Put a score on 0 to 1 by dividing by its top level number."""
    top_level = len(TRIAGE_QUESTIONS[question_id].criteria) - 1
    return answers[question_id].score / top_level

def priority(ticket: str) -> float:
    with TypeSafeClient() as client:
        response = client.system_one(
            state=ticket,
            questions=TRIAGE_QUESTIONS,
        )
    answers = response.answers

    severity = normalized(answers, "severity")
    frustration = normalized(answers, "frustration")
    report_quality = normalized(answers, "report_quality")

    # A detailed report helps an engineer investigate, so it raises priority a little.
    return 0.6 * severity + 0.3 * frustration + 0.1 * report_quality

Para la respuesta de ejemplo de arriba, las puntuaciones normalizadas son 0.62 para severity, 0.64 para frustration y 1.0 para report quality. La prioridad es 0.6 × 0.62 + 0.3 × 0.64 + 0.1 × 1.0 = 0.664, que se redondea a 0.66.

Los pesos viven en tu código, así que puedes ver exactamente cómo se forma el número y cambiarlo cuando la clasificación no coincida con lo que haría tu equipo. Si más adelante necesitas más preguntas Score, añádelas a TRIAGE_QUESTIONS. El número de solicitudes sigue siendo uno. Esta técnica de dividir un juicio complejo en Scores separados y luego combinarlos con pesos en tu código se llama patrón Puntuación compuesta.

Descripciones de nivel estructuradas

Empieza con una descripción de texto básica para cada nivel. Cuando el modelo siga puntuando entre dos niveles vecinos en entradas que tú consideras claras, dale a cada nivel un objeto en lugar de una cadena, con un campo para qué cubre el nivel y un campo con algunos ejemplos de situaciones. Usa los mismos nombres de campo en todos los niveles para que el modelo pueda comparar cosas equivalentes.

La solicitud de abajo es el ticket del indicador de carga que usamos antes, pero con ejemplos en cada nivel:

request
{
  "state": "Export to PDF fails with a spinner that never finishes. Some of our team say CSV export still works for them, others say it fails too.",
  "questions": {
    "bug_severity": {
      "type": "score",
      "instructions": "How severe is the reported issue?",
      "criteria": [
        {
          "what": "Cosmetic; no impact to functionality",
          "examples": [
            "typo in a label",
            "misaligned icon"
          ]
        },
        {
          "what": "Broken or degraded feature, but workaround exists",
          "examples": [
            "export fails in one browser but works in another"
          ]
        },
        {
          "what": "Blocking issue; no workaround exists",
          "examples": [
            "cannot log in",
            "data loss"
          ]
        }
      ]
    }
  }
}

La respuesta:

{
  "model": "jev-1.13.0",
  "answers": {
    "bug_severity": {
      "type": "score",
      "score": 1.09,
      "confidence": 0.87,
      "legend": {
        "0": {
          "what": "Cosmetic; no impact to functionality",
          "examples": [
            "typo in a label",
            "misaligned icon"
          ]
        },
        "1": {
          "what": "Broken or degraded feature, but workaround exists",
          "examples": [
            "export fails in one browser but works in another"
          ]
        },
        "2": {
          "what": "Blocking issue; no workaround exists",
          "examples": [
            "cannot log in",
            "data loss"
          ]
        }
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.91,
        "2": 0.09
      }
    }
  },
  "usage": {
    "input_tokens": 379,
    "output_tokens": 18
  }
}

Con cadenas simples, este ticket puntuó 1.11 con una confianza de 0.84. Con ejemplos, puntúa 1.09 con una confianza de 0.87, un cambio pequeño porque las cadenas simples ya lo situaban bien. El efecto es mayor cuando las cadenas simples dejan al modelo dividido, como muestra la siguiente tabla.

Los ejemplos guían al modelo, y solo ayudan cuando se parecen a tus entradas reales. La tabla de abajo es el informe de Safari inicial con tres conjuntos distintos de objetos de nivel:

Descripción del nivel score confidence
cadena simple: sin objeto con ejemplos 1.43 0.35
array de examples añadido con un ejemplo útil: «la exportación falla en un navegador pero funciona en otro» 1.03 0.96
array de examples añadido con un ejemplo no relacionado con navegadores: «la búsqueda falla, pero navegar por las categorías sigue funcionando» 1.43 0.35

En esta comparación, el ejemplo que encaja concentra casi toda la probabilidad en un nivel. El ejemplo no relacionado devuelve el mismo resultado que las cadenas simples. Una confianza más alta no determina qué respuesta es correcta. Elige ejemplos con niveles esperados conocidos y luego prueba las descripciones revisadas con entradas aparte antes de quedártelas.