Skip to content

TypeSafe

Edit this page

TypeSafe's Jev is a System One model: instead of generating text, it answers typed questions about a piece of content - the state - with calibrated probabilities your code can act on directly. This makes it a good fit for classification, routing, scoring and guardrails, where an application needs a decision rather than a sentence.

For comprehensive information about TypeSafe, see the TypeSafe API reference.

Setup

Installation

1
$ composer require symfony/ai-type-safe-platform

Authentication

TypeSafe requires an API key, which you can set up in the TypeSafe console.

Usage

An invocation takes an Evaluation, made of a state and the questions to answer about it, keyed by an identifier of your choice. Jev reads the state once and answers every question against it, so asking several questions at once is both faster and cheaper than one invocation per question:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use Symfony\AI\Platform\Bridge\TypeSafe\Evaluation;
use Symfony\AI\Platform\Bridge\TypeSafe\Factory;
use Symfony\AI\Platform\Bridge\TypeSafe\Question\ChoiceQuestion;
use Symfony\AI\Platform\Bridge\TypeSafe\Question\NoulQuestion;
use Symfony\AI\Platform\Bridge\TypeSafe\Question\ScoreQuestion;

$platform = Factory::createPlatform($_ENV['TYPESAFE_API_KEY'], $httpClient);

$result = $platform->invoke('jev-latest', new Evaluation($ticket, [
    'department' => new ChoiceQuestion('Which team should handle this?', [
        'billing' => 'Payment or subscription issues',
        'technical' => 'Bugs or integration problems',
        'sales' => 'Pricing or account questions',
    ]),
    'frustration' => new ScoreQuestion('How frustrated does the customer appear?', [
        'Calm, just stating facts',
        'Frustrated but civil',
        'Very angry, strong language',
    ]),
    'is_urgent' => new NoulQuestion('Does the message convey urgency?'),
]));

$answers = $result->asObject();

The state is either plain text or structured data, like a list of chat messages or a record of your application.

Questions

There are three types of questions, each one coming with its own type of answer:

  • NoulQuestion asks a yes/no question. An optional description of what a yes and a no mean can be given as second and third argument;
  • ChoiceQuestion picks one option out of a set. Every option maps to its description, or to null when the name of the option speaks for itself;
  • ScoreQuestion rates the state along levels, ordered from the lowest to the highest.

Answers

The result holds an Answers object, giving access to every answer by the identifier of its question. The getNoul(), getChoice() and getScore() methods return the answer with its type, and throw an exception when the answer is of another type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$urgent = $answers->getNoul('is_urgent');
$urgent->getProbability(); // 0.98, the probability that the answer is yes
$urgent->isTrue();         // true, as the probability reaches the default threshold of 0.5
$urgent->isTrue(0.99);     // false

$department = $answers->getChoice('department');
$department->getChoice();        // 'billing'
$department->getProbabilities(); // ['billing' => 0.65, 'technical' => 0.35, 'sales' => 0.0]
$department->getConfidence();    // 0.48

$frustration = $answers->getScore('frustration');
$frustration->getScore();         // 1.0, the probability-weighted level, which can land between two levels
$frustration->getLegend();        // [0 => 'Calm, just stating facts', 1 => 'Frustrated but civil', ...]
$frustration->getProbabilities(); // [0 => 0.0, 1 => 1.0, 2 => 0.0]
$frustration->getConfidence();    // 1.0

The confidence tells how certain the model is about a choice or a score, which is what lets your code decide whether to act on an answer, or to fall back to another model or to a human:

1
2
3
if ($department->getConfidence() < 0.7) {
    // route the ticket to a human for review
}

Note

Jev does not take messages, call tools nor stream its answers, so it cannot be the model of an agent. Use it next to one instead, for example to classify the input of a user before choosing the agent to hand it to.

Models

The jev-latest and jev-preview aliases follow the releases of Jev, so their answers can change over time. Use a versioned model, like jev-1.13.0, once confidence thresholds are tuned against it. The model that answered is part of the token usage:

1
$result->getMetadata()->get('token_usage')->getModel(); // 'jev-1.13.0'

Symfony Bundle Configuration

When using the AI Bundle, configure the API key under the typesafe platform section:

1
2
3
4
5
# config/packages/ai.yaml
ai:
    platform:
        typesafe:
            api_key: '%env(TYPESAFE_API_KEY)%'

The platform is then available as the ai.platform.typesafe service.

Examples

See the examples/typesafe/ directory for complete working examples:

  • evaluate.php - Triaging a support ticket with the three types of questions
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version