过去和 ChatGPT 聊天,每次开新对话就像重新认识一个人——你得反复告诉它你偏好中文回复、你用的是 Python 3.11、你的项目在 Kubernetes 上跑。OpenAI 最近推出的 "Dreaming" 记忆系统,试图终结这种重复劳动。
记忆到底记了什么
新系统不是简单地把历史对话存下来再全文检索。它做的是偏好提取与压缩:从你的多次对话中识别出稳定倾向(编程语言、回复风格、常用框架、团队规模等),压缩成结构化的记忆条目,然后在后续对话中自动注入上下文。
这意味着:
- 你在对话 A 里说过"我偏好 TypeScript",对话 B 里不用再提。
- 你在对话 C 里描述过项目架构,对话 D 中 ChatGPT 能直接沿用。
- 记忆不是无限膨胀的——系统会淘汰过时条目,保持上下文窗口干净。
本质上,这是从"无状态函数调用"转向"有状态会话代理"的一步。
从开发者视角看记忆机制
如果你用 OpenAI API 构建自己的应用,ChatGPT 的记忆机制可以类比为你需要在服务端维护的用户偏好层。下面用一个最小示例展示如何实现类似的记忆注入逻辑:
import json
from openai import OpenAI
client = OpenAI()
# 模拟一个用户记忆存储(生产环境应使用数据库)
MEMORY_FILE = "user_memory.json"
def load_memory(user_id: str) -> str:
"""加载用户记忆,返回自然语言摘要用于注入 system prompt"""
try:
with open(MEMORY_FILE, "r") as f:
all_memories = json.load(f)
entries = all_memories.get(user_id, [])
if not entries:
return ""
# 把记忆条目拼成一段补充说明
summary = "关于该用户的已知偏好:\n"
for entry in entries:
summary += f"- {entry['category']}: {entry['value']}\n"
return summary
except FileNotFoundError:
return ""
def save_memory(user_id: str, category: str, value: str):
"""保存一条记忆条目"""
try:
with open(MEMORY_FILE, "r") as f:
all_memories = json.load(f)
except FileNotFoundError:
all_memories = {}
if user_id not in all_memories:
all_memories[user_id] = []
# 避免重复:同类别只保留最新值
all_memories[user_id] = [
e for e in all_memories[user_id] if e["category"] != category
]
all_memories[user_id].append({"category": category, "value": value})
with open(MEMORY_FILE, "w") as f:
json.dump(all_memories, f, indent=2)
def chat_with_memory(user_id: str, user_message: str) -> str:
"""带记忆注入的对话"""
memory_context = load_memory(user_id)
system_prompt = "你是一个技术助手,根据用户偏好调整回复风格和内容。"
if memory_context:
system_prompt += "\n\n" + memory_context
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message},
],
)
return response.choices[0].message.content
# --- 使用示例 ---
# 先存几条偏好
save_memory("dev_zhang", "编程语言", "TypeScript / Node.js")
save_memory("dev_zhang", "部署环境", "AWS ECS,不用 Kubernetes")
save_memory("dev_zhang", "回复风格", "简洁,直接给代码,少解释原理")
# 然后对话——不需要再重复偏好
reply = chat_with_memory(
"dev_zhang",
"帮我写一个 Lambda 函数,处理 S3 上传事件,把文件元数据写入 DynamoDB"
)
print(reply)
运行前确保已设置 OPENAI_API_KEY 环境变量:
export OPENAI_API_KEY="sk-..."
pip install openai
python chat_with_memory.py
这个示例的核心思路和 ChatGPT 的 Dreaming 系统一致:把用户偏好从对话内容中抽离,持久化存储,在每次新对话时自动注入 system prompt。区别在于 ChatGPT 用 LLM 自身来做偏好提取和淘汰决策,而这里我们手动管理——但原理相同。
记忆的淘汰与冲突
记忆不是越多越好。几个实际问题:
过时记忆——你半年前说"我用 MySQL",现在已迁移到 PostgreSQL。如果系统不淘汰旧条目,它会持续给你写 MySQL 语法。ChatGPT 的做法是让模型自行判断记忆条目是否仍然适用,在冲突时用新信息覆盖旧条目。
记忆冲突——你在不同对话中说了不一致的偏好(比如一次说"用 FastAPI",另一次说"用 Flask")。系统需要合并或选择,而不是两条都保留。
隐私边界——记忆可能记录了你不希望跨对话保留的信息(比如临时讨论的敏感数据)。ChatGPT 提供了手动查看和删除记忆条目的入口。
如果你自己实现类似系统,建议加一层记忆审核:
def review_memory_before_save(user_id: str, category: str, value: str) -> bool:
"""简单审核:拒绝保存明显敏感的信息"""
sensitive_keywords = ["密码", "secret", "token", "api_key", "credential"]
combined = f"{category} {value}".lower()
for kw in sensitive_keywords:
if kw in combined:
print(f"[审核拒绝] 记忆条目包含敏感关键词: {kw}")
return False
return True
# 在 save_memory 中调用
if not review_memory_before_save(user_id, category, value):
return # 不保存
实际使用中的取舍
| 维度 | 优势 | 需要注意 |
|---|---|---|
| 上下文窗口 | 记忆压缩后注入,不占用大量 token | 条目过多仍会挤占有效空间 |
| 交互效率 | 减少重复说明,对话更高效 | 首次建立记忆需要几轮对话 |
| 一致性 | 跨对话风格和技术栈一致 | 偏好变化时需要主动纠正或删除旧记忆 |
| 隐私 | 用户可查看/删除 | 记忆可能无意中保留不该跨对话的信息 |
上手建议
- 先让 ChatGPT 建立记忆——在几次对话中自然地提及你的常用工具、偏好风格,观察它是否在后续对话中自动沿用。
- 定期检查记忆条目——在 ChatGPT 设置中查看已保存的记忆,删除过时或不需要的条目。
- 如果你是 API 开发者——参考上面的代码模式,在自己的应用中实现偏好层。关键决策点是:用 LLM 自动提取偏好,还是用结构化表单让用户显式设置。前者更智能但不可控,后者更可靠但体验重。
- 对敏感场景保持无状态——处理医疗、金融、法律等高风险内容时,建议关闭记忆或每次对话后清除,避免跨会话信息泄漏。
记忆系统让 ChatGPT 从"一次性工具"向"长期协作伙伴"迈了一步。对开发者来说,理解它的压缩-注入-淘汰机制,比单纯体验"它记住我了"更有价值——因为同样的模式,可以用在你自己构建的每一个 AI 应用里。