Skip to content

模型上下文与模型记忆 - AI 面试题全解析 ​

一、核心要点速览 ​

💡 核心考点

  • 上下文(Context): 模型单次推理时能"看到"的全部输入,包括系统提示、历史对话与当前问题,以 Token 计量
  • 上下文窗口(Context Window): 模型能处理的最大 Token 数,超出即被截断或遗忘
  • 模型记忆(Memory): LLM 本身无状态,"记忆"是通过外部手段把历史信息重新塞回上下文而实现的
  • 两类记忆: 短期记忆(对话上下文)与长期记忆(向量库/数据库持久化)
  • 关键矛盾: 上下文越长成本越高、延迟越大,如何高效管理记忆是工程核心

二、什么是模型上下文 ​

1. 基本概念 ​

上下文(Context) 是大语言模型在一次推理中接收到的完整输入序列。模型基于这段输入预测下一个 Token,因此"上下文里有什么"直接决定了"模型能回答什么"。

一次请求的上下文 = 系统提示(System) + 历史对话(History) + 当前输入(User)
                   └──────────────── 全部计入 Token ────────────────┘

2. 上下文的组成 ​

组成部分角色说明
系统提示system设定模型身份、规则与风格,优先级最高
历史对话user / assistant之前的多轮问答,提供连贯性
当前输入user本轮用户的提问
工具/检索结果tool / 注入RAG 检索片段、函数调用返回等
python
messages = [
    {"role": "system",    "content": "你是一位前端面试官"},   # 系统提示
    {"role": "user",      "content": "什么是闭包?"},          # 历史
    {"role": "assistant", "content": "闭包是指……"},           # 历史
    {"role": "user",      "content": "那它会导致内存泄漏吗?"}, # 当前输入
]
# 以上全部内容一起作为"上下文"送入模型

3. 上下文窗口(Context Window) ​

上下文窗口是模型单次能处理的最大 Token 数(输入 + 输出共享或分别计算,视模型而定)。超过窗口的内容会被截断,模型"看不到"也就无法利用。

模型上下文窗口约等于
GPT-3.5 Turbo16K tokens~1.2 万字
GPT-4 Turbo128K tokens~10 万字
Claude 3/4200K tokens~15 万字
Gemini 1.5 Pro1M~2M tokens一本长篇小说
Llama 38K / 128K tokens~0.6 万 / 10 万字

⚠️ 常见误区

上下文窗口大 ≠ 效果一定好。实践中存在 "Lost in the Middle"(中间迷失) 现象:模型对上下文开头和结尾的信息敏感,而容易忽略中间的内容。关键信息应放在首尾。


三、什么是模型记忆 ​

1. LLM 本质是无状态的 ​

一个容易被忽视的事实:大模型本身没有记忆。每次 API 调用都是独立的,模型不会"记得"上一次说过什么。所谓的"记忆",全靠把历史信息重新放进上下文来模拟。

❌ 误解: 模型像人一样记住了之前的对话
✅ 真相: 每次请求都把历史对话重新发给模型,模型"重新读一遍"

2. 短期记忆 vs 长期记忆 ​

维度短期记忆长期记忆
载体上下文窗口内的对话历史外部存储(向量库、数据库、文件)
生命周期当前会话,窗口满即遗忘跨会话持久保存
容量受窗口 Token 限制理论上无限
读取方式直接拼接进 messages按需检索后注入上下文
典型实现多轮对话历史RAG、Memory 模块

3. 记忆的工作流程 ​

用户提问
   │
   ▼
检索相关长期记忆 (向量相似度) ──┐
   │                          │
   ▼                          ▼
拼接: 系统提示 + 长期记忆 + 短期对话历史 + 当前问题
   │
   ▼
送入模型 → 生成回答
   │
   ▼
将本轮问答写回记忆 (短期追加 / 长期持久化)

四、上下文与记忆的管理策略 ​

当对话变长、超出窗口限制时,必须对上下文/记忆做管理。常见策略:

1. 滑动窗口(Sliding Window) ​

只保留最近 N 轮对话,丢弃更早的内容。

  • ✅ 实现简单,成本可控
  • ❌ 会丢失早期关键信息

2. 摘要压缩(Summarization) ​

把较早的对话用模型压缩成摘要,再放回上下文。

原始: [10 轮详细对话,共 8000 tokens]
      ↓ 摘要
压缩: "用户是前端开发者,正在准备面试,已讨论闭包、原型链…" (300 tokens)
  • ✅ 大幅节省 Token,保留核心语义
  • ❌ 摘要会损失细节,且额外消耗一次模型调用

3. 向量检索(RAG / 长期记忆) ​

把历史信息向量化存入向量数据库,提问时按语义相似度检索最相关的片段注入上下文。

python
# 伪代码:基于向量检索的长期记忆
query_vec = embed(user_question)
relevant = vector_db.search(query_vec, top_k=3)   # 检索最相关的 3 条记忆
context = system_prompt + "\n".join(relevant) + user_question
answer = llm(context)
  • ✅ 突破窗口限制,支持海量知识
  • ❌ 依赖检索质量,架构更复杂

4. 策略对比 ​

策略成本信息完整度适用场景
滑动窗口低低(丢早期)闲聊、短期任务
摘要压缩中中长对话、需保留脉络
向量检索中高高(按需)知识库问答、Agent
混合策略高最高生产级智能助手

💡 工程实践

生产环境常采用混合策略:近期对话用滑动窗口保留原文 + 远期对话做摘要 + 关键事实存入向量库长期记忆,兼顾连贯性、成本与可扩展性。


五、常见面试题 ​

Q1: 大模型到底有没有记忆? ​

标准回答: 严格来说,LLM 本身是无状态的,单次推理之间不保留任何信息。我们感知到的"记忆"是工程手段模拟出来的——每次请求都把历史对话(短期记忆)或从外部存储检索到的信息(长期记忆)重新拼进上下文,模型相当于"每次重新读一遍"。所以记忆的本质是上下文管理问题。

记忆口诀: "模型本无忆,全靠上下文;短期塞历史,长期靠检索"


Q2: 上下文窗口越大越好吗? ​

标准回答: 不完全是。更大的窗口能容纳更多信息,但有三个代价与局限:

  1. 成本与延迟: Token 越多,费用越高、推理越慢;
  2. Lost in the Middle: 模型对中间部分信息利用率低,塞太多反而稀释关键信息;
  3. 噪声干扰: 无关内容过多会降低回答精度。

因此实践中更强调往上下文里放对的东西(精准检索、压缩),而非一味塞满。


Q3: 短期记忆和长期记忆有什么区别? ​

标准回答:

  • 短期记忆指当前会话窗口内的对话历史,直接拼接进 messages,窗口满就会被遗忘,生命周期是单次会话;
  • 长期记忆指持久化到向量库/数据库的信息,可跨会话保存,通过检索按需注入上下文,容量理论上无限。

二者常配合使用:短期保证对话连贯,长期提供跨会话的个性化与知识积累。


Q4: 对话变长超出窗口怎么办? ​

标准回答: 常见三种方案:滑动窗口(只留最近 N 轮,简单但丢早期信息)、摘要压缩(把旧对话压成摘要,省 Token 但损细节)、向量检索(历史向量化后按需检索,突破窗口但依赖检索质量)。生产环境通常混合使用:近期保原文、远期做摘要、关键事实入向量库。


六、实战案例 ​

案例 1: 带滑动窗口的多轮对话 ​

python
class ChatSession:
    """保留最近 N 轮对话的简单短期记忆"""
    def __init__(self, system_prompt: str, max_turns: int = 5):
        self.system = {"role": "system", "content": system_prompt}
        self.history = []
        self.max_turns = max_turns

    def ask(self, user_input: str) -> str:
        self.history.append({"role": "user", "content": user_input})
        # 滑动窗口:只保留最近 max_turns 轮(每轮 2 条消息)
        window = self.history[-self.max_turns * 2:]
        messages = [self.system] + window

        answer = llm(messages)  # 调用模型
        self.history.append({"role": "assistant", "content": answer})
        return answer

案例 2: 向量检索实现长期记忆 ​

python
def chat_with_memory(user_question: str) -> str:
    """结合长期记忆(向量检索)的问答"""
    # 1. 检索相关长期记忆
    query_vec = embed(user_question)
    memories = vector_db.search(query_vec, top_k=3)

    # 2. 组装上下文
    memory_text = "\n".join(f"- {m.text}" for m in memories)
    messages = [
        {"role": "system", "content": f"已知用户相关信息:\n{memory_text}"},
        {"role": "user", "content": user_question},
    ]

    # 3. 生成回答
    answer = llm(messages)

    # 4. 将本轮重要信息写回长期记忆
    vector_db.add(embed(user_question), text=user_question)
    return answer

七、总结与展望 ​

核心要点回顾 ​

维度关键点
上下文模型单次推理可见的全部输入,以 Token 计量
上下文窗口可处理的最大 Token 数,超出即遗忘
模型记忆LLM 无状态,记忆靠把历史重新塞回上下文
短期记忆对话历史,窗口内有效
长期记忆外部存储 + 检索,跨会话持久
管理策略滑动窗口 / 摘要压缩 / 向量检索 / 混合

未来趋势 ​

  1. 超长上下文: 百万级 Token 窗口逐渐普及(Gemini、Claude)
  2. 原生记忆机制: 模型内置记忆模块,减少对外部拼接的依赖
  3. 记忆检索优化: 更智能的记忆取舍与遗忘机制(如 MemGPT)
  4. 成本下降: 长上下文的推理成本持续优化(KV Cache、注意力优化)

八、扩展阅读 ​

最近更新