> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Jev decision model

> Use TypeSafe AI's Jev for classification, filtering, reranking, cluster labeling and hierarchical cluster search

Jev is an evaluation model from TypeSafe AI. It answers typed questions about a piece of text and returns calibrated probabilities. It does not generate text. Use it for steps that are a decision over a fixed set of options: keep or discard, pick a label, rate on a scale, route to a branch.

| Question type | Jev returns | Example |
| - | - | - |
| Yes/no | Probability that the answer is yes | Does this document mention side effects? |
| Choice | The chosen option and a probability for each option | Which category fits: footwear, apparel or electronics? |
| Score | A value across ordered levels you define | How severe is the complaint, 1 to 5? |

Jev reads text only, up to 32,000 tokens per request. Media documents are judged on their text fields, such as descriptions, transcripts and metadata. TypeSafe prices Jev at \$0.042 per million input tokens, and output is free.

## Jev in Mixpeek

| Surface | How to select Jev | What Jev decides |
| - | - | - |
| [Text extractor](/docs/processing/extractors/text) | `llm_provider: "typesafe"` | Each `response_shape` field, at ingestion |
| [Cluster labeling](/docs/enrichment/clusters) | `llm_labeling.provider: "typesafe"` + `candidate_labels` | The label for each cluster, from your vocabulary |
| [LLM Filter](/docs/retrieval/stages/llm-filter) | `model_name: "jev-latest"` | Keep or discard each document |
| [LLM Enrich](/docs/retrieval/stages/llm-enrich) | `model_name: "jev-latest"` + `output_schema` | Each schema field for each document |
| [Rerank](/docs/retrieval/stages/rerank) | `inference_name: "typesafe__jev"` | Relevance probability for each query and document pair |
| [Classify](/docs/retrieval/stages/classify) | `inference_name: "typesafe__jev"` + `labels` | Probability of each label for each document |
| [Agent Search](/docs/retrieval/stages/agent-search) | `strategy: "cluster_navigation"` + `model_name: "jev-latest"` | Which child cluster to descend into, at every level |
| Inference API | `inference_name: "typesafe__jev"` | Any of the question types, called directly |

## Swap the decision model

Jev belongs to a category Mixpeek calls decision models: a model that answers typed questions (yes/no, choice, score) and returns a probability with each answer. Every surface above asks its question through one factory, so any generative model can take Jev's place. A generative model answers the same questions and reports its own confidence, and Mixpeek marks those probabilities as uncalibrated.

| Scope | How to swap | Example |
| - | - | - |
| One request | `inference_name: "mixpeek__decision"` with `parameters.model` | `"model": "gemini-2.5-flash-lite"` |
| One stage | `inference_name: "mixpeek__decision"` plus `decision_model` on [Rerank](/docs/retrieval/stages/rerank) or [Classify](/docs/retrieval/stages/classify), `model_name` on [Agent Search](/docs/retrieval/stages/agent-search) | `"decision_model": "gemini-2.5-flash-lite"` |
| One cluster | `llm_labeling.provider` and `model_name` with `candidate_labels` | `"provider": "google", "model_name": "gemini-2.5-flash-lite"` |
| The deployment | `DECISION_MODEL_DEFAULT` on the API and engine | `DECISION_MODEL_DEFAULT=gemini-2.5-flash-lite` |

`mixpeek__decision` takes the same four input shapes as `typesafe__jev` and uses `DECISION_MODEL_DEFAULT` when `parameters.model` is unset. `typesafe__jev` always calls Jev. Every response names the model that answered in `model` and says whether its probabilities are calibrated in `calibrated`.

## Where the probabilities go

Mixpeek writes the decision model's probability next to every answer it produces, so you can threshold, audit or route on it later.

Rerank, Classify, cluster labeling and Agent Search record a probability from any decision model. The text extractor, LLM Filter and LLM Enrich record one when Jev answers. With a generative model those three run as ordinary LLM calls and write no probability.

| Surface | Field | Holds |
| - | - | - |
| Text extractor | `extraction_confidence` | Probability of each extracted field's value |
| Cluster labeling | `label_confidence`, `label_candidates`, `label_model`, `label_calibrated` | Probability of the chosen label, the top three labels, and the model |
| LLM Filter | `scores.<stage_name>` on each kept document, `llm_decisions[].keep_probability` in stage metadata | Probability that the document meets the condition |
| LLM Enrich | `<output_field>_confidence` | Probability of each enriched field's value |
| Rerank | `score` on each document, `model_used` and `probabilities_calibrated` in stage metadata | Probability that the document is relevant |
| Classify | `labels[].confidence` | Probability of each label |
| Agent Search | `cluster_path_score` on each document, `navigation_trace` and `probabilities_calibrated` in stage metadata | Geometric mean of the decisions on the path, and every decision's probabilities |

## Schema fields and the questions they become

Extraction, cluster labeling and LLM Enrich describe their output as a JSON schema. Jev answers each field as one question, and all questions for one document go in one request.

| Schema field | Question |
| - | - |
| `boolean` | Yes/no. The value is true when the probability is at least 0.5 |
| `number` with `minimum: 0` and `maximum: 1` | Yes/no. The value is the probability |
| `string` with `enum` (2 to 255 values) | Choice. Add `enumDescriptions` to describe each option |
| `integer` with `minimum` and `maximum` (2 to 10 levels) | Score |
| `array` of `enum` strings | One yes/no per value. The value lists each option at 0.5 or above |
| `object` | Its properties, answered the same way |

A string field named `reason`, `reasoning`, `explanation`, `rationale` or `justification` receives the probabilities behind the answer. Any other field without a closed set of values is rejected before a request is sent, and the error names the field. Use a generative model such as `gemini-2.5-flash-lite` for free-text fields.

## Call Jev through the inference API

`typesafe__jev` accepts four input shapes.

| Inputs | Parameters | Returns |
| - | - | - |
| `pairs`: list of `[query, document]` | `relevance_criteria` (optional) | `scores`: one probability per pair |
| `text` | `labels`: list, or map of label to description | `labels`: every label with its probability, highest first |
| `text` + `schema` | none | `data` shaped like the schema, and `answers` with the probabilities |
| `state` + `questions` | none | TypeSafe's response, unchanged |

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS -X POST "$MP_API_URL/v1/inference" \
    -H "Authorization: Bearer $MP_API_KEY" \
    -H "X-Namespace: $MP_NAMESPACE" \
    -H "Content-Type: application/json" \
    -d '{
      "inference_name": "typesafe__jev",
      "inputs": {
        "text": "Kickflip down the eight stair at the city skatepark",
        "schema": {
          "type": "object",
          "properties": {
            "sport": {"type": "string", "enum": ["skateboarding", "surfing", "basketball"]},
            "is_tutorial": {"type": "boolean"}
          }
        }
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      f"{MP_API_URL}/v1/inference",
      headers={"Authorization": f"Bearer {MP_API_KEY}", "X-Namespace": MP_NAMESPACE},
      json={
          "inference_name": "typesafe__jev",
          "inputs": {
              "text": "Kickflip down the eight stair at the city skatepark",
              "schema": {
                  "type": "object",
                  "properties": {
                      "sport": {"type": "string", "enum": ["skateboarding", "surfing", "basketball"]},
                      "is_tutorial": {"type": "boolean"},
                  },
              },
          },
      },
  )
  print(resp.json())
  ```

  ```javascript JavaScript theme={null}
  const resp = await fetch(`${MP_API_URL}/v1/inference`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${MP_API_KEY}`,
      "X-Namespace": MP_NAMESPACE,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      inference_name: "typesafe__jev",
      inputs: {
        text: "Kickflip down the eight stair at the city skatepark",
        schema: {
          type: "object",
          properties: {
            sport: { type: "string", enum: ["skateboarding", "surfing", "basketball"] },
            is_tutorial: { type: "boolean" },
          },
        },
      },
    }),
  });
  console.log(await resp.json());
  ```
</CodeGroup>

## Writing questions Jev answers well

* State the exact condition. Jev reads criteria word for word, so "The document states the refund policy for damaged items" works better than "relevant to refunds".
* Keep arithmetic, counting and date comparison in code. Ask Jev for the parts, then compute.
* Send only the text the question needs. Unrelated content lowers accuracy.
* Use the probabilities. Route answers below a threshold you choose to review or to a generative model.

## Bring your own key

The inference API accepts `parameters.api_key` to call Jev with your own TypeSafe key.
