Skip to content
Patterns

Composite scores

Ask one score per criterion and combine them in your code with weights you choose. You get one number to rank or threshold, and you can still say where it came from.

When to use it

  • A decision depends on several criteria: lead quality, vendor risk, how well a CV fits a role.
  • You need to rank many items, or set one cut-off, and one question would hide too much.
  • The weights may change, or differ by team or customer, and you do not want to rewrite questions for that.

How it works

Ask each criterion as its own score in the same request (see fan-out). Divide each expected score by its highest level so they all run from 0 to 1, then take a weighted sum. The result is yours: you can explain it ("strong on budget, weak on timing") and change the weights without touching the questions.

  1. Questions

    One score per criterion

    • budgetscore
    • timelinescore
    • decision_makerscore
  2. Your weights

    0.4 · 0.3 · 0.3

    • each score normalized to 0–1
  3. Result

    One number

    • fit = Σ weight × score / max
Three scores on a sales lead, weighted and summed in your code.

A sales lead scored on three criteria, each on a three-level scale:

from typesafe_sdk import Score, TypeSafeClient # Reads TYPESAFE_BASE_URL (https://api.vakyn.com) and TYPESAFE_API_KEY from the environment.client = TypeSafeClient()LEVELS = ["Not at all", "Partly", "Clearly"]WEIGHTS = {"budget": 0.4, "timeline": 0.3, "decision_maker": 0.3} lead = (    "Hi, I run operations at a 40-person logistics firm. We set aside budget for a scheduling "    "tool this quarter and want something live before the summer peak. I'll loop in our CFO.")result = client.system_one(    state=lead,    questions={        "budget": Score(instructions="Does the lead have budget for a purchase?", criteria=LEVELS),        "timeline": Score(instructions="Does the lead need a solution soon?", criteria=LEVELS),        "decision_maker": Score(instructions="Is the writer able to approve the purchase?", criteria=LEVELS),    },)# Each score runs from 0 to 2; normalise to 0-1 and weigh.fit = sum(WEIGHTS[k] * result.scores[k].score / 2 for k in WEIGHTS)print(f"fit: {fit:.2f}")

Tips

  • Keep each criterion about one thing. A score that mixes budget and timing cannot be weighted apart.
  • Look at each score's confidence too. If a criterion that carries a lot of weight is unsure, send the item for review instead of ranking it; see routing by confidence.
  • Store the parts, not only the total, so you can recompute it when the weights change.

Loading the docs…