Each prompt follows the same format: Objective (what it does), the copyable block (copy and replace the parts between <chevrons>) e How to verify (what to look at in the usage to know it worked). They all rely on the same truth: caching is prefix matching, and the sum of cache_read_input_tokens + cache_creation_input_tokens + input_tokens is the prompt size.
Legend: the three steps purples prepare and run; the step cyan confirm in the usage whether the cache improved.
🕵️ Audit a pipeline's cache
Use when the cache “doesn’t hit” and you don’t know why. This prompt has Claude Code scan the code that builds the prefix and return a actionable list of silent invalidators, each with a file, line, and fix.
Objective
List every byte of variation in your pipeline that prevents caching, prioritized by impact.
Prompt (copy and replace <…>)
Audite o prompt caching do meu pipeline em <caminho/do/projeto>. Varra TUDO que alimenta o prefixo (a lista de `tools`, o `system` e o começo estável das `messages`) e liste cada silent invalidator: - datetime.now() / Date.now() / uuid / id aleatório no prefixo; - json.dumps sem sort_keys=True; - iteração de set (ordem não garantida); - tools montadas por usuário/modo; - seção condicional no system (if flag: system += ...). Para cada achado, dê: arquivo, linha, por que quebra o cache e o fix mínimo. Ordene por impacto — o que fica mais na FRENTE do prefixo primeiro.
How to verify
Apply the fixes and run two identical requests. In the usage, cache_read_input_tokens must stop being 0 starting with the 2nd. If it’s still 0, an invalidator remains — use Prompt 4.
Tools + system + messages
Actionable finding
Front of the prefix before
read > 0 on the 2nd request
🔤 Make the tools list deterministic
Use when the tools come from a set/dict and the order can vary. Since the tools are in the position 0, any change in order invalidates the entire prefix.
Objective
Ensure that the list of tools always come out in the same order across requests.
Prompt (copy and replace <…>)
Em <caminho/do/arquivo>, a lista de `tools` é montada assim: <cole aqui o trecho que monta as tools> Reescreva pra serialização ficar DETERMINÍSTICA: 1) ordene as tools por nome antes de enviar (ex.: sorted(tools, key=lambda t: t["name"])); 2) garanta que cada objeto interno saia ordenado (json.dumps(..., sort_keys=True)); 3) confirme que a ordem é IDÊNTICA entre dois requests. Mostre o diff e explique por que isso preserva o prefixo (posição 0).
How to verify
Send two identical requests: cache_read_input_tokens becomes > 0 on the 2nd. Before the fix, it stayed at 0 even when repeating the same prompt.
Tools before everything
Sort by name
Internal objects too
Between requests
🤔 Decide whether to compact or continue
Use when the context has grown and you’re not sure whether it’s worth it /compact. This prompt puts numbers in the decision: cost per turn of continuing vs. the one-time cost of compacting, with the payback.
Objective
Compare the per-turn cost of loading the current context with the one-time cost of compacting, and recommend an option.
Prompt (copy and replace <…>)
Estou com um contexto de ~<N> tokens e ainda faltam ~<M> turnos.
Compare os dois caminhos (use read≈0,1× · write 5min≈1,25×):
(a) CONTINUAR sem compactar: custo por turno = N @ 0,1× ≈ N/10-equiv,
repetido em todos os <M> turnos;
(b) COMPACTAR pra ~<K> tokens: 1 write frio K @ 1,25× (uma vez) e
depois K @ 0,1× por turno.
Diga o payback (em quantos turnos a compactação se paga) e recomende
compactar OU continuar — considerando também o teto de 1M e a qualidade
(context rot). Se a conversa for curta, avise que continuar pode ser melhor.How to verify
The recommendation should follow the guideline from module 3.1: small context / few turns → continue (keeps the cache warm); large context, near the limit, or declining quality → compact (payback in ~1 turn).
N @ 0,1×
K at 1.25×, once
How many turns until it pays off
Small → continue
🩺 Diagnose cache_read = 0
Use when cache_read_input_tokens comes always 0 even when repeating the same prompt. This proves there's a silent invalidator; this prompt makes the byte diff to find the culprit.
Legend: two "identical" prefixes, one different section. That byte is why cache_read stay 0.
Objective
Find the first byte that changes between two identical requests and its source.
Prompt (copy and replace <…>)
Meu cache_read_input_tokens vem SEMPRE 0 repetindo o MESMO prompt. Capture os bytes exatos do prefixo (tools + system + começo das messages) de DOIS requests consecutivos e faça o diff entre eles. Aponte o PRIMEIRO ponto que difere e explique a origem (relógio/datetime.now(), uuid, ordem de set/dict, json.dumps sem sort_keys, seção condicional no system). Proponha o fix determinístico. Arquivos que montam o prefixo: <cole os caminhos>.
How to verify
After the fix, diff the two prefixes again: it should be empty. Then cache_read_input_tokens starts increasing with each repeated turn.
The symptom
Equal, consecutive
1st byte that changes
Clean diff = fixed
🧊 Review the cache-friendly system prompt
Use when the system prompt has an interpolated date, user name, or mode. This prompt freezes the system and moves the dynamic context to the end of the messages, without losing information.
Objective
Remove all dynamic interpolation from the system and return it as a ready-to-use block for the end of the messages.
Prompt (copy and replace <…>)
Aqui está meu system prompt: <cole o system prompt inteiro> Remova TODA interpolação dinâmica dele (data/hora, nome do usuário, modo, e qualquer valor que muda entre requests) e mova esse contexto pro FIM das messages — nunca no system. Devolva: 1) o system CONGELADO (fixo, sem variáveis); 2) o bloco de contexto dinâmico pronto pra ir nas messages; 3) o diff comentado, explicando por que cada mudança preserva o prefixo.
How to verify
After the change, the system is byte-for-byte identical across requests. The cache for tools + system stop invalidating and cache_read_input_tokens covers this section.
System without variables
Dynamic → end of messages
Context is still there
Identical prefix
📍 Breakpoint strategy
Use when you control the cache_control manually (outside Claude Code, in the API). They are at most 4 per request; this prompt suggests where to put them and warns about the 20-block lookback.
Legend: two well-placed breakpoints (end of the system, end of the shared section) cover almost everything; the variable portion intentionally left out.
Objective
Decide where to position the cache_control and avoid the 20-block lookback gap.
Prompt (copy and replace <…>)
Meu prompt tem esta estrutura: <descreva: tamanho do system; se as tools mudam; se há um trecho compartilhado seguido de um sufixo que varia por request> Sugira onde colocar os cache_control (MÁX. 4 por request). Tipicamente: - no fim do `system` estável; - no fim do maior trecho COMPARTILHADO, antes da parte variável. Alerte sobre o 20-block lookback: se um turno adiciona >20 blocos (loops com muitos tool_use/tool_result), proponha um breakpoint intermediário (~a cada 15 blocos). Explique cada escolha.
How to verify
cache_read_input_tokens stays high and stable from turn to turn. If a turn with many blocks drops the read to 0, the lookback is missing an intermediate breakpoint.
Breakpoints per request
Cache tools+system
Before the variable part
Lookback: intermediate pt.
The complete toolkit
cache_control and the 20-block lookback warning.End of Track 3
You’ve covered the advanced best practices: deciding between caching and compaction, building a cache-friendly architecture, and keeping your prompts handy. Mark the topics as read and track your progress in “My journey.”