messages 数组和 token 讲了和大模型交互的底层机制:messages 数组(上下文)、token 计费、缓存命中。
理解了这些原理,很多日常使用 AI 工具时困惑的问题就能想通了,比如:
- 为什么建议不同的问题开新会话,在一个会话里一直聊下去不行吗?
- 聊久了 AI 怎么开始「变笨」了,前面说过的事情它又忘了?
- 为什么有些产品感觉「越用越懂我」?
- 用 Claude Code 这类编程 Agent,为什么第一条消息比较贵,后面就便宜了?
- 写代码写到一半网断了,或者手动打断了对话,之前的工作进度会丢吗?
这篇就基于上篇的原理来回答这几个问题。
什么是 session
先明确一个概念:session(会话)。你在 ChatGPT、Claude 这类产品里点「New Chat」开一个新对话,这就是开了一个新 session。
每个 session 底层是一个独立的 messages 数组(上下文)。在一个 session 里,你和模型的所有交流都在这个数组里累积。开新会话,本质就是清空数组从头开始,模型对之前的会话一无所知。
你可能会问:那为什么用 ChatGPT 久了,感觉它越来越「懂我」,好像记得我是做什么的、喜欢什么风格?
这是因为 ChatGPT、Gemini 这些产品在应用层做了一个优化:用户记忆(Memory)。
它们会从你每天的对话中提取一些个人信息(比如你的职业、技术栈、偏好的回答风格),持久化存储下来。每次你开新会话时,这些信息会被注入到 messages 数组的开头,相当于在 system prompt 里加了一段「用户画像」。
所以模型并没有真的「学会」了什么,它还是无状态的。只是产品帮你把积累的个人信息自动塞进了每次对话的上下文里,让模型看起来「记得」你。本质上和你每次手动告诉模型「我是一个后端程序员,请用简洁风格回答」没有区别,只不过产品帮你自动化了这个过程。
对话越长,效果越差
和 AI 对话时一个简单原则:一个会话只聊一个主题。
如果你问完一个编程问题,接着在同一个对话里又问一个完全不相关的问题(比如翻译一封邮件),效果会差在两个方面:
一是费用更高。前面讲过,每次请求都要把整个上下文发过去。你继续在同一个对话里问不相关的问题,之前那些无关消息也一起发送。虽然前缀可能命中缓存,价格便宜一些,但也不是免费的,而且对话越长 token 消耗越大。
二是回答质量会下降,这是更严重的问题。LLM 本质是基于上下文做概率预测,上下文里的所有内容都会影响输出。如果数组里堆了一大堆和当前问题无关的对话历史,这些无关信息会分散模型的注意力,导致回答跑偏或质量下降。
所以不同主题的问题应该开新会话,使用本站的 AI 助教 中也提过同样的建议。
哪怕是同一个主题的讨论,聊太久了效果也会变差。你可能遇到过:前面明明讨论过的事情,后面模型突然就「忘」了。原因有两个:
第一,上下文窗口有容量上限,当快要超出上下文最大容量时,AI 工具会做摘要压缩:让模型把早期对话生成一段简短总结,用总结替换掉原始记录。压缩之后早期的细节就丢了,比如你在开头定义的命名规范,几百轮之后可能就被压缩掉了。
ChatGPT 网页版会自动处理压缩,用户无法手动控制;Claude Code 也会自动压缩,同时提供了 /compact 命令让你主动触发。
第二,即使没触发压缩,模型本身对上下文开头和结尾的内容印象最深,中间部分容易一扫而过。就好比你读一本长书,最记得开头和结尾,中间章节容易模糊。
这个现象被称为 Lost in the Middle,斯坦福和 Meta AI 在 2023 年的研究中证实了这一点。
虽然现在模型能力越来越强,很多模型都支持 1M 甚至更长的上下文,但只能说那是模型的能力上限(不会强制自动压缩),但根据我的实际体验,当上下文变长后模型难免有些降智。
所以如果聊同一个问题但前面积累了比较冗长的中间过程,可以主动执行压缩命令(比如 Claude Code / Codex 的 /compact 命令),不要等上下文快撑满了才让工具自动压缩,趁对话还不太长的时候主动做摘要,信息保留得更完整,后续的回答质量也更好。
第一条消息为什么「贵」
如果你用过 Claude Code 这类编程 Agent,按量计费的话,会发现一个有趣的现象:刚开一个新会话,哪怕只发了一个「Hi」,可能就花了好几毛钱。但接着继续聊,每条消息可能才几分钱。
首先,Claude Code 这类工具有非常长的 system prompt(系统提示词),包含了行为规范、几十个内置工具的参数定义、你的项目上下文等等,加起来可能有上万 token,相当于一篇万字长文。
这些内容你在聊天界面里看不到,但它们全都塞在上下文的最前面,每次都会发给模型。
你发的「Hi」只是数组末尾的一小条消息,但第一次调用时前面那上万 token 的 system prompt 没有被缓存过,全部按原价计算,费用自然就高了。
从第二条消息开始,这个巨大的前缀 命中缓存,只有你新增的内容按原价算,成本就降下来了。所以不用因为第一条消息的花费紧张,继续聊下去就便宜了。
当然还要注意缓存是有时效的,比如 Claude Code 的默认缓存是 5 分钟,如果你超过 5 分钟没有继续聊,之前的缓存就会被清理掉,下次再聊的时候又要重新计算前缀。
重启电脑/打断对话/切换模型会失忆吗?
刚接触 AI 编程工具的同学经常担心:用 Claude Code 写代码写到一半,网络突然断了怎么办?或者回答到一半手动打断了,之前的工作会不会丢?
还有就是,如果和 AI 聊到一半,想要换个模型继续聊,模型会不会失忆,完全忘记之前的对话内容?
答案是不会,放心吧。
回想一下 messages 数组和 token 中讲解的原理:模型是无状态的,所有「记忆」都在 messages 数组(上下文)里。这个数组不存在模型服务商那边,而是由你使用的工具单独保存。
Claude Code/Codex 把它存在你的本地电脑上(可以通过 /resume 命令 回到之前的对话),ChatGPT 网页版把它存在 OpenAI 的服务器上。无论存在哪里,关键是它和模型是分开的。
每次你发消息,客户端都会把完整的对话历史一起发给模型。即使中途断网或手动打断,下次发消息时整个历史会再次完整发送,模型读到这些消息就像经历了完整的对话一样。
唯一的影响是,如果你切换模型,或者隔了很久重新打开旧的会话,第一条消息无法 命中缓存,费用会稍微高一些,但这属于正常行为,不必担心。