Jev AI Hub
Start Learning

Scoring · Score

Score Customer Sentiment with Jev

Jev sentiment as a Score: situational levels, a full probability distribution, and a code path that escalates angry mail.

Published
Sep 20, 2026
Updated
Sep 20, 2026
Last verified
Sep 20, 2026

Quick answer

Rate message tone on an ordered rubric instead of asking Jev for a happy/sad adjective.

Problem

A CSAT follow-up and a public review feed need a tone rank so agents see the worst threads first. A binary 'negative' flag loses the middle.

Why Jev fits this task

Tone is a spectrum. Official docs use customer frustration as the Score example. Keep the levels about observable language, not unstated emotion.

Input state

Send only the fields the questions name. Official docs warn that extra unrelated state costs accuracy.

{
  "source": "in-app chat",
  "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday."
}

Question

How negative or positive is this customer message?

Question type: Score.

Jev schema

{
  "model": "jev-latest",
  "state": {
    "source": "in-app chat",
    "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday."
  },
  "questions": {
    "sentiment": {
      "type": "score",
      "instructions": "What is the overall tone of `message`?",
      "criteria": [
        "Praise or thanks, no complaint",
        "Neutral update or a contained complaint with a workaround",
        "Strong dissatisfaction, demand, or public-threat language"
      ]
    }
  }
}

Python example

from typesafe_sdk import Score, TypeSafeClient

state = {
    "source": "in-app chat",
    "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday.",
}

with TypeSafeClient() as client:
    response = client.system_one(
        state=state,
        questions={
        "sentiment": Score(
            instructions="What is the overall tone of `message`?",
            criteria=[
                            "Praise or thanks, no complaint",
                            "Neutral update or a contained complaint with a workaround",
                            "Strong dissatisfaction, demand, or public-threat language",
                        ],
        ),
        },
    )

print(response.answers["sentiment"].score)
print(response.model)

TypeScript example

import { score, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient();

const response = await client.systemOne({
  state: {
    "source": "in-app chat",
    "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday."
  },
  questions: {
    sentiment: score("What is the overall tone of `message`?", [
      "Praise or thanks, no complaint",
      "Neutral update or a contained complaint with a workaround",
      "Strong dissatisfaction, demand, or public-threat language"
    ]),
  },
});

console.log(response.answers.sentiment.score);
console.log(response.model);

JavaScript example

import { score, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient();

const response = await client.systemOne({
  state: {
    "source": "in-app chat",
    "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday."
  },
  questions: {
    sentiment: score("What is the overall tone of `message`?", [
      "Praise or thanks, no complaint",
      "Neutral update or a contained complaint with a workaround",
      "Strong dissatisfaction, demand, or public-threat language"
    ]),
  },
});

console.log(response.answers.sentiment.score);
console.log(response.model);

cURL example

curl -s https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<'EOF'
{
  "model": "jev-latest",
  "state": {
    "source": "in-app chat",
    "message": "The new export is slower than last month, but your status page explained the backlog. I can wait until Friday."
  },
  "questions": {
    "sentiment": {
      "type": "score",
      "instructions": "What is the overall tone of `message`?",
      "criteria": [
        "Praise or thanks, no complaint",
        "Neutral update or a contained complaint with a workaround",
        "Strong dissatisfaction, demand, or public-threat language"
      ]
    }
  }
}
EOF

Expected output

{
  "model": "jev-1.13.0",
  "answers": {
    "sentiment": {
      "type": "score",
      "score": 1.05,
      "legend": {
        "0": "Praise or thanks, no complaint",
        "1": "Neutral update or a contained complaint with a workaround",
        "2": "Strong dissatisfaction, demand, or public-threat language"
      },
      "probabilities": {
        "0": 0.08,
        "1": 0.79,
        "2": 0.13
      },
      "confidence": 0.68
    }
  },
  "usage": {
    "input_tokens": 190,
    "output_tokens": 20
  }
}

Confidence handling

Low confidence plus a mid score usually means mixed signals. Do not auto-tweet a reply. Official three-path pattern: act / confirm / escalate.

Production considerations

Store probabilities, not only the scalar. A U-shaped distribution (mass on 0 and 2) is a different ticket than a peaked 1.0.

Queue ordering, review triage, and 'do not auto-reply' gates.

When to use Jev

You want a rank to sort a queue and you can describe each rank in a sentence.

When not to use Jev

You need a marketing-grade emotion taxonomy, or you are trying to detect a specific intent — use the intent example.

Sentiment is not the same as urgency or refund eligibility. Official notes: one Score, one dimension. Sarcasm and non-English text need your own tests — English is officially strongest.

Common mistakes

  • Asking a Noul 'is the customer unhappy?' and reading 0.5 as medium sentiment.
  • Putting 'angry about billing' into one level so billing and tone get tangled.

FAQ

Is this an official sentiment API?

No. Sentiment here is an ordinary Score you define. TypeSafe does not ship a separate sentiment product in the public docs we verified.

Sources

  1. Primitives (Questions)TypeSafe · accessed 2026-09-20 · documentation
  2. API referenceTypeSafe · accessed 2026-09-20 · documentation
  3. Jev 1.13 jaggednessTypeSafe · 2026-09-17 · accessed 2026-09-20 · documentation

All Jev examples