An agent that looks like one system is really four caches stacked on top of each other, and each one fails in a different way. Getting the vocabulary straight is the first step, because teams routinely argue about "caching" while meaning completely different things.
Prompt caching stores the key-value tensors the model computes during prefill, the phase where it reads the input tokens. A later request with the same prefix skips that recomputation and starts reading at the bookmark, which cutting teams describe as cost savings of 50 to 90 percent and latency savings of up to 80 percent in this explainer. The model's outputs still change between calls; only the processing of the input is reused.
Response caching sits in front of the provider. An identical request body, model, key and streaming mode is hashed into a cache key, and a hit returns the stored response with zero tokens billed per these docs. This is exact match only: one character different and you have a new key.
Semantic caching embeds the query and returns a stored answer when cosine similarity clears a threshold, which catches paraphrases that exact-match caching misses as described here. It trades precision for hit rate, so a threshold set too low returns confident answers to the wrong question.
Tool and retrieval caches store the outputs of external calls: a vector search, a database read, an HTTP fetch. These are the cheapest wins in agent loops because they avoid network round trips as well as tokens.
| Layer | What is stored | Match rule | Freshness risk |
|---|---|---|---|
| Prompt cache | KV tensors for a prefix | Exact prefix, byte for byte | Low on content, expires on its own |
| Response cache | Full response body | Exact request hash | Medium, replay of old output |
| Semantic cache | Query embedding plus answer | Similarity above threshold | High, wrong-question risk |
| Tool cache | Return value of a call | Cache key you define | Depends on the data source |
A useful rule: prompt caching is nearly free and almost never wrong, so turn it on first. Every other layer needs an explicit freshness argument.



