Where should tool/function call schemas live in the assembled context, and why?
Tool schemas go at the top in the cached prefix because they are static and load-bearing; any per-user variation lives in a small separate per-call block to keep the cache hit rate high.
Think of a giant menu at a restaurant. The menu stays the same all day, so the restaurant prints it once and puts it on every table. They do not retype it for each customer. Now imagine one customer is allergic to peanuts. The restaurant does not reprint the whole menu without peanut dishes. They hand that one customer a small slip of paper that says, skip these two dishes. The menu is the tool schemas, printed once and reused for everyone. The slip is the per-user flag. If you put the slip into the big menu, you have to reprint the menu for every customer, which is slow and expensive. Keep the big static thing static, and put the small variable thing on its own slip.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
If you have eight tools at three hundred tokens each, you are carrying 2,400 tokens of schema on every call. That is not optional weight, the model has to read it to know what actions exist. The question is whether you pay for those 2,400 tokens at full price every call or at 10-15% of full price after the first call.
The answer depends entirely on where the schemas sit in the assembled prompt. Top placement, inside a stable cached prefix, is essentially free after the first call. Anywhere else and you are paying every time, plus losing the primacy slot that helps the model anchor on the available action space.
This question shows up in agent design in 2026 because every production stack runs against providers that offer prompt caching, and getting cache hit rates above 90% is the difference between a sustainable agent and a money pit. The placement decision sounds like a small detail. At scale it is the biggest single cost lever you have on the system-prompt side.
How prompt caching actually works in 2026
Every major provider exposes some form of prompt caching, and they all share the same primitive: the cache is keyed on the contiguous byte-identical prefix of the prompt. The first call pays the full input cost; subsequent calls within the cache TTL pay roughly 10-15% of the input cost for everything before the first divergence.
Anthropic Claude uses explicit cache_control markers. You annotate the prompt with cache_control: {type: 'ephemeral'} at up to four checkpoints, and Anthropic caches the content up to each checkpoint. The TTL is 5 minutes by default with an option to extend to 1 hour at a 2x write cost.
OpenAI GPT-5.5 uses automatic prefix caching. There is no API surface; if your prompt is over ~1024 tokens and starts with a prefix identical to a recent call, the cached portion is billed at 50% of input cost. No control over what gets cached, it is purely 'longest matching prefix wins.'
Google Gemini offers explicit CachedContent objects via the API. You upload the cached portion once, get back a cache handle, and reference it on subsequent calls. Pricing is by cached tokens per hour. Best for long-running sessions where the same context block is reused many times.
The rule across all three: caching only pays off if the prefix is stable. A single byte of variation, a different user ID, a new timestamp, a reordered list, invalidates the cache for everything after that byte. Tool schemas at the top of the prompt, byte-identical across every call, are the ideal cache target.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Placement | Cache hit rate | Anchoring | When to use |
|---|---|---|---|
| System prompt top | High (90%+) | Strong (primacy) | Default for static schemas |
| Per-call user block | None | Weak | Only the per-user diff goes here |
| End of prompt | Low (varies per call) | Weak (recency stolen by question) | Never; antipattern |
| Mixed inline with task | None | Diluted | Never; antipattern |
Real products, models, and research that use this idea.
- Anthropic Claude Opus 4.7 prompt caching uses cache_control markers; production Claude Code agents place all tool definitions before the first cache boundary for ~10x cost reduction on the prefix.
- OpenAI GPT-5.5 automatic prefix caching kicks in on identical prompt prefixes over ~1024 tokens; agent stacks structure tool blocks at the top to hit the cache for free.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow do you handle a tool whose description must include per-user data, like the user's timezone or current account balance?
Keep the tool description static and pass the per-user data as part of the user turn or a dedicated per-call context block. The description says 'use the user's local timezone'; the actual timezone arrives separately and is not part of the cached schema.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Dropping per-user feature flags into the middle of the tool definitions block. That one byte of variation invalidates the entire cached prefix and you pay full price every call.
60 second bullets to scan on the way to the call.
Why prompt caching requires a stable prefix
What happens to the cache when a per-user flag is dropped into the middle of the schema block
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.