How to Use Jev
This is the practical path from zero to a working Jev call. If you want the concept first, read What Is Jev? — this page assumes you already know that Jev takes a state plus questions and returns typed decisions with probabilities.
Before You Start
Three things to line up:
- Early access. Jev is not open to everyone yet — request access from TypeSafe first.
- An API key, created from the TypeSafe console once you’re in.
- Python 3.10 or newer, if you plan to use the official SDK.
The distinction that trips people up: the state is the content you want judged; the questions are the judgements you want made about it. Keep them separate.
Step 1 — Try It in the Playground First
Before writing any code, open the TypeSafe playground. Paste any text as the state:
Hi, I've been trying to connect my Stripe account for 3 days and the integration
keeps failing. I'm losing sales. Please help ASAP.
Then add a Noul question:
{
"urgency": {
"type": "noul",
"instructions": "Does this message express urgency?"
}
}
Now add a Choice and a Score to the same request and watch all the answers come back at once. This is the fastest way to feel the difference between Jev and a chat model.
Step 2 — Send Your First API Call
The endpoint takes a POST with your key in the Authorization header:
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"state": "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP.",
"model": "jev-latest",
"questions": {
"urgency": {
"type": "noul",
"instructions": "Does this message express urgency?"
}
}
}
EOF
Step 3 — The Same Call in Python
Install the SDK — it reads your key from the environment and defaults to jev-latest:
pip install typesafe-sdk
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
ticket = "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP."
response = client.system_one(
state=ticket,
questions={
"department": Choice(
instructions="Which team should handle this",
criteria={
"billing": "Payment or subscription issues",
"technical": "Bugs or integration problems",
"sales": "Pricing or account questions",
},
),
"frustration": Score(
instructions="How frustrated the customer appears",
criteria=[
"Calm, just stating facts",
"Frustrated but civil",
"Very angry, strong language",
],
),
"is_urgent": Noul(
instructions="The message conveys urgency or time-sensitivity",
),
},
)
print(response.answers["department"].choice) # "technical"
print(response.answers["frustration"].score) # 1.0
print(response.answers["is_urgent"].noul) # 1.0
Step 4 — Read the Response Correctly
Each question type returns a different shape. For the request above you get back something like:
{
"model": "jev-1.13.0",
"answers": {
"department": {
"type": "choice",
"choice": "technical",
"confidence": 0.78,
"probabilities": { "technical": 0.85, "sales": 0.0, "billing": 0.15 }
},
"frustration": {
"type": "score",
"score": 1.0,
"confidence": 1.0,
"legend": {
"0": "Calm, just stating facts",
"1": "Frustrated but civil",
"2": "Very angry, strong language"
}
},
"is_urgent": { "type": "noul", "noul": 1.0 }
},
"usage": { "input_tokens": 392, "output_tokens": 65 }
}
Two practical notes. choice is the top option, but you should usually branch on confidence — in the example the model is only 78% confident, so a production system might route anything below 0.9 to a human. And you requested jev-latest but the response echoes a pinned version like jev-1.13.0: the alias resolves to whatever is current, which is convenient but means you should log the returned model name if you care about reproducibility.
Step 5 — Ask Everything You Need in One Call
Because System One models evaluate every question in parallel, the idiomatic pattern is to send all the judgements you need about one state at once, rather than making five separate calls. Adding questions to a request barely changes the latency — this is the main cost lever you have, since input tokens cost $0.042 per million and output tokens are free.
Step 6 — Put Jev Inside a Real Application
Jev slots into existing frameworks rather than replacing them. The LangChain integration exposes it through TypeSafeClassifier:
pip install langchain-typesafe
from langchain_typesafe import Noul, TypeSafeClassifier
classifier = TypeSafeClassifier()
response = classifier.invoke({
"state": (
"The deploy failed twice and customers are seeing 500s. "
"Can someone look now?"
),
"questions": {
"urgent": Noul(instructions="Does this need attention right now?"),
},
})
urgency = response.nouls["urgent"].noul
Two middleware patterns are worth knowing:
- Model routing — Jev assesses an incoming request and picks which model should handle it, so simple lookups go to a cheap model and hard problems go to a strong one.
- Auto mode / tool-risk gating — Jev checks a tool call before it executes and blocks risky ones. This is the same guardrail pattern coding harnesses use internally, now available to any agent.
Troubleshooting Checklist
- Confidence too low? Don’t force a decision. Route to a human — this is the whole point of calibrated probabilities.
- Sending an image? Not supported. State must be text, a JSON object, or an array of text values.
- Mixed-language input? English is the primary training language. Chinese and Japanese inputs work but currently score lower accuracy.
- Getting inconsistent labels? Move the judgement criteria into the question’s
instructionsandcriteria, and keep the state free of instructions.