
On September 24, 2026 (Korea time), the Contrastive-LM team, which includes Stanford and NVIDIA researchers, released the code and weights for the decision model CLM-8B. It is a System One model that turns the current situation and candidate actions into vectors and compares them, and it reported performance similar to Jev on computer use, games, and tool calling with up to 9x lower latency. The code and the released CLM-specific head weights are under the Apache-2.0 license.
The announcement video is about 1 minute 19 seconds long. You can check the setup and how to run it in the repository's CLM code, the Hugging Face model card, and the project introduction.
Jev and CLM: making an agent's choices fast
Jev is TypeSafe's System One decision model. It handles structured judgments: Choice, which picks one of the candidates an agent has set; Noul, which decides true or false; and Score, which scores against a rubric.
CLM-8B offers the same style of API, but it compares options differently. It encodes the current state and each candidate action into vectors and picks the action whose vector is most similar to the state's. For example, after reading a screen state, if it receives "press the settings button" and "go back" as candidates, it compares the screen context with each action description and picks the better fit.
Candidate action vectors can be stored in a cache and reused for the next state. When the screen state changes, it makes a new state vector and computes scores against the action vectors already calculated. This structure creates a speed advantage in tasks where candidates repeat, like menu items or tool lists.
From computer use to coding verification
In the published zero-shot evaluations, CLM-8B showed performance similar to Jev on computer use, game, and tool-calling tasks, with up to 9x lower latency. In conditions with about 1,000 candidate actions, the announcement's evaluation showed results up to 13x faster than Jev.
| Evaluation | Result | Condition |
|---|---|---|
| Computer use, games, tool calling | Performance similar to Jev, up to 9x lower latency | Public zero-shot comparison |
| Large sets of candidate actions | Up to 13x faster | About 1,000 candidates |
| DeepSWE | 81.6% (31/38) | Head fine-tuned as a verifier, 38 held-out tasks |
| Terminal-Bench 2.1 | 87.6% | Head fine-tuned as a verifier, 30 held-out tasks |
The DeepSWE and Terminal-Bench figures come from using CLM-8B as a verifier that picks the best result among several candidate solutions, after lightly fine-tuning the head for that task. They can be read separately from the base zero-shot evaluation.
Learning state and action in three stages
Training starts with large-scale pretraining that treats questions and answers as states and actions. It then goes through a stage that tells correct answers apart from wrong answers with similar meaning, and finally learns the relationship between situations and choices from records of agents actually doing tasks.
- It pretrains broad state and action representations on about 60 million Nemotron question-answer pairs.
- It does mid-training on about 30 million synthetic hard negatives to tell apart candidate actions that look similar but are wrong.
- It does follow-up training on decisions in real task context, using about 1 million agent trajectories and terminal logs.
Installing CLM-8B and running the server
The quick-start environment is Python 3.10 or later, Linux, and an NVIDIA GPU. You run a CLM API server and a Qwen3-8B embedding server, and the 75MB CLM-specific head checkpoint is downloaded from Hugging Face on first run. The Qwen3-8B encoder runs separately.
git clone https://github.com/Contrastive-LM/CLM.git && cd CLM
pip install -r requirements.txt
# Qwen3-8B embedding server
vllm serve Qwen/Qwen3-8B --served-model-name qwen3-8b --runner pooling \
--enable-prefix-caching --max-model-len 2048 \
--gpu-memory-utilization 0.35 --port 8090
# CLM API server
clm-serve --port 8700 --emb-url http://127.0.0.1:8090/v1/embeddingsThe Python client can bundle Choice, Noul, and Score judgments into a single system_one call. The example below classifies a customer inquiry's urgency, responsible department, and frustration score together.
from clm import CLMClient, Choice, Noul, Score
client = CLMClient() # default address http://127.0.0.1:8700
result = client.system_one(
state="A customer says they were charged twice for the same bill and can't get through by phone.",
questions={
"urgency": Noul(instructions="Is this an urgent inquiry?"),
"department": Choice(
instructions="Which team should handle this?",
criteria={"billing": "Payments, invoices, refunds", "technical": "Errors and service outages"},
),
"frustration": Score(
instructions="How frustrated is the customer?",
criteria=["Calm", "Frustrated", "Very angry"],
),
},
)
print(result.answers["department"].choice)To rank text candidates directly, you can use the repository's Engine.rank(). The API server also provides a web playground by default, and you set the server address and API key with the CLM_BASE_URL and CLM_API_KEY environment variables.
Apache-2.0 release and CLM-35B
The CLM code and the released 75MB head weights are licensed under Apache-2.0. The CLM-8B setup combines a Qwen3-8B encoder with the CLM decision head. The researchers also previewed that they are training CLM-35B, which handles multimodal input such as images and video.
