SemanticCache stores responses keyed on embedding similarity rather than exact string matching, so a new prompt that is close enough to a cached one returns the stored answer instantly without touching the model.
How it works
When you callcache.get(prompt), SemanticCache embeds the prompt and queries the backing vector store for the nearest stored entry. If the top result’s cosine similarity exceeds the configured threshold (default 0.95) and the entry has not expired, it’s a cache hit and the stored response is returned. On a miss, your code calls the LLM as normal, then stores the response with cache.set() for future hits.
The cache.wrap() convenience method handles the full get-or-produce flow in one call.
Setup
Constructor options
SemanticCacheOptions
SemanticCacheOptions
The default
store is an in-process MemoryVectorStore. Use SqliteVectorStore or another persistent store to keep the cache across process restarts.API
cache.get(prompt, opts?)
Looks up a prompt in the cache. Returns a CacheLookup object.
CacheLookup fields:
The optional
opts object accepts:
cache.set(prompt, value)
Stores a response string paired with the prompt’s embedding. Call this after a model response to prime future cache hits.
cache.wrap(prompt, produce, opts?)
The recommended entry point. Checks the cache, calls produce() on a miss, stores the new response, and returns a result object.
Integrating with an agent
Wrap the model call insidedefineAgent with cache.wrap() to cache agent responses by their user query:
Tuning the threshold
The rightthreshold depends on how similar “equivalent” prompts need to be for your use case.
Observability
When you pass atrace handle to cache.get() or cache.wrap(), Anvil records a cache span that includes:
hit— whether the lookup was a cache hitscore— the cosine similarity of the nearest entrythreshold— the configured threshold