Skip to content

Jev Practices & Patterns

Caching and deduplication for repeated decisions

Repeated decisions are common. How to cache, deduplicate, and invalidate without serving stale policy or hiding a distribution change.
Published
Category
Jev Practices & Patterns
Resources cited
12
Reading time
6 min
Tags#operations#caching#deduplication#cost

A decision cache sounds like a contradiction. If two inputs are different, the answer may be different, and serving the first answer for the second is how a cache becomes a bug. But most decision traffic is not unique. It is the same ticket reopened, the same document reclassified after a field changed, or the same policy question asked in five branches of one workflow.

The useful move is to separate the kinds of repetition before choosing a cache.

Three repeats worth separating

The first is an exact repeat: the same state, the same questions, the same model version. Hashing that tuple is cheap and safe, and the cache hit is not a model decision at all.

The second is a same-intent paraphrase: a retried agent turn, a reworded support message, or the same request with a different greeting. A string hash misses it; an embedding cache may match it too loosely. This is the case that needs an adjudicator.

The third is repeated computation inside one request. If two branches both need urgency and refund risk, asking both questions once against one state is cheaper than two requests and avoids the cache entirely. The speculative fan-out pattern is the design version of this idea: ask everything the workflow might need, then ignore the answers the taken branch does not use.

Exact caching is a hash, not a model

For exact repeats, build the key from the full request: state bytes, question ids and wording, criteria, model version, and any instructions. Then store the answer with a timestamp. No model call, no ambiguity.

This is also the right place to put idempotency. The LLM cost optimizer records idempotency keys alongside its cost provenance and limits itself to at most two attempts. That combination (a key that identifies the logical request and an attempt counter that does not multiply the work) is what keeps a retry storm from becoming a billing incident.

The API reference helps here because answers come back keyed by the ids you choose, and those ids are never sent to the model. You can keep internal cache keys and question names inside your system.

Semantic caching needs an adjudicator

A cosine-similarity cache answers a different question: are these two inputs close enough in embedding space? That is a retrieval heuristic, not a decision. Two tickets about the same product can have nearly identical embeddings and opposite urgency.

jevcache takes the more defensible route. It sits in front of an OpenAI-compatible endpoint and asks a Jev or local System One adjudicator whether a paraphrase has the same intent, with a freshness check and a time bound. It fails open on adjudicator errors, and the repository reports zero false positives on a live 100-pair run against a Jaccard baseline, while explicitly treating that as precision-first practice, not a guarantee. The caveat matters: personalized content, tool-call replays, and multi-tenant use without a tenant header are out of scope.

GPTCache is the older, more general version of the idea. It supports exact and similarity matching, and its TypeSafe integration uses Noul checks to judge whether a cached response is still fresh for the current query. The project is MIT-licensed and widely used, but its README warns that the API may change and that new model adapters are no longer being added. Treat it as infrastructure you may need to fork, not a turnkey policy layer.

Deduplicate inside the request first

Before adding a cache, check whether you are paying twice for the same state; parallel questions are the structural fix. The parallel questions cookbook ran 13 questions (8 Noul, 2 Choice, 3 Score) over a 54,000-character document. One batched call cost $0.000497 and took 0.27 s; 13 single-question calls cost $0.006090 and 2.71 s. That is 12.2x cheaper and 10x faster, with the same answers across five repeats.

The mechanism is simple: the state is billed once, not once per question. The fan-out benchmark measured the same effect across 2,976 requests: median input-token savings at eight questions were 76% on a tiny control, 77% on a small state, 84% on a medium state, and 86% on a large state. Every request also carried about 261 input tokens of fixed overhead, which is the floor you pay even for a one-word state.

If your workflow sends five separate calls because the code is organized around five functions, the first optimization is not a cache. It is one request with five questions.

Freshness, tenancy, and versioning

A cache key that omits the model version is a time bomb. The models page shows that jev-latest and jev-preview both pointed at jev-1.13.0 at capture time, and that aliases can move. A cached answer produced by 1.13.0 may not be the answer 1.14.0 would give, especially on multilingual input where the release notes expect the largest gain.

The key also needs a tenant boundary. A cache shared across customers can leak one customer's phrasing into another's decision, even if the stored value is just a probability. If you cannot isolate the cache, isolate the key.

jev-workbench offers a useful model for the versioning problem: publishing a judgment function freezes the config and model version, and grants pin a client token to specific function versions. A published v2 does not silently upgrade callers. You can copy the principle without adopting the tool.

What a cache cannot fix

A cache does not improve a bad question. It makes the same bad answer cheaper. The workflow evals put Jev at 67.8% average accuracy at $0.0004 per case across four workflows, against 74.1% for a frontier model at $0.0836 and 23.3 s in the independent audit. A cache can cut the $0.0004; it cannot close the accuracy gap on invoice processing, where Jev scored 61.8% against 79.1% in that audit.

A cache also does not replace a confidence policy. The confidence docs recommend routing low-confidence answers to a human or a fallback, and a cached high-confidence answer from last month is not the same evidence as a fresh one. If the decision is consequential, cache the inputs and the model call, but re-run the policy.

The Jev inbox queue is a good small example of caching used correctly. It answers seven typed questions per email thread, keeps the policy in code, and caches answers so changing a threshold does not require new API calls. Its demo sorted 47 hand-labelled emails in 1.4 s with 0 of 23 actionable emails missed, and a real 100-email inbox in 2.7 s. The author is explicit that the demo labels are his own and that your inbox is the real test.

A cache policy you can defend

Write down four rules. Exact repeats use a hash key that includes model version, question text, and criteria. Semantic matches require an adjudicated same-intent verdict and a freshness window, and they fail open only if a stale answer is safer than no answer. Tenant and sensitivity labels are part of the key, not metadata added later. And every cache hit is logged with the key, the age, and the model version that produced it, so a wrong answer can be traced to the stored decision rather than to the current request.

Then measure hit rate and error rate together. A cache that saves 30% of calls but raises the error rate by one point is not a saving; it is a quality regression with a smaller invoice. The cost of a decision and one request, many questions explain why the input side is the right place to optimize. The reproducibility article explains why the key has to include the version.

From the Jev directory

The resources behind this article.

Ask everything the system might need in one request, then let code throw away what it does not use. The ticket-triage example sends a category plus four speculative questions in parallel.
Jev Practices & PatternsDocs#official#patterns#batching
Official
Fixture-first LLM router that picks the lowest expected-cost qualified route, verifies output before release, and records cost provenance with idempotency keys.
Jev Tools & CLIs#community#github
The raw HTTP contract behind every SDK: POST a state plus typed noul, choice, and score questions to /v1/systemone, and get one answer per question, with error codes and retry guidance.
Jev Guides & ArticlesDocs#official#docs#api
Official
12GitHub stars
Local OpenAI-compatible proxy that skips repeat model calls on same-intent paraphrases and retried agent turns, judged by Jev or a local System One model.
Jev Agents & MCP#community#awesomejev#catalog-import
8.2kGitHub stars
A semantic cache for LLM queries, fully integrated with LangChain and llama_index. Zilliz's cache integrates TypeSafe Jev Noul checks to evaluate cache hit freshness and time-dependent query validity, cutting repeated requests and API cost.
Jev Integrations & Adapters#community#semantic-cache#langchain
A 13-question regulatory briefing that shows batching every question into one call is 12.2x cheaper and 10x faster with no change in answers.
Jev CookbooksDocs#official#cookbook#batching
Official
0GitHub stars
Reproducible billing and stability measurement of Jev's fan-out behavior across 2,976 requests to jev-1.13-20260917: asking N questions in one call bills the state once, with raw data, exact invoice checks and a batched-versus-single answer comparison.
Jev Benchmarks & Evaluations#community#benchmarking#billing
The model card for jev-1.13.0: $42 per billion input tokens with free output, a 64k context, 250k tokens per second, and how to list the models your account can call.
Jev Guides & ArticlesDocs#official#docs#models
Official
3GitHub stars
Local service for authoring versioned judgment functions on TypeSafe Jev in a browser, then publishing one immutable version that both your backend calls over HTTP and your coding agents call over MCP, using a scoped client token.
Jev Agents & MCP#community#jevbest#catalog-import
Published evaluations of four automation workflows, security incidents, agent trace observability, invoice processing, and customer service, comparing Jev and frontier LLMs as structured workflows versus single prompts.
Jev Practices & PatternsDocs#official#benchmarks#evaluation
Official
How TypeSafe reports certainty, how it differs from probability, and how to use it architecturally to gate and route decisions.
Jev Practices & PatternsDocs#official#confidence#routing
Official
1GitHub stars
Turns an inbox into a short action queue: Jev answers seven typed questions per email thread in one request, plain Python rules decide what enters the queue, and cached answers mean changing a rule never needs new API calls.
Jev Tools & CLIs#community#catalog-import#logicrw
Back to all articles

Related Jev articles

Reprocessing a corpus is a different workload from serving one request. How to batch, fan out, and backfill decisions without blowing the budget.
Jev Practices & Patterns#operations#batching#backfills
Read article
The hosted price is a number; the self-hosted price is a system. How to compare hardware, utilization, operations, and evaluation honestly.
Jev Models & Reimplementations#models#cost#self-hosted
Read article

From the Jev AI model community

Posts from builders shipping with Jev right now.

Follow @typesafeai