Patterns
Using Jev inside an AI agent
Agents spend most of their tokens deciding, not doing. Tool selection, routing and self-checks are exactly the shape of problem a System One model exists for — which is why the first serious Jev projects are all agents.
Pattern 1: tool selection
The classic agent loop asks an LLM “here are 40 tools, which do you call and with what arguments?” That one prompt carries every tool schema, costs real latency, and gets worse as you add tools. Jev splits the decision from the argument-writing:
# 1. Jev picks the tool (fast, cheap, calibrated).
# criteria maps each tool to when it should be used — built per turn.
response = client.system_one(
model="jev-latest",
state=conversation_so_far,
questions={
"tool": Choice(
instructions="Which tool should run next?",
criteria={t.name: t.description for t in available_tools},
),
},
)
# 2. An LLM only fills in arguments for the tool that won
answer = response.answers["tool"]
if answer.confidence >= THRESHOLD:
tool = registry[answer.choice]
args = llm.fill_arguments(tool.schema, conversation_so_far)
return tool.run(**args)
else:
return llm.full_agent_step(conversation_so_far) # fall backjev-eval-agent tests precisely this: a personal assistant with 100 mocked tools, measuring how many steps the agent needs when the LLM picks the tool itself versus when Jev picks it. It also implements the confidence gate above with a configurable threshold.
Pattern 2: a dynamic action space
Tool selection gets more interesting when the options change every turn. A browser agent's action space is whatever is on the page right now — you cannot enumerate it in advance.
jev-ultrafast handles this by indexing the live page into a dynamic action space, then asking Jev to pick both the operation and the target element. A small LLM is invoked only for TYPE_TEXT operations, where actual text has to be written. Everything else — click, scroll, select — never touches a generative model.
Pattern 3: confidence-gated routing
The cheapest possible agent is one that only wakes the expensive model when it has to. Use Jev as a triage layer in front of your LLM:
High confidence
Act directly on Jev's choice. Milliseconds, fractions of a cent.
Middling
Hand to a small or mid-tier LLM with Jev's distribution as a hint.
Low / tie
Escalate to a frontier model or a human. Log it — these are your training signal.
Pattern 4: cheap self-checks with Noul
Because questions are evaluated in parallel against one state, verification is nearly free. Before an agent returns an answer, fan out a handful of Noul questions in a single call:
def check(instructions, yes, no):
return Noul(instructions=instructions,
criteria=NoulCriteria(true=yes, false=no))
questions = {
"answers_question": check("Does this answer the user's question?",
"Directly addresses the ask", "Evasive or off-topic"),
"no_pii": check("Is this free of personal data?",
"No names, emails or IDs", "Contains personal data"),
"tone_ok": check("Is the tone professional?",
"Courteous and appropriate", "Rude or off-brand"),
}
# one call, ~same latency as asking just oneThis is the guardrail pattern that used to require either a second LLM pass or a pile of regexes.
Where this breaks down
- Arguments still need an LLM. Jev picks; it does not fill in parameters. Your loop needs both models and the plumbing between them.
- Two vendors, two failure modes. A Jev outage now breaks your agent too. Keep an LLM-only fallback path that actually works.
- Thresholds are yours to earn. Do not ship a guessed confidence cutoff — measure it against labelled examples from your own traffic.
- Long context. With a ~32K request budget, a long agent transcript needs summarising or windowing before it becomes the state.