Todos os produtos
Search
Central de documentação

Alibaba Cloud Model Studio:Context Cache

Última atualização: Sep 11, 2026

Requisições de inferência para modelos grandes frequentemente contêm entradas sobrepostas, como em conversas de múltiplos turnos ou séries de perguntas sobre o mesmo livro. O Context Cache reduz a computação redundante ao armazenar em cache o prefixo comum dessas requisições. Isso melhora a velocidade de resposta e diminui os custos de uso sem afetar a qualidade da resposta.

Para atender a diferentes cenários, o context cache oferece dois modos. Escolha um modo com base nos seus requisitos de conveniência, determinismo e custo:

  • Cache explícito: Modo ativado manualmente. Crie um cache para conteúdo específico e garanta um acerto determinístico dentro do período de validade de 5 minutos. Os tokens usados para criar o cache são geralmente cobrados a 125% do preço padrão do token de entrada, enquanto os acertos subsequentes no cache são cobrados a apenas 10% desse preço. Para preços específicos, consulte Faturamento.
  • Cache implícito: Este modo automático não exige configuração extra e não pode ser desativado, sendo ideal para cenários que priorizam a conveniência. O sistema identifica automaticamente e armazena em cache o prefixo comum das requisições, mas a probabilidade de acerto não é garantida. A parte da entrada servida a partir do cache é geralmente cobrada a 20% do preço padrão do token de entrada. Para preços específicos, consulte Faturamento.

Item

Cache explícito

Cache implícito

Impacto na qualidade da resposta

Nenhum

Nenhum

Cobrança por tokens de criação de cache

Geralmente 125% do preço padrão do token de entrada

100% do preço padrão do token de entrada

Cobrança por tokens de entrada em cache

Geralmente 10% do preço padrão do token de entrada (consulte Faturamento)

Geralmente 20% do preço padrão do token de entrada (consulte Faturamento)

Mínimo de tokens para cache

1.024

256

Período de validade do cache

5 minutos (reinicia após acerto)

Indeterminado. O sistema limpa periodicamente dados de cache antigos e não utilizados.

ObservaçãoO cache explícito e o cache implícito são mutuamente exclusivos.

ObservaçãoImplantações de Provisioned Throughput Unit (PTU) também suportam context cache. Quando ocorre um acerto de cache, o sistema calcula o uso de PTU com um fator de desconto de cache. Para mais informações, consulte Entradas longas e cache para PTU.

ObservaçãoPara interfaces compatíveis com OpenAI Chat Completions, DashScope e Anthropic, use a Responses API com o cache de sessão para reduzir a latência e o custo de inferência. Consulte cache de sessão para detalhes.

Cache explícito

Diferentemente do cache implícito, o cache explícito exige criação manual e gera sobrecarga, mas oferece uma taxa de acerto maior e menor latência de acesso.

Como funciona

Adicione um marcador "cache_control": {"type": "ephemeral"} ao array messages. O sistema então busca retroativamente a partir de cada marcador cache_control e examina até 20 blocos content anteriores para encontrar um acerto de cache.

Uma única requisição suporta até quatro marcadores de cache.

  • Falha de cache

    Se ocorrer uma falha de cache, o sistema cria um novo bloco de cache a partir do conteúdo entre o início do array messages e o marcador cache_control. O novo bloco de cache tem um período de validade de 5 minutos.

    O sistema cria o cache após o modelo gerar uma resposta. Aguarde a conclusão da requisição de criação antes de tentar obter um acerto nesse cache.

    Um bloco de cache contém pelo menos 1.024 tokens.

  • Acerto de cache

    Se ocorrer um acerto de cache, o sistema seleciona o prefixo correspondente mais longo e redefine o período de validade do bloco de cache correspondente para 5 minutos.

O exemplo a seguir demonstra esse funcionamento:

  1. Envie a primeira requisição: Envie uma mensagem de sistema contendo o texto A (mais de 1.024 tokens) e adicione um marcador de cache:
[{"role": "system", "content": [{"type": "text", "text": A, "cache_control": {"type": "ephemeral"}}]}]

O sistema cria o primeiro bloco de cache, denominado bloco de cache A. 2. Envie a segunda requisição: Envie uma requisição com a seguinte estrutura:

[
    {"role": "system", "content": A},
    <Other messages>
    {"role": "user","content": [{"type": "text", "text": B, "cache_control": {"type": "ephemeral"}}]}
]
  • Se houver 20 ou menos "Outras mensagens", a requisição obtém um acerto no bloco de cache A, redefinindo seu período de validade para 5 minutos. O sistema também cria um novo bloco de cache baseado em A, nas outras mensagens e em B.
  • Caso existam mais de 20 "Outras mensagens", a requisição falha no bloco de cache A. Ainda assim, o sistema cria um novo bloco de cache baseado no contexto completo (A, as outras mensagens e B).

Modelos suportados

Singapore

Os modelos a seguir estão disponíveis no escopo de implantação International.

Qwen Max: qwen3.8-max, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3.6-max-preview, qwen3-max

Qwen Open-source: qwen3.8-2.4t-a95b, qwen3.8-27b

Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen3.5-plus-2026-04-20, qwen-plus

Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, qwen3.6-flash, qwen3.5-flash, qwen-flash

Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

Qwen VL: qwen3-vl-plus, qwen3-vl-flash

DeepSeek: deepseek-v3.2

China (Beijing)

Qwen Max: qwen3.8-max, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3.6-max-preview, qwen3-max

Qwen Open-source: qwen3.8-2.4t-a95b, qwen3.8-27b

Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen3.5-plus-2026-04-20, qwen-plus

Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, qwen3.6-flash, qwen3.5-flash, qwen-flash

Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

Qwen VL: qwen3-vl-plus, qwen3-vl-flash

DeepSeek: deepseek-v3.2

Kimi: kimi-k2.7-code, kimi-k2.6, kimi-k2.5

GLM: glm-5.1

Germany (Frankfurt)

Os modelos suportados variam dependendo do escopo de implantação do service.

  • Escopo Global:

    Qwen Max: qwen3.8-max, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen-plus

    Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, qwen3.6-flash, qwen3.5-flash, qwen-flash

    Qwen VL: qwen3-vl-plus

    Qwen Coder: qwen3-coder-plus, qwen3-coder-flash

    Kimi: kimi-k2.7-code, kimi-k2.5

  • Escopo EU:

    Qwen Max: qwen3-max

    Qwen Plus: qwen-plus

    Qwen Flash: qwen3.6-flash, qwen3.5-flash

    Qwen VL: qwen3-vl-plus, qwen3-vl-flash

Hong Kong (China)

Os modelos suportados variam dependendo do escopo de implantação do service.

  • Escopo Global:

    Qwen Max: qwen3.8-max, qwen3.8-max-0902, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus

    Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, qwen3.6-flash

    Kimi: kimi-k2.7-code

  • Escopo Hong Kong (China):

    Qwen Max: qwen3-max

    Qwen Plus: qwen-plus

    Qwen Flash: qwen3.5-flash

    Qwen VL: qwen3-vl-plus

Japan (Tokyo)

Os modelos suportados variam dependendo do escopo de implantação do service.

  • Escopo Japan:

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26

  • Escopo Global:

    Qwen Max: qwen3.8-max, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Plus: qwen3.7-plus, qwen3.7-plus-2026-05-26, qwen3.6-plus, qwen3.5-plus, qwen-plus

    Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, qwen3.6-flash, qwen3.5-flash, qwen-flash

    Kimi: kimi-k2.7-code

US (Virginia)

Os modelos a seguir estão disponíveis no escopo de implantação US.

  • Escopo Global:

    Qwen Max: qwen3.8-max, qwen3.7-max, qwen3.7-max-2026-05-20, qwen3.7-max-2026-06-08, qwen3-max

    Qwen Flash: qwen3.8-flash, qwen3.7-flash, qwen3.7-flash-2026-07-15, kimi-k2.7-code

  • Escopo US:

    Qwen Max: qwen3.7-max-us

    Qwen Plus: qwen3.7-plus-us

    Qwen Flash: qwen3.6-flash-us

Início rápido

Os exemplos a seguir demonstram os mecanismos de criação de bloco de cache e acerto de cache para protocolos compatíveis com OpenAI, DashScope e Anthropic.

OpenAI compatible

from openai import OpenAI
import os

client = OpenAI(
    # If the environment variable is not set, replace the following line with: api_key="sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use a model in China (Beijing), replace the base_url with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# Mock code repository content. The minimum cacheable prompt length is 1,024 tokens.
long_text_content = "<Your Code Here>" * 400

# Function to make a request
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # Place the cache_control marker here. This creates a cache block containing all content from the start of the messages array up to this point.
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        # The user's question is different for each request.
        {
            "role": "user",
            "content": user_input,
        },
    ]
    completion = client.chat.completions.create(
        # Select a model that supports explicit cache.
        model="qwen3.8-max",
        messages=messages,
    )
    return completion

# First request
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"First request cached tokens: {first_completion.usage.prompt_tokens_details.cached_tokens}")
print("=" * 20)
# Second request. The code content is the same, but the question is different.
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Second request cached tokens: {second_completion.usage.prompt_tokens_details.cached_tokens}")

DashScope

import os
from dashscope import MultiModalConversation
# The following URL is for Singapore. Replace {WorkspaceId} with your workspace ID. The URL varies by region.
dashscope.base_http_api_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1"

# Mock code repository content. The minimum cacheable prompt length is 1,024 tokens.
long_text_content = "<Your Code Here>" * 400

# Function to make a request
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # Place the cache_control marker here. This creates a cache block containing all content from the start of the messages array up to this point.
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        # The user's question is different for each request.
        {
            "role": "user",
            "content": [{"text": user_input}],
        },
    ]
    response = MultiModalConversation.call(
        # If the environment variable is not set, use your Model Studio API key directly: api_key = "sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        model="qwen3.8-max",
        messages=messages,
    )
    return response

# First request
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.prompt_tokens_details['cache_creation_input_tokens']}")
print(f"First request cached tokens: {first_completion.usage.prompt_tokens_details['cached_tokens']}")
print("=" * 20)
# Second request. The code content is the same, but the question is different.
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.prompt_tokens_details['cache_creation_input_tokens']}")
print(f"Second request cached tokens: {second_completion.usage.prompt_tokens_details['cached_tokens']}")
// Minimum Java SDK version: 2.21.6
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageContentText;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;

import java.util.Arrays;
import java.util.Collections;

public class Main {
    private static final String MODEL = "qwen3-coder-plus";
    // Mock code repository content (repeated 400 times to ensure it exceeds 1,024 tokens).
    private static final String LONG_TEXT_CONTENT = generateLongText(400);
    private static String generateLongText(int repeatCount) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < repeatCount; i++) {
            sb.append("<Your Code Here>");
        }
        return sb.toString();
    }
    private static GenerationResult getCompletion(String userQuestion)
            throws NoApiKeyException, ApiException, InputRequiredException {
        // The following URL is for Singapore. Replace {WorkspaceId} with your workspace ID. The URL varies by region.
        Generation gen = new Generation("http", "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");

        // Build the system message with cache control.
        MessageContentText systemContent = MessageContentText.builder()
                .type("text")
                .text(LONG_TEXT_CONTENT)
                .cacheControl(MessageContentText.CacheControl.builder()
                        .type("ephemeral") // Set the cache type.
                        .build())
                .build();

        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .contents(Collections.singletonList(systemContent))
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content(userQuestion)
                .build();

        // Build the request parameters.
        GenerationParam param = GenerationParam.builder()
                .model(MODEL)
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();
        return gen.call(param);
    }

    private static void printCacheInfo(GenerationResult result, String requestLabel) {
        System.out.printf("%s cache creation tokens: %d%n", requestLabel, result.getUsage().getPromptTokensDetails().getCacheCreationInputTokens());
        System.out.printf("%s cached tokens: %d%n", requestLabel, result.getUsage().getPromptTokensDetails().getCachedTokens());
    }

    public static void main(String[] args) {
        try {
            // First request
            GenerationResult firstResult = getCompletion("What is the content of this code?");
            printCacheInfo(firstResult, "First request");
            System.out.println(new String(new char[20]).replace('\0', '='));            // Second request
            GenerationResult secondResult = getCompletion("How can this code be optimized?");
            printCacheInfo(secondResult, "Second request");
        } catch (NoApiKeyException | ApiException | InputRequiredException e) {
            System.err.println("API call failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Anthropic compatible

import anthropic
import os

api_key = os.getenv("DASHSCOPE_API_KEY")
client = anthropic.Anthropic(
    # If the environment variable is not set, replace the following line with: api_key="sk-xxx"
    api_key=api_key,
    # If you use a model in China (Beijing), replace the base_url with: https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/apps/anthropic
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/apps/anthropic",
    default_headers={"Authorization": f"Bearer {api_key}"},
)

# Mock code repository content. The minimum cacheable prompt length is 1,024 tokens.
long_text_content = "<Your Code Here>" * 400

# Function to make a request
def get_completion(user_input):
    response = client.messages.create(
        # Select a model that supports explicit cache.
        model="qwen3.8-max",
        max_tokens=1024,
        system=[
            {
                "type": "text",
                "text": long_text_content,
                # Place the cache_control marker here to create a cache block from the system text content. This marker can also be placed in `messages`.
                "cache_control": {"type": "ephemeral"},
            }
        ],
        messages=[
            # The user's question is different for each request.
            {"role": "user", "content": user_input},
        ],
    )
    return response

# First request
first_completion = get_completion("What is the content of this code?")
print(f"First request cache creation tokens: {first_completion.usage.cache_creation_input_tokens}")
print(f"First request cached tokens: {first_completion.usage.cache_read_input_tokens}")
print("=" * 20)
# Second request. The code content is the same, but the question is different.
second_completion = get_completion("How can this code be optimized?")
print(f"Second request cache creation tokens: {second_completion.usage.cache_creation_input_tokens}")
print(f"Second request cached tokens: {second_completion.usage.cache_read_input_tokens}")

Adicionar o marcador cache_control ativa o cache explícito para o conteúdo simulado do repositório de código. Nas requisições subsequentes que consultam esse conteúdo, o sistema reutiliza o bloco de cache, eliminando a recomputação. Isso torna as requisições com acerto de cache mais rápidas e baratas do que a requisição inicial de criação de cache.

First request cache creation tokens: 1605
First request cached tokens: 0
====================
Second request cache creation tokens: 0
Second request cached tokens: 1605

Controle refinado com múltiplos marcadores de cache

Em cenários complexos, um prompt geralmente consiste em várias partes com frequências de reutilização diferentes. Use múltiplos marcadores de cache para obter controle refinado.

Por exemplo, o prompt para um agente inteligente de atendimento ao cliente normalmente inclui:

  • Persona do sistema: Altamente estável e raramente muda.
  • Conhecimento externo: Obtido da base de conhecimento ou por meio de consultas a ferramentas, podendo não mudar durante uma única conversa.
  • Histórico da conversa: Cresce dinamicamente.
  • Pergunta atual: Diferente para cada requisição.

Se você armazenar todo o prompt em cache como uma única unidade, qualquer alteração menor, como uma atualização no conhecimento externo, pode causar uma falha de cache.

É possível adicionar até quatro marcadores de cache em uma requisição para criar blocos de cache separados para diferentes partes do prompt. Isso melhora a taxa de acerto de cache e permite controle refinado.

Faturamento

O cache explícito afeta apenas a cobrança dos tokens de entrada. As regras são as seguintes:

  • Criação de cache: O conteúdo usado para criar um novo cache é cobrado a 125% do preço padrão do token de entrada. Se o conteúdo para um novo cache incluir um cache existente como prefixo, apenas a parte incremental é cobrada pela criação do cache (ou seja, o número de novos tokens de cache menos o número de tokens de cache existentes).

    Por exemplo, se você tem um cache existente de 1.200 tokens (Cache A) e usa uma nova requisição para armazenar 1.500 tokens de conteúdo (Conteúdo AB), os primeiros 1.200 tokens são cobrados como acerto de cache a 10% do preço padrão. Os novos 300 tokens são cobrados pela criação de cache a 125% do preço padrão.

    O parâmetro cache_creation_input_tokens especifica o número de tokens usados para a criação do cache.

  • Acerto de cache: Cobrado a 10% do preço padrão do token de entrada.

    O parâmetro cached_tokens especifica o número de tokens em cache.

  • Outros tokens: Tokens que não representam nem um acerto de cache nem foram usados para criação de cache são cobrados ao preço padrão do token de entrada.

  • Exceção: O preço de acerto de cache explícito para qwen3.8-max e qwen3.8-2.4t-a95b não é 10% do preço padrão do token de entrada. Para preços específicos, consulte o console do Model Studio. (O preço de criação de cache permanece 125% do preço padrão.)

Conteúdo armazenável em cache

Apenas os seguintes tipos de mensagem no array messages suportam a adição de marcadores de cache:

  • Mensagem de sistema

    ObservaçãoPara function calling, se uma requisição incluir o parâmetro tools, a definição da ferramenta será incluída na mensagem de sistema para cálculo de cache. Definições de ferramentas não podem ser armazenadas em cache independentemente. Marcadores de cache adicionados a definições de ferramentas são ignorados, pois só podem ser adicionados ao conteúdo de uma mensagem.

  • Mensagem de usuário

    Ao criar um cache com o modelo qwen3-vl-plus , posicione o marcador cache_control após o conteúdo multimodal ou texto. Sua posição não afeta como toda a mensagem do usuário é armazenada em cache.

  • Mensagem de assistente

  • Mensagem de ferramenta (resultado da execução da ferramenta)

Por exemplo, para uma mensagem de sistema, altere o campo content para um array e adicione o campo cache_control:

{
  "role": "system",
  "content": [
    {
      "type": "text",
      "text": "<your specified prompt>",
      "cache_control": {
        "type": "ephemeral"
      }
    }
  ]
}

Essa estrutura também se aplica a outros tipos de mensagem no array messages.

Limitações do cache

  • O comprimento mínimo do prompt armazenável em cache é de 1.024 tokens.

  • O cache utiliza uma estratégia de correspondência de prefixo retroativa. Ocorre uma falha de cache se o conteúdo correspondente e a mensagem com o marcador cache_control estiverem separados por mais de 20 blocos de conteúdo.

  • O type só pode ser definido como ephemeral, o que cria um cache com período de validade de 5 minutos.

  • Uma única requisição suporta até quatro marcadores de cache.

    Se mais de quatro marcadores de cache forem fornecidos, apenas os últimos quatro terão efeito.

Otimização de cache para Function Calling

Uma definição de ferramenta é serializada em uma string JSON para armazenamento em cache. Para evitar invalidação do cache, essa definição deve ser idêntica em todas as requisições. Observe o seguinte:

  • Ordem consistente das ferramentas: A ordem das ferramentas no array tools deve ser consistente em todas as requisições.
  • Ordem consistente dos campos: A ordem dos campos JSON dentro da mesma ferramenta deve ser consistente em todas as requisições.
  • Estrutura consistente dos campos: Não omita nem adicione campos, mesmo que estejam vazios ou sejam opcionais.

Otimizando a estrutura de mensagens para chamadas paralelas de ferramentas

Ao usar chamadas paralelas de ferramentas, o modelo retorna múltiplos tool_calls em uma única resposta. Se você enviar cada resultado de ferramenta como uma mensagem tool separada, o número de blocos de conteúdo no array messages cresce rapidamente. Quando mais de 20 blocos de conteúdo separam o marcador cache_control de conteúdos anteriores, a janela de busca retroativa não consegue alcançar esses blocos anteriores, causando uma falha de cache.

Para resolver isso, mescle mensagens consecutivas de ferramenta com a mesma função em uma única mensagem tool com múltiplos blocos de conteúdo antes de enviar a próxima requisição. Isso reduz a contagem total de blocos de conteúdo e mantém o conteúdo que você deseja armazenar em cache dentro da janela de busca de 20 blocos.

Antes da otimização (mensagens de ferramenta separadas — menor taxa de acerto de cache):


# After the model returns parallel tool_calls, send each result as a separate message
messages.append(assistant_message)  # assistant message containing parallel tool_calls
# Each tool result is its own message — increases content block count by N
messages.append({"role": "tool", "tool_call_id": "call_1", "content": "result_1"})
messages.append({"role": "tool", "tool_call_id": "call_2", "content": "result_2"})

Após a otimização (mensagem de ferramenta mesclada — maior taxa de acerto de cache):


# After the model returns parallel tool_calls, merge all results into one message
messages.append(assistant_message)  # assistant message containing parallel tool_calls
# Merge all tool results into a single message with multiple content blocks
messages.append({
    "role": "tool",
    "tool_call_id": "call_1",
    "content": [
        {"type": "text", "text": "result_1"},
        {"type": "text", "text": "result_2", "tool_call_id": "call_2"},
    ],
})

Para melhorar ainda mais a taxa de acerto de cache, posicione marcadores cache_control em posições estáveis no array messages (por exemplo, na mensagem de sistema ou em outro conteúdo que muda com pouca frequência). Uma única requisição suporta até quatro marcadores de cache.

Exemplos de uso

Consultando um texto longo

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # This is the base_url for the Singapore region. When making a call, replace {WorkspaceId} with your actual WorkspaceId. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# Mock code repository content
long_text_content = "<Your Code Here>" * 400

# Function to send a request
def get_completion(user_input):
    messages = [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": long_text_content,
                    # Place the cache_control marker here to create a cache from the start of the prompt to the end of this content object (the mock code repository content).
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        {
            "role": "user",
            "content": user_input,
        },
    ]
    completion = client.chat.completions.create(
        # Select a model that supports explicit cache
        model="qwen3.8-max",
        messages=messages,
    )
    return completion

# First request
first_completion = get_completion("What is the content of this code?")
created_cache_tokens = first_completion.usage.prompt_tokens_details.cache_creation_input_tokens
print(f"First request - Cache creation tokens: {created_cache_tokens}")
hit_cached_tokens = first_completion.usage.prompt_tokens_details.cached_tokens
print(f"First request - Cache hit tokens: {hit_cached_tokens}")
print(f"First request - Uncached tokens: {first_completion.usage.prompt_tokens-created_cache_tokens-hit_cached_tokens}")
print("=" * 20)
# Second request with the same code content but a different question
second_completion = get_completion("What are some possible optimizations for this code?")
created_cache_tokens = second_completion.usage.prompt_tokens_details.cache_creation_input_tokens
print(f"Second request - Cache creation tokens: {created_cache_tokens}")
hit_cached_tokens = second_completion.usage.prompt_tokens_details.cached_tokens
print(f"Second request - Cache hit tokens: {hit_cached_tokens}")
print(f"Second request - Uncached tokens: {second_completion.usage.prompt_tokens-created_cache_tokens-hit_cached_tokens}")

Este exemplo armazena o conteúdo do repositório de código em cache como prefixo. Requisições subsequentes fazem perguntas diferentes sobre o mesmo repositório.

First request - Cache creation tokens: 1605
First request - Cache hit tokens: 0
First request - Uncached tokens: 13
====================
Second request - Cache creation tokens: 0
Second request - Cache hit tokens: 1605
Second request - Uncached tokens: 15

Para garantir o desempenho do modelo, o sistema anexa alguns tokens internos. Esses tokens são cobrados ao preço padrão de entrada. Para mais informações, consulte o FAQ .

Armazenando ferramentas em cache para function calling

Ao armazenar mensagens de sistema em cache para Function Calling, o parâmetro tools é armazenado como parte da mensagem de sistema. Garanta que a definição da ferramenta seja idêntica para cada requisição (incluindo ordem das ferramentas, ordem dos campos e estrutura dos campos) e adicione um sinalizador cache_control ao último content em messages.

O fluxo completo é mostrado a seguir: a primeira requisição cria o cache e a segunda requisição obtém um acerto no cache.

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

# Mock code repository content, ensuring it exceeds the minimum 1,024-token threshold for explicit cache.
long_text_content = "<Your Code Here>" * 400

# Tool definition: Ensure it is identical for every request (tool order, field order, and field structure).
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather information for a specified city.",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "The city name, e.g., Beijing, Shanghai, or New York."
                    },
                    "unit": {
                        "type": "string",
                        "description": "The temperature unit, 'celsius' or 'fahrenheit'. Defaults to 'celsius'.",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["city"],
                "additionalProperties": False
            },
            "strict": True
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "Get the current date and time for a specified time zone.",
            "parameters": {
                "type": "object",
                "properties": {
                    "timezone": {
                        "type": "string",
                        "description": "IANA time zone name, e.g., 'Asia/Shanghai' or 'America/New_York'. Defaults to 'Asia/Shanghai'."
                    }
                },
                "required": [],
                "additionalProperties": False
            },
            "strict": True
        }
    },
    {
        "type": "function",
        "function": {
            "name": "convert_currency",
            "description": "Convert currency amounts based on real-time exchange rates.",
            "parameters": {
                "type": "object",
                "properties": {
                    "from_currency": {
                        "type": "string",
                        "description": "The ISO 4217 code of the source currency, e.g., CNY, USD, or EUR."
                    },
                    "to_currency": {
                        "type": "string",
                        "description": "The ISO 4217 code of the target currency."
                    },
                    "amount": {
                        "type": "number",
                        "description": "The amount to be converted."
                    }
                },
                "required": ["from_currency", "to_currency", "amount"],
                "additionalProperties": False
            },
            "strict": True
        }
    }
]

def get_completion(user_input, messages=None):
    if messages is None:
        messages = [
            {
                "role": "system",
                "content": [
                    {
                        "type": "text",
                        "text": long_text_content,
                        # Place the cache_control marker here. This creates a cache block with all content from the start of the messages array to the current content object.
                        # The cache_control marker must be on the 'content' of a message, not on 'tools'.
                        "cache_control": {"type": "ephemeral"},
                    }
                ],
            }
        ]

    messages.append({"role": "user", "content": user_input})

    completion = client.chat.completions.create(
        # Select a model that supports explicit cache
        model="qwen3.7-plus",
        messages=messages,
        tools=tools,
        # Disable thinking mode
        extra_body={"enable_thinking": False},
    )
    return completion

# First request: Create cache
print("=== First request (Create cache) ===")
first_completion = get_completion("What's the weather like in Beijing now?")
usage = first_completion.usage
print(f"Prompt Tokens: {usage.prompt_tokens}")
print(f"Cache creation tokens: {usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Model selected tool(s): {[t.function.name for t in first_completion.choices[0].message.tool_calls or []]}")
print()

# Second request: Hits the cache with the same system message but a different question
print("=== Second request (Cache hit) ===")
messages = [
    {
        "role": "system",
        "content": [
            {
                "type": "text",
                "text": long_text_content,
                "cache_control": {"type": "ephemeral"},
            }
        ],
    }
]
second_completion = get_completion("What's the weather like in Shanghai now?", messages=messages)
usage = second_completion.usage
print(f"Prompt Tokens: {usage.prompt_tokens}")
print(f"Cache creation tokens: {usage.prompt_tokens_details.cache_creation_input_tokens}")
print(f"Cache hit tokens: {usage.prompt_tokens_details.cached_tokens}")
print(f"Model selected tool(s): {[t.function.name for t in second_completion.choices[0].message.tool_calls or []]}")

Executar o código produz uma saída semelhante à seguinte:

=== First request (Create cache) ===
 Prompt Tokens: 2174
 Cache creation tokens: 2156
 Cache hit tokens: 0
 Model selected tool(s): ['get_weather']

 === Second request (Cache hit) ===
 Prompt Tokens: 2174
 Cache creation tokens: 0
 Cache hit tokens: 2156
 Model selected tool(s): ['get_weather']

Conversa contínua de múltiplos turnos

Em um cenário típico de conversa de múltiplos turnos, adicione um marcador de cache ao último objeto de conteúdo no array messages para cada requisição. A partir do segundo turno, cada requisição obtém um acerto e atualiza o cache do turno anterior, enquanto cria um novo bloco de cache para o turno atual.

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # This is the base_url for the Singapore region. When making a call, replace {WorkspaceId} with your actual WorkspaceId. URLs vary by region.
    base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)

system_prompt = "You are a witty person." * 400
messages = [{"role": "system", "content": system_prompt}]

def get_completion(messages):
    completion = client.chat.completions.create(
        model="qwen3.8-max",
        messages=messages,
    )
    return completion

while True:
    user_input = input("User: ")
    messages.append({"role": "user", "content": [{"type": "text", "text": user_input, "cache_control": {"type": "ephemeral"}}]})
    completion = get_completion(messages)
    print(f"[AI Response] {completion.choices[0].message.content}")
    messages.append(completion.choices[0].message)
    created_cache_tokens = completion.usage.prompt_tokens_details.cache_creation_input_tokens
    hit_cached_tokens = completion.usage.prompt_tokens_details.cached_tokens
    uncached_tokens = completion.usage.prompt_tokens - created_cache_tokens - hit_cached_tokens
    print(f"[Cache Info] Cache creation tokens: {created_cache_tokens}")
    print(f"[Cache Info] Cache hit tokens: {hit_cached_tokens}")
    print(f"[Cache Info] Uncached tokens: {uncached_tokens}")

Execute o código para iniciar uma conversa com o modelo de linguagem grande. Cada pergunta subsequente obtém um acerto no cache criado no turno anterior.

Cache implícito