1、每次都发送历史,模型也要全部重新计算吗?
模型每生成一个token都得根据前面所有的token计算得来,如果每轮都重头计算一次,开销会随着上下文长度爆炸式增长。因此不会全部重新计算,这里就引入了KV Cache的理念,具体做法就是把前文的中间计算结果缓存下来,下一轮只需要计算新增token的部分。但这么做有一个前提------复用的上下文token前缀保持不变。哪里发生了变化就从首个不同token及以后的KV状态都得重新计算(该位置之前的依旧可以复用不受影响)
2、从messages到Token:模型实际接收的是什么?
虽然上下文中给模型的是一些结构化的信息 比如消息列表,但模型不是直接接收的。结构化的消息会被Chat Template翻译为模型训练时见过的固定token序列,这也是不推荐自行使用字符串拼接消息的原因(类似"USER: ... ASSISTANT: ...")因为这偏离了这种训练格式,会削弱模型的多步思考能力。具体的内容下面展开:
2.1 Chat Template如何组织信息?

上述图片展示了把标准化消息经过Chat Template组织后的过程,使用特殊标记 (如 <|im_start|> system、<|im_end|>)划分每条消息的边界和角色。每个模型家族会使用不同的组织方式,这个过程一般是由API服务端根据模型的Chat Template自动完成转换的,无需开发者手动处理。
2.2 为什么消息内容和排列顺序会影响缓存?
(1)为什么必须使用标准的API格式
如果开发者绕过API自行拼接消息内容(比如把工具的结果作为user消息而非tool消息进行传递),Chat Template会误将工具的影响视为新的用户需求,导致模型的思维链保留机制被破坏。
(2)为什么对前缀如此敏感
Chat Template 将 system 消息和工具定义转换为固定的token序列放在最前面,这些token的K-V键值对被缓存后可以夸请求复用。但是如果前缀中某个token发生了变化,首个不同token及其之后的缓存就无法复用。
3、KV Cache缓存了什么?
就是把已经计算过的K与V缓存起来,让新词的产生能直接复用。举一个简单的例子:现在上下文有4个tokenA ,B ,C , D,模型要生成第五个token E,根据注意力机制 的操作,使用token D的Q与A,B,C,D四个token的K做点积来计算匹配度,再根据相关性对这4个token的V加权求和,得到D这个位置的输出表示(模型使用它预测下一个token E)。不使用 KV Cache 时 ,每生成一个新 token 都要把整个前缀从头前向计算一遍;使用 KV Cache 时,每个 token 的 K、V 只在它第一次进入上下文时计算一次,之后一直留在缓存里。
KV Cache 省去的是历史 token 的 K、V 投影重算,使每步解码不必重算整个前缀。
4、KV Cache与Prompt Cache有何区别?
KV Cache 是模型内部的机制 ------在一次推理过程中,缓存已计算 token 的键值对,避免重复计算。Prompt Cache 则是推理引擎的优化 ------在多次 API 请求之间缓存相同前缀(本次完整的上下文)的计算结果。两者的作用层级不同:KV Cache加速单次请求的token生成也就是一次生成过程中,怎样复用历史计算? Prompt Cache 减少跨请求的重复计算成本也就是多次请求之间,怎样复用相同的前缀?。
5、怎样设计对缓存友好的Agent上下文?
(1)提示工程与动态提示词
①系统提示词和工具定义一旦确定就不要改:任何改动都可能改变token序列,使首个不同token及其之后缓存无法复用;
②动态信息永远追加到末尾:时间戳、用户状态等变化的内容,作为新消息追加到对话末尾,而不是修改已有的系统提示词;
③使用标准 API 格式,不要自行拼接消息:这个前面已经有说到
当提示词越写越长、覆盖的场景越来越多时,把所有内容塞进一个系统提示词就不再可行了(既浪费 token,也会导致注意力被稀释),于是自然演化出 Agent Skills 的 渐进式披露机制------按需加载,而非一次性塞满。
(2)Agent状态栏
通过在上下文末尾注入动态的元信息(任务进度、环境观察摘要、工具调用计数等),弥补模型无法主动归纳隐式状态的不足。
(3)上下文压缩策略
解决上下文不断膨胀的问题。