ByteByteGo Newsletter

Do LLMs Have the Memory of a Goldfish?

8.5内容质量
Do LLMs Have the Memory of a Goldfish?

TL;DR · AI 摘要

LLMs缺乏持久记忆,依赖应用层维护上下文信息以处理复杂任务。

核心要点

  • LLMs通过应用层而非模型自身维护对话上下文
  • 对话增长会导致成本和延迟显著增加
  • 有效上下文管理是提升LLM实用性的关键

结构提纲

按章节快速跳转。

  1. 揭示LLMs在对话中看似有记忆实则依赖应用层支撑的现象

  2. ·LLM记忆的定义

    区分训练记忆、上下文记忆和应用层记忆三类不同机制

  3. 模型通过参数编码的通用知识不属于个人记忆

  4. 对话历史需通过应用层主动注入模型上下文窗口

  5. 外部系统负责存储、摘要和检索历史信息

  6. 对话扩展导致的上下文窗口限制需要分层处理策略

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • LLM记忆机制
    • 训练记忆
      • 参数编码的通用知识
    • 上下文记忆
      • 应用层注入历史信息
      • 上下文窗口限制
    • 应用层记忆
      • 存储系统
      • 摘要策略
      • 检索机制

金句 / Highlights

值得收藏与分享的关键句。

#LLM#记忆机制#应用层#上下文管理
打开原文

大语言模型是否像金鱼一样记忆力短暂?

ByteByteGo

2026年9月15日

[网络研讨会] 如何停止对代理的过度监管(赞助)

代理可以生成代码。但要使其符合系统需求、团队规范和过往决策,才是真正的难点。你最终会花费大量时间与资源在修正循环中。

更多的MCPs、规则和更大的上下文窗口虽然让代理能够访问信息,但并未带来理解能力。那些走在前列的团队会构建一个上下文层,为代理提供当前任务所需的精准信息。

9月23日,加入我们免费的网络研讨会,了解以下内容:

  • 团队在AI成熟度曲线上遇到的瓶颈及常见解决方案为何失效
  • 上下文层如何提升质量、效率与成本控制
  • 实时演示:有无上下文层时完成相同编程任务的对比

如果你想最大化利用AI代理的价值,这场活动绝对值得你参与。

立即注册

大语言模型可以分析100页文档,跟踪复杂的编程讨论,并引用数条信息前的内容。然而,一旦开启新对话且没有历史记录时,它会立即遗忘所有内容。这似乎表明大语言模型的记忆力与金鱼无异。

这一观察结果确实成立。大语言模型通常没有对过往交互的个人或持久记忆。那么,它为何能引用我们之前说过的话?

实际上,大语言模型不像人类那样记忆对话。但每次向模型发送新消息时,它都会接收到当前对话的信息。所有这些处理都由围绕模型构建的应用程序完成,而非模型本身。例如,聊天应用可能会存储消息、维护早期讨论的摘要、检索相关记忆并维护用户档案。它可以在需要时将部分信息提供给模型。从用户角度看,模型似乎具备记忆能力。但技术上讲,外围应用承担了大部分记忆工作。

模型与外围应用之间的这种差异是理解大语言模型记忆的关键。

这种设计带来重要影响。随着对话增长,应用必须处理更多文本,从而增加成本和延迟。最终,对话内容可能超出模型的上下文窗口容量。此时,必须删除、总结或存储旧信息。

在本文中,我们将探讨大语言模型如何处理记忆,使其在需要对话和上下文保持的复杂任务中对终端用户有价值。

对大语言模型而言,“记忆”意味着什么?

在大语言模型的语境中,“记忆”一词用于描述多个不同概念,不应混淆。让我们逐一详细分析。

训练记忆

在训练过程中,大语言模型从海量数据中学习模式。这些模式被编码在称为参数或权重的数十亿个数值中。

这就是模型能够在未收到当前提示信息的情况下解释JavaScript、识别常见历史事件或撰写电子邮件的原因。

但这并非个人记忆。如果用户告诉模型“我偏好的编程语言是TypeScript”,常规的API响应不会重写模型的权重。基础模型不会从对话中永久学习这一事实。

#### 工作记忆

模型的临时工作内存是其上下文窗口。该窗口包含模型在生成当前响应时可以考虑的所有内容。

它可能包括:

  • 系统和开发者的指令
  • 当前用户消息
  • 对话中的历史消息
  • 检索到的文档
  • 工具描述和工具执行结果
  • 保存的用户偏好
  • 更早对话的摘要
  • 模型输出所需的空间

上下文窗口更类似于桌面而非人类记忆。模型可以处理放置在桌面上的任何文档。一旦桌面被清空,除非应用程序再次将文档放置到上下文中,否则模型无法恢复这些文档。

持久化应用内存

持久化内存通常存储在模型外部的数据库、文件、向量存储或配置文件服务中。当模型需要这些信息时,应用程序会检索并插入到当前上下文中。

因此,模型本身并不具备持久化内存。它通过其他系统接收持久化信息。

构建和扩展成功的AI代理策略(赞助内容)

将代理部署到生产环境只是容易的部分。保持其可靠性、可治理性并随时间改进,才是大多数企业AI项目停滞的地方。

顶尖团队是如何做到的?他们采用智能体运营模型(Agentic Operating Model),这是一个分步骤的框架,用于协调人员、流程和技术,使企业代理在扩展时持续改进。

在LangChain最新指南中,你将学习:

  • 为什么AI代理不会像传统软件那样崩溃
  • 覆盖整个代理生命周期的工程架构
  • 从“构建和部署”转向“运营和持续改进”

了解更多

基础API调用期间会发生什么?

考虑最简单的API请求:

code
{
  "messages": [
    {
      "role": "user",
      "content": "My name is Adam."
    }
  ]
}

模型可能会回答:"很高兴认识你,Adam。"

假设下一个请求只包含以下内容:

code
{
  "messages": [
    {
      "role": "user",
      "content": "What is my name?"
    }
  ]
}

模型无法可靠回答,因为第二个请求未包含姓名。之前的请求已经完成,且模型内部不存在自动更新的私人日记。

为了让对话正常进行,应用程序必须重新发送之前的对话记录:

code
{
  "messages": [
    {
      "role": "user",
      "content": "My name is Adam."
    },
    {
      "role": "assistant",
      "content": "Nice to meet you, Adam."
    },
    {
      "role": "user",
      "content": "What is my name?"
    }
  ]
}

现在模型可以回答"Adam",因为姓名在当前输入中可见。

大多数模型提供商都提供无状态的Messages API,进行多轮对话时需要显式传入对话历史记录。

每次API调用真的都是从零开始吗?

新的模型调用通常不会完全缺乏知识。模型仍然具备以下内容:

  • 训练得到的权重
  • 通用语言能力
  • 训练过程中获得的知识
  • 平台提供的安全与行为指令
  • 当前上下文中的所有内容

它所缺乏的是对特定用户或对话的自动更新记忆。

更准确的说法是,每个响应都是基于模型的现有权重以及为该响应提供的上下文生成的。除非系统主动传递,否则对话历史中的信息无法被访问。

一些 API 提供由服务器管理的对话状态。在这种情况下,我们无需手动重新发送每条消息。只需提供一个对话标识符,服务器就能根据该标识符定位之前的对话内容,从而重建必要的上下文。这使 API 更加易用,但这并不意味着模型已经形成了个人记忆。

AI 聊天机器人如何制造记忆的假象

假设一段对话包含五条用户消息和五条助手回复。

当用户发送下一条消息时,应用程序可能会构建一个包含以下内容的输入:

code
系统指令

用户消息 1
助手回复 1

用户消息 2
助手回复 2

用户消息 3
助手回复 3

用户消息 4
助手回复 4

用户消息 5
助手回复 5

新用户消息

模型会将所有内容作为单一的大输入进行处理。例如,在之前的对话中,用户可能提到过数据库问题,选择了 PostgreSQL,并要求 TypeScript 示例。因此,模型可以基于这些信息更自然地延续回答。

对用户来说,这可能感觉像是模型记住了之前的对话内容。但从模型的角度来看,这些信息只是当前正在处理的文本中的一部分。我们不能简单地称其为“虚假记忆”,因为在应用层面上确实存在真实的连续性。更准确的说法是“重构记忆”或“基于上下文的记忆”。

上下文窗口是工作内存的预算

大语言模型的上下文窗口以标记(token)为单位进行衡量。标记是文本的最小单位。一个简单的单词可能是一个标记,而较长或较复杂的单词可能会被拆分为多个标记。

上下文窗口通常包含的不只是可见的对话内容,还可能包含隐藏指令、工具定义、搜索结果、文档以及回答空间。假设有一个假设的模型,其上下文窗口容量为 100,000 个标记。一个应用程序可能需要将以下内容放入这个空间中:

  • 系统指令:3,000 标记
  • 工具定义:8,000 标记
  • 对话历史:55,000 标记
  • 检索到的文档:20,000 标记
  • 当前问题:1,000 标记
  • 剩余回答预算:13,000 标记

一旦可用空间耗尽,应用程序无法无限添加信息。它必须删除、压缩或替换部分内容。

即使拥有大容量的上下文窗口,也无法保证完美记忆。随着信息量的增加,模型可能更难区分重要事实与无关、重复或矛盾的内容。这种性能下降现象也被称为“上下文腐化”(context rot)。即使拥有非常大的上下文窗口,我们也需要筛选有用的上下文。因此,上下文窗口既是容量限制,也是注意力管理问题。

为什么长对话会变得昂贵

大语言模型 API 通常根据处理的输入和输出标记数量收费。假设每次完整的对话回合大约增加 1000 个标记:

  • 请求 1 处理约 1,000 个标记
  • 请求 2 处理约 2,000 个标记
  • 请求 3 处理约 3,000 个标记
  • 每个请求处理约 10,000 个标记。

在这些请求中,应用程序总共处理了约 55,000 个输入标记。

可见对话内容仅包含约 10,000 个标记,但早期内容已被重复处理。过长的系统提示、庞大的工具定义和检索到的文档会进一步增加这一成本。

更长的上下文也会增加延迟。这是因为模型开始回答前需要处理更多信息。

提示缓存等技术可以帮助降低成本,但它们不会创造记忆。

服务提供商可以缓存重复的前缀(如系统提示和之前的对话历史)。当下一个请求以相同内容开头时,提供商可能会复用之前计算的信息。这可以降低成本和延迟。然而,缓存的标记会占用部分上下文窗口。缓存只是改变了重复上下文的处理效率,不会为模型提供无限记忆。

因此,提示缓存是一种优化手段,而非记忆架构。

当上下文窗口填满时会发生什么?

当上下文窗口填满时,大语言模型没有统一的行为模式。根据 API 和应用的不同,可能会发生以下几种情况:

  • API 可能会因请求过大而拒绝处理。
  • 应用程序可能会删除最早的对话消息。
  • 聊天产品可能会使用滑动窗口管理历史记录。
  • 系统可能会用简洁摘要替换旧内容。
  • 一些 API 还提供服务器端压缩机制。

压缩是通过更紧凑的表示方式保留关键状态,使长期交互以更低的上下文使用量继续进行。这意味着非常长的对话可能不会在活跃上下文中包含每一条原始语句。模型可能接收到类似以下内容:

对话摘要:

用户正在使用 TypeScript 构建发票服务。

选择了 PostgreSQL 作为数据库。

API 使用了 Express 和 Prisma。

当前问题涉及重复创建发票。

之前尝试的应用层检查在并发情况下失败。

摘要保留了核心状态,同时丢弃了问候语、重复解释、被放弃的想法和低价值细节。权衡是摘要会丢失信息。在摘要时看似不重要的小细节,之后可能会变得重要。

扩展记忆的主要技术

实际应用通常会结合多种技术来扩展记忆,而非依赖单一方法。让我们详细探讨几种技术。

滑动窗口记忆

滑动窗口仅保留对话的最新部分。当新消息到达时,最旧的消息会被移除。

例如,应用程序可能始终保留:

  • 系统指令
  • 最近的 20 轮对话

这种方法简单、快速且可预测。当近期消息比旧消息重要得多时,效果良好。

其弱点是一旦旧事实离开上下文窗口,就会彻底消失。如果用户在 30 轮对话前提到过一个重要需求,模型可能再也无法处理该需求。

对话摘要

摘要技术会定期将较旧消息压缩为更短的描述。摘要保留在上下文中,而原始消息被删除。

常见结构为:

  • 系统指令
  • 对话摘要
  • 最近的未摘要消息
  • 当前用户消息

This helps preserve the general direction of the conversation much more efficiently than retaining every original message.

However, a summary is more of an interpretation. It omits nuance, simplifies uncertainty, or accidentally turns an assumption into a fact. If we repeatedly summarize previous summaries, it can gradually distort the meaning of the conversation, much like repeatedly copying a photocopy. Therefore, it’s a much better approach to store important facts separately rather than trusting them to be retained in a simple narrative summary.

Structured Entity Extraction

Instead of remembering the conversation as prose, the application can extract specific facts into structured fields. For example:

code
{
  “preferred_language”: “TypeScript”,
  “database”: “PostgreSQL”,
  “framework”: “Express”,
  “current_project”: “invoice service”,
  “confirmed_decisions”: [
    “Use optimistic concurrency control”,
    “Do not introduce Redis”
  ]
}

This is more reliable than searching through a long summary when the application needs exact project state.

Structured memory is really useful for the following types of information:

  • User preferences
  • Names and identifiers
  • Confirmed technical decisions
  • Current tasks
  • Workflow status
  • Dates and deadlines
  • Product configuration

However, structured entity is doesn’t work well for subtle, narrative information that cannot be expressed neatly into predefined fields.

Vector-store-backed Memory

In this approach, a vector store supports semantic retrieval. Instead of putting the entire conversation history into every request, the application divides past conversations into small pieces and creates an embedding for each piece.

An embedding is a numerical representation of meaning. This means that texts concerning similar ideas receive similar representations even when they don’t use exactly the same words.

For example, let’s say the user asks: “Why did we reject Redis for the invoice service?” The memory system searches for past passages semantically related to “Redis,” “invoice service”, and “rejected architecture decisions.”

It may retrieve information such as “we decided against Redis because the deployment environment does not provide a managed Redis service, and PostgreSQL advisory locks already cover the required coordination.”

Only the retrieved passage is added to the current context. Here’s how the process works roughly:

  • Store selected pieces of earlier conversations.
  • Convert those pieces into embeddings.
  • Convert the new question into an embedding.
  • Find semantically similar memories.
  • Filter and rank the candidates.
  • Insert the best candidates into the model’s prompt.

This doesn’t enlarge the context window. It selects which memories deserve space inside it.

However, vector retrieval can also sometimes fail. It may retrieve something similar but irrelevant. It can miss a memory because it was phrased strangely. It can also come up with an outdated decision. Metadata such as user ID, project ID, date, and memory type is therefore essential to make sense of this data.

Long-term User Profiles

A long-term profile stores durable facts that may be useful across many conversations. For example, this could include things like:

  • The user generally prefers beginner-friendly technical explanations.
  • Examples should use TypeScript where practical.
  • Explanations should use complete paragraphs rather than fragmented bullets.

用户档案应包含稳定的偏好,而非转瞬即逝的陈述。例如,“我今天在测试Python”可能属于会话信息,而“我使用Python处理所有数据项目”若经多次验证,可能属于持久性偏好。

我们还需要更新用户档案。这是由于偏好可能随时间变化。优秀的系统会为记忆条目附加时间戳、来源信息,有时还会附加置信度评分。

跨会话记忆的工作原理

跨会话记忆意味着信息在一次对话结束后仍能保留,并可能影响后续对话。

典型实现方式如下:

  • 在对话期间或结束后,记忆处理模块会识别潜在的持久性信息。
  • 将这些信息存储在用户级、项目级或组织级的记忆存储中。
  • 开始新的对话。
  • 应用程序筛选与新对话相关联的记忆。
  • 这些记忆被插入到新对话的上下文中。
  • 模型基于提供的记忆生成响应。

关键步骤是第五步。新的模型调用仍需要将记忆信息嵌入到当前上下文中。

结论

在本文中,我们详细探讨了大语言模型的记忆机制。核心要点如下:

  • 模型权重包含训练过程中学习到的通用知识。
  • 上下文窗口包含当前响应可用的信息。
  • 对话存储保留历史消息。
  • 长期记忆存储精选的事实、偏好和过往事件。
  • 记忆管理器决定需要检索并置入工作台的信息。

可以说,大语言模型及其周边应用系统并不具备金鱼般的记忆能力。它们能够同时处理海量信息,但不会自动将个人体验从一次调用传递到下一次调用。

看似记忆的功能,实际上是精心构建的上下文重构、摘要、检索和持久化存储系统。大语言模型应用的记忆质量,至少与周边架构的设计水平同样重要,甚至更为关键。