当我问 ChatGPT 还记得关于我的哪些事情时,它列出了 33 条信息,从我的名字、职业目标,到我当前的健身计划。但它究竟是如何存储并检索这些信息的?又为什么这一切用起来感觉如此无缝、自然?
在经过大量实验之后,我发现 ChatGPT 的记忆系统远比我想象的要简单得多。没有向量数据库,也没有基于对话历史的 RAG。取而代之的是,它使用了四个彼此独立的层次:会根据你的使用环境动态调整的会话元数据、长期存储的显式事实、近期对话的轻量级摘要,以及当前对话的滑动窗口。
这篇博客将详细拆解每一层是如何运作的,以及为什么这种设计方式可能优于传统的检索系统。文中所有结论都来自通过对话对 ChatGPT 行为的逆向分析,而非官方资料——OpenAI 并未公开这些实现细节。
ChatGPT 的上下文结构
在理解记忆机制之前,先理解 ChatGPT 在每一条消息中所接收到的完整上下文非常重要。它的整体结构大致如下:
[0] 系统指令(System Instructions)
[1] 开发者指令(Developer Instructions)
[2] 会话元数据(Session Metadata,临时)
[3] 用户记忆(User Memory,长期事实)
[4] 最近对话摘要(过往聊天:标题 + 片段)
[5] 当前会话消息(本次聊天内容)
[6] 你的最新一条消息
前两个组成部分用于定义高层行为和安全规则,它们并不是本文讨论的重点。真正有意思的内容,是从 会话元数据(Session Metadata) 开始的。
Session Metadata
这些信息会在一次会话开始时被注入一次。它们不会被永久存储,也不会进入长期记忆。这一部分通常包括:
-
设备类型(桌面端 / 移动端)
-
浏览器信息与 User Agent
-
大致的地理位置 / 时区
-
订阅等级
-
使用模式与活跃频率
-
最近使用过的模型分布情况
-
屏幕尺寸、是否开启深色模式、是否启用 JavaScript 等
一个会话元数据(Session Metadata)的示例如下:
Session Metadata:
- User subscription: ChatGPT Go
- Device: Desktop browser
- Browser user-agent: Chrome on macOS (Intel)
- Approximate location: India (may be VPN)
- Local time: ~16:00
- Account age: ~157 weeks
- Recent activity:
- Active 1 day in the last 1
- Active 5 days in the last 7
- Active 18 days in the last 30
- Conversation patterns:
- Average conversation depth: ~14.8 messages
- Average user message length: ~4057 characters
- Model usage distribution:
* 5% gpt-5.1
* 49% gpt-5
* 17% gpt-4o
* 6% gpt-5-a-t-mini
* etc.
- Device environment:
- JS enabled
- Dark mode enabled
- Screen size: 900×1440
- Page viewport: 812×1440
- Device pixel ratio: 2.0
- Session duration so far: ~1100 seconds
User Memory
ChatGPT有一个专门的工具,用于存储和删除关于用户的稳定、长期事实。正是这些信息在数周乃至数月中不断累积,逐渐形成一个持久存在的“用户画像(profile)”。 在我的这个案例中,模型一共存储了 33 条事实信息,例如:
-
我的姓名、年龄
-
职业目标
-
背景经历与过往角色
-
当前正在进行的项目
-
正在学习的领域
-
健身计划
-
个人偏好
-
长期兴趣
这些信息并不是模型“猜出来”的,而只有在以下情况下才会被明确地存储:
- 用户明确表示“记住这个”或“把这个存到记忆里”,或者
- 模型检测到某条信息符合 OpenAI的存储标准(例如你的名字、职位、或明确表达的偏好),并且用户在对话中对这种记录方式给予了隐式同意
这些记忆会作为一个独立的区块,被注入到之后的每一次提示(prompt)中。 如果你想新增或删除任何内容,只需要直接说一句:
- “把这条信息存入记忆中……”
- “把这条信息从记忆中删除……”
示例:
- 用户名是 Manthan Gupta。
- 曾在 Merkle Science 和 Qoohoo(YC W23)工作。
- 偏好通过视频、论文与动手实践相结合的方式学习。
- 构建过 TigerDB、CricLang、Load Balancer、FitMe 等项目。
- 正在研究现代信息检索(IR)系统,包括 LDA、BM25、混合检索、稠密向量嵌入、FAISS、RRF 以及基于 LLM 的重排序(reranking)。
Recent Conversations Summary
这一部分是最让我感到意外的,因为我原本以为 ChatGPT 会在过往对话上使用某种形式的 RAG。结果却发现,它采用的是一种轻量级的摘要机制。 ChatGPT 会以如下格式保存一份近期对话摘要列表:
1. <Timestamp>: <Chat Title>
|||| user message snippet ||||
|||| user message snippet ||||
观察结论:
- 只会摘要我的消息,而不是助手的回复。
- 可用的摘要数量大约在 15 条左右。
- 它们更像是一张近期兴趣的粗略地图,而不是可直接使用的详细上下文。
这个区块让 ChatGPT 在不同对话之间保持一种连续感,而无需加载完整的聊天记录。 传统的 RAG 系统通常需要:
-
对每一条历史消息都进行向量嵌入
-
在每次查询时运行相似度搜索
-
将完整的消息上下文拉取进来
-
带来更高的延迟和更高的 token 成本
ChatGPT 的做法要简单得多:预先计算轻量级摘要,并直接注入到上下文中。这种方式用对细节上下文的牺牲,换取了速度和效率。
当前会话消息
这是当前对话的常规滑动窗口,其中包含本次会话中所有已交换消息的完整历史记录(未经过摘要处理)。 我没能从 ChatGPT 那里得到一个精确的 token 上限,但它确实确认了以下几点:
-
上限是基于 token 数量,而不是消息条数
-
一旦达到上限,当前会话中较早的消息会被逐步移出(但长期记忆事实和对话摘要仍然保留)
-
这个区块中的所有内容都会逐字不变地传递给模型,从而维持完整的对话上下文
正是这一机制,才使得助手能够在单个会话内进行连贯的推理和回应。
整体是如何协同运作的
当你向 ChatGPT 发送一条消息时,实际发生的流程如下:
- 会话开始时:会话元数据会被注入一次,为 ChatGPT 提供关于你的设备、订阅情况以及使用模式的上下文信息。
- 每一条消息中:你已存储的记忆事实(在我的例子中是 33 条)都会始终被包含在内,确保回复能够与你的偏好和背景保持一致。
- 跨对话感知:近期对话摘要在不引入完整聊天记录的情况下,提供了一张关于你兴趣方向的轻量级“地图”。
- 当前上下文:当前会话消息的滑动窗口用于维持对话内部的连贯性。
- Token 预算:随着会话不断增长,较早的消息会被逐步移出,但你的长期记忆事实和对话摘要仍然保留,从而维持整体的连续性。
这种分层式的设计,使 ChatGPT 能在不需要检索成千上万条历史消息、也不承担高昂计算成本的前提下,依然呈现出个性化、具备上下文感知能力的体验。
结论
ChatGPT 的记忆系统是一种多层架构,在个性化体验、性能和 token 效率之间取得了平衡。通过将临时的会话元数据、显式的长期事实、轻量级的对话摘要以及当前会话消息的滑动窗口组合在一起,ChatGPT 实现了一件相当了不起的事情:在不承担传统 RAG 系统计算开销的情况下,依然让人感觉它是“懂你”的、具备上下文感知能力的。
这里的核心洞见在于:并非所有信息都需要以传统意义上的“记忆”形式存在。会话元数据会实时适配你的使用环境;显式事实可以跨会话长期保留;对话摘要在不引入细节的情况下提供连续性;而当前会话则负责维持语境的一致性。正是这些动态组件——随着会话推进和用户偏好变化不断更新——共同营造出一种系统“真正了解你”的错觉。
对用户而言,这意味着 ChatGPT 会随着时间推移变得越来越个性化,而无需你去显式管理某个知识库。对开发者来说,这是一个务实工程思维的范例:在你能够控制整个流程的前提下,更简单、更精心设计的方案,往往比复杂的检索系统表现得更好。
这种取舍也很清晰:ChatGPT 用牺牲详尽的历史上下文,换取了速度与效率。但对大多数对话场景而言,这恰恰是最合适的平衡点。系统记住真正重要的东西——你的偏好、目标和近期兴趣——同时保持快速、流畅的响应体验。