在动手实操前,我们先简要回顾一下提示词缓存的核心概念。提示词缓存是前沿模型API服务(如OpenAI API或Claude API)提供的一项功能,允许缓存并复用大语言模型(LLM)输入中频繁重复的部分。这些重复部分可能是系统提示词或指令——在运行AI应用时,它们会与用户查询、从知识库中检索到的信息等可变内容一起,每次都传递给模型。
要成功触发提示词缓存,提示词中重复的部分必须位于开头(即作为提示词前缀)。此外,要激活提示词缓存,该前缀必须超过特定阈值(例如,OpenAI要求前缀超过1024个token,而Claude针对不同模型有不同的最小缓存长度)。只要满足这两个条件——重复token作为前缀且超过API服务和模型定义的大小阈值——就可以激活缓存,从而在运行AI应用时实现规模经济。
与(检索增强生成)或其他AI应用中其他组件的缓存不同,提示词缓存在大语言模型的内部流程中,以token为单位运行。具体来说,大语言模型的推理过程分为两个步骤:
-
预填充(Pre-fill):大语言模型接收用户提示词,生成第一个token;
-
解码(Decoding):大语言模型递归地逐个生成输出的token。
简而言之,提示词缓存会存储预填充阶段发生的计算,因此当相同的前缀再次出现时,模型无需重新计算。而解码迭代阶段发生的任何计算,即使重复,也不会被缓存。
在本文的其余部分,我将重点介绍提示词缓存在OpenAI API中的使用方法。
OpenAI API于2024年10月1日首次引入提示词缓存功能。最初,缓存token可享受50%的折扣,而如今折扣最高可达90%。此外,通过命中提示词缓存,延迟最多可降低80%。
当提示词缓存被激活时,API服务会尝试将提交的提示词路由到相应的机器(预期缓存存在的机器),以命中缓存。这一过程称为缓存路由(Cache Routing),API服务通常会利用提示词前256个token的哈希值来实现这一点。
此外,OpenAI API还允许在向模型发送的API请求中,显式定义prompt_cache_key参数。这是一个用于指定缓存的单一密钥,旨在进一步提高提示词被路由到正确机器并命中缓存的概率。
同时,OpenAI API根据缓存持续时间,通过prompt_cache_retention参数提供两种不同类型的缓存:
-
内存中提示词缓存(In-memory prompt cache retention):这是默认的缓存类型,适用于所有支持提示词缓存的模型。使用内存缓存时,缓存数据在请求之间的有效期为5-10分钟。
-
扩展提示词缓存(Extended prompt cache retention):仅适用于特定模型。扩展缓存允许将数据在缓存中保留更长时间,最长可达24小时。
关于成本方面,无论是否激活提示词缓存,OpenAI对输入(非缓存)token的收费标准都是相同的。如果成功命中缓存,缓存token将按大幅折扣后的价格计费,折扣最高可达90%。此外,内存缓存和扩展缓存的输入token单价保持一致。
接下来,我们通过一个简单的Python示例,看看提示词缓存在OpenAI API中实际如何工作。具体来说,我们将模拟一个真实场景:多个请求复用一个较长的系统提示词(前缀)。如果你看到这里,想必你已经准备好OpenAI API密钥,并安装了所需的库。那么,首先要做的就是导入OpenAI库、用于捕获延迟的time库,并初始化OpenAI客户端实例:
from openai import OpenAI
import time
client = OpenAI(api_key="your_api_key_here")
然后,我们定义前缀(即要重复使用并希望缓存的token):
long_prefix = """
You are a highly knowledgeable assistant specialized in machine learning.
Answer questions with detailed, structured explanations, including examples when relevant.
"""
* 200
注意,我们通过乘以200来人为增加前缀长度,以确保满足1024个token的缓存阈值。接着,我们设置一个计时器来衡量延迟节省情况,然后就可以发起请求了:
start = time.time()
response1 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is overfitting in machine learning?"
)
end = time.time()
print("First response time:", round(end - start, 2), "seconds")
print(response1.output[0].content[0].text)
那么,我们预期会发生什么?对于gpt-4o及更新版本的模型,提示词缓存默认是激活的,而我们的输入包含4616个token,远超过1024个token的前缀阈值,因此缓存可以正常生效。这个请求首先会检查输入是否命中缓存(由于这是第一次使用该前缀发起请求,所以不会命中),然后处理整个输入并将其缓存。下次我们发送包含相同前缀初始token的输入时,就会命中缓存。
让我们通过发起第二个使用相同前缀的请求,来实际验证这一点:
start = time.time()
response2 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is regularization?"
)
end = time.time()
print("Second response time:", round(end - start, 2), "seconds")
print(response2.output[0].content[0].text)
果然!第二个请求的运行速度明显更快(例如23.31秒 vs 15.37秒)。这是因为模型已经完成了对缓存前缀的计算,只需从头处理新的部分——“What is regularization?”(什么是正则化?)。因此,通过使用提示词缓存,我们获得了显著更低的延迟和更低的成本,因为缓存token享受折扣优惠。
我们之前提到过OpenAI文档中的prompt_cache_key参数。根据文档,我们可以在发起请求时显式定义提示词缓存密钥,从而指定需要使用相同缓存的请求。不过,我尝试在示例中适当调整请求参数以加入该参数,但效果并不理想:
response1 = client.responses.create(
prompt_cache_key = 'prompt_cache_test1',
model="gpt-5.1",
input=long_prefix + "What is overfitting in machine learning?"
)
樂 看来,虽然prompt_cache_key是API的一项功能,但它尚未在Python SDK中开放。换句话说,我们目前还无法显式控制缓存的复用,它更多是自动且尽力而为的。
从我们目前的讨论来看,激活提示词缓存并命中缓存似乎相当简单。那么,可能会出现哪些问题导致缓存未命中呢?遗憾的是,可能出现的问题有很多。尽管过程简单,但提示词缓存需要满足多种前提条件,只要缺少其中任何一个,就会导致缓存未命中。让我们详细看看!
一个明显的未命中情况是:前缀长度小于激活提示词缓存的阈值(即不足1024个token)。不过,这很容易解决——我们可以像上面的示例那样,通过适当乘以某个数值,人为增加前缀的token数量。
另一个可能的问题是“无声破坏前缀”。具体来说,即使我们在所有请求中使用固定长度合适的指令和系统提示词,也必须格外小心,不要在模型输入的开头(前缀之前)添加任何可变内容。这是一种必然会破坏缓存的做法,无论后续的前缀多长、重复多少次。容易陷入这个陷阱的常见情况是使用动态数据,例如在提示词开头添加用户ID或时间戳。因此,在所有AI应用开发中,一个**实践是:任何动态内容都应添加在提示词的末尾——永远不要放在开头。
最后,值得强调的是,提示词缓存仅针对预填充阶段——解码阶段永远不会被缓存。这意味着,即使我们强制模型按照特定模板生成响应(该模板以某些固定token开头),这些token也不会被缓存,我们仍需按常规为其处理付费。
相反,对于某些特定用例,使用提示词缓存并没有实际意义。例如:高度动态的提示词(如几乎没有重复内容的聊天机器人)、一次性请求,或实时个性化系统。
提示词缓存可以显著提升AI应用的性能,无论是在成本还是时间方面。特别是在需要扩展AI应用时,提示词缓存对于将成本和延迟维持在可接受水平非常有用。
对于OpenAI API,提示词缓存默认是激活的,无论是否激活提示词缓存,输入(非缓存)token的成本都是相同的。因此,即使不一定能成功命中缓存,激活提示词缓存并尝试在每次请求中命中它,对你来说都只有好处。
Claude也通过其API提供了丰富的提示词缓存功能,我们将在后续文章中详细探讨这一点。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/264840.html