# Décisions

> Posez à un modèle un ensemble fixe de questions sur un texte et récupérez des réponses typées avec leurs probabilités, au lieu de prose à parser.

- Canonical: https://tchavi.com/fr/docs/decisions

---


<Endpoint method="POST" path="/v1/decisions" />

Un modèle de décision répond à un **ensemble fixe de questions** sur un texte et renvoie des réponses typées avec leurs probabilités. Utilisez-le là où vous demanderiez sinon du JSON à un modèle de chat en espérant qu'il obéisse : router un ticket vers une équipe, noter l'urgence, repérer si un client est bloqué.

La différence avec `/v1/chat/completions` est que la forme de la réponse est garantie. Vous déclarez les questions : il n'y a rien à parser, et rien à réessayer quand le modèle enrobe son JSON d'une excuse.

Les modèles de décision ne fonctionnent que sur cet endpoint. Envoyer `jev-1.13` à `/v1/chat/completions` renvoie une `400`, et envoyer un modèle de chat ici renvoie également une `400`.

## Les questions

`state` est le texte à juger. `questions` est un dictionnaire de vos propres noms vers une question. Trois types, et le champ `criteria` diffère de l'un à l'autre :

| type     | la question                         | `criteria`                              | ce que vous recevez        |
| -------- | ----------------------------------- | --------------------------------------- | -------------------------- |
| `choice` | choisir parmi plusieurs libellés    | un dictionnaire libellé → sa définition | `choice` + `probabilities` |
| `score`  | situer sur une échelle ordonnée     | un tableau **ordonné**, du bas au haut  | `score` + `legend`         |
| `noul`   | quelle probabilité que ce soit vrai | aucun                                   | `noul`, entre 0 et 1       |

Les noms sont les vôtres : `answers` revient indexé exactement par les noms que vous avez envoyés.

## Exemple

<CodeTabs>

```tchavi
import Tchavi from '@tchavi/sdk';

const client = new Tchavi({ apiKey: 'VOTRE_CLE_API' });

const result = await client.decisions.create({
  model: 'jev-1.13',
  state: "Le client écrit : « Ma clé API ne marche plus depuis que je l'ai renouvelée. »",
  questions: {
    team: {
      type: 'choice',
      instructions: 'Quelle équipe doit traiter cela ?',
      criteria: { billing: 'paiements ou crédits', technical: 'API, clés' },
    },
    urgency: {
      type: 'score',
      instructions: "Quel est le niveau d'urgence ?",
      criteria: ['pas urgent', 'normal', 'urgent', 'critique'],
    },
    blocked: {
      type: 'noul',
      instructions: "Le client est-il incapable d'utiliser le produit ?",
    },
  },
});

// Les réponses se discriminent sur `type`.
if (result.answers.team.type === 'choice') {
  console.log(result.answers.team.choice, result.answers.team.probabilities);
}
if (result.answers.blocked.type === 'noul') {
  console.log('probabilité bloqué :', result.answers.blocked.noul);
}
```

```javascript
const response = await fetch('https://tchavi.com/api/v1/decisions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer VOTRE_CLE_API',
  },
  body: JSON.stringify({
    model: 'jev-1.13',
    state: "Le client écrit : Ma clé API ne marche plus depuis que je l'ai renouvelée.",
    questions: {
      team: {
        type: 'choice',
        instructions: 'Quelle équipe doit traiter cela ?',
        criteria: { billing: 'paiements ou crédits', technical: 'API, clés' },
      },
      urgency: {
        type: 'score',
        instructions: "Quel est le niveau d'urgence ?",
        criteria: ['pas urgent', 'normal', 'urgent', 'critique'],
      },
      blocked: { type: 'noul', instructions: "Le client est-il incapable d'utiliser le produit ?" },
    },
  }),
});

const result = await response.json();
console.log(result.answers);
console.log('crédits utilisés :', response.headers.get('x-credits-used'));
```

```python
import requests

response = requests.post(
    "https://tchavi.com/api/v1/decisions",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer VOTRE_CLE_API",
    },
    json={
        "model": "jev-1.13",
        "state": "Le client écrit : Ma clé API ne marche plus depuis que je l'ai renouvelée.",
        "questions": {
            "team": {
                "type": "choice",
                "instructions": "Quelle équipe doit traiter cela ?",
                "criteria": {"billing": "paiements ou crédits", "technical": "API, clés"},
            },
            "urgency": {
                "type": "score",
                "instructions": "Quel est le niveau d'urgence ?",
                "criteria": ["pas urgent", "normal", "urgent", "critique"],
            },
            "blocked": {
                "type": "noul",
                "instructions": "Le client est-il incapable d'utiliser le produit ?",
            },
        },
    },
)

result = response.json()
print(result["answers"])
print("crédits utilisés :", response.headers.get("x-credits-used"))
```

```curl
curl -X POST https://tchavi.com/api/v1/decisions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer VOTRE_CLE_API" \
  -d '{
    "model": "jev-1.13",
    "state": "Le client ecrit : Ma cle API ne marche plus depuis que je l ai renouvelee.",
    "questions": {
      "team": {
        "type": "choice",
        "instructions": "Quelle equipe doit traiter cela ?",
        "criteria": { "billing": "paiements ou credits", "technical": "API, cles" }
      },
      "urgency": {
        "type": "score",
        "instructions": "Quel est le niveau d urgence ?",
        "criteria": ["pas urgent", "normal", "urgent", "critique"]
      },
      "blocked": {
        "type": "noul",
        "instructions": "Le client est-il incapable d utiliser le produit ?"
      }
    }
  }'
```

</CodeTabs>

## La réponse

```json
{
  "model": "jev-1.13.0",
  "answers": {
    "team": {
      "type": "choice",
      "choice": "technical",
      "confidence": 1,
      "probabilities": { "billing": 0, "technical": 1 }
    },
    "urgency": {
      "type": "score",
      "score": 1.67,
      "confidence": 0.65,
      "legend": { "0": "pas urgent", "1": "normal", "2": "urgent", "3": "critique" },
      "probabilities": { "0": 0, "1": 0.34, "2": 0.65, "3": 0.01 }
    },
    "blocked": { "type": "noul", "noul": 0.76 }
  },
  "usage": { "input_tokens": 382, "output_tokens": 62 }
}
```

Un `score` est continu, pas un indice : `1.67` se situe entre `normal` et `urgent`, et penche vers urgent. `legend` remet les positions en face des libellés que vous avez envoyés, à vous d'arrondir ou de fixer un seuil selon votre besoin.

`confidence` est la certitude du modèle. Sur un `choice`, c'est la probabilité du libellé gagnant ; une valeur basse est votre signal pour passer la main à un humain plutôt que d'agir sur la réponse.

## Crédits

Une réponse de décision est le corps renvoyé par le fournisseur : le coût est donc dans les en-têtes, pas dans le JSON.

```
X-Credits-Used: 0.001
X-Credits-Remaining: 115397.775
```

Les décisions sont facturées au token comme tout autre modèle, et elles coûtent peu — l'exemple ci-dessus revient à un millième de crédit. C'est tout l'intérêt : un modèle de décision est fait pour tourner sur chaque message, pas seulement sur ceux dont vous avez déjà décidé qu'ils méritaient un gros modèle.

