O problema: agentes de IA vivem no Dia da Marmota
No filme Groundhog Day (Feitiço do Tempo), o personagem de Bill Murray acorda todo dia repetindo exatamente o mesmo 2 de fevereiro, do zero, sem carregar nada do que viveu no dia anterior. Agentes de Inteligência Artificial (IA) enfrentam um problema parecido: a cada passo da execução — cada chamada de ferramenta, cada resultado retornado, cada decisão tomada — o modelo precisa receber novamente todo o contexto acumulado da conversa.
Isso acontece porque Modelos de Linguagem de Grande Escala (LLMs) não têm memória entre requisições. Na virada do turno 20 de uma sessão de trabalho, o modelo relê os turnos 1 a 19 inteiros — e você paga por cada token repetido. A AWS publicou um guia técnico explicando como o prompt caching quebra esse ciclo no Amazon Bedrock, com foco em modelos OpenAI.
O que um agente envia ao modelo em cada turno
Antes de entender o cache, vale entender o que compõe uma requisição típica de agente:
- Lista de ferramentas: as definições de cada função que o agente pode chamar. Muda quando há uma nova versão.
- Instruções: o prompt de desenvolvedor com regras, persona, políticas e exemplos. Também muda por versão.
- Histórico: tudo que aconteceu na sessão até agora — tarefa, chamadas de ferramentas e resultados. Cresce a cada turno.
- Novo turno: o resultado mais recente de uma ferramenta ou a mensagem do usuário.
Sem cache, o agente reenvia tudo isso ao modelo a cada turno. O prompt caching resolve isso armazenando o estado processado do prompt e reutilizando-o nas requisições seguintes, a uma fração do preço de entrada normal.
Como o prompt caching funciona por dentro
Quando o modelo lê um prompt, ele executa uma etapa chamada prefill: processa cada token de entrada e constrói seus vetores internos de chave e valor (KV — Key-Value), que formam o estado de trabalho do modelo antes de gerar qualquer resposta. O prompt caching salva esse estado.
Quando uma requisição posterior começa com os mesmos tokens de entrada, o serviço carrega o estado salvo em vez de recomputá-lo. Apenas o conteúdo novo é processado.
O cache pode ser implícito — onde o Amazon Bedrock decide automaticamente onde termina o prefixo reutilizável — ou explícito — onde o código marca esse ponto usando prompt_cache_breakpoint. As duas abordagens podem ser combinadas, e a AWS recomenda isso para cargas de trabalho de agentes.
Primeiro cache: conteúdo estático
O primeiro ganho é cachear a parte estática do prompt: ferramentas e instruções que não mudam entre requisições. O prefixo reutilizável precisa ter pelo menos 1.024 tokens para ser elegível. Para conteúdo estático, o modo explícito é o mais indicado — você escolhe exatamente onde o prefixo salvo termina:
KEY = "support-agent:v7:gpt-6-astra"
INSTRUCTIONS = "Your full support policies and examples..." # Rendered context: [provider context][TOOLS][INSTRUCTIONS] | [task]
# Cache starts at the beginning; the marker below chooses its end.
resp = client.responses.create(
model="us.openai.gpt-6-astra",
store=False, # Response storage; prompt caching still works.
include=["reasoning.encrypted_content"],
prompt_cache_key=KEY,
prompt_cache_options={"mode": "explicit", "ttl": "30m"},
tools=TOOLS, # Rendered before instructions; keep order stable.
input=[
{
"role": "developer",
"content": [{
"type": "input_text",
"text": INSTRUCTIONS, # Save through this whole block, including TOOLS.
"prompt_cache_breakpoint": {"mode": "explicit"},
}],
},
# User message is processed but not cached.
{"role": "user", "content": task},
],
)
O prompt_cache_key indica ao serviço quais requisições devem compartilhar um cache. Em testes com esse padrão, um prefixo de cerca de 4.000 tokens escreveu 4.120 tokens na primeira requisição e leu esses mesmos 4.120 tokens nas requisições seguintes.
Um ponto de atenção importante: o prompt caching só funciona quando você passa exatamente o mesmo texto. Instruções e listas de ferramentas precisam ser serializadas da mesma forma sempre. Qualquer conteúdo variável — como data, nome do usuário ou ID de requisição — deve vir após o limite do cache.
Cache implícito para histórico crescente
À medida que a conversa cresce com ferramentas e conteúdos diferentes, o modo implícito permite que o serviço acompanhe o histórico automaticamente:
def ask_with_implicit_cache(history):
return client.responses.create(
model="us.openai.gpt-6-astra",
store=False,
include=["reasoning.encrypted_content"],
prompt_cache_key=KEY,
prompt_cache_options={"mode": "implicit", "ttl": "30m"},
tools=TOOLS,
input=history, # Everything gets cached
)
history = [
{"role": "developer", "content": INSTRUCTIONS},
{"role": "user", "content": task},
]
# Automatic endpoint: the end of the user message.
resp = ask_with_implicit_cache(history)
Para combinar os dois modos — um ponto de partida compartilhado explícito e um histórico crescente gerenciado implicitamente — basta adicionar o marcador no bloco do desenvolvedor e chamar a função com modo implícito no nível da requisição:
history = [
{
"role": "developer",
"content": [{
"type": "input_text",
"text": INSTRUCTIONS,
"prompt_cache_breakpoint": {"mode": "explicit"},
}],
},
{"role": "user", "content": task},
]
# Still implicit mode, now with an explicit startup save point in the history.
resp = ask_with_implicit_cache(history)
Cacheando histórico e resultados de ferramentas
O loop de execução do agente acumula saídas do modelo e resultados de ferramentas no histórico. Em modo implícito, o Amazon Bedrock pode reutilizar o prefixo inalterado e cachear o conteúdo adicionado até o último resultado de ferramenta:
import json
# Map tool names to their Python implementations.
TOOL_HANDLERS = {
"get_owner": get_owner,
# Register your other initial tools here.
}
def execute_function(name, arguments):
"""Run the requested tool and return its result."""
handler = TOOL_HANDLERS.get(name)
if handler is None:
return {"error": f"Unknown tool: {name}"}
return handler(**arguments)
while True:
# Preserve all output items, including encrypted reasoning.
history.extend(resp.output)
calls = [x for x in resp.output if x.type == "function_call"]
if not calls:
break
for call in calls:
result = execute_function(call.name, json.loads(call.arguments))
history.append({
"type": "function_call_output",
"call_id": call.call_id,
"output": json.dumps(result),
})
# The last result in this group supplies the automatic endpoint.
resp = ask_with_implicit_cache(history)
Para o modo explícito puro, o loop marca o resultado final de cada lote com um prompt_cache_breakpoint, mantendo os marcadores anteriores no histórico. Consulte as regras atuais de lookup para conversas longas na documentação oficial.
Em testes com seis turnos, o GPT-6 Astra com breakpoints implícitos apresentou cerca de 62% de redução no custo de entrada em comparação com execução sem cache. O modo explícito com rolling breakpoints economizou cerca de 61% no mesmo modelo.
Quando as ferramentas mudam durante a sessão
Adicionar, remover ou reordenar definições de ferramentas invalida o prefixo cacheado. Para lidar com isso, a AWS descreve duas abordagens:
- Ferramentas conhecidas em etapas diferentes: mantenha a lista
TOOLSestável e useallowed_toolspara limitar o que o modelo pode chamar em cada etapa, sem alterar o catálogo cacheado. - Novas ferramentas durante a sessão: os endpoints Amazon Bedrock Runtime e Amazon Bedrock Mantle aceitam um tipo de item de entrada chamado
additional_toolspara GPT-6 Astra, GPT-6.1 Sol e GPT-5.6 Luna. Para disponibilidade por região da AWS, consulte os modelos suportados por região da AWS no Amazon Bedrock.
TOOL_HANDLERS["get_due_date"] = get_due_date
NEW_TOOL = {
"type": "function",
"name": "get_due_date",
"description": "Return the due date for a support case.",
"strict": True,
"parameters": {
"type": "object",
"properties": {"case_id": {"type": "string"}},
"required": ["case_id"],
"additionalProperties": False,
},
}
history.append({
"type": "additional_tools",
"role": "developer",
"tools": [NEW_TOOL],
})
history.append({
"role": "user",
"content": "Find the due date for case C-123.",
})
# Implicit mode saves through this new user message, including NEW_TOOL.
resp = ask_with_implicit_cache(history)
d = resp.usage.input_tokens_details
print("old prefix read", d.cached_tokens, "new write", d.cache_write_tokens)
# Example output:
# old prefix read 2048 new write 256
Subagentes e chamadas paralelas
Ao delegar tarefas a agentes auxiliares, é possível compartilhar o prefixo cacheado entre eles. A recomendação da AWS é fazer um “aquecimento” (warm-up) antes de disparar os helpers em paralelo:
shared = {"role": "developer", "content": [{
"type": "input_text",
"text": INSTRUCTIONS,
"prompt_cache_breakpoint": {"mode": "explicit"},
}]}
warm = client.responses.create(
model="us.openai.gpt-6-astra",
store=False,
tools=TOOLS,
prompt_cache_key=KEY,
prompt_cache_options={"mode": "implicit", "ttl": "30m"},
max_output_tokens=16,
input=[shared, {"role": "user", "content": "Reply READY."}],
)
d = warm.usage.input_tokens_details
if not (d.cache_write_tokens or d.cached_tokens):
raise RuntimeError("Shared prefix was not cached.")
from concurrent.futures import ThreadPoolExecutor
# helper_tasks contains the task text for each helper.
helper_inputs = [
[shared, {"role": "user", "content": task}]
for task in helper_tasks
]
with ThreadPoolExecutor(max_workers=4) as pool:
helpers = list(pool.map(ask_with_implicit_cache, helper_inputs))
Para chamadas laterais como sumarizadores ou juízes, basta copiar o histórico completo do agente pai e adicionar a instrução específica do helper:
from copy import deepcopy
# history is the completed history built by the agent loop above.
# Copy it so the helper can add instructions without changing the parent.
helper_history = deepcopy(history)
helper_history.append({
"role": "developer",
"content": "Summarize this conversation in one sentence. Do not call tools.",
})
summary = ask_with_implicit_cache(helper_history)
d = summary.usage.input_tokens_details
print("history read", d.cached_tokens, "write", d.cache_write_tokens)
print(summary.output_text)
# Example output (assumed values and conversation):
# history read 4096 write 32
# Case C-123 is due on October 31, 2026.
Pausas, reinícios e chaves de cache
Prefixos cacheados têm um tempo de vida (TTL — Time to Live) mínimo de 30 minutos, renovado a cada reutilização bem-sucedida. Para novas sessões que precisam reutilizar o mesmo prefixo, a chave de cache deve ser estável. Uma chave específica por sessão isola as entradas de cache mesmo quando os prompts coincidem.
A AWS recomenda derivar a chave de cache a partir do conteúdo das instruções usando um hash:
import hashlib
def cache_key(app, model, prompt_version, instructions):
digest = hashlib.sha256(instructions.encode()).hexdigest()[:12]
return f"{app}:{prompt_version}:{model}:{digest}"
KEY = cache_key("support-agent", "us.openai.gpt-6-astra", "v7", INSTRUCTIONS)
prefix = {"role": "developer", "content": [{
"type": "input_text",
"text": INSTRUCTIONS,
"prompt_cache_breakpoint": {"mode": "explicit"},
}]}
for label, question in [
("session A", "Explain the refund policy without calling tools."),
("session B", "Explain the escalation policy without calling tools."),
]:
# A fresh conversation for each session; the startup prefix matches.
session_history = [prefix, {"role": "user", "content": question}]
result = ask_with_implicit_cache(session_history)
d = result.usage.input_tokens_details
print(label, "read", d.cached_tokens, "write", d.cache_write_tokens)
Na primeira execução a frio, a sessão A escreve o prefixo compartilhado. A sessão B pode lê-lo mesmo com uma tarefa diferente. A reutilização do cache exige o mesmo modelo, conta AWS e região.
O que o prompt caching entrega em números
Para um agente baseado em GPT-6 Astra com um prefixo inicial de 8.000 tokens e seis turnos adicionando 2.000 tokens cada, os resultados modelados pela AWS foram:
- Cache estático de uma vez: custo reduzido a US$ 0,50 por sessão.
- Rolling breakpoints explícitos: redução de 64% no custo de entrada modelado — de US$ 0,87 para US$ 0,32 por sessão.
Esses são resultados de uma carga de trabalho específica. A AWS recomenda medir os ganhos do seu próprio agente.
Como verificar se o cache está funcionando
O campo cached_tokens no uso da resposta indica tokens lidos do cache; cache_write_tokens indica tokens escritos. Para monitoramento em produção no endpoint Amazon Bedrock Runtime, as métricas CacheReadInputTokenCount e CacheWriteInputTokenCount estão disponíveis no Amazon CloudWatch. Para custos, filtre o AWS Cost Explorer pelo Amazon Bedrock e agrupe por tipo de uso — leituras, escritas e entradas não cacheadas aparecem como entradas separadas por modelo.
Lista de verificação rápida
- Mantenha o prefixo reutilizável estável: ferramentas e instruções compartilhadas primeiro, histórico e novos turnos depois.
- Use cache implícito para histórico crescente, marcadores explícitos para prefixos compartilhados, ou ambos.
- No modo explícito puro, mantenha os marcadores de turnos anteriores para que requisições futuras encontrem os prefixos salvos.
- Mantenha o catálogo inicial de ferramentas inalterado; use
allowed_toolspara restringir chamadas eadditional_toolspara adicionar novas ferramentas. - O prefixo cacheável precisa ter pelo menos 1.024 tokens e permanece elegível por pelo menos 30 minutos após a última escrita ou reutilização bem-sucedida.
- Aqueça o conteúdo compartilhado antes de disparar helpers em paralelo.
- Use chaves de cache estáveis dentro de cada grupo de compartilhamento.
- Escritas de cache custam 1,25 vez a taxa normal de entrada; leituras dependem do modelo.
Conclusão
Assim como Bill Murray só escapa do Dia da Marmota quando para de repetir os mesmos erros e começa a carregar o que aprendeu de um dia para o outro, agentes de IA saem do ciclo de reprocessamento quando mantêm o início do prompt estável e usam limites de cache automáticos ou explícitos à medida que o histórico cresce.
A combinação de cache implícito para conversas em evolução e marcadores explícitos para conteúdo compartilhado cobre a maioria dos cenários. Para aplicar esses padrões, a AWS disponibiliza a documentação de prompt caching para modelos OpenAI no Amazon Bedrock e informações sobre disponibilidade de modelos por região e endpoint.
Fonte
Groundhog Day for AI agents: Prompt caching patterns for using OpenAI models on Amazon Bedrock (https://aws.amazon.com/blogs/machine-learning/groundhog-day-for-ai-agents-prompt-caching-patterns-for-using-openai-models-on-amazon-bedrock/)
Leave a Reply