Este tópico descreve como usar o cache explícito e suas melhores práticas. Ao adicionar marcadores de cache às requisições, você garante acertos determinísticos para conteúdos de entrada idênticos, o que reduz significativamente custos e latência.
Quando usar o cache explícito
- Necessidade de acertos garantidos: O cache explícito oferece 100% de acertos determinísticos, independentemente do agendamento de recursos do backend. Se sua aplicação exige reutilização estável de conteúdo, essa é a escolha ideal.
- Reutilização frequente do mesmo prompt: O envio repetido de prompts idênticos ou altamente consistentes reduz drasticamente os custos com o cache explícito. A criação do cache gera apenas uma sobretaxa de 25% sobre o preço padrão de entrada, enquanto cada acerto subsequente economiza 90%. Um único acerto já compensa o investimento inicial.
- Gestão de contextos longos em Agents de produção: Em aplicações de Agent, mecanismos comuns como compressão, resumo e lembretes do sistema alteram o contexto continuamente. O cache explícito permite fixar e reutilizar segmentos-chave, mantendo-os em cache mesmo quando o contexto ao redor evolui.
Ferramentas de Agent e codificação
As ferramentas de Agent e codificação listadas abaixo se conectam ao Alibaba Cloud Model Studio via protocolo Anthropic e suportam nativamente o cache explícito. Configure-as conforme as respectivas documentações para que aproveitem automaticamente o cache explícito na otimização do gerenciamento de contexto.
Os exemplos abaixo usam o endpoint de Singapura. Para outras regiões, substitua a URL base pelo endpoint regional correspondente.
Claude Code
O Claude Code v2.x e versões posteriores incluem automaticamente marcadores cache_control nas requisições (system, env e mensagem mais recente do usuário). Nenhuma configuração adicional é necessária após a conexão ao endpoint compatível com Anthropic do Alibaba Cloud Model Studio.
Crie ou edite o arquivo ~/.claude/settings.json (Windows: C:\Users<username>.claude\settings.json) com as configurações de plano apropriadas. Alternativamente, conecte-se via variáveis de ambiente:
export ANTHROPIC_BASE_URL="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic"
export ANTHROPIC_AUTH_TOKEN="${DASHSCOPE_API_KEY}"
export ANTHROPIC_MODEL="qwen3.7-max"
claude
Defina o endpoint do protocolo Anthropic:
-
Token Plan (Team): https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic
-
Coding Plan: https://coding-intl.dashscope.aliyuncs.com/apps/anthropic
-
Pagamento conforme o uso: https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic
Substitua
WorkspaceIdpelo seu ID do Workspace real.
Para mais detalhes, consulte Claude Code.
Opcional: Melhorar a taxa de acerto entre sessõesPor padrão, o Claude Code inclui informações dinâmicas no prompt do sistema (diretório atual, data, status do git), o que pode reduzir as taxas de acerto de cache entre sessões. Adicione a seguinte flag na inicialização para mover seções dinâmicas para as mensagens do usuário:
claude --exclude-dynamic-system-prompt-sections
Open Code
Quando o OpenCode se conecta ao endpoint compatível com Anthropic do Alibaba Cloud Model Studio via @ai-sdk/anthropic, ele injeta automaticamente cache_control na mensagem do sistema e na mensagem não-sistema mais recente.
npm install -g opencode-ai
ConfiguraçãoCrie o arquivo de configuração ~/.config/opencode/opencode.json (Windows: C:\Users<username>.config\opencode\opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"bailian": {
"npm": "@ai-sdk/anthropic",
"name": "Alibaba Cloud Model Studio",
"options": {
"baseURL": "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1",
"apiKey": "{env:DASHSCOPE_API_KEY}"
},
"models": {
"qwen3.7-max": { "name": "qwen3.7-max" }
}
}
}
}
ObservaçãoA baseURL deve terminar com /v1.
export DASHSCOPE_API_KEY=sk-xxxxx
opencode run -m "bailian/qwen3.7-max" "..."
Outras URLs base de planos:
- Token Plan (Team): https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
- Coding Plan: https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1
Para mais detalhes, consulte OpenCode.
OpenClaw
Ao usar o endpoint compatível com Anthropic, o OpenClaw injeta automaticamente marcadores cache_control no prompt do sistema e na mensagem mais recente do usuário. Nenhuma configuração extra é necessária — desde que a Base URL do provedor aponte para /apps/anthropic, o cache explícito será ativado automaticamente.
npm install -g openclaw
# or
curl -fsSL https://openclaw.ai/install.sh | bash
ConfiguraçãoEdite o arquivo de configuração ~/.openclaw/openclaw.json. Defina "api" como "anthropic-messages" e configure a URL base:
- Token Plan (Team): https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
- Coding Plan: https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1
- Pagamento conforme o uso: https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
Para mais detalhes, consulte OpenClaw.
Opcional: Limite de cache personalizadoSe o prompt do sistema contiver tanto conteúdo de modelo estável quanto conteúdo dinâmico (carimbos de data/hora, CWD etc.), insira <!-- OPENCLAW_CACHE_BOUNDARY --> entre eles. O OpenClaw aplicará cache_control apenas ao prefixo estável antes do limite, melhorando as taxas de acerto entre sessões:
You are a Python engineer following these conventions:
- type hints required
- docstrings in Google format
<!-- OPENCLAW_CACHE_BOUNDARY -->
Current time: 2026-05-25 18:42
Working directory: /Users/<username>/project
Sem esse limite, o OpenClaw aplica cache_control a todo o prompt do sistema usando sua estratégia integrada, ainda se beneficiando do cache explícito.
Hermes
Configure usando o comando hermes config set. Defina a URL base:
- Token Plan (Team): https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
- Coding Plan: https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1
- Pagamento conforme o uso: https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
Para mais detalhes, consulte Hermes Agent.
Integração via API
Pontos principais
- Adicione
"cache_control": {"type": "ephemeral"}ao conteúdo da mensagem que deseja armazenar em cache. Todo o conteúdo desde o início do array de mensagens até esse marcador será armazenado em cache como um bloco. - O conteúdo em cache deve ter pelo menos 1.024 tokens.
- Uma única requisição suporta até 4 marcadores de cache.
- O TTL do cache é de 5 minutos, renovado automaticamente a cada acerto.
- As definições de ferramentas fazem parte do prompt do sistema para fins de cache. Se as ferramentas mudarem, não haverá acerto de cache.
Início rápido
O exemplo a seguir demonstra o fluxo de trabalho básico: a primeira requisição cria um cache e a segunda o utiliza.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace WorkspaceId with your actual Workspace ID.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# Long text to cache (must exceed 1024 tokens)
long_text_content = "<Your Long Text Here>" * 400
def get_completion(user_input):
messages = [
{
"role": "system",
"content": [
{
"type": "text",
"text": long_text_content,
# Cache marker: content from the start of messages to this point will be cached
"cache_control": {"type": "ephemeral"},
}
],
},
{"role": "user", "content": user_input},
]
completion = client.chat.completions.create(
model="qwen3.7-max",
messages=messages,
extra_body={"enable_thinking": False},
)
return completion
# First request: creates cache
first = get_completion("Summarize the key points of this document")
print(f"Cache created: {first.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit: {first.usage.prompt_tokens_details.cached_tokens}")
# Second request: same system content, different question — hits cache
second = get_completion("What precautions are mentioned in the document?")
print(f"Cache created: {second.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit: {second.usage.prompt_tokens_details.cached_tokens}")
import anthropic
import os
client = anthropic.Anthropic(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic",
)
# Long text to cache (must exceed 1024 tokens)
long_text_content = "<Your Long Text Here>" * 400
def get_completion(user_input):
response = client.messages.create(
model="qwen3.7-max",
max_tokens=1024,
system=[
{
"type": "text",
"text": long_text_content,
# Cache marker
"cache_control": {"type": "ephemeral"},
}
],
messages=[
{"role": "user", "content": user_input},
],
)
return response
# First request: creates cache
first = get_completion("Summarize the key points of this document")
print(f"Cache created: {first.usage.cache_creation_input_tokens}")
print(f"Cache hit: {first.usage.cache_read_input_tokens}")
# Second request: hits cache
second = get_completion("What precautions are mentioned in the document?")
print(f"Cache created: {second.usage.cache_creation_input_tokens}")
print(f"Cache hit: {second.usage.cache_read_input_tokens}")
Saída esperada:
Cache created: 2005
Cache hit: 0
Cache created: 0
Cache hit: 2005
A primeira requisição cria um bloco de cache. A segunda requisição utiliza o cache porque o conteúdo do prompt do sistema é idêntico. Tokens em cache são cobrados a apenas 10% do preço padrão de entrada.
Verificar status do cache
Verifique o campo usage na resposta para confirmar o comportamento do cache:
cache_creation_input_tokens: Número de tokens para os quais um novo cache foi criado. Um valor maior que 0 indica a criação de um novo bloco de cache.cached_tokens(compatível com OpenAI) oucache_read_input_tokens(compatível com Anthropic): Número de tokens que utilizaram o cache. Um valor maior que 0 significa que o cache foi utilizado com sucesso.
Melhores práticas por cenário
Conversas de múltiplas rodadas
Características:- Usuários interagem com o modelo em várias rodadas, e cada requisição carrega o histórico completo da conversa.
- Casos de uso típicos: atendimento ao cliente, perguntas e respostas de conhecimento, assistentes de código.
Melhor prática: Adicione um marcador cache_control à última mensagem de cada requisição. Cada rodada utiliza o cache criado pela rodada anterior (o histórico da conversa) e cria um novo cache que inclui a rodada atual para a próxima iteração.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace WorkspaceId with your actual Workspace ID.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# System prompt: product manual (must exceed 1024 tokens)
product_manual = """You are the support assistant for "BaiLian SmartHome" smart home controller. Here is the complete product manual:
## Product Overview
BaiLian SmartHome is a whole-home smart controller supporting voice control, scene automation, and energy management...
## Installation Guide
1. Install at a central location with good WiFi coverage...
2. Connect the power adapter (5V/2A)...
## FAQ
Q: Cannot connect to WiFi? A: Make sure your router supports 2.4GHz...
""" * 80 # Repeat to exceed 1024 tokens
messages = [{"role": "system", "content": product_manual}]
def chat(user_input):
# Key: add cache_control to the last user message
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": user_input,
"cache_control": {"type": "ephemeral"},
}
],
})
completion = client.chat.completions.create(
model="qwen3.7-max",
messages=messages,
extra_body={"enable_thinking": False},
)
assistant_msg = completion.choices[0].message.content
messages.append({"role": "assistant", "content": assistant_msg})
usage = completion.usage
created = usage.prompt_tokens_details.cache_creation_input_tokens
cached = usage.prompt_tokens_details.cached_tokens
print(f" [Cache] Created: {created} tokens, Hit: {cached} tokens")
return assistant_msg
# Simulate multi-turn conversation
print("User: What voice assistants does BaiLian SmartHome support?")
print(f"Agent: {chat('What voice assistants does BaiLian SmartHome support?')[:80]}...\n")
print("User: What if I cannot connect to WiFi?")
print(f"Agent: {chat('What if I cannot connect to WiFi?')[:80]}...\n")
print("User: How many devices can it control simultaneously?")
print(f"Agent: {chat('How many devices can it control simultaneously?')[:80]}...")
Saída esperada:
User: What voice assistants does BaiLian SmartHome support?
[Cache] Created: 8739 tokens, Hit: 0 tokens
Agent: BaiLian SmartHome supports Tmall Genie, XiaoAi, Siri, and other voice assistants...
User: What if I cannot connect to WiFi?
[Cache] Created: 151 tokens, Hit: 8739 tokens
Agent: For WiFi connectivity issues, try the following: 1. Confirm your router supports 2.4GHz...
User: How many devices can it control simultaneously?
[Cache] Created: 101 tokens, Hit: 8890 tokens
Agent: BaiLian SmartHome can control up to 256 smart devices simultaneously...
A partir da segunda rodada, cada requisição utiliza o cache da rodada anterior (o histórico da conversa) e cria um novo cache que inclui a rodada atual. Quanto mais rodadas na conversa, maior a economia.
Agent de produção (múltiplos marcadores de cache)
Características:- Conversas longas de múltiplas rodadas compreendendo: prompt do sistema + definições de habilidades/ferramentas + contexto do projeto + mensagens do usuário/chamadas de ferramentas.
- Diferentes seções mudam em frequências diferentes.
- Casos de uso típicos: assistentes de codificação IA (Claude Code, OpenClaw), sistemas de perguntas e respostas baseados em RAG.
Melhor prática: Use múltiplos marcadores de cache (até 4) para fixar conteúdo em diferentes níveis de estabilidade. Cada marcador deve estar em uma mensagem separada (função diferente) para servir como um ponto de interrupção independente:
- Prompt do sistema — um marcador (raramente muda).
- Definições de habilidades/ferramentas — um marcador (pode mudar em combinação).
- Contexto do projeto — um marcador (pode alternar ou comprimir).
- Mensagens do usuário/chamadas de ferramentas — um marcador (cresce a cada rodada).
Exemplo: Este exemplo simula uma arquitetura típica de Agent com 3 marcadores de cache fixando a persona do sistema e ferramentas (marcador 1), base de conhecimento (marcador 2) e histórico de conversa (marcador 3). Note que a base de conhecimento está em uma mensagem de usuário para garantir seu próprio ponto de interrupção de cache independente, pois múltiplas mensagens de sistema são mescladas internamente e não podem servir como pontos de interrupção separados:
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace WorkspaceId with your actual Workspace ID.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# Layer 1: System persona (rarely changes)
system_persona = """You are the senior AI support agent for "Model Studio Electronics". Your guidelines:
1. Answer questions based on the knowledge base
2. For information not in the knowledge base, say "Let me transfer you to a human agent"
3. Maintain a professional and friendly tone
4. If the user is unhappy, apologize first then resolve the issue
Below is your complete service specification and script guide:
""" + "Detailed service specification..." * 200 # Ensure > 1024 tokens
# Layer 2: Tools/skills definitions (changes occasionally, e.g. when new features launch)
tools_description = """### Available Tools
- search_product(query): Search product information
- check_inventory(sku, color): Check stock status
- create_ticket(type, description): Create a support ticket
- transfer_to_human(reason): Transfer to a human agent
### Tool Usage Rules
1. When user asks about product details, use search_product first
2. When user asks about stock/shipping, use check_inventory
3. When user requests return/exchange, use create_ticket
4. When a tool returns an error, apologize and transfer_to_human
""" + "Detailed tool usage examples..." * 150 # Ensure > 1024 tokens
# Layer 3: Project knowledge base (semi-stable, changes when user switches products)
knowledge_base_product_a = """### Current product: Model Studio Pro Max Wireless Earbuds
- SKU: BL-PM-2024
- Price: CNY 599
- Colors: Night Black / Nebula White / Ice Blue
- Battery: 8 hours (ANC on), 12 hours (ANC off)
- Water resistance: IPX5
- Warranty: 1 year, 7-day no-questions-asked return
- Stock: Night Black (in stock) / Nebula White (low) / Ice Blue (out of stock)
""" * 50 # Ensure > 1024 tokens
def ask_agent(user_question, history=None):
if history is None:
history = []
messages = [
{
"role": "system",
"content": [
{
"type": "text",
"text": system_persona + "\n\n" + tools_description,
"cache_control": {"type": "ephemeral"}, # Marker 1: system persona + tools
}
],
},
{
"role": "user",
"content": [
{
"type": "text",
"text": f"Here is the knowledge base for the current product:\n{knowledge_base_product_a}",
"cache_control": {"type": "ephemeral"}, # Marker 2: knowledge base
}
],
},
{"role": "assistant", "content": "Got it. I have the product details ready. How can I help you?"},
]
messages.extend(history)
# Add current question with marker 3
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": user_question,
"cache_control": {"type": "ephemeral"}, # Marker 3: conversation history
}
],
})
completion = client.chat.completions.create(
model="qwen3.7-max",
messages=messages,
extra_body={"enable_thinking": False},
)
usage = completion.usage
print(f" Created: {usage.prompt_tokens_details.cache_creation_input_tokens}, "
f"Hit: {usage.prompt_tokens_details.cached_tokens}")
return completion.choices[0].message.content
# First request
print("Q1: Is the Ice Blue color available?")
a1 = ask_agent("Is the Ice Blue color available?")
print(f"A1: {a1}\n")
# Second request: same product (persona + tools + knowledge base all hit)
history = [
{"role": "user", "content": "Is the Ice Blue color available?"},
{"role": "assistant", "content": a1},
]
print("Q2: When will it be back in stock?")
a2 = ask_agent("When will it be back in stock?", history)
print(f"A2: {a2}")
Saída esperada:
Q1: Is the Ice Blue color available?
Created: 7659, Hit: 0
A1: I'm sorry, but the Ice Blue color... is currently out of stock...
Q2: When will it be back in stock?
Created: 73, Hit: 7659
A2: I don't have access to specific restock dates... Let me transfer you to a human agent...
Na Q2, o prefixo até o marcador 2 (persona + ferramentas + base de conhecimento = 7.659 tokens) permanece inalterado, resultando em um acerto total de cache. Apenas o novo conteúdo após o marcador 2 (histórico de conversa + nova pergunta) requer processamento.
Como funciona o cache com múltiplos marcadores:- Usuário continua perguntando sobre o mesmo produto: Persona, ferramentas e base de conhecimento permanecem inalterados, utilizando o cache no marcador 2 (correspondência de prefixo mais longa) para máxima economia.
- Mais rodadas de conversa: O conteúdo anterior (persona + ferramentas + base de conhecimento + histórico) utiliza o cache da rodada anterior; apenas o novo conteúdo requer um novo cache.
ObservaçãoOrganize o conteúdo do mais estável para o menos estável: coloque o conteúdo que muda menos no início (por exemplo, persona do sistema) e o conteúdo que muda mais no final (por exemplo, conversa atual) para maximizar as taxas de acerto de cache.
Processamento em lote (conclusão de tarefas)
Características:- Requisições de rodada única, sem necessidade de memória de contexto.
- Prompt de sistema longo e fixo (instruções de tarefa) + entrada de usuário variável (dados a processar).
- Casos de uso típicos: classificação de texto, reconhecimento de intenção, extração de dados, moderação de conteúdo.
Melhor prática: Adicione o marcador cache_control apenas no prompt do sistema. Todas as requisições subsequentes utilizarão o cache desde que o prompt do sistema permaneça inalterado.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace WorkspaceId with your actual Workspace ID.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# Long system prompt: detailed classification rules (must exceed 1024 tokens)
classification_prompt = """You are a product review classifier. Classify each review into one of these categories:
- Positive
- Negative
- Neutral
- Question
- Complaint
Output only the category name, nothing else.
Detailed classification rules and examples:
""" + """Rules:
1. Positive: Contains positive sentiment words (e.g., "great", "excellent", "recommend"), or expresses satisfaction.
2. Negative: Contains negative sentiment words (e.g., "terrible", "disappointed", "return"), or expresses dissatisfaction.
3. Neutral: No clear sentiment, merely states facts.
4. Question: Phrased as a question asking for product information.
5. Complaint: Expresses suggestions for improvement or lodges a complaint.
""" * 100
# Reviews to classify (simulating batch processing)
reviews = [
"This product is amazing, great quality, highly recommended!",
"Shipping took a week and the packaging was damaged",
"Does this come in red? Does it run large or small?",
"You should add more size options, medium is too big for me",
"It's okay I guess, nothing special, does what it says",
]
print("=== Batch Classification (Explicit Cache) ===")
for i, review in enumerate(reviews):
completion = client.chat.completions.create(
model="qwen3.7-max",
messages=[
{
"role": "system",
"content": [
{
"type": "text",
"text": classification_prompt,
"cache_control": {"type": "ephemeral"}, # Cache classification rules
}
],
},
{"role": "user", "content": review},
],
)
result = completion.choices[0].message.content
cached = completion.usage.prompt_tokens_details.cached_tokens
created = completion.usage.prompt_tokens_details.cache_creation_input_tokens
print(f"Review {i+1}: \"{review[:40]}...\" -> {result}")
print(f" Created: {created}, Hit: {cached}")
Saída esperada:
Review 1: "This product is amazing, great quality, ..." -> Positive
Created: 10353, Hit: 0
Review 2: "Shipping took a week and the packaging w..." -> Negative
Created: 0, Hit: 10353
Review 3: "Does this come in red? Does it run large..." -> Question
Created: 0, Hit: 10353
Review 4: "You should add more size options, medium..." -> Complaint
Created: 0, Hit: 10353
Review 5: "It's okay I guess, nothing special, does..." -> Neutral
Created: 0, Hit: 10353
Após a primeira requisição criar o cache, todas as requisições subsequentes o utilizam. Ao processar 1.000 itens, 999 requisições obtêm uma redução de 90% no custo de tokens de entrada.
Function Calling com definições de ferramentas em cache
Características:- Uso de Function Calling com uma longa lista de definições de ferramentas.
- Definições de ferramentas permanecem inalteradas entre requisições.
Melhor prática: O conteúdo do parâmetro tools faz parte do prompt do sistema para fins de cache. Garanta que as definições de ferramentas sejam exatamente idênticas entre requisições (mesma ordem, mesma ordem de campos, mesma estrutura) e adicione um marcador cache_control ao conteúdo da mensagem.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Replace WorkspaceId with your actual Workspace ID.
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# Long text to meet the 1024-token minimum
long_text_content = "<Your Code Here>" * 400
# Tool definitions: must be exactly identical across requests
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_flights",
"description": "Search flights between two cities",
"parameters": {
"type": "object",
"properties": {
"origin": {"type": "string", "description": "Departure city"},
"destination": {"type": "string", "description": "Destination city"},
"date": {"type": "string", "description": "Departure date in YYYY-MM-DD format"}
},
"required": ["origin", "destination", "date"]
}
}
}
]
def ask(user_input):
messages = [
{
"role": "system",
"content": [
{
"type": "text",
"text": long_text_content,
# cache_control can only be added to message content, not to tools
"cache_control": {"type": "ephemeral"},
}
],
},
{"role": "user", "content": user_input},
]
completion = client.chat.completions.create(
model="qwen3.7-max",
messages=messages,
tools=tools,
extra_body={"enable_thinking": False},
)
usage = completion.usage
print(f" Created: {usage.prompt_tokens_details.cache_creation_input_tokens}, "
f"Hit: {usage.prompt_tokens_details.cached_tokens}")
tool_calls = completion.choices[0].message.tool_calls
if tool_calls:
print(f" Tools called: {[t.function.name for t in tool_calls]}")
return completion
# First request: creates cache (includes tool definitions)
print("Q1: What's the weather in Beijing today?")
ask("What's the weather in Beijing today?")
# Second request: hits cache
print("\nQ2: Find flights from Shanghai to Beijing tomorrow")
ask("Find flights from Shanghai to Beijing tomorrow")
Saída esperada:
Q1: What's the weather in Beijing today?
Created: 1995, Hit: 0
Tools called: ['get_weather']
Q2: Find flights from Shanghai to Beijing tomorrow
Created: 0, Hit: 1995
Tools called: ['search_flights']
ImportanteChaves para maximizar os acertos de cache no Function Calling:
- Ordem consistente de ferramentas: Mantenha a mesma ordenação das ferramentas no array
tools. - Ordem consistente de campos: Mantenha a ordenação dos campos JSON igual dentro de cada definição de ferramenta.
- Estrutura consistente: Não adicione, remova ou reordene campos entre requisições, mesmo que sejam opcionais ou vazios.
Notas importantes
- Requisito de formato de conteúdo: Ao adicionar
cache_control, o campo de conteúdo deve estar em formato de array. Conteúdo em formato de string não suporta marcadores de cache. - Granularidade do marcador de cache: Modelos Qwen3.5 e posteriores suportam apenas pontos de interrupção de cache no nível da mensagem. Colocar múltiplos marcadores
cache_controldentro do array de conteúdo de uma única mensagem não cria pontos de interrupção separados. O sistema armazena cache apenas na última posição do marcador dentro dessa mensagem e não pode realizar correspondência por truncamento em blocos de conteúdo intermediários. Além disso, múltiplas mensagens de sistema são mescladas internamente em um único segmento e não podem servir como pontos de interrupção separados. Para criar múltiplos pontos de interrupção independentes, distribua marcadorescache_controlentre mensagens com funções diferentes (por exemplo, um no sistema, um no usuário). Modelos anteriores ao Qwen3.5 suportam pontos de interrupção no nível de conteúdo (intramensagem). - Mutuamente exclusivo com cache implícito: Uma requisição pode usar apenas um modo de cache. Se a requisição contiver um marcador
cache_control, o cache explícito será usado; caso contrário, o sistema usará automaticamente o cache implícito.
Modelos suportados
Para a lista de modelos que suportam cache explícito, consulte Cache de contexto.