Este tema describe cómo utilizar la caché explícita y sus mejores prácticas. Al agregar marcadores de caché a sus solicitudes, la caché explícita garantiza aciertos deterministas para contenido de entrada idéntico, lo que reduce significativamente el costo y la latencia.
Cuándo usar la caché explícita
- Necesita aciertos de caché garantizados: La caché explícita ofrece aciertos deterministas al 100% independientemente de la programación de recursos del backend. Si su aplicación requiere una reutilización estable de contenido, la caché explícita es la opción adecuada.
- Usted reutiliza frecuentemente el mismo prompt: Cuando se envían repetidamente prompts idénticos o altamente consistentes, la caché explícita reduce significativamente los costos. La creación de la caché incurre solo en un recargo de 25% sobre el precio estándar de entrada, mientras que cada acierto posterior ahorra un 90%. Un solo acierto es suficiente para alcanzar el punto de equilibrio.
- Usted administra contextos largos en agentes de producción: En las aplicaciones de agente, mecanismos comunes como la compresión, el resumen y los recordatorios del sistema provocan que el contexto cambie continuamente. La caché explícita le permite fijar y reutilizar segmentos clave del contexto para que permanezcan en la caché incluso mientras el contexto circundante evoluciona.
Herramientas de agente y codificación
Las siguientes herramientas de agente y codificación se conectan a Model Studio a través del protocolo Anthropic y admiten nativamente la caché explícita. Configúrelas siguiendo su documentación respectiva, y aprovecharán automáticamente la caché explícita para optimizar la gestión del contexto.
Los ejemplos a continuación utilizan el endpoint de Singapore. Para otras regiones, reemplace la URL base con el endpoint regional correspondiente.
Claude Code
Claude Code v2.x y versiones posteriores incluyen automáticamente marcadores cache_control en las solicitudes (sistema, entorno y mensaje de usuario más reciente). No se necesita configuración adicional después de conectarse al endpoint compatible con Anthropic de Model Studio.
Cree o edite ~/.claude/settings.json (Windows: C:\Users\<username>\.claude\settings.json) con la configuración de plan adecuada. Alternativamente, conéctese mediante variables de entorno:
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
Configure el endpoint del protocolo Anthropic:
-
Plan de Tokens (Equipo):
https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic -
Plan de Codificación:
https://coding-intl.dashscope.aliyuncs.com/apps/anthropic -
Pago por uso:
https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropicReemplace
WorkspaceIdcon su ID de espacio de trabajo real.
Para más detalles, consulte Claude Code.
Opcional: Mejorar la tasa de aciertos entre sesionesDe forma predeterminada, Claude Code incluye información dinámica en el prompt del sistema (directorio actual, fecha, estado de git), lo que puede reducir las tasas de aciertos de caché entre sesiones. Agregue la siguiente bandera al inicio para mover las secciones dinámicas a los mensajes de usuario:
claude --exclude-dynamic-system-prompt-sections
Abrir código
Cuando OpenCode se conecta al endpoint compatible con Anthropic de Model Studio mediante @ai-sdk/anthropic, inyecta automáticamente cache_control en el mensaje del sistema y en el mensaje no del sistema más reciente.
npm install -g opencode-ai
ConfiguraciónCree el archivo de configuración ~/.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" }
}
}
}
}
NotabaseURL debe terminar con /v1.
export DASHSCOPE_API_KEY=sk-xxxxx
opencode run -m "bailian/qwen3.7-max" "..."
Otras URL base de planes:
- Plan de Tokens (Equipo):
https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1 - Plan de Codificación:
https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1
Para más detalles, consulte OpenCode.
OpenClaw
Al utilizar el endpoint compatible con Anthropic, OpenClaw inyecta automáticamente marcadores cache_control en el prompt del sistema y en el mensaje de usuario más reciente. No se necesita configuración adicional; siempre que la URL base del proveedor apunte a /apps/anthropic, la caché explícita se habilita automáticamente.
npm install -g openclaw
# or
curl -fsSL https://openclaw.ai/install.sh | bash
ConfiguraciónEdite el archivo de configuración ~/.openclaw/openclaw.json. Establezca "api" en "anthropic-messages" y configure la URL base:
- Plan de Tokens (Equipo):
https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1 - Plan de Codificación:
https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1 - Pago por uso:
https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
Para más detalles, consulte OpenClaw.
Opcional: Límite de caché personalizadoSi su prompt del sistema contiene tanto contenido de plantilla estable como contenido dinámico (marcas de tiempo, CWD, etc.), inserte <!-- OPENCLAW_CACHE_BOUNDARY --> entre ellos. OpenClaw aplicará cache_control solo al prefijo estable antes del límite, mejorando las tasas de aciertos entre sesiones:
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
Sin este límite, OpenClaw aplica cache_control a todo el prompt del sistema utilizando su estrategia integrada, beneficiándose igualmente de la caché explícita.
Hermes
Configure mediante el comando hermes config set. Establezca la URL base:
- Plan de Tokens (Equipo):
https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1 - Plan de Codificación:
https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1 - Pago por uso:
https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1
Para más detalles, consulte Hermes Agent.
Integración de API
Puntos clave
- Agregue
"cache_control": {"type": "ephemeral"}al contenido del mensaje que want almacenar en caché. Todo el contenido desde el inicio del array de mensajes hasta ese marcador se almacenará en caché como un bloque. - El contenido almacenado en caché debe tener al menos 1024 tokens.
- Una sola solicitud admite hasta 4 marcadores de caché.
- El TTL de la caché es de 5 minutos, renovado automáticamente en cada acierto.
- Las definiciones de herramientas forman parte del prompt del sistema a efectos de almacenamiento en caché. Si las herramientas cambian, no se producirá un acierto de caché.
Inicio rápido
El siguiente ejemplo demuestra el flujo de trabajo básico: la primera solicitud crea una caché y la segunda solicitud la 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}")
Salida esperada:
Cache created: 2005
Cache hit: 0
Cache created: 0
Cache hit: 2005
La primera solicitud crea un bloque de caché. La segunda solicitud utiliza la caché porque el contenido del prompt del sistema es idéntico. Los tokens almacenados en caché se facturan a solo el 10% del precio estándar de entrada.
Verificar estado de la caché
Revise el campo usage en la respuesta para confirmar el comportamiento de la caché:
cache_creation_input_tokens: Cantidad de tokens para los cuales se creó una nueva caché. Un valor mayor que 0 significa que se creó un nuevo bloque de caché.cached_tokens(compatible con OpenAI) ocache_read_input_tokens(compatible con Anthropic): Cantidad de tokens que utilizaron la caché. Un valor mayor que 0 significa que la caché se utilizó correctamente.
Mejores prácticas por escenario
Conversaciones de múltiples turnos
Características:- Los usuarios interactúan con el modelo a lo largo de múltiples turnos, y cada solicitud lleva consigo el historial completo de la conversación
- Casos de uso típicos: servicio al cliente, preguntas y respuestas de conocimiento, asistentes de código
Mejor práctica: Agregue un marcador cache_control al último mensaje en cada solicitud. Cada turno utiliza la caché creada por el turno anterior (el historial de conversación), mientras crea una nueva caché que incluye el turno actual para la siguiente ronda.
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]}...")
Salida 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 del segundo turno, cada solicitud utiliza la caché del turno anterior (el historial de conversación), mientras crea una nueva caché que incluye el turno actual. Cuantos más turnos haya en la conversación, mayor será el ahorro.
Agente de producción (múltiples marcadores de caché)
Características:- Conversaciones largas de múltiples turnos que comprenden: prompt del sistema + definiciones de habilidades/herramientas + contexto del proyecto + mensajes de usuario / llamadas a herramientas
- Diferentes secciones cambian con distintas frecuencias
- Casos de uso típicos: asistentes de codificación con IA (Claude Code, OpenClaw), sistemas de preguntas y respuestas basados en RAG
Mejor práctica: Utilice múltiples marcadores de caché (hasta 4) para fijar contenido en diferentes niveles de estabilidad. Cada marcador debe estar en un mensaje separado (diferente rol) para servir como un punto de interrupción independiente:
- Prompt del sistema — un marcador (cambia raramente)
- Definiciones de habilidades/herramientas — un marcador (puede cambiar en combinación)
- Contexto del proyecto — un marcador (puede cambiar o comprimirse)
- Mensajes de usuario / llamadas a herramientas — un marcador (crece en cada turno)
Ejemplo: Este ejemplo simula una arquitectura típica de agente con 3 marcadores de caché que fijan la personalidad del sistema y las herramientas (marcador 1), la base de conocimientos (marcador 2) y el historial de conversaciones (marcador 3). Tenga en cuenta que la base de conocimientos se coloca en un mensaje de usuario para garantizar que tenga su propio punto de interrupción de caché independiente; varios mensajes del sistema se fusionan internamente y no pueden servir como puntos de interrupción 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}")
Salida 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...
En Q2, el prefijo hasta el marcador 2 (persona + herramientas + base de conocimientos = 7,659 tokens) permanece sin cambios, lo que resulta en un acierto total de caché. Solo el contenido nuevo después del marcador 2 (historial de conversación + nueva pregunta) requiere procesamiento.
Cómo funciona el almacenamiento en caché con múltiples marcadores:- El usuario continúa preguntando sobre el mismo producto: La persona, las herramientas y la base de conocimientos permanecen sin cambios, utilizando la caché en el marcador 2 (coincidencia de prefijo más larga) para obtener el máximo ahorro.
- Más turnos de conversación: El contenido anterior (persona + herramientas + base de conocimientos + historial) utiliza la caché del turno previo; solo el contenido nuevo requiere una nueva caché.
NotaOrganice el contenido de más estable a menos estable: coloque el contenido que cambia menos al principio (por ejemplo, la persona del sistema) y el contenido que cambia más al final (por ejemplo, la conversación actual) para maximizar las tasas de aciertos de caché.
Procesamiento por lotes (finalización de tareas)
Características:- Solicitudes de un solo turno, no se requiere memoria de contexto
- Prompt del sistema largo y fijo (instrucciones de tarea) + entrada de usuario variable (datos a procesar)
- Casos de uso típicos: clasificación de texto, reconocimiento de intenciones, extracción de datos, moderación de contenido
Mejor práctica: Agregue el marcador cache_control únicamente en el prompt del sistema. Todas las solicitudes subsiguientes utilizarán la caché siempre que el prompt del sistema permanezca sin cambios.
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}")
Salida 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
Después de que la primera solicitud crea la caché, todas las solicitudes subsiguientes la utilizan. Al procesar 1,000 elementos, 999 solicitudes experimentan una reducción del 90% en el costo de tokens de entrada.
Function Calling con definiciones de herramientas en caché
Características:- Uso de Function Calling con una lista extensa de definiciones de herramientas
- Las definiciones de herramientas permanecen sin cambios entre solicitudes
Mejor práctica: El contenido del parámetro tools forma parte del prompt del sistema para el almacenamiento en caché. Asegúrese de que las definiciones de herramientas sean exactamente idénticas en todas las solicitudes (mismo orden, mismo orden de campos, misma estructura) y agregue un marcador cache_control al contenido del mensaje.
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")
Salida 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']
ImportanteClaves para maximizar los aciertos de caché en Function Calling:
- Orden consistente de herramientas: Mantenga el mismo orden de herramientas en el array de herramientas.
- Orden consistente de campos: Mantenga el mismo orden de campos JSON dentro de cada definición de herramienta.
- Estructura consistente: No agregue, elimine ni reordene campos entre solicitudes, incluso si son opcionales o están vacíos.
Notas importantes
- Requisito de formato de contenido: Al agregar
cache_control, el campo de contenido debe estar en formato de array. El contenido en formato de cadena no admite marcadores de caché. - Granularidad de los marcadores de caché: Los modelos Qwen3.5 y posteriores solo admiten puntos de interrupción de caché a nivel de mensaje. Colocar múltiples marcadores
cache_controldentro de la matriz de contenido de un solo mensaje no crea puntos de interrupción separados; el sistema solo almacena la caché en la última posición del marcador dentro de ese mensaje y no puede realizar coincidencias por truncamiento en bloques de contenido intermedios. Además, varios mensajes del sistema se fusionan internamente en un solo segmento y no pueden servir como puntos de interrupción separados. Para crear múltiples puntos de interrupción independientes, distribuya los marcadorescache_controlentre mensajes con diferentes roles (por ejemplo, uno en system, otro en user). Los modelos anteriores a Qwen3.5 admiten puntos de interrupción a nivel de contenido (intra-mensaje). - Mutuamente excluyente con la caché implícita: Una solicitud solo puede utilizar un modo de almacenamiento en caché. Si la solicitud contiene un marcador
cache_control, se utiliza la caché explícita; de lo contrario, el sistema utiliza automáticamente la caché implícita.
Modelos admitidos
Para ver la lista de modelos que admiten caché explícita, consulte Caché de contexto.