
# 记忆与上下文：长对话不丢信息的实战方案

记忆和上下文管理是 Agent 面试中“看起来简单但很容易答浅”的维度。面试官不想听你说“用向量数据库”——他想知道的是**存什么、怎么查、怎么融合**，以及面对模糊输入时 Agent 怎么利用记忆给出好体验。

---

## 上下文管理基础

### Q：上下文窗口不够用，对话太长了怎么办？

> 来源：Agent 岗面试高频题 / 字节 Agent 实习二面 【小红书 Agent 岗一面追问：两层压缩、LLM 保留判定与大结果落盘】

**新手答**：“截断早期消息，只保留最近几轮。”

**高手答**：

截断是最粗暴的做法，会丢失关键上下文。我们的处理分四层：

1. **早期对话压缩成摘要**：不是直接丢掉，而是每隔一段对话，让模型把已完成的部分压缩成结构化摘要（“用户需求是什么、已确认的参数、当前进展”），只保留摘要，释放原始 token
2. **大任务拆子任务**：一个 30 步的复杂任务，不要在一个上下文里硬撑。拆成 5 个子任务，每个子任务用独立对话完成，中间结果通过数据库传递，而不是全靠上下文承载
3. **中间结果落库**：工具调用的返回值、中间计算结果，不要全留在对话里。提取关键字段存数据库，需要时再查回来，上下文里只保留一句“已完成 XX，结果存储在 task_123”
4. **按需回溯而非全量携带**：不是每轮都把所有历史带上。建一个索引，标记每段对话的主题和关键实体，需要时按主题精准召回，而不是全量塞回去

核心思路是：**先用工程手段省 token，实在不够再考虑模型层面的压缩。**

**差距在哪**：新手的”截断”是单一策略，且会造成信息丢失。高手的四层方案各有分工——摘要保留语义、拆任务降低单次复杂度、落库减少冗余、按需召回精准补充。面试官考的是”你有没有在生产环境里处理过长对话的工程经验”，这不是模型能力问题，是系统设计问题。

**追问：智能客服场景下，Agent 的上下文压缩机制有哪些？各自优劣？**

> 来源：币安 AI大模型实习一面

智能客服比通用 Agent 更复杂——用户可能聊了 50 轮还没解决问题，且中间夹杂大量无效信息（寒暄、重复、情绪表达）。压缩机制需要在**保留关键信息**和**释放 token 空间**之间取舍：

| 机制 | 原理 | 优点 | 缺点 | 适合场景 |
|------|------|------|------|---------|
| 滑动窗口截断 | 只保留最近 N 轮 | 简单、零额外成本 | 丢失早期关键信息（如订单号、投诉原因） | 简单咨询，无需长记忆 |
| 摘要压缩 | LLM 定期把历史压缩成摘要 | 保留语义、释放 70%+ token | 摘要可能丢细节、额外 LLM 调用成本 | 多轮复杂咨询 |
| 关键信息外置 | 提取实体/约束存独立 state，每轮注入 | 关键信息不丢、最可靠 | 需要 NER 提取逻辑、实体识别有误差 | 涉及订单、金额等硬约束 |
| 分话题记忆 | 按话题分段，只加载当前话题完整记忆 | 话题切换时体验好 | 话题检测准确率是瓶颈 | 用户问题跨多个领域 |
| 子任务拆分 | 复杂任务拆成独立子对话，结果通过数据库传递 | 每个子任务上下文干净 | 用户感知到”被转接” | 需要跨系统协作的复杂售后 |

**生产环境中的组合策略**：不是选一种，而是分层组合——关键信息外置（保底）+ 摘要压缩（主力）+ 滑动窗口（兜底）。每轮对话的上下文结构：

```text
[System Prompt] + [外置关键信息：用户ID/订单号/问题类型] + [近期摘要] + [最近3轮原始对话]
```

**追问：上下文压缩怎么避免压缩后丢失关键约束（比如否定条件、硬性限制）？**

> 来源：阿里国际AI应用开发二面

压缩最怕丢的不是“聊了什么”，而是**否定约束和硬性条件**——“绝不能推荐含坚果的食物”“预算不超过 500”这类信息一旦被摘要吞掉，后续生成会直接违反用户意图。

**解决方案分三层**：

| 层级 | 策略 | 做法 |
|------|------|------|
| 提取层 | 约束显式外置 | 对话中出现否定词/条件句时，用规则或 NER 提取到独立的 `constraints` 字段，不参与压缩 |
| 压缩层 | 带约束的摘要 Prompt | 摘要指令中显式要求“保留所有否定条件和数字约束原文” |
| 验证层 | 压缩后回检 | 压缩完成后，用另一次 LLM 调用对比原文和摘要，检查约束是否丢失 |

**工程实践**：

```text
# 每轮对话注入的结构
[硬性约束（从不压缩）]
  - 不含坚果
  - 预算 ≤ 500
[压缩摘要（定期更新）]
  用户正在为朋友选生日礼物，偏好实用型...
[最近原始对话]
  ...
```

核心思路：**约束和摘要分离存储**——摘要可以丢细节，但约束永远不压缩、不合并、不降权。这和数据库事务中“关键字段不可 null”是同一个设计原则。

---

### Q：长上下文里，怎么让 Agent 不忘记关键信息？

> 来源：腾讯 Agent 岗终面

**新手答**：“用向量数据库存起来。”

**高手答**：

单一向量检索在长对话中很容易丢关键信息。我们的方案是**三段式记忆**：

1. **滚动窗口记忆**：最近 3-5 轮对话原样保留，保证强相关
2. **关键实体记忆**：用 NER 实时抽取用户提到的时间、地点、人物、任务，存入一个类似知识图谱的结构，随时可查
3. **周期性摘要记忆**：每 10 轮对话，让模型生成一段结构化摘要（“用户想做什么，目前进展到哪，遇到了什么障碍”）

查询时，三段信息同时召回，按权重融合。这样既能记住”用户对花生过敏”这种细节，又不会被 50 轮前的闲聊干扰。

**模型层面的遗忘缓解机制**：

除了工程手段，还有多种模型/架构层面的技术可以缓解长上下文信息遗忘：

| 机制 | 原理 | 效果 |
|------|------|------|
| 滑动窗口注意力 | 只关注最近 N 个 token，超出窗口的不计算 attention | 降低计算量，但会丢失远距离依赖 |
| 稀疏注意力（Longformer） | 局部窗口 + 全局 token 混合 attention | 平衡效率和长距离关注 |
| 关键信息锚定 | 把关键约束标记为”全局 token”，始终参与 attention | 防止关键信息被稀释 |
| 检索增强生成 | 长文本不全放上下文，关键段落按需检索注入 | 上下文精简，信息不丢 |
| 结构化状态外置 | 关键参数提取到独立 state，每轮强制注入 | 最可靠，不依赖模型记忆力 |

对于 Agent 场景，**结构化状态外置是最可靠的方案**——不依赖模型的 attention 分布，用系统机制保证关键信息每轮都在。模型层面的优化是锦上添花，工程层面的外置才是兜底。

**差距在哪**：新手的”向量数据库”是一个工具，不是方案。它解决了存储问题，但没解决“存什么、怎么查、怎么融合”的问题。高手的三段式记忆在不同时间粒度上各有分工——短期精确、中期结构化、长期摘要——这是 Memory 系统设计的核心思路。面试官考的是“你理不理解 Agent Memory 的多层次需求”。

---

### Q：用户说“按老样子帮我订一下”，这种模糊需求怎么处理？

> 来源：腾讯 Agent 岗终面

**新手答**：“问用户‘老样子’具体指什么。”

**高手答**：

分两步处理，**先“猜”再“问”**：

1. **猜**：立刻检索用户的历史订单，找出时间最近、频次最高、或用户标记过“喜欢”的订单，作为候选
2. **问**：把候选的 1-3 个选项（例如“是订上次的 XX 酒店吗？”）清晰地抛给用户确认

绝不能模型自己去“猜”一个就执行。这个流程把模糊需求转化成了一个清晰的选择题，体验好，且不会错。

**差距在哪**：新手的“直接问”看起来安全，但体验差——用户说“老样子”就是不想再描述一遍，你让他重新说等于没理解他的意图。高手的“先猜再确认”是更好的交互模式：展示你理解了他的意思（通过历史数据），同时用确认保证不出错。面试官考的是“你有没有产品思维”，Agent 不只是技术系统，也是用户交互系统。

---

### Q：多 Agent / 多异步任务下，如何防止上下文污染？

> 来源：字节后端开发 Agent 一面

**新手答**：“每个 Agent 用独立的上下文。”

**高手答**：

上下文污染是多 Agent 系统最隐蔽的 bug——一个 Agent 的中间状态泄漏到另一个 Agent 的上下文里，导致输出偏离。

**污染来源**：
- **共享上下文变量**：多个 Agent 读写同一个 conversation history，A 的中间推理过程被 B 当成了事实
- **异步竞态**：并行 Agent 同时更新共享状态，后写入的覆盖先写入的
- **prompt 拼接错误**：动态拼接 Prompt 时，把不属于当前 Agent 的信息混了进去

**防治方案**：

1. **上下文隔离**：每个 Agent 维护独立的消息历史，不共享 conversation history。需要传递信息时，通过**显式的结构化消息**（而不是共享上下文）
2. **作用域控制**：定义每个 Agent 能看到什么——只传入它的 System Prompt、当前任务描述、和上游传来的结构化结果，不传无关历史
3. **状态快照**：并行任务启动前，对共享状态做快照。每个 Agent 基于快照执行，结果通过合并策略写回，不直接覆盖
4. **消息签名**：每条消息标记来源 Agent ID，下游 Agent 可以按来源过滤，只接收自己应该看到的信息

```text
核心原则：Agent 之间传递"结论"，不传递"过程"
```

对比后端思维：这和微服务之间不共享数据库、用 API 通信是同一个原则——**进程隔离，接口通信**。

**差距在哪**：新手只说了“独立上下文”——知道方向但没有方案。高手先分析了三种污染来源，再给出四种防治方案，且类比了后端微服务的隔离原则。面试官用“并发安全”视角考你对多 Agent 系统的理解——上下文污染本质就是“共享可变状态”问题。

---

## 记忆架构与优先级

### Q：讲一下 Agent 中的”长短期记忆”

> 来源：字节后端开发 Agent 一面 【蚂蚁AI应用开发二面同题：Agent 长期记忆设计思路】【淘天Agent开发同题：短期对话记忆和长期记忆分别怎么提取和存储】

**新手答**：“短期记忆是当前对话，长期记忆存数据库。”

**高手答**：

Agent 的记忆系统可以类比人类认知模型，分三层：

| 记忆类型 | 对应人类认知 | Agent 中的实现 | 生命周期 |
|---------|-----------|--------------|---------|
| 感知记忆 | 瞬时记忆 | 当前输入 + 最近 1-2 轮对话 | 当前请求 |
| 短期记忆 | 工作记忆 | 上下文窗口内的全部对话历史 | 当前会话 |
| 长期记忆 | 长时记忆 | 外部存储（向量库、数据库、文件） | 跨会话持久 |

**短期记忆的工程挑战**：

上下文窗口有限。对话轮次多了，早期信息被截断或被淹没。解决方案：
- **滚动窗口**：只保留最近 N 轮原始对话
- **摘要压缩**：定期让模型把已完成的对话压缩成结构化摘要
- **关键信息外置**：实时提取用户提到的关键约束（预算、日期、偏好），存到独立的状态变量里，每轮强制注入

**长期记忆的工程挑战**：

存什么、怎么查、怎么融合：
- **存什么**：不是把所有对话都存，而是提取有价值的信息——用户偏好、历史决策、学到的经验
- **怎么查**：用 embedding 做语义检索，但要控制召回数量——塞太多长期记忆会干扰当前任务
- **怎么融合**：长期记忆和短期上下文可能矛盾（用户偏好变了），需要有时效性权重——最近的记忆优先级更高

进阶：还有一类”工作记忆”——Agent 在执行多步任务时的中间状态（to-do list、已完成步骤、中间结果）。它不属于对话历史，也不属于长期记忆，是任务级别的临时状态。

**记忆更新策略**：

记忆写入后不是一成不变的，需要一套更新机制保证数据质量：

- **增量更新**：新信息覆盖旧信息时不直接替换，而是版本化存储——“用户从北京搬到上海”→ 旧记忆降权但保留，新记忆设为当前有效版本
- **冲突检测**：每次写入前和已有记忆做语义比对，发现矛盾时触发更新流程而非简单追加
- **TTL 分级淘汰**：事实性记忆（手机号、住址）设长 TTL，偏好性记忆（上次选了经济舱）设短 TTL，上下文性记忆（刚才聊了天气）会话结束即清理
- **主动验证**：高频使用的记忆定期通过用户交互确认——“我记得您偏好素食，现在还是吗？”

**差距在哪**：新手只分了两层且没有展开。高手分了三层（感知/短期/长期），每层都说了工程挑战和解法，还补充了“工作记忆”这个进阶概念。面试官要的不是“存数据库”三个字，而是你能不能把记忆按层次拆清楚。

---

### Q：一个 Agent 系统里，什么时候应该追问用户，什么时候应该自己继续推理？

> 来源：腾讯大模型应用开发二面

**新手答**：“不确定就问用户。”

**高手答**：

判断标准主要有两个：**信息缺口是否影响正确执行**，以及**这个缺口能不能通过工具或外部知识补上**。

| 情况 | 策略 |
|------|------|
| 缺的是执行必需参数（如订单号） | 追问用户 |
| 缺的是可由外部系统补齐的信息（如城市从画像获取） | 自己继续推理 |
| 能猜到但猜错代价极高（如支付、删除） | 宁愿追问，不擅自补全 |

追问不是因为模型”不聪明”，而是因为系统要在**体验和风险之间做平衡**。无脑追问体验差，无脑猜测风险高——好的 Agent 需要根据操作的可逆性和代价来决定。

**主动澄清 vs 历史画像推断的决策框架**：

在电商、导购等场景中，Agent 还面临一个更精细的判断：用户说”帮我挑个好用的”——是追问”您需要什么功能？”还是直接结合历史购买记录推荐？

| 条件 | 策略 | 原因 |
|------|------|------|
| 有高置信度历史画像 + 低风险操作 | 强行推断，直接推荐 | 体验好，用户觉得”懂我” |
| 有历史画像但置信度低（很久没买/品类陌生） | 展示推断 + 请求确认 | “根据您之前的偏好，推荐XX，是否合适？” |
| 无历史画像 + 高风险操作（支付/删除） | 必须追问 | 猜错代价大于追问成本 |
| 无历史画像 + 低风险操作 | 给出默认推荐 + 提供修改入口 | 先动起来，不阻塞流程 |

核心原则：**追问的目的是减少不确定性，不是收集所有信息**。如果历史画像能把不确定性降到可接受水平，就不要追问。

**差距在哪**：新手的”不确定就问”看起来安全，但会导致过度追问、体验打折。高手用两个判断标准（是否影响执行 + 能否自动补齐）加一个风险维度（猜错代价）构建了完整的决策框架。面试官考的是你能不能在”用户体验”和”执行安全”之间做工程化的平衡。

**追问：用户表达极度模糊（如”帮我看看””随便推荐”），Agent 在工程上怎么处理？**

上面的决策框架处理的是”有部分信息但不完整”的情况。但实际场景中还有**信息量接近于零**的极端情况——用户说”帮我看看”，连意图分类都做不了。

**工程处理的三层兜底**：

| 层级 | 方法 | 何时触发 |
|------|------|---------|
| 第一层：隐式信号补全 | 从用户当前页面、最近行为、会话上下文推断意图 | 有可用的行为信号时 |
| 第二层：选择式澄清 | 给出 2~3 个最可能的意图选项，让用户选 | 行为信号不足以做高置信推断时 |
| 第三层：默认行动 + 修正入口 | 执行最常见的默认意图，提供”不是我想要的”修正按钮 | 用户对追问不耐烦或场景要求快速响应时 |

**第二层的实现细节**——选择式澄清比开放式追问效果好得多：

```text
❌ 开放式：”您想要什么？”（用户不知道从何说起，可能直接走了）
✅ 选择式：”您是想——A. 看看最近的热门推荐 B. 找上次浏览过的商品 C. 有具体想买的东西？”
```

选项生成的方法：
1. **频率统计**：从历史数据中挖掘该类模糊 query 最常对应的 Top-3 意图
2. **用户画像**：结合用户历史行为，个性化排序选项
3. **场景上下文**：从当前页面/入口推断（从首页进来 vs 从售后页进来，默认选项完全不同）

核心原则：**不要让用户做填空题，让用户做选择题**。每次澄清最多问一个问题，且必须带选项。

---

### Q：对于上下文工程有什么经验？有没有做过 to-do list？为什么让模型更聚焦？

> 来源：抖音基础架构 Agent 一面 / 字节 Agent 实习二面

**新手答**：“就是把相关信息塞到上下文里。”

**高手答**：

上下文工程的核心不是“塞更多信息”，是**让模型在每一步都能看到恰好需要的信息，不多不少**。

**To-do list 机制**是上下文工程的一个重要实践：

1. **任务开始时**，让模型把复杂任务拆解成一个结构化的 to-do list，每个 item 有状态标记（pending / in_progress / completed）
2. **每一步执行后**，更新对应 item 的状态，并把当前 to-do list 注入到下一步的上下文中
3. **模型在每一步**都能看到“全局做到哪了、当前该做什么、还剩什么没做”

**为什么这样能让模型更聚焦**：

大模型的一个核心问题是**上下文越长越容易迷失**——长对话中，模型会忘记最初的任务目标，或者在中间步骤偏离方向。To-do list 起到**锚点（Anchor）**的作用：
- 它把隐式的任务进度变成了**显式的结构化状态**，模型不需要从历史消息中推断“我做到哪了”
- 每一步都有明确的当前任务，减少了模型的决策空间
- 已完成的 item 可以压缩或折叠，只保留结论，释放上下文空间给当前任务

**实现方式**：
- 在 System Prompt 中定义 to-do list 的格式规范
- 用工具调用（如 `task_update`）让模型显式更新任务状态
- 每轮对话前，把最新的 to-do list 作为上下文的固定部分注入，位置放在历史消息之前、当前任务之前

**差距在哪**：新手把上下文工程等同于“塞信息”。高手展示了 to-do list 这个具体的上下文管理手段，且解释了它为什么有效——把隐式进度变成显式状态。面试官考的是你有没有超越“Prompt Engineering”的认知——上下文工程是系统级的信息管理。

---

### Q：Agent 需要同时读知识库、调外部 API、结合用户历史偏好，怎么处理这三类上下文的优先级？

> 来源：腾讯大模型应用开发二面

**新手答**：“都放进上下文里让模型自己判断。”

**高手答**：

三类信息不能混着塞，要**先定义优先级**：

```text
优先级从高到低：
1. 系统规则（最高）
2. 当前轮用户明确输入
3. 外部工具返回 + 知识库证据
4. 用户历史偏好（最低）
```

因为偏好只影响表达方式或默认选择，不能覆盖当前事实。比如用户历史里一直偏好 Python，但这轮明确说“用 Java 给我写”，那当前轮约定一定优先。又比如知识库里有旧规则，外部 API 返回的是实时状态，那实时状态优先于静态知识。

真正做 Prompt 组装时，**最好按槽位拼接**，把“当前目标”“实时证据”“历史画像”分开，而不是混成一段自然语言。这样模型能清楚地看到每类信息的边界和权重。

**差距在哪**：新手把所有信息混在一起丢给模型——模型没有优先级意识，容易被低优先级信息干扰。高手定义了四级优先级，且在 Prompt 组装时按槽位分离。面试官考的是你有没有对多源上下文做过系统性的优先级设计。

---

### Q：你怎么理解 Agent 里的“状态”而不是“上下文”？

> 来源：腾讯大模型应用开发二面

**新手答**：“状态就是上下文的一部分。”

**高手答**：

上下文更像模型看到的输入材料，状态则是**系统对任务推进过程的结构化刻画**。Agent 做得深一点以后，不能只靠大段对话历史维持执行，因为模型并不天然擅长长期状态一致性。

状态通常包括：

```text
当前阶段、已完成任务、失败次数、已调用工具、关键中间结果、待确认信息
```

这样做的好处是，模型不用每次从自然语言自己猜任务进行到哪一步，系统可以**明确告诉它现在在什么节点**。很多所谓 Agent 不稳定，本质上不是上下文不够，而是**没有显式状态**。

**差距在哪**：新手把状态和上下文混为一谈。高手区分了两者——上下文是“模型看到的输入”，状态是“系统对任务进度的结构化刻画”。面试官考的是你理不理解 Agent 的核心工程挑战：把隐式的执行进度变成显式的结构化状态。

---

## 记忆系统工程

### Q：Agent 记忆系统里的「做梦机制」（Dreaming）是什么？和 Reflection 有什么区别？

> 来源：阿里云暑期实习 Agent 面经

**新手答**：”就是 Reflection 的另一种叫法吧。”

**高手答**：

Reflection 和 Dreaming 都属于「离线记忆整合」，但机制和目标不同：

| 维度 | Reflection（反思） | Dreaming（做梦） |
|------|-------------------|-----------------|
| 触发时机 | 记忆重要性累计超阈值时 | Agent 空闲期/会话间隙，定时后台运行 |
| 核心操作 | 从低级记忆归纳高级认知 | 跨时间跨主题的记忆重组、冲突检测、遗忘衰减 |
| 产出物 | 高层推断（”用户正在学 Python”） | 记忆图谱更新、矛盾消解、长尾记忆淘汰 |
| 类比 | 人类的”复盘总结” | 人类睡眠时的记忆巩固与海马体重放 |

Dreaming 机制的核心工作：

1. **记忆重放与巩固**：将短期缓存中频繁被访问的记忆标记为”值得长期保存”，低频记忆逐步衰减
2. **冲突检测与消解**：扫描记忆库，发现矛盾条目（如用户先说”不吃辣”后说”来点辣的”），主动标注冲突或触发下次交互时确认
3. **跨会话关联发现**：不同会话中看似无关的记忆，通过离线推理发现隐含关联（如用户周一聊健身、周三买蛋白粉 → 推断健身需求）
4. **记忆压缩与抽象层级提升**：将多条具体记忆合并为更抽象的用户画像条目

在工程实现上，Dreaming 通常是一个异步后台任务（CronJob 或事件驱动），在用户不活跃时运行。Claude Code 的记忆系统中，每次会话结束后将重要信息写入持久化 Memory 文件、并在下次会话加载时做相关性筛选，本质上就是一种轻量的 Dreaming——会话间隙完成记忆的筛选和固化。

**差距在哪**：新手认为 Dreaming 只是 Reflection 的别名。高手区分了两者的触发时机（在线 vs 离线）、操作粒度（单次归纳 vs 全局重组）和工程实现（阈值触发 vs 定时后台任务）。面试官考的是你对 Agent 记忆系统”后台维护能力”的理解——不只是对话时处理记忆，还要在空闲时主动整理。

---

### Q：设计一个能支持亿级用户、千亿级记忆条目的 Agent 记忆系统，你会如何做技术选型和架构设计？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“用向量数据库存记忆，加个缓存层。”

**高手答**：

亿级用户 × 千亿条目，核心挑战是**存储成本、检索延迟和写入吞吐**三角平衡。架构分三层：

1. **热记忆层**（最近 7 天 / 高频访问）：Redis Cluster 或 MemoryDB，按 user_id 分片，毫秒级读写。容量小但访问频繁
2. **温记忆层**（近期 + 中等频率）：向量数据库（Milvus / Qdrant）+ 倒排索引（Elasticsearch），支持语义检索和关键词混合召回
3. **冷记忆层**（历史归档）：对象存储（S3 / OSS）+ 列式数据库（ClickHouse），压缩存储，按需加载

关键设计决策：
- **分片策略**：按 user_id 一致性哈希分片，同一用户的记忆在同一分片上，减少跨分片查询
- **冷热分离**：记忆条目带 TTL 和访问计数器，定期冷热迁移。大部分记忆 30 天后几乎不再被访问
- **写入优化**：记忆写入走异步队列（Kafka），批量写入存储层，避免高并发写入打爆数据库
- **索引策略**：不是所有记忆都建向量索引——高频查询的建索引，低频的只做全文检索或按时间范围查
- **Embedding 服务独立部署**：向量化计算是 CPU/GPU 密集型，和业务服务混部会互相影响。独立部署 Embedding 服务（K8s 上按需扩缩），写入时异步调用，避免阻塞主链路
- **两阶段检索**：第一阶段用 ANN（近似最近邻）从百万级候选中快速召回 top-100，第二阶段用 Re-ranking 模型（Cross-Encoder）对候选集做精排，兼顾速度和精度

千亿级的核心不是“用什么数据库”，而是**分层存储 + 冷热分离 + 异步写入**的架构设计。

**差距在哪**：新手只想到了一个组件。高手按访问频率做了三层分离，每层有不同的存储引擎和访问模式，且点出了分片、冷热迁移、异步写入三个关键工程决策。面试官考的是你能不能把“用什么数据库”的问题升级成一个完整的系统架构设计。

---

### Q：如何处理记忆的“新鲜度”与“重要性”之间的冲突？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“最新的优先。”

**高手答**：

新鲜度和重要性是记忆排序的两个独立维度，不能简单让一个压过另一个。处理思路是**多因子加权 + 衰减函数**：

```text
FinalScore = w1 × Relevance + w2 × Importance + w3 × Recency
```

- **相关性（Relevance）**：当前查询和记忆条目的语义匹配度，用 embedding 相似度或 Cross-Encoder 打分
- **重要性（Importance）**：由记忆的语义权重决定——用户明确表达的偏好（“我对花生过敏”）权重高；闲聊、过渡性对话权重低。可以用分类器或规则标注
- **新鲜度（Recency）**：用时间衰减函数，比如指数衰减 `decay = e^(-λt)`，越久越低

权重 w1、w2、w3 不是拍脑袋定的——通过 **A/B 测试**在线上调优，不同业务场景的最优权重可能完全不同（客服场景重要性权重高，新闻场景新鲜度权重高）。

**冲突消解的关键**是按记忆类型定不同的衰减策略：
- 事实性记忆（如过敏信息）：重要性权重极高，几乎不衰减
- 偏好性记忆（如“喜欢中餐”）：中等衰减，允许被新偏好覆盖
- 上下文性记忆（如“上次聊到了旅行”）：快速衰减，主要靠新鲜度

核心是**不同类型的记忆用不同的衰减策略**，而不是一刀切。

**差距在哪**：新手用单一维度做排序。高手引入了三因子加权模型（相关性 + 重要性 + 新鲜度），按记忆类型定义不同的衰减策略，且用 A/B 测试调优权重。面试官考的是你有没有把“排序”问题建模成一个可量化、可调优的工程方案。

---

### Q：Agent 的记忆可能存在偏见（Bias）或事实性错误，如何发现并纠正？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“定期清理过期记忆。”

**高手答**：

记忆偏见主要有三种来源：
1. **采样偏差**：如果用户只在不满时反馈，Agent 记住的全是负面信息，导致后续交互过度谨慎
2. **确认偏差**：Agent 用已有记忆过滤新信息，只保留和已有记忆一致的内容，形成“信息茧房”
3. **事实过期**：用户之前说“在北京工作”，后来搬去了上海，旧记忆变成了错误记忆

**发现机制**：
- **矛盾检测**：新记忆写入时，和已有记忆做冲突检查。如果新信息和旧记忆矛盾（“我现在在上海” vs 记忆中的“用户在北京”），触发更新流程
- **置信度衰减**：事实性记忆带置信度分数，长时间未被验证的逐步降低置信度
- **周期性审计**：定期用模型对关键记忆做事实性检查——“这条记忆是否仍然有效？”

**纠正机制**：
- 用户主动纠正时，不只更新当前记忆，还要**级联更新**所有基于错误记忆推导出的下游记忆
- 高置信度新信息覆盖低置信度旧信息，但旧信息不删除，做版本化存储，方便溯源

**差距在哪**：新手只想到了“清理过期”——这是最粗暴的方式。高手从偏见来源、发现机制、纠正策略三个层面构建了完整方案，且提到了级联更新和版本化存储。面试官考的是你有没有意识到记忆系统的“数据质量”问题。

---

### Q：什么是记忆的 Reflection 机制？它与简单的 Summarization 有何不同？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“Reflection 就是对记忆做总结。”

**高手答**：

Summarization 是**压缩**——把 10 段对话压成 1 段摘要，信息量减少但核心保留。Reflection 是**提炼 + 推理**——不只压缩，还要从记忆中**抽象出更高层次的认知**。这个概念最早在 Stanford 的 Generative Agents 论文中被系统化提出。

```text
原始记忆：
- "用户问了三次 Python 装饰器的用法"
- "用户在 Java 泛型问题上回答得很快"
- "用户说自己是后端开发"

Summarization 输出：
"用户是后端开发，问过 Python 装饰器和 Java 泛型"

Reflection 输出：
"用户是有经验的 Java 后端开发，正在学习 Python。
 Python 基础语法可能已掌握，但高级特性（装饰器、元编程）是薄弱点。
 后续交互建议：Python 解释可以类比 Java 概念来辅助理解。"
```

Reflection 的价值在于它产生了**原始记忆中不存在的新知识**——“正在学习 Python”“可以用 Java 类比”这些推断不是任何一条原始记忆直接包含的。本质上，Reflection 做了三件 Summarization 做不到的事：**归纳**（从多条记忆中提取共性）、**抽象**（从具体事件上升到模式识别）、**策略推导**（基于认知产出行动建议）。

实现上，Reflection 通常是定期运行的后台任务：积累一批记忆后，让模型做一次反思性分析，产出高级认知，存入独立的“反思记忆层”。Generative Agents 的做法是设置一个“重要性累计阈值”——当最近记忆的重要性总分超过阈值时触发一次 Reflection，而不是简单按时间间隔。

**差距在哪**：新手把 Reflection 等同于 Summarization。高手用具体例子展示了本质区别——Summarization 压缩信息，Reflection 通过归纳、抽象、策略推导产生新认知，并引用了 Generative Agents 的触发机制。面试官考的是你对记忆系统”知识蒸馏”能力的理解。

---

### Q：在实现长期记忆时，什么情况选向量数据库，什么情况选传统的 KV 或关系数据库？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“记忆都用向量数据库。”

**高手答**：

选什么取决于**查询模式**，不是记忆类型：

| 查询模式 | 适用存储 | 示例 |
|---------|---------|------|
| 语义相似性搜索 | 向量数据库 | “用户之前说过关于旅行的偏好” |
| 精确键值查找 | KV 存储 | user_id → 最近 5 条对话（情景记忆 / Episodic Memory） |
| 结构化条件过滤 + 事务 | 关系数据库 | “最近 7 天内、重要性 > 0.8 的记忆”，或需要跨表 JOIN、ACID 事务的场景 |
| 图关系查询 | 图数据库 | “和用户提到的‘张三’相关的所有记忆” |

实际系统通常是**混合存储**：
- 用户画像和结构化偏好 → 关系数据库（PostgreSQL），支持精确查询、复杂 JOIN 和事务——当记忆条目之间有强关联关系（如偏好变更历史、记忆版本链）时，关系数据库的事务保证不可替代
- 最近对话和热记忆 → KV 存储（Redis / DynamoDB），毫秒级读取，适合存储情景记忆（Episodic Memory）——按时间线组织的对话片段
- 语义检索场景 → 向量数据库（Milvus / Qdrant），支持 embedding 相似度召回
- 实体关系 → 图数据库（Neo4j），支持多跳关联查询

向量数据库的局限：不擅长精确匹配、不支持事务、更新成本高。如果你的查询是“查用户的手机号”，向量数据库反而不如 KV 直查。

**差距在哪**：新手“全用向量数据库”是一刀切。高手按查询模式选存储，区分了情景记忆（KV）、语义记忆（向量库）、结构化记忆（关系库）、关联记忆（图库），且指出实际系统是混合架构。面试官考的是你有没有数据存储选型的工程经验——不同查询模式对应不同的最优存储引擎。

---

### Q：什么是记忆的幻觉问题？它和 LLM 本身的幻觉有何区别？如何缓解？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“都是模型编造信息。”

**高手答**：

两者的来源不同，治理手段也不同：

- **LLM 幻觉**：模型在生成时凭空编造事实，来源是模型参数中的统计偏差。比如问“某公司 CEO 是谁”，模型编了一个不存在的名字
- **记忆幻觉**：Agent 从记忆中检索到了信息，但这条记忆本身是错的、过期的、或被错误关联的。比如检索到“用户喜欢辣”（其实是另一个用户的记忆），然后基于这条错误记忆做了推荐

关键区别：LLM 幻觉是“无中生有”，记忆幻觉是**“有据但据错”**。记忆幻觉更难发现——因为 Agent 确实引用了一条“记忆”，看起来有理有据，但根基是错的。

**缓解手段**：
1. **置信度过滤**：记忆条目带来源标签和置信度分数，检索时设相关性阈值，低置信度记忆降权或标注“不确定”
2. **交叉验证**：关键记忆在使用前和外部数据源做一致性校验
3. **用户确认**：基于记忆做高风险操作前，先向用户确认“我记得你上次说过 XX，是否正确？”

**差距在哪**：新手混淆了两种幻觉。高手区分了来源（模型参数 vs 记忆存储）和表现（无中生有 vs 有据但据错），且针对记忆幻觉给出了置信度过滤、交叉验证、用户确认三种缓解手段。面试官考的是你对 Agent 系统中不同类型错误的精确认知。

---

### Q：什么是“工具态记忆”（Tool-state Memory）？它在 Agent 工作流中如何发挥作用？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“就是记住工具的使用方法。”

**高手答**：

工具态记忆（也叫 **Procedural Memory**，程序性记忆）是指 Agent 在调用工具过程中产生的**中间状态和执行上下文**，包括四类：

1. **工具调用历史**：哪些工具被调用过、参数是什么、返回了什么——避免重复调用
2. **工具执行状态**：每次工具调用的生命周期状态（`pending → running → success/failed`），供编排层做流转控制和超时检测
3. **工具能力记忆**：某个工具在特定条件下的成功率、平均延迟、已知限制——辅助工具选择决策
4. **失败记忆**：哪些参数组合导致过工具调用失败，失败原因是什么——避免重复犯错，支持自动重试策略调整

**在工作流中的作用**：
- **避免重复调用**：查过一次天气就不需要再查，除非时间过了很久
- **上下文传递**：前一个工具的输出是后一个工具的输入参数，中间需要工具态记忆做承接
- **动态工具选型**：根据历史失败记忆，自动跳过当前不可用的工具，选择备选方案
- **执行状态追踪**：编排层通过工具执行状态判断当前步骤是否完成、是否需要超时干预，这是实现可靠多步工作流的基础

和对话记忆的区别：对话记忆是“用户说了什么”，工具态记忆是“系统做了什么”。很多 Agent 只维护对话记忆，丢失了工具态——导致重复调用、参数丢失、无法从失败中学习。

**差距在哪**：新手把工具态记忆理解成“记住工具说明书”。高手用 Procedural Memory 概念框架，区分了四类工具态记忆（调用历史、执行状态、能力记忆、失败记忆），且说清了它在避免重复、上下文传递、动态选型、状态追踪四个场景的作用。面试官考的是你对 Agent 工作流中“执行态信息”管理的理解。

---

### Q：记忆的容量规划需要考虑哪些因素？如何估算存储成本？

> 来源：后端 AI 八股 / Memory 系统

**新手答**：“按用户数乘以平均记忆条数估算。”

**高手答**：

容量规划要考虑三类因素：

**单条记忆存储拆解**：
```text
原始文本：200-500 字，UTF-8 编码约 0.6-1.5 KB
Embedding 向量：768 维 float32 约 3 KB，1536 维约 6 KB
元数据索引：时间戳、标签、置信度等约 0.5 KB
─────────────────────────────────
单条记忆总存储 ≈ 5-8 KB
```

**规模估算**（两种口径交叉验证）：
```text
口径一：按总用户估算
1 亿用户 × 平均 1000 条/用户 = 1000 亿条
1000 亿条 × 7 KB/条 ≈ 700 TB 原始存储
加上索引、副本、冗余 → 约 2-3 PB

口径二：按 DAU 增长估算
100 万 DAU × 50 条/天 × 365 天 = 182.5 亿条/年
第一年原始存储 ≈ 128 TB，三年累计 ≈ 400 TB
```

**成本估算**（以 AWS 为例）：
```text
冷存储（S3 Standard）：$0.023/GB/月 → 400 TB ≈ $9,200/月
热存储（Redis）：按 50 TB 热数据，r6g.xlarge 集群 ≈ $15,000/月
向量索引（Milvus on EKS）：100 TB 向量 ≈ $8,000/月
Embedding 计算：按 5000 万条/天 × $0.0001/条 ≈ $5,000/月
```

**成本优化手段**：
- **冷热分离**：80% 的记忆超过 30 天不再被访问，转冷存储成本降 10 倍+
- **向量量化**：int8 量化可以把向量存储减半，精度损失约 1-2%
- **记忆合并**：相似记忆做去重和合并，减少冗余条目
- **TTL 策略**：低重要性记忆设过期时间，自动清理

还要考虑**读写比**（记忆系统通常读多写少 10:1 以上，读扩展比写扩展更重要）和**增长速率**（每天新增多少条记忆，决定扩容节奏）。

**差距在哪**：新手只做了简单乘法。高手从单条存储拆解、双口径规模估算、具体云服务成本核算、优化手段四个层面做了完整规划，且给出了可落地的数字（精确到美元/月）。面试官考的是你有没有做过大规模存储系统的容量规划，能不能把一个抽象的“多大”变成具体的数字和优化策略。

---

## 记忆检索与维护

### Q：如何判断当前对话与历史对话是否相关？

> 来源：字节 Agent 实习二面

**新手答**：“看关键词有没有重叠。”

**高手答**：

相关性判断是上下文管理的前置环节——Agent 需要决定是否召回历史对话来辅助当前回答。做错了要么遗漏关键信息，要么引入无关噪声。

**判断方法分三个层次**：

**1. 实体和意图匹配**（快、粗）：

- 提取当前对话的关键实体（人名、产品名、任务名）和意图标签
- 与历史对话的实体/意图做交集匹配
- 有交集 → 可能相关，进入下一步精判
- 无交集 → 大概率无关，跳过

**2. 语义相似度**（中等精度）：

- 对当前对话和历史对话分别做 embedding
- 计算余弦相似度，设阈值（如 0.7）
- 注意：不能只拿最后一句话做 embedding，应该取当前对话的主题摘要

**3. 模型精判**（慢、准）：

- 把当前对话和候选历史对话组合成一个 prompt，让小模型（7B）判断“这两段对话是否讨论同一主题或有因果关系”
- 适合高价值场景（如客服接续、任务继续），不适合每次都调

**工程实践中的组合策略**：

```text
当前对话 → 实体/意图提取（规则/小模型）
        → 用实体做倒排检索，召回候选历史
        → embedding 相似度粗排，保留 top-K
        → （可选）模型精排
        → 判断是否关联
```

**关键设计点**：

- **时间衰减**：越近的历史对话越可能相关，给相似度分数加时间衰减权重
- **主题切换检测**：如果用户明确说“换个话题”或提了一个完全无关的新需求，直接判定与历史无关
- **会话级 vs 跨会话级**：同一会话内的历史默认相关，跨会话的才需要判断

**差距在哪**：新手只想到关键词匹配，这在语义相近但用词不同时会失效。高手用三层递进的判断方法（实体匹配 → 语义相似 → 模型精判），且考虑了时间衰减和主题切换等实际场景。面试官考的是你能不能把“相关性判断”设计成一个可工程化的方案，而不是拍脑袋设阈值。

---

### Q：记忆摘要、压缩、去重、合并这几件事，你会怎么设计触发时机？

> 来源：Agent 开发面试 30 题

**新手答**：“定时跑一个清理任务。”

**高手答**：

定时清理是最简单但最粗糙的方案——可能还没到清理时间记忆就爆了，也可能频繁清理浪费资源。更合理的做法是**事件驱动 + 阈值触发**的组合：

| 操作 | 触发时机 | 原因 |
|------|---------|------|
| **摘要** | 单次会话结束时 | 会话原始内容太长，摘要后再存入长期记忆 |
| **压缩** | 当前上下文 token 数达到窗口 70% | 预留 30% 给模型生成和新信息，不等到 100% 才压缩 |
| **去重** | 新记忆写入时 | 写入前和已有记忆做相似度检查，发现重复就合并而非追加 |
| **合并** | 同一主题的记忆条目超过 N 条时 | 5 条关于“用户喜欢日料”的记忆可以合并成 1 条 |

**设计关键点**：

1. **压缩不是简单截断**：不能直接砍掉前面的对话。用模型对历史消息做摘要压缩——保留关键决策和约束条件，丢弃中间推理过程
2. **去重要看语义不是看字面**：“用户偏好日料”和“用户喜欢吃日本菜”字面不同但语义重复，需要用 embedding 相似度判断
3. **合并要保留时间线**：合并后的记忆应保留“最早/最近出现时间”，方便后续做时效性判断

```text
触发策略优先级：
  写入时去重（实时）> 会话结束时摘要（会话级）> 上下文压缩（对话中）> 主题合并（后台异步）
```

**差距在哪**：新手用定时任务一刀切。高手按操作类型分别设计了不同的触发时机——摘要在会话结束、压缩在 token 阈值、去重在写入时、合并在条目超限时，且说清了每个操作的关键约束。面试官考的是你对记忆生命周期管理的工程化设计能力。

**追问：向量记忆库中，用户重复表述同一内容时，是重复存储还是语义合并？去重方案怎么设计？**

> 来源：阿里淘天 AI应用开发一面

用户说了三次“我不吃辣”——第一次直接说、第二次在点餐时说、第三次投诉时说。如果每次都存一条，记忆库迅速膨胀且检索时返回大量冗余。但简单去重又可能丢失上下文差异。

**写入时语义去重的三步方案**：

| 步骤 | 做什么 | 实现 |
|------|--------|------|
| 相似度检测 | 新记忆入库前，和已有记忆做 embedding 相似度匹配 | cosine similarity > 0.85 判为语义重复 |
| 冲突判断 | 语义相似但内容矛盾（“喜欢辣” vs “不吃辣”）→ 不合并，保留最新 | 用 LLM 做一致性判断 |
| 语义合并 | 确认是同一含义的重复 → 合并为一条，更新置信度和时间戳 | 保留最丰富的表述 + 出现次数计数 |

核心原则：**高频重复 = 高置信度**。“不吃辣”被说了 3 次，合并后这条记忆的权重应该更高，而不是存 3 条占 3 倍空间。

---

### Q：你会如何判断一条历史信息该进入长期记忆，还是只留在当前会话里？

> 来源：Agent 开发面试 30 题

**新手答**：“重要的存长期，不重要的只留会话。”

**高手答**：

“重要不重要”太主观了。需要一套**可程序化的判断标准**：

**进入长期记忆的条件（满足任一）**：

| 条件 | 示例 | 原因 |
|------|------|------|
| 用户显式声明的偏好 | “我不吃辣”“预算一般在 5000 以内” | 跨会话复用价值高 |
| 反复出现的模式 | 连续三次对话都查某只股票 | 隐式偏好，值得记住 |
| 身份性信息 | 姓名、角色、所在城市、公司 | 个性化服务的基础 |
| 已确认的事实性结论 | “上次排查发现是 Redis 配置问题” | 避免重复排查 |

**只留在当前会话的条件**：

| 条件 | 示例 | 原因 |
|------|------|------|
| 一次性的任务上下文 | “帮我写封邮件”的具体内容 | 任务完成后无复用价值 |
| 中间推理过程 | 模型的 chain-of-thought | 占空间大、复用价值低 |
| 临时性的环境信息 | “现在网络不好” | 下次对话时已过期 |
| 未经确认的猜测 | Agent 推测用户可能想要 X | 未验证的信息不应持久化 |

**工程实现**：每轮对话结束后，用一个轻量模型做“记忆准入判断”——从当前对话中提取候选记忆条目，按上述条件过滤，通过的写入长期存储。关键是**去重**——新记忆和已有记忆做语义相似度检查，重复的合并而非追加。

**差距在哪**：新手用“重要性”做主观判断。高手给出了可程序化的准入条件表——显式偏好、反复模式、身份信息、确认事实四类进长期，一次性上下文、中间过程、临时信息、未确认猜测只留会话。面试官考的是你能不能把模糊的“重要性”转化成可执行的工程规则。

---

### Q：长期记忆检索时，怎么避免把“语义相关但当前无用”的内容召回进来污染理解？

> 来源：Agent 开发面试 30 题

**新手答**：“调高相似度阈值。”

**高手答**：

单纯调高阈值会漏掉真正有用的记忆。问题的根源不是“检索到了不相关的”，而是**“语义相关”不等于“当前有用”**。

比如用户以前聊过北京的餐厅推荐，现在在聊北京的天气——“北京”“推荐”这些词语义上确实相关，但餐厅记忆对天气问题毫无帮助。

解决方案是**多阶段过滤**：

1. **意图匹配过滤**：每条长期记忆存储时打上意图标签（美食、出行、技术、偏好等），召回时只取和当前意图匹配的类别
2. **时效性过滤**：带时间戳的记忆检查是否过期——“上周的天气”对本周没用，但“用户不吃辣”长期有效
3. **相关性精排**：用一个轻量模型或 Cross-Encoder 判断：“这条记忆对回答当前问题是否有帮助？”

关键原则：**宁可少召回，不要多召回**。注入一条无关记忆的危害比漏掉一条有用记忆更大——因为无关信息会干扰模型的推理方向，而缺少信息模型会主动追问。

**差距在哪**：新手靠调阈值——这是一维调节，解决不了“语义相关但无用”的核心矛盾。高手用四阶段过滤（向量召回 → 意图匹配 → 时效性 → 精排）逐步缩小范围，且给出了“宁少勿多”的设计原则。面试官考的是你对记忆检索质量的工程化思考。

---

### Q：如果用户偏好、事实记忆、系统状态三者冲突了，Agent 应该信谁？

> 来源：Agent 开发面试 30 题

**新手答**：“听用户的。”

**高手答**：

不能无条件听用户的。三者的优先级要**按冲突类型分别处理**：

**冲突类型 1：用户偏好 vs 事实记忆**

用户说“我预算不限”，但历史记忆显示用户每次都选最便宜的 → **以当前偏好为准，但可以柔性提醒**：“好的，预算不限。顺便说一下，之前您几次选的都是经济型方案，需要我也推荐一些高端选项吗？”

原则：当前会话的显式声明 > 历史隐式行为模式。

**冲突类型 2：用户偏好 vs 系统状态**

用户说“帮我订明天的机票”，但系统状态显示用户账户已被风控冻结 → **系统状态优先，必须拦截**。不能因为用户想做就帮他做——安全约束、权限约束、业务规则是硬性边界。

原则：系统安全/合规约束 > 一切用户偏好。

**冲突类型 3：事实记忆 vs 系统状态**

记忆里存的是“用户 VIP 等级为金卡”，但系统实时查询显示已降级为银卡 → **以系统实时状态为准**。记忆可能过期，系统状态是当前事实。

原则：实时系统状态 > 历史记忆快照。

**总结优先级**：

```text
系统安全/合规约束（不可违反）
    > 系统实时状态（当前事实）
        > 用户当前显式声明（当前意愿）
            > 历史记忆/行为模式（参考但可被覆盖）
```

**差距在哪**：新手无条件听用户的——但如果用户要做违反安全规则的事呢？高手按冲突类型分别处理，给出了明确的优先级链：安全 > 实时状态 > 当前声明 > 历史记忆。面试官考的是你在设计 Agent 决策逻辑时有没有考虑过“信息源冲突”这个关键问题。

---

## 上下文工程进阶

### Q：Agent 的 Checkpoint 用什么数据库存？初始化 session 时如何优化加载 Checkpoint 的速度？

> 来源：AI 工程师面试 【CVTE AI应用工程师一面追问：短期记忆为什么用 sqlite checkpointer / 长期记忆如何实现】【钉学科技 FDE 实习一面追问：字段、一致性与换模型恢复】

**新手答**：”用 Redis 存，读取快。”

**高手答**：

Checkpoint 是 Agent 执行状态的持久化快照——包括当前节点、中间变量、已完成步骤、工具返回结果等。选什么数据库存、怎么优化加载速度，取决于**数据特征和访问模式**。

**存储选型**：

| 方案 | 适用场景 | 优缺点 |
|------|---------|--------|
| **PostgreSQL**（LangGraph 默认） | 生产环境首选 | 事务保证、支持复杂查询、数据持久可靠；延迟略高 |
| **SQLite** | 本地开发、单用户场景 | 零配置、嵌入式；不支持并发写入 |
| **Redis** | 高频读写、短期状态 | 极低延迟；但数据持久性弱，重启可能丢失 |
| **MongoDB** | Checkpoint 结构复杂且多变 | Schema 灵活；但事务支持弱于 PG |

LangGraph 生产部署推荐 **PostgreSQL + 异步连接池**（`AsyncPostgresSaver` + `asyncpg`），兼顾可靠性和性能。

**Checkpoint 表结构设计**（以 LangGraph 为例）：

```text
checkpoints 表：
  thread_id      -- 会话标识
  checkpoint_id  -- 检查点版本号（单调递增）
  parent_id      -- 父检查点 ID（支持版本链）
  channel_values -- 序列化的状态数据（JSON/msgpack）
  metadata       -- 节点名、时间戳、自定义标签
```

通过 `thread_id` 定位会话，`checkpoint_id` 定位最新版本，`parent_id` 支持状态回溯。

生产中的字段通常还要更完整：租户、用户、`run_id` 与 `thread_id`；当前节点、下一候选节点、运行状态；State 快照、channel 版本与待处理写入；已完成/待执行任务；工具调用结果及幂等键；中断原因与人工审批状态；创建时间、过期策略；以及 `model_id`、Prompt、Tool Schema 和运行配置版本。不是所有字段都要塞进一个 JSON，但必须能回答“恢复哪次执行、从哪里继续、依赖哪个运行时版本、哪些副作用已经发生”。

**加载速度优化**：

初始化 session 时加载 Checkpoint 的瓶颈通常在**序列化数据的读取和反序列化**。优化分四个方向：

**1. 数据库层优化**：

```text
- 对 (thread_id, checkpoint_id) 建复合索引，精确命中，避免全表扫描
- 使用连接池（asyncpg pool）复用数据库连接，省掉每次建连的开销
- 对历史 checkpoint 做定期归档，保持主表体积小
```

**2. 缓存层**：

热点 session 的最新 Checkpoint 缓存到 Redis，TTL 设为 session 超时时间。命中率高时加载延迟从 10ms 级降到 1ms 级。

这里应把 PostgreSQL/MySQL 当作事实源，Redis 只做**带版本的缓存**。写入时在关系数据库内用 `checkpoint_version` 做 CAS/乐观锁校验，事务提交成功后再失效或更新 Redis；缓存值也携带版本号，发现版本落后或恢复时的 `expected_version` 不匹配，就回源并回填。TTL、提交后失效消息和定时 reconciliation 共同修复漏删缓存，避免“数据库已经到 v12，Redis 还让任务从 v11 继续”的并发覆盖。

**3. 懒加载（Lazy Loading）**：

不一次性加载完整 Checkpoint。先加载元数据（当前节点、步骤数），`channel_values` 中的大字段（如工具返回的长文本、检索结果）按需加载：

```text
第一步：加载 metadata + 当前节点位置（<1ms）
第二步：用户实际交互时，按需加载具体 channel 的值
```

**4. 状态压缩**：

- 历史步骤的完整工具返回可以压缩为摘要——只保留关键结论，丢弃原始 JSON
- 用 msgpack 替代 JSON 做序列化，体积缩小 30-50%，反序列化速度更快
- 超过一定步数的历史 Checkpoint 只保留最近 N 个完整快照，更早的合并为摘要快照

**恢复时切换模型怎么办**：Checkpoint 不只保存业务 State，还要绑定模型、Prompt、Tool Schema、结构化输出 schema 和关键配置版本。恢复时优先固定到原版本；若旧版本不可用，先执行显式迁移，重新校验待执行工具参数、状态 schema 和安全策略，再从最近的稳定节点继续。不能把旧模型生成到一半的 tool call 直接交给新 schema 执行，否则“状态能反序列化”并不等于“语义还能安全续跑”。

**差距在哪**：新手只想到 Redis——快但不可靠，且没考虑加载优化。高手从存储选型（PostgreSQL + 异步连接池）、表结构设计、四层加载优化（索引 + 缓存 + 懒加载 + 压缩）给出了完整方案。面试官考的是你对状态持久化的工程化设计能力——Checkpoint 是 Agent 断点恢复和多轮对话的基石。

---

### Q：Code Agent 的上下文工程，和普通对话 Agent 相比有哪些独特挑战？

> 来源：蚂蚁集团 Agent 开发一面

**新手答**：“代码多了上下文放不下，截断就行。”

**高手答**：

Code Agent 的上下文工程比普通对话 Agent 难得多，因为**代码的上下文结构是网状的，不是线性的**。

**挑战一：依赖关系是隐式的**

普通对话的上下文是线性的——前几轮说了什么。但代码的上下文是**跨文件、跨模块的依赖图**。要修改一个函数，可能需要知道：调用它的地方、它依赖的类型定义、相关的配置文件、对应的测试文件。这些信息分散在整个项目里，不在对话历史中。

```text
普通对话 Agent：上下文 = 最近 N 轮对话（线性）
Code Agent：上下文 = 当前文件 + 依赖文件 + 类型定义 + 测试 + 配置 + git history（网状）
```

**挑战二：精度要求极高**

自然语言对话“大差不差”也能用，但代码差一个字符就编译不过。上下文里缺少一个类型定义，模型就可能自己编造一个不存在的接口。所以 Code Agent 的上下文不能只求“相关”，必须求**精确和完整**。

**挑战三：上下文随操作动态变化**

Code Agent 每做一步操作（写文件、运行测试），项目状态就变了。下一步的上下文必须基于**操作后的最新状态**，不能用缓存的旧版本。这意味着上下文需要持续刷新，而不是一次组装完就够了。

**工程解法**：

1. **结构化索引**：不把整个文件塞进上下文，而是用 AST/LSP 建立项目的结构化索引——函数签名、类型定义、调用关系。需要时按依赖路径精确召回
2. **分层加载**：当前编辑文件全量加载 → 直接依赖文件加载签名 → 间接依赖只加载类型定义
3. **操作后刷新**：每次文件修改或命令执行后，增量更新受影响文件的上下文，而非全量重建
4. **项目规则注入**：用 CLAUDE.md / .cursorrules 等机制注入编码规范和架构约束，让模型在生成代码时遵守项目约定

**差距在哪**：新手把 Code Agent 的上下文当成普通对话来处理。高手看到了代码上下文的三个独特挑战（网状依赖、精度要求、动态变化），并给出了结构化索引、分层加载、操作后刷新、规则注入四个工程解法。面试官考的是你对 Code Agent 这个垂直场景的深度理解。

---

### Q：做上下文工程最关键的工作是什么？

> 来源：蚂蚁集团 Agent 开发二面

**新手答**：“把相关信息尽量多地塞进上下文。”

**高手答**：

上下文工程最关键的工作不是“塞更多信息”，而是**在有限的窗口里，让模型在每一步都能看到恰好需要的信息——不多不少**。

这个工作可以拆成三个关键环节：

**1. 信息分级——决定“什么信息该在上下文里”**

```text
必须在（每轮注入）：系统规则、当前任务目标、关键约束条件
按需在（检索注入）：相关知识、历史记录、工具返回结果
不该在（外置存储）：中间推理过程、已处理的原始数据、过长的工具返回
```

最常见的错误是把所有东西都往上下文里塞——信息越多，模型越容易在噪声中迷失。

**2. 注入位置——决定“信息放在上下文的哪个位置”**

大模型对上下文不同位置的信息敏感度不同（Lost in the Middle 现象）。关键信息的最佳位置：

```text
System Prompt：系统规则、角色约束、输出格式要求（最稳定的锚点）
对话开头：任务目标、关键约束（不会被中间对话淹没）
最近几轮：工具返回结果、当前步骤信息（和当前决策最相关）
```

**3. 生命周期管理——决定“信息什么时候进、什么时候出”**

上下文不是只进不出的。最关键的工程决策是**信息的退出策略**：

- 工具返回的原始 JSON：提取关键字段后，原始数据退出上下文
- 已完成的子任务：压缩成一句摘要，详情落库
- 过时的约束条件：用户改了需求后，旧约束必须显式移除，不能让它残留干扰

**差距在哪**：新手以为上下文工程就是”塞信息”。高手把它拆成信息分级、注入位置、生命周期管理三个关键环节——重点不是”放什么进去”，而是”什么时候让什么退出”。面试官考的是你对上下文工程的系统性认知，而不只是”会用 RAG 注入知识”。

---

### Q：如何减少无关上下文对模型的干扰？当前上下文有哪些优化思路？

> 来源：快手 AI Agent 开发一面

**新手答**：“把不相关的信息删掉。”

**高手答**：

无关上下文对模型的干扰比“缺少信息”更严重——缺信息模型会说“我不知道”，但噪声信息会让模型**自信地给出错误答案**。这是 Lost in the Middle 现象的根源。

**干扰来源和对应优化**：

**优化策略一：信息准入控制（入口减噪）**

不是所有信息都该进上下文。每类信息设**准入条件**：

```text
RAG 检索结果：rerank 分数 > 阈值才注入，低于阈值的宁可不给
工具返回值：提取关键字段（如 status、result），丢弃原始 JSON 全文
历史对话：超过 N 轮的压缩为摘要，只保留关键决策和约束条件
```

**优化策略二：注入位置优化（利用注意力分布）**

大模型对上下文不同位置的关注度不同（开头和结尾关注度高，中间容易被忽略）：

```text
System Prompt 区（最稳定）：系统规则、安全约束、输出格式
上下文开头：当前任务目标、关键约束
上下文结尾（靠近用户输入）：最相关的检索结果
中间区域：次要参考信息（即使被忽略影响也不大）
```

**优化策略三：上下文压缩（动态瘦身）**

| 压缩手段 | 适用对象 | 效果 |
|---------|---------|------|
| 摘要压缩 | 早期对话历史 | 保留语义，释放 70%+ token |
| 字段提取 | 工具返回的 JSON | 只保留关键字段，丢弃冗余 |
| 关键信息外置 | 用户约束（预算、日期） | 存入独立状态变量，每轮强制注入，不依赖上下文传递 |
| 去重 | 多轮对话中重复出现的信息 | 同一信息只保留最新版本 |

**优化策略四：结构化分隔（防止信息混淆）**

用明确的标签/分隔符区分不同来源的信息，让模型清楚知道每段信息的角色：

```text
【系统规则】你是一个客服助手，回答必须基于以下参考资料...
【用户约束】预算：5000元以内，时间：本周末
【检索结果】[来源: 产品手册 v2.3] ...
【当前问题】用户问：...
```

不加分隔符时，模型可能把检索结果当成系统指令，或把历史对话当成当前需求。

**差距在哪**：新手只想到”删掉不相关的”——但怎么判断”不相关”？高手从四个维度给出了完整方案：准入控制（入口减噪）、位置优化（利用注意力分布）、动态压缩（释放 token）、结构化分隔（防止混淆）。面试官考的是你对”上下文质量”这个 Agent 核心问题的系统性思考。

---

### Q：在电商或导购场景下，用户的请求往往高度模糊，Agent 怎么来精准理解这种需求？

> 来源：淘天 AI Agent 一面

**新手答**：”问用户想要什么。”

**高手答**：

电商场景的模糊需求和普通对话不一样——用户说”推荐个好用的””性价比高的””送女朋友的”，这些表述没有明确的商品属性，但用户期望 Agent 能”懂”。直接追问”您想要什么功能？”体验很差，等于把理解工作丢回给了用户。

精准理解模糊需求需要**三层递进的理解管线**：

**第一层：意图解析**

先判断用户的意图类型——是随便逛逛（浏览）、在做对比（比较）、准备下单（购买）、还是来投诉的。不同意图对应完全不同的处理策略。同时提取用户输入中的显式约束：价格范围、品牌偏好、品类限定。”推荐个好用的”意图是浏览/购买，但显式约束几乎为零。

**第二层：画像补全**

显式约束不够时，从用户历史中补齐：
- **购买记录**：过去买过什么品类、什么价位段、什么品牌
- **浏览行为**：最近看了哪些商品、在哪些商品页停留时间长
- **退货模式**：退过什么、退货原因是什么（”质量差”说明用户重品质，”不好用”说明用户重体验）

这些信号组合起来能大幅缩小候选范围——比如历史数据显示用户习惯买 200-500 元价位的电子产品，品牌偏好国产，那”推荐个好用的”就不需要从全品类全价位去猜了。

**第三层：知识落地**

模糊表述需要通过**商品知识图谱**映射到具体的商品属性：
- “好用” → 耐用性评分高 + 用户好评率高 + 操作复杂度低
- “性价比” → 同品类中价格/性能比排名靠前
- “送女朋友” → 品类偏向（美妆/饰品/数码）+ 外观评分高 + 有礼盒包装选项

这一步不是模型自己猜的，而是基于预先构建的品类知识图谱做结构化映射。

**消歧策略**：当多种理解并存时，不要问开放式问题（”您想要什么？”），而是用知识图谱生成**选择式澄清**——“您说的‘好用’，是更看重耐用不容易坏，还是操作简单上手快？”把模糊需求转化成二选一或三选一，用户决策成本低，Agent 也能精准收窄范围。

**差距在哪**：新手只会问开放式问题，把理解工作甩给用户。高手用三层管线（意图解析 → 画像补全 → 知识落地）做多信号融合，在追问之前先把不确定性降到最低，追问时也用选择题而不是开放题。面试官考的是你能不能把”理解用户”从一个模糊的概念变成一个可工程化的管线。

---

### Q：摘要总结往往会丢失关键细节，在长文本 Agent 中一般怎么来处理这一块？

> 来源：淘天 AI Agent 一面

**新手答**：”用模型做摘要就行。”

**高手答**：

一次性摘要是最常见的做法，也是最容易丢信息的做法。问题在于：模型做摘要时会倾向保留”大意”而丢弃”细节”——但在 Agent 场景中，往往**细节才是关键**：一个具体的数字、一条用户约束、一个边界条件，丢了就会导致后续执行出错。

解决思路是**不要让摘要承担所有压缩任务**，而是把关键细节和叙事流分开处理：

**策略一：分层摘要**

不要一次性把长文本压成一段摘要，而是分层递进：

```text
第一层：段落级摘要 —— 每段保留核心论点和关键数据
第二层：章节级摘要 —— 合并同主题段落，保留结论和依据
第三层：全文级摘要 —— 提炼整体结论和核心约束
```

每一层保留不同粒度的信息。需要概览时用第三层，需要细节时回溯到第一层。比单次压缩损失少得多。

**策略二：先提取后摘要**

在做摘要之前，先用 NER + 规则提取把**结构化关键事实**抽出来存到独立的 key-value 存储中：

| 提取类型 | 示例 | 存储位置 |
|---------|------|---------|
| 日期时间 | “截止日期是 4 月 30 日” | 结构化事实库 |
| 数字约束 | “预算不超过 5000 元” | 结构化事实库 |
| 人名/实体 | “负责人是张三” | 结构化事实库 |
| 明确约束 | “必须支持 iOS 和 Android” | 结构化事实库 |
| 叙事内容 | 讨论过程、背景说明 | 交给摘要处理 |

摘要只负责压缩叙事流（讨论了什么、结论是什么），不承担保留具体数字和约束的责任。最终上下文 = 结构化事实 + 叙事摘要，两者合并注入。

**策略三：选择性压缩**

不是所有内容都需要同等程度的压缩：

| 内容类型 | 压缩策略 | 保留程度 |
|---------|---------|---------|
| 用户约束和决策 | 保留原文 | 100% |
| 错误详情和边界条件 | 保留原文 | 100% |
| 工具返回的关键结果 | 提取关键字段 | 50% |
| 讨论过程和背景 | 摘要压缩 | 20% |
| 寒暄和确认性回复 | 直接丢弃 | 0% |

关键部分不压缩，常规部分重度压缩，无价值内容直接丢弃——这比均匀压缩的信息保真度高得多。

**差距在哪**：新手用一次性摘要解决所有问题——模型会自动丢弃它认为”不重要”的细节，但在 Agent 场景中这些细节往往是执行的关键。高手把压缩任务拆成结构化提取 + 分层摘要 + 选择性压缩三个策略，确保关键细节不被摘要过程吞掉。面试官考的是你对长文本信息压缩的精细化设计能力——摘要不是”一键总结”，是一个有策略的信息管理流程。

---

## 会话记忆与前沿

### Q：有没有了解过最前沿的记忆设计？

> 来源：字节 Agent 开发实习一面 【CVTE AI应用工程师一面追问：openclaw 的记忆机制怎么实现的？有借鉴吗】

**新手答**：“用向量数据库存历史对话。”

**高手答**：

前沿的 Agent 记忆研究正在从“被动存储”走向“主动知识管理”。三个最值得关注的方向：

**1. MemGPT / Letta——虚拟内存管理**

类比操作系统的虚拟内存：主上下文窗口 = “内存”，外部存储 = “磁盘”。

核心创新：**把上下文管理变成了 Agent 可以主动调用的操作**——Agent 自己决定“记住什么、忘掉什么、什么时候召回”。不是被动地被截断，而是主动地管理自己的记忆空间。

**2. Generative Agents（Stanford）——记忆的反思与抽象**

斯坦福“AI 小镇”实验中提出的三层记忆机制：

```text
观察流（Observation Stream）
  → 反思（Reflection）：定期元认知——"最近观察到的最重要洞察是什么？"
    → 规划（Planning）：基于反思结果调整行为策略
```

关键机制：
- **重要性评分**：每条记忆按 **时效性 x 重要性 x 相关性** 综合打分
- **反思触发**：当最近记忆的重要性累计分数超过阈值时触发一次 Reflection，而不是简单按时间间隔
- **效果**：Agent 能形成“关系”、记住过去的交互、随时间演化行为模式

Reflection 和简单 Summarization 的本质区别：Summarization 压缩信息量，Reflection 产生**原始记忆中不存在的新认知**（归纳共性、识别模式、推导策略）。

**3. Claude Code 的实践路线——工程化分层记忆**

没有用复杂的记忆架构，而是用简单但有效的分层方案：Auto Memory 文件 + CLAUDE.md + Context Compaction。

```text
学术路线：复杂的记忆管理算法（MemGPT 的换页、Generative Agents 的反思）
工程路线：简单、可调试、可维护的分层文件系统（Claude Code）

生产系统更倾向后者——简单可调试的记忆 > 精巧但脆弱的架构
```

**元趋势**：记忆正在从**被动存储**走向**主动知识管理**——Agent 不只是存储和检索，还在**筛选、抽象、自我反思**自己的记忆。未来的方向是“给 Agent 管理自己记忆的工具”，而不是“帮 Agent 建更大的记忆库”。

**差距在哪**：新手只知道向量数据库做检索。高手能讨论 MemGPT 的虚拟内存范式（Agent 自主管理上下文换入换出）、Generative Agents 的反思机制（从记忆中产生新认知）、以及生产环境中简单分层记忆的工程优势，展现出对前沿研究的了解和对工程落地的务实判断。面试官考的是你的技术视野——知不知道这个领域最前沿在探索什么方向。

**追问：对比 OpenClaw 和 Hermes 的记忆机制，重点说说分层压缩方案和 .md 文件使用方式？**

> 来源：淘宝闪购 Agent 一面

两者代表了 Agent 记忆的两种设计哲学：

| 维度 | OpenClaw | Hermes |
|------|----------|--------|
| 核心理念 | 时间轴分层压缩 | 情景记忆(Episodic Memory) |
| 压缩策略 | T-1h 完整保留 → T-24h 段落摘要 → T-7d 关键词图 | 双索引（语义+时间），长历史按事件聚类 |
| 召回方式 | 语义相似度 + 时间衰减加权 | 事件关联度 + 上下文匹配 |
| .md 文件角色 | Human-in-the-Loop 审查入口，人可直接编辑记忆 | 配置文件，定义记忆策略和索引规则 |
| 优势 | 压缩粒度精细，长历史不膨胀 | 事件间关联保留好，适合多轮复杂任务 |
| 劣势 | 关键词图层可能丢失语义细节 | 长历史压缩粒度不如 OpenClaw |

**实践融合方案**：工程中可取两者之长——用 OpenClaw 的分层压缩策略控制存储规模，用 Hermes 的双索引提升召回质量，.md 文件作为 human-in-the-loop 审查接口让人可以直接校正记忆偏差。

**追问：Mem0 的原理是什么？和自己实现记忆有什么区别？**

> 来源：美团Keeta Agent开发一面

Mem0 是目前开源社区最流行的 Agent 记忆中间件，核心定位是**「给任何 LLM 应用加上长期记忆」**。

**Mem0 的工作原理**：

核心流程：每轮对话后，用 LLM 从对话中抽取值得记住的信息（偏好、事实、约束），以结构化形式存入向量数据库；下一轮对话时，根据当前 query 检索相关记忆，注入上下文。

**Mem0 的关键设计**：

| 设计点 | 实现方式 | 解决的问题 |
|--------|---------|-----------|
| 记忆抽取 | LLM 判断「这段对话有什么值得记住的」 | 不是全存，而是选择性存储 |
| 冲突处理 | 新记忆和旧记忆矛盾时，用 LLM 判断保留哪个 | 防止过期信息污染 |
| 双存储 | 向量数据库（语义检索）+ 图数据库（关系推理） | 兼顾语义相似和实体关联 |
| 用户隔离 | 每个用户独立的记忆空间 | 多用户场景不串记忆 |

**和自己实现记忆的区别**：

自己实现通常是**粗粒度的全量存储**——把对话历史全部存进向量库，检索时按相似度召回。Mem0 多了两个关键步骤：**选择性抽取**（不是所有信息都值得记）和**冲突消解**（用户改了偏好要更新旧记忆）。代价是每轮多一次 LLM 调用做抽取判断，但记忆质量显著提升。

---

### Q：Claude Code 的记忆架构是什么？上下文真的等于记忆吗？

> 来源：字节 Agent 开发实习一面 【小红书数据库智能化一面追问：主流 Agent 与 Claude Code 的上下文管理策略】

**新手答**：“上下文就是记忆，对话历史就是全部。”

**高手答**：

Claude Code 的记忆**不是**一个单一系统，而是一个**多层架构**，每一层解决不同的持久化和访问需求：

**五层记忆架构**：

| 层级 | 持久性 | 容量 | 更新方式 | 访问时机 |
|------|--------|------|---------|---------|
| 会话上下文（Session Context） | 仅当前会话 | Token 窗口限制 | 自动（每轮更新） | 始终加载 |
| 项目记忆（CLAUDE.md） | 持久化 | 无硬性限制 | 手动维护 | 会话启动时加载 |
| 自动记忆（Auto Memory） | 持久化 | 无硬性限制 | Claude 自动写入 | 会话启动时加载 |
| 技能记忆（Skills） | 持久化 | 无硬性限制 | 手动创建 | 按需加载 |
| 环境状态（Environment） | 实时 | N/A | 外部变化 | 按需（工具调用） |

**上下文等于记忆吗？——不等于。**

上下文是**工作记忆**（当前窗口中加载的内容），而记忆是一个更广的概念——包含了跨会话持久化的知识。两者的关系：

```text
上下文 属于 记忆

上下文：临时性的，会话结束即消失
记忆：持久性的，跨会话存活

上下文：受 token 窗口硬限制
记忆：存储在外部文件中，无硬性容量限制

压缩（Compaction）会销毁上下文细节
但 CLAUDE.md 和 Auto Memory 文件不受影响
```

**核心洞察**：Claude Code 的设计创新在于认识到**不同类型的信息需要不同的持久化和访问模式**。不是所有东西都该塞进上下文窗口——会话上下文是高速但易失的“内存”，CLAUDE.md 和 Auto Memory 是可靠但需要显式加载的“磁盘”，环境状态是实时但需要主动查询的“外设”。

**差距在哪**：新手把上下文等同于记忆，认为对话历史就是 Agent 知道的一切。高手能画出五层记忆架构，清楚地区分临时上下文与持久记忆的关系——上下文只是记忆加载到当前会话的子集，Compaction 会销毁上下文但不影响持久记忆文件。面试官考的是你对 Agent 记忆系统的结构性认知，而不只是“对话历史”三个字。

---

### Q：会话记忆具体是怎么实现的？滑动窗口设几轮？摘要压缩怎么触发？

> 来源：高德 AI 应用开发实习一面

**新手答**：“存最近几轮对话就行。”

**高手答**：

单纯存最近几轮是最朴素的实现，但生产环境中会话记忆需要一个**双层架构：Buffer Memory（近期原始对话）+ Summary Memory（历史压缩摘要）**。

**Buffer Memory（滑动窗口）**：

保留最近 5-10 轮的原始对话。为什么是这个范围？

- 5 轮对话大约消耗 2K-4K token，覆盖了绝大多数即时上下文需求
- 太少（<3 轮）→ 连上一个问题的追问都接不上
- 太多（>15 轮）→ 大量 token 浪费在已经不相关的早期闲聊上

存储介质选 Redis 或内存（快速读写），因为 Buffer 的访问频率极高——每轮对话都要读。

**Summary Memory（摘要层）**：

当 Buffer 中的旧轮次被挤出去时，不是直接丢弃，而是经过摘要压缩后存入持久化存储（数据库）。

**摘要压缩的触发条件**（满足任一即触发）：

| 触发条件 | 具体阈值 | 原因 |
|---------|---------|------|
| Token 数超限 | 总上下文达到窗口的 70% | 预留 30% 给模型生成和新信息 |
| 轮次超限 | Buffer 超过 N 轮（如 8 轮） | 最早的轮次已经不太相关 |
| 话题切换 | 当前轮与 Buffer 的语义相似度低于阈值 | 话题变了，旧话题的细节可以压缩 |

**压缩实现**：将最早的 K 轮对话喂给一个小模型，Prompt 要求：“从以下对话中提取关键事实、用户偏好、已做决策和未解决问题。”

**压缩时保留什么、丢弃什么**：

```text
✅ 保留：用户偏好、关键决策、事实性承诺、未解决的问题
❌ 丢弃：寒暄客套、重复信息、中间推理步骤
```

**双层流转全景**：

**差距在哪**：新手只有一个简单的 Buffer，不知道溢出后怎么办。高手设计了双层架构（Buffer + Summary），明确了滑动窗口的轮次范围及其原因，定义了三种压缩触发条件，且区分了压缩时该保留和该丢弃的信息类型。面试官考的是你能不能把“存最近几轮”这个模糊概念，落地成一个有触发机制、有存储分层、有信息筛选策略的完整方案。

---

### Q：设计会话记忆系统时需要考虑哪些维度？

> 来源：高德 AI 应用开发实习一面

**新手答**：“考虑存多少轮。”

**高手答**：

只考虑容量是远远不够的。设计会话记忆系统需要从**五个核心维度**出发：

| 维度 | 实现策略 | 常见陷阱 |
|------|---------|---------|
| **时效性** | 衰减函数：recency-weighted scoring，越近的记忆权重越高 | 有些信息永远不该衰减（用户名、过敏信息），需要设置“不衰减白名单” |
| **相关性** | 注入上下文前做语义相似度过滤，只取和当前查询相关的记忆 | 不过滤就全塞进去，导致无关记忆干扰模型推理 |
| **重要性** | 重要性评分器（规则 or LLM）：用户承诺（“我要退货”）、关键决策、纠错信息为高重要性；闲聊为低重要性 | 把所有记忆一视同仁，闲聊占满了上下文空间 |
| **容量** | 固定 token 预算分配：系统指令 > 当前查询上下文 > 相关记忆 > 工具结果 | 记忆占了太多 token，挤压了当前任务的空间 |
| **一致性** | 用户更新偏好时（“其实我想要红色的，不是蓝色的”），旧记忆必须被更新而非追加 | 只做追加不做更新，导致记忆自相矛盾，模型不知道该信哪条 |

**五个维度之间的关系**：

**元原则**：记忆不是一份日志（log），而是一个**精心维护的知识库**。日志只管追加，知识库要管理增删改查和数据质量。很多系统把记忆当日志来做——只管往里写、不管清理和更新——最终记忆越来越多，质量越来越差，模型被噪声淹没。

**差距在哪**：新手只想到了容量这一个维度。高手从时效性、相关性、重要性、容量、一致性五个维度系统分析，每个维度都有具体的实现策略和常见陷阱。面试官考的是你对记忆系统的认知深度——它不是一个“存东西的地方”，而是一个需要多维度设计的知识管理系统。

---

### Q：用户对话中频繁切换话题，会话记忆该怎么设计？

> 来源：高德 AI 应用开发实习一面

**新手答**：“按时间顺序存就行。”

**高手答**：

按时间线性存储在话题频繁切换时会崩溃。举个例子：用户先问机票 → 切到酒店 → 又回到机票问“刚才说的那个航班呢”。如果用简单的滑动窗口，第一次讨论机票的对话可能已经被挤出去了，Agent 完全接不上。

核心问题是：**线性对话历史无法处理话题交错**。解决方案是**基于话题分段的记忆架构**。

**整体架构**：

**五个关键机制**：

**1. 话题检测**：对每条用户消息做 embedding，和当前所有活跃话题的 embedding 计算相似度。相似度高于阈值 → 属于该话题；低于所有话题 → 新话题。

**2. 分话题记忆段**：每个话题维护独立的 mini-buffer 和摘要。数据结构：

```text
topics: [
  { id: "flight", label: "机票预订", turns: [...], summary: "...", last_active: "..." },
  { id: "hotel",  label: "酒店预订", turns: [...], summary: "...", last_active: "..." }
]
```

**3. 活跃话题追踪**：维护一个“话题栈”或“话题集合”。当前正在讨论的话题为活跃状态，其他话题为“暂停”（parked）状态——暂停不等于遗忘。

**4. 话题重激活**：当用户说“刚才说的机票呢”时，检测到话题切换回“机票”→ 将机票话题的记忆段重新加载到活跃上下文中，Agent 能无缝接续之前的讨论。

**5. 上下文组装**：

```text
当前上下文 = System Prompt
           + 活跃话题的完整记忆（原始对话）
           + 暂停话题的简要摘要（一句话概括进展）
           + 当前用户输入
```

**关键难点：话题检测的准确性**。误判会导致两种问题：

- 把同一话题的延续误判为新话题 → 记忆碎片化，上下文断裂
- 把新话题误归为已有话题 → 记忆污染，不同话题的信息混杂

**降级方案**：如果话题检测不够可靠，可以用更简单的方式——仍然按时间线保留所有近期对话，但给每轮对话打上话题标签。检索时按话题标签过滤，而不是按时间截断。这样即使检测偶尔出错，也不会丢失关键信息。

**差距在哪**：新手按时间线性存储，话题一交错就丢失上下文。高手设计了基于话题分段的记忆架构，包括话题检测、分话题 buffer、活跃追踪、重激活和智能上下文组装五个机制。核心洞察是：**会话记忆应该按话题组织，而不是按时间组织**。面试官考的是你面对非线性对话场景时的架构设计能力。

---

### Q：Lost in the Middle 问题是什么？有哪些解决方案？

> 来源：淘宝闪购 AI应用研发 一面

**新手答**：“把重要信息放在 Prompt 的前面就行了。”

**高手答**：

Lost in the Middle 是指模型处理长上下文时，**对中间位置信息的注意力显著低于开头和结尾**——即使信息在上下文里，放在中间位置也可能被“忽略”。这个现象在 2023 年被 Stanford 的论文系统验证过。

解决方案从四个层面入手：

**1. 信息布局优化**

最直接的策略——把最重要的信息放在上下文的**开头或结尾**：
- 检索结果按相关度排序后，最相关的放最前面
- 系统级指令放在 System Prompt 开头
- 关键约束在 Prompt 末尾再强调一次

**2. 检索阶段优化**

从源头减少“中间”的长度：
- 控制检索结果数量：不是越多越好，Top-3 到 Top-5 通常就够
- Rerank 后严格截断：只保留真正相关的内容，宁缺毋滥
- 结果去重：多路召回后去除重复或高度相似的内容

**3. 上下文压缩**

把长上下文压缩成更短、更密集的形式：
- 摘要压缩：对检索结果先做摘要，只保留与查询相关的部分
- 递归摘要：超长文本分段摘要后再合并
- 提取式压缩：只抽取与问题直接相关的句子，丢弃背景信息

**4. 结构化标记**

用显式的结构标记帮助模型定位信息：
- 给每段检索结果加编号和标签：`[文档1-最相关]`、`[文档2-补充]`
- 在 Prompt 中显式引用：`请主要参考文档1回答`
- 分隔符：用明确的分隔符区分不同来源的信息

**本质理解**：Lost in the Middle 的根因是 Attention 机制的分布不均匀——位置靠前和靠后的 token 天然获得更多注意力权重。上述方案都是在工程层面缓解这个问题，而不是从模型层面根治。随着模型上下文处理能力的提升（如 Claude 的 200K 上下文），这个问题在缓解但未消失。

**差距在哪**：新手只知道”放前面”这一个策略。高手从信息布局、检索控制、上下文压缩、结构化标记四个层面系统解决，且理解问题的本质是 Attention 分布不均。面试官考的是你对长上下文处理的工程经验和对底层机制的理解。

---

### Q：什么是上下文缓存（Prompt Caching）？它在 Agent 系统中有什么价值？

> 来源：蚂蚁 AI应用开发 二面

**新手答**：”就是把常用的 Prompt 缓存起来，下次直接用。”

**高手答**：

上下文缓存（Prompt Caching）是模型服务层面的优化技术。核心原理：当多次 API 调用共享相同的 Prompt 前缀时，模型服务端可以**缓存前缀部分的 KV Cache**，后续请求只需要计算新增的部分，大幅降低延迟和成本。

**在 Agent 系统中的价值**：

Agent 的典型调用模式是：每轮对话都带上完整的 System Prompt + 工具定义 + 历史对话。其中 System Prompt 和工具定义在整个会话中不变，可能占 2000-5000 token——每次都重新计算这部分是巨大的浪费。

| 场景 | 不用缓存 | 用缓存 | 节省 |
|------|---------|-------|------|
| 10 轮对话 | 每轮处理完整 System Prompt | 第 2-10 轮跳过前缀计算 | ~40% token 成本 |
| 多用户相同 Agent | 每用户独立处理 | 跨用户共享前缀缓存 | 延迟降低 50%+ |

**工程实践**：

1. **前缀稳定性**：缓存命中要求前缀**逐字节一致**。动态注入的内容（如用户画像、时间戳）不能放在 System Prompt 开头，否则前缀不匹配导致缓存失效。正确做法：静态内容（身份、规则、工具定义）放前面，动态内容放后面

2. **缓存粒度**：Anthropic 的 Prompt Caching 以 block 为单位缓存，支持在请求中用 `cache_control` 标记缓存断点。OpenAI 的自动前缀匹配则不需要显式标记

3. **在 Agent 循环中的应用**：Agent 的 ReAct 循环每轮都在上下文末尾追加新的 Thought-Action-Observation，前缀部分（System Prompt + 历史轮次）保持不变——天然适合前缀缓存

**差距在哪**：新手把上下文缓存等同于”存 Prompt 字符串”。高手理解的是模型服务层面的 KV Cache 复用机制，且能说清楚在 Agent 系统中的适用场景（System Prompt 不变、工具定义不变）和工程约束（前缀必须一致）。面试官考的是你对模型调用成本优化的工程理解。

---

### Q：长周期对话（间隔数周后继续）如何管理历史？冷启动怎么做？

> 来源：淘宝闪购 Agent 一面

**新手答**：“把所有历史存数据库，下次全部加载到上下文。”

**高手答**：

长周期对话的核心挑战不是“存不存”，而是**间隔数周后如何用最少 token 恢复最相关的上下文**。全量加载既不现实（token 限制）也不必要（大部分历史已无关）。

**分层压缩策略**：

```text
近期（T < 1h）：  完整原文保留，无压缩
中期（1h < T < 24h）：段落级摘要，保留关键决策和结论
远期（T > 7d）：  关键事件 + 决策结果 → 结构化存入向量数据库
```

**冷启动流程**（间隔数周后的新会话）：

1. **检索相关历史**：基于新会话的首条消息，向量检索最相关的历史片段（Top-K，通常 K=3-5）
2. **注入 System Prompt**：将检索到的历史摘要作为背景信息注入 system prompt，格式如“上次对话关键信息：...”
3. **渐进补充**：如果用户引用了更早的上下文（“上次说的那个方案”），再按需检索补充

**关键设计决策**：

| 决策点 | 方案 | 原因 |
|-------|------|------|
| 压缩触发时机 | 会话结束时异步压缩 | 不影响实时交互体验 |
| 摘要粒度 | 按“话题段”而非固定长度 | 保持语义完整性 |
| 召回排序 | 时间衰减 × 语义相似度 | 既相关又新鲜的优先 |
| 冲突处理 | 历史结论 vs 当前输入冲突时，以当前为准 | 用户的最新意图优先 |

**和短周期对话管理的本质区别**：短周期靠滑动窗口就够了，长周期的核心是**压缩质量**——摘要不能丢关键信息，结构化存储不能丢决策上下文。压缩是一次性的（压坏了不可逆），所以远期存储要保留原文备查，结构化数据只是索引层。

**差距在哪**：新手的方案会撑爆上下文窗口或加载大量无关历史。高手展示了分层压缩（近/中/远三层策略）+ 语义冷启动（检索注入而非全量加载）的完整方案。面试官考的是你对“记忆 ≠ 存储，记忆 = 选择性遗忘 + 精准召回”这个核心认知的理解。

---

### Q：怎么判断当前用户的提问需不需要去检索长期记忆？

> 来源：淘天 Agent 开发

**新手答**：“每次都检索，反正多查一次也不慢。”

**高手答**：

每次都检索的方案在生产中有三个问题：**延迟增加**（向量检索 50-200ms）、**噪声引入**（召回不相关的历史信息污染上下文）、**成本浪费**（Embedding + 向量检索都要钱）。需要一个**检索路由判断**：

**判断框架**：

**实现方案**：

| 方案 | 做法 | 适用场景 |
|------|------|---------|
| **规则先行** | 关键词检测（「上次」「之前」「我的」「还记得」等）→ 触发检索 | 覆盖显式引用，零延迟 |
| **意图分类器** | 轻量分类器判断当前 query 是否需要历史上下文（二分类） | 隐式引用场景 |
| **相关性预判** | 用当前 query 和最近 N 轮对话的 embedding 算相似度，低于阈值才去检索长期记忆 | 平衡精度和成本 |

**关键工程细节**：即使判断「需要检索」，也不是把所有长期记忆都拉回来。检索后还要做**相关性过滤**——召回的记忆和当前 query 的相关度低于阈值就丢弃，避免注入过时或无关的历史信息。

**差距在哪**：新手的「每次都检索」在 Demo 里没问题，上线后会带来延迟、噪声和成本三重问题。高手设计了分层判断框架——先规则过滤，再意图分类，最后相关性预判——在检索价值和成本之间取得平衡。面试官考的是你对记忆系统「精准召回」而非「暴力检索」的工程认知。

---

### Q：怎么实现多轮对话过程中，根据用户反馈自我调整的功能？

> 来源：腾讯 AI 应用开发实习一面

**新手答**：「把用户反馈加到上下文里，模型自然就会调整。」

**高手答**：

把反馈丢进上下文只是最原始的做法——模型可能「看到了但没改」。真正的自我调整需要**显式检测反馈 → 识别调整方向 → 修改执行策略**三步闭环：

**反馈检测——区分显式和隐式**：

| 反馈类型 | 示例 | 检测方式 |
|---------|------|---------|
| 显式否定 | 「不对」「错了」「我问的不是这个」 | 关键词 + 意图分类 |
| 显式修正 | 「太长了」「简洁点」「换个角度」 | 解析用户期望的调整方向 |
| 隐式否定 | 重复相同问题、换个说法再问一次 | 检测 query 和上一轮 query 的语义重叠度 |
| 隐式满意 | 追问细节、在回答基础上继续深入 | 检测 query 是上一轮回答的自然延伸 |

**调整策略——按反馈类型走不同分支**：

**工程实现的三个关键点**：

1. **反馈不只是放进上下文，而是转化为结构化指令**：检测到「太长了」后，不只是在 Prompt 里加一句「用户说太长了」——而是把输出控制参数从 `max_tokens=1000` 调到 `max_tokens=300`，或在 System Prompt 里注入「本轮回答限制在 3 句话内」。结构化参数比自然语言提示更可靠

2. **累积偏好跨轮生效**：用户连续两次说「简洁点」，应该记住这个偏好并应用到后续所有回答，而非每轮重新判断。实现方式是维护一个**会话级偏好状态**：

```text
session_preferences = {
    "output_style": "concise",     // 用户反馈「太长了」后更新
    "detail_level": "overview",    // 用户反馈「不需要这么细」后更新
    "language_style": "technical"  // 用户追问技术细节后推断
}
```

3. **隐式反馈的检测阈值**：用户重复提问不一定是不满意——可能是换了个角度。判断标准是**语义重叠度 + 是否有新约束**：重叠度高且没有新约束 → 上一轮回答不满意，换策略；重叠度高但加了新约束 → 正常追问，基于上一轮结果继续

**差距在哪**：新手以为「放进上下文模型就能调整」——这依赖模型的隐式理解，不可控。高手把反馈处理拆成检测→分类→结构化调整三步，用显式参数控制而非依赖模型自行理解，且区分了会话级偏好和单轮调整。面试官考的是你对多轮对话系统**可控性**的理解——不是「模型能不能做到」，而是「你怎么保证它每次都做到」。

---

### Q：基于滑动窗口对最近 N 轮进行摘要时，是将之前摘要和新摘要合并还是分别保留？各自适合什么场景？

> 来源：快手 AI应用开发 一面

**新手答**：“合并成一条摘要就行，省空间。”

**高手答**：

这是一个经典的摘要策略选型问题。两种方案本质上是**信息密度和时序保留**之间的权衡：

| 维度 | 合并式摘要（Rolling Summary） | 分段式摘要（Segmented Summary） |
|------|---------------------------|-------------------------------|
| 做法 | 每次新内容到来时，将旧摘要 + 新对话一起重新生成一份更新的单一摘要 | 每段独立生成摘要，按时间线保留多份摘要 |
| Token 占用 | 始终只占一份摘要的空间（固定大小） | 随时间线性增长（每段一份） |
| 时序信息 | 丢失——无法区分“先说了什么、后说了什么” | 保留——每份摘要带时间标记，时序清晰 |
| 信息衰减 | 早期信息经过多次压缩后逐渐丢失细节 | 每段独立压缩，早期段落精度不衰减 |
| 适合场景 | 单一目标的稳定任务（客服工单、单次购买流程） | 话题频繁切换、需要回溯的长对话（技术咨询、项目讨论） |

**工程实现的关键细节**：

```text
合并式实现：
  prompt = f"将以下旧摘要和新对话合并为一份更新的摘要：\n旧摘要：{old_summary}\n新对话：{new_turns}"
  → 输出一份新摘要，替换旧摘要

分段式实现：
  每 N 轮生成一份独立摘要，存入 list：
  summaries = [
    {time: T1, summary: "讨论了预算问题..."},
    {time: T2, summary: "切换到技术选型..."},
    {time: T3, summary: "确认了部署方案..."},
  ]
  检索时按时间或语义相关度选择注入哪几段
```

**混合策略**（生产推荐）：对最近 2-3 段用分段式保留时序细节，更早的段落合并为一份全局摘要。兼顾 token 预算和时序信息保留。

**差距在哪**：新手不区分两种策略直接选合并。高手理解两者的 trade-off——合并省 token 但丢时序，分段保时序但占空间——并根据任务特征选型，生产中用混合策略取长补短。面试官考的是你对摘要压缩策略的精细化设计能力。

---

### Q：如果让你设计一个三层记忆机制，你会如何设计？从整体架构和具体压缩方法进行描述。

> 来源：快手 AI应用开发 一面

**新手答**：“短期记忆、长期记忆、向量数据库，三层。”

**高手答**：

三层记忆的设计核心不是“分几层存”，而是**每层的信息密度、访问模式和压缩触发机制**的协同设计：

**整体架构**：

**三层详细设计**：

| 层级 | 内容 | 存储 | 压缩方法 | 触发时机 |
|------|------|------|---------|---------|
| 工作记忆 | 最近 3-5 轮原始消息 | 内存/Redis | 无压缩 | 每轮对话自动滚动 |
| 短期记忆 | 超出窗口的对话 → 结构化摘要 | 数据库（JSON） | LLM 提取关键决策 + 约束条件 + 未解决问题 | 工作记忆窗口满时 |
| 长期记忆 | 用户偏好、事实性知识、历史决策模式 | 向量数据库 + KV | 实体提取 → embedding → upsert | 会话结束时异步提取 |

**压缩方法的具体实现**：

**工作记忆 → 短期记忆**（结构化压缩）：

```text
压缩 Prompt：
  "从以下对话中提取：
   1. 用户的关键约束（预算、时间、偏好）
   2. 已确认的决策
   3. 未解决的问题
   输出 JSON 格式。"

输入：5 轮原始对话（~2000 token）
输出：结构化摘要（~200 token）
压缩率：~10:1
```

**短期记忆 → 长期记忆**（语义提取）：

```text
提取 Prompt：
  "从以下会话摘要中提取可跨会话复用的信息：
   - 用户偏好（永久有效）
   - 事实性信息（身份、联系方式）
   - 行为模式（购买习惯、沟通风格）"

提取结果 → embedding → 向量库 upsert（按 user_id 分区）
```

**检索融合**：每轮对话组装上下文时，三层信息按优先级融合注入：

```text
上下文 = System Prompt
       + 长期记忆检索结果（相关偏好和事实）
       + 短期记忆摘要（当前会话进展）
       + 工作记忆原始对话（最近几轮）
       + 当前用户输入
```

**差距在哪**：新手只列了三层名字没有设计细节。高手对每层的内容、存储、压缩方法、触发时机都给出了具体方案，且设计了层间的数据流转和融合机制。面试官考的是你能不能把“三层记忆”从概念落地为一个可实现的工程方案。

---

### Q：你的向量记忆库是如何更新用户画像的？

> 来源：快手 AI应用开发算法 一面

**新手答**：“用户说了新的偏好就存进去。”

**高手答**：

用户画像更新不是简单的覆盖写入——新信息可能和已有画像矛盾、补充或过时。核心是**增量提取 + 冲突解决 + 时间衰减**三步机制：

**更新流程**：

**三种冲突场景的处理**：

| 冲突类型 | 示例 | 处理策略 |
|---------|------|---------|
| 新增补充 | 已有“喜欢日料”，新增“对花生过敏” | 直接追加新维度 |
| 矛盾覆盖 | 已有“在北京”，新说“搬到上海了” | 新记录设为当前有效，旧记录标记过期但保留（支持溯源） |
| 重复强化 | 第三次提到“不吃辣” | 该偏好的置信度 +1，检索时权重更高 |

**工程实现要点**：

1. **异步提取**：对话结束后触发异步任务（不阻塞主链路），用小模型提取结构化偏好
2. **向量化存储**：每条偏好/事实独立 embedding，而非整个画像一条向量。粒度越细，检索时越精准
3. **时间权重**：检索时加时间衰减——`score = similarity × decay(time_elapsed)`，最近的偏好优先
4. **定期清理**：低置信度 + 长时间未被检索命中的记录，定期降权或归档

**实际存储结构**：

```text
user_profile_vectors:
  user_id: "u_12345"
  entries: [
    {text: "偏好日料", embedding: [...], confidence: 3, updated_at: "2026-04-01", source: "session_89"},
    {text: "对花生过敏", embedding: [...], confidence: 1, updated_at: "2026-05-10", source: "session_102"},
    {text: "居住在上海", embedding: [...], confidence: 1, updated_at: "2026-05-12", source: "session_105",
     supersedes: "entry_old_beijing"}
  ]
```

**差距在哪**：新手把画像更新当成简单的”存进去”。高手设计了增量提取 + 冲突检测 + 时间衰减的完整更新机制，处理了新增、矛盾、重复三种场景，且在工程实现上用了异步提取、细粒度向量化、定期清理等手段。面试官考的是你对用户画像这种持续演化的数据的工程化管理能力。

---

## Q：压缩过程中会丢失工具调用历史，导致模型重复调用工具，怎么解决？

> 来源：美团Agent开发（智能客服方向）二面

**新手答**：”压缩的时候保留所有工具调用记录不就行了。”

**高手答**：

这是上下文压缩的经典陷阱——摘要只保留语义，丢失了结构化的行为记录。解决方案：
1. **分区压缩策略**：将上下文分为”对话区”和”动作区”，对话区可摘要压缩，动作区（工具调用名+参数+结果摘要）保留结构化格式不压缩
2. **工具调用摘要表**：压缩时生成一个紧凑的”已完成动作清单”（tool_name + 核心参数 + 成功/失败），插入 system prompt 末尾
3. **去重指令注入**：在 system prompt 中加入规则：”以下工具已在本轮调用过且结果已获取：[列表]，请勿重复调用”
4. **调用指纹缓存**：维护 (tool_name, params_hash) 的短期缓存，Agent Runtime 层拦截重复调用

**差距在哪**：面试官考的是”你理不理解压缩是有损的，以及如何在有损中保留关键行为信息”。这道题把记忆和工具管理打通了。

---

## Q：记忆冲突怎么解决？比如用户前后说了不同的过敏信息

> 来源：美团Agent开发（智能客服方向）二面

**新手答**：”以最新的为准呗。”

**高手答**：
记忆冲突在智能客服/健康问诊场景极为常见。”以最新为准”会丢失关键历史，解决方案需要分层：

1. **冲突检测**：写入新记忆时，对同一实体字段做语义对比。检测到矛盾时标记为”待确认”状态，而非直接覆盖
2. **主动澄清**：检测到冲突后，Agent 应主动追问用户（”您之前提到对花生过敏，现在又说不过敏，请问以哪个为准？”），而不是静默处理
3. **时间戳 + 置信度**：每条记忆带时间戳和来源置信度（用户明确陈述 > 推断 > 第三方信息），冲突时优先级排序
4. **版本保留**：不删除旧值，保留历史版本链（类似 git log），支持回溯审计
5. **分域隔离**：不同来源的记忆分开存储（用户自述 vs 系统推断 vs 外部导入），冲突仅在同源内自动合并，跨源冲突需人工或模型仲裁

**差距在哪**：面试官要看你对”记忆不是只有一个值”的理解——生产级系统需要冲突检测+主动澄清+版本保留，而不是简单覆盖。这在医疗、金融等高风险场景尤为关键。

---

## Q：短期记忆压缩后，过了很长时间又需要当时完整信息怎么办？

> 来源：AI初创Agent开发实习

**新手答**：“那就别压缩呗，全保留。”

**高手答**：

这是记忆系统“有损压缩”的经典两难——压缩省 token 但丢细节。解决方案是分层存储：

1. **双写策略**：压缩后的摘要送入上下文供模型使用，但原始完整对话同时持久化到数据库/文件系统（不删除原文）
2. **按需回溯**：当模型需要历史细节时（如用户说“我之前第三轮提到的那个方案”），Agent 根据时间/关键词去原始存储检索完整内容，临时注入上下文
3. **摘要 + 指针**：压缩摘要中保留关键片段的“指针”（如 session_id + turn_id），需要时通过指针回查原文
4. **分级 TTL**：热数据（近期对话）保留完整，温数据（几天前）保留摘要+原文可查，冷数据（很久前）只保留摘要
5. **重要性标记**：压缩时对“含决策/承诺/关键事实”的对话轮次打标，这些永远保留完整版本

**差距在哪**：面试官要看你是否理解“给模型的上下文”和“系统持久化的完整记录”是两码事——上下文可以压缩，但原始数据不能丢。

---

## Prompt 长度 vs 内容对决策的影响

### Q：如何判断是 Prompt 内容影响了决策，还是 Prompt 太长导致注意力涣散影响了决策？

> 来源：淘天 AI Agent 暑期实习一面

**新手答**：“缩短 Prompt 试试？”

**高手答**：

这是一个因果归因问题——两种失效模式（内容误导 vs 注意力稀释）的表现类似（输出质量下降），但根因不同，解法也不同。需要设计对照实验来区分。

**实验设计方法：**

| 实验组 | 操作 | 预期 |
|--------|------|------|
| A（基线） | 短 Prompt + 核心指令 | 正常输出 |
| B（内容影响） | 短 Prompt + 核心指令 + 可能干扰的内容 | 如果 B 变差 → 内容本身干扰了决策 |
| C（长度影响） | 长 Prompt + 核心指令 + 无关但无害的填充文本 | 如果 C 变差 → 纯长度导致注意力涣散 |
| D（双因素） | 长 Prompt + 核心指令 + 可能干扰的内容 | 对比 B 和 C 判断哪个因素占主导 |

**判断标准：**
- **B 差而 C 不差** → 问题在内容本身（误导性信息干扰了模型推理）
- **C 差而 B 不差** → 问题在长度（Lost in the Middle 效应）
- **B 和 C 都差** → 双重影响，需要同时解决

**工程化诊断方法：**
1. **关键指令位置测试**：把同一条核心指令分别放在 Prompt 开头、中间、结尾，观察遵循率变化。如果中间明显差 → 注意力涣散问题
2. **注意力可视化**：用模型的 attention weight 分布看关键 token 是否被正确关注（需要开源模型支持）
3. **逐段消融**：逐步删除 Prompt 中的某些段落，观察哪段删除后输出质量提升 → 该段是干扰源

**差距在哪**：面试官考的是你对“模型行为诊断”的方法论。只说“缩短试试”是瞎猜，能设计出控制变量的对照实验并说出判断标准，说明你有科学化调优 Agent 的能力。

---

### Q：为什么要区分静态长期记忆和动态长期记忆？各自存什么？

> 来源：字节跳动 Agent 二面（Coding Agent）

**新手答**：“长期记忆就是把重要信息存起来，不用分那么细。”

**高手答**：

区分静态和动态长期记忆的根本原因是**更新频率和置信度完全不同**，混在一起存会导致两个问题：高频更新的数据冲刷掉稳定的事实，以及不同衰减策略无法精细化控制。

**静态长期记忆——变化极少、置信度极高的事实性信息**：

| 内容类型 | 示例 | 特征 |
|---------|------|------|
| 身份信息 | 用户名、公司、角色 | 几乎不变，一旦确认就固定 |
| 硬性约束 | 过敏信息、合规红线 | 绝不能被覆盖或衰减 |
| 系统规则 | 项目编码规范、架构约定 | 人工维护，变更走审批流程 |
| 工具能力描述 | 工具的功能边界和限制 | 随版本更新，但频率低 |

**动态长期记忆——会随时间演化、需要持续更新的偏好和行为模式**：

| 内容类型 | 示例 | 特征 |
|---------|------|------|
| 用户偏好 | “最近喜欢简洁风格”“倾向用 TypeScript” | 可能随时间改变 |
| 行为模式 | “每次都先跑测试再提交” | 从多次观察中归纳，有置信度 |
| 上下文习惯 | “习惯在下午处理复杂任务” | 统计规律，非绝对 |
| 历史决策 | “上次选了方案 A，原因是性能优先” | 有时效性，新决策覆盖旧决策 |

**为什么必须分开**：

**工程实现的关键差异**：

1. **查询方式不同**：静态记忆用精确键值查询（`user.allergy = "花生"`），动态记忆用语义检索（embedding 相似度）
2. **写入保护不同**：静态记忆写入需要高置信度确认（用户明确说“我对花生过敏”），动态记忆可以从行为中推断写入
3. **注入策略不同**：静态记忆每轮强制注入 System Prompt（因为永远相关），动态记忆按当前 query 的语义相关度选择性注入

**差距在哪**：新手把长期记忆当成一个“大桶”——什么都往里扔。高手区分了静态和动态两类，每类有独立的存储引擎、更新策略、衰减机制和注入逻辑。面试官考的是你对记忆系统“数据治理”的精细化认知——不同性质的信息需要不同的管理策略，混着管必然出问题。

---

### Q：每轮对话都触发长期记忆存储，用户记忆快速积累、存得过多怎么办？

> 来源：字节跳动 Agent 二面（Coding Agent）

**新手答**：“设个上限，满了就删最早的。”

**高手答**：

“删最早的”是最粗暴的策略——可能把用户三个月前说的“我对花生过敏”删掉，留下昨天的闲聊。问题的根源不是“存太多”，而是**没有准入控制和质量管理**。

**解决方案分四层**：

**第一层：写入准入控制——不是所有信息都值得存**

每轮对话结束后，用轻量模型做“记忆价值评估”：

| 条件 | 处理 | 示例 |
|------|------|------|
| 显式偏好/事实声明 | 高优先级存入 | “我不吃辣”“我在北京” |
| 反复出现的模式 | 中优先级存入 | 连续三次选了最便宜的 |
| 一次性任务上下文 | 不存 | “帮我写封邮件” |
| 寒暄/确认性回复 | 不存 | “好的”“谢谢” |
| 中间推理过程 | 不存 | Agent 的 chain-of-thought |

准入率控制在 20-30%——绝大多数对话不产生持久化记忆。

**第二层：写入时去重合并——同一信息不重复存**

用户说了 5 次“不吃辣”，最终只存一条，但置信度为 5——不是存 5 条占 5 倍空间。

**第三层：定期淘汰——低价值记忆主动清理**

不是按时间删，而是按**综合分数**淘汰：

```text
保留分数 = 重要性权重 × 访问频率 × 时间衰减系数

  - 重要性高 + 近期被检索命中 → 分数高，保留
  - 重要性低 + 长期未被检索 → 分数低，淘汰候选
  - 事实性记忆（过敏、身份）→ 永不淘汰（白名单）
```

定时任务（如每周一次）扫描用户记忆库，淘汰分数最低的 N% 记忆。淘汰不是物理删除，而是归档到冷存储——万一误删还能恢复。

**第四层：记忆抽象提升——用 Reflection 压缩细节**

当同一主题的记忆积累过多时，触发 Reflection：

```text
原始记忆（10 条）：
  - "第一次选了 Python"
  - "第二次又用 Python"
  - "问了 Python 装饰器"
  - "问了 Python 异步"
  - ...

Reflection 产出（1 条）：
  "用户是 Python 重度使用者，关注高级特性（装饰器、异步），
   代码风格偏好函数式。"
```

10 条细节记忆被 1 条高级认知替代——信息密度提升 10 倍，存储空间释放 90%。

**差距在哪**：新手只想到容量限制和粗暴删除。高手从准入控制、去重合并、智能淘汰、记忆抽象四层构建了完整的记忆容量治理方案。面试官考的是你对“记忆是需要主动管理的资产”这个核心认知——不管理的记忆会变成垃圾堆，管理好的记忆才是竞争力。

---

## Q：已进行 10 轮并做了总结，第 11 轮开始时，总结怎么处理？是重算前 11 轮还是叠加？

> 来源：月之暗面/Agent开发岗

**新手答**：“全部重新总结一遍。”

**高手答**：

正确做法是**增量叠加，而非全量重算**。

第 10 轮结束时已有摘要 S_1-10（约 300 token），第 11 轮新对话 D_11（约 800 token），直接将 S_1-10 + D_11 拼在一起发给模型——不重新处理前 10 轮的原始对话。

**为什么不重算**：

- 全量重算的时间复杂度是 O(n^2)——每新增一轮都要重处理所有历史
- Token 消耗是增量方式的 10 倍以上——重算意味着每轮都把全部原始对话喂一遍
- 在延迟敏感场景（对话系统）中，额外几秒的等待直接影响体验

**关键陷阱**：当 S_1-10 + D_11 又到达阈值时，第 12 轮触发新一次总结——此时对 S_1-10 + D_11 做一次新总结生成 S_1-11，然后丢弃旧的 S_1-10。这本质是一棵**分层摘要树**，每一层是对上一层的压缩：

**工程实现要点**：
- 摘要生成用异步任务，不阻塞当前轮的响应
- 每次新摘要生成后，保留旧摘要的引用（方便调试和回溯）
- 设置摘要的最大嵌套层数（通常 3-4 层），防止“摘要的摘要的摘要”信息损失过大

**差距在哪**：面试官通过连续追问考察你对摘要策略的工程实现细节——是真写过还是只看过文章。全量重算暴露的是“没算过复杂度”，增量叠加+分层摘要树暴露的是“真正实现过这个系统”。

---

## Q：前 10 轮都变成了总结，之前的原始上下文就不需要了吗？

> 来源：月之暗面/Agent开发岗

**新手答**：“不需要了，已经总结过了。”

**高手答**：

原始上下文**必须持久化存储**，但不发送给模型。

发给模型的是压缩后的摘要 + 最近几轮原始对话，而完整的原始数据保存在后端存储中。两者的关系是：

```text
发给模型的上下文 = 压缩摘要 + 最近 N 轮原始对话
持久化存储 = 所有原始对话（完整保留，带时间戳和 session_id）
```

**存储原始数据的三个用途**：

| 用途 | 场景 | 为什么摘要不够 |
|------|------|--------------|
| 审计溯源 | 模型给出错误答案，需要回放“它当时看到了什么” | 摘要丢失了细节，无法精确还原上下文 |
| 摘要重建 | 发现摘要质量差（丢了关键约束），需要重新生成 | 没有原始数据就只能从零积累 |
| 长期记忆检索 | 用户某句关键指令在摘要里被压缩丢了，但需要找回 | 向量检索原始对话能找到被摘要遗漏的信息 |

**工程实现**：

```text
写入路径：
  用户消息 → 实时写入持久化存储（PostgreSQL/MongoDB）
           → 同时进入内存中的 Buffer Memory
           → Buffer 满时触发摘要压缩 → 摘要存入 Summary 层

读取路径（正常对话）：
  上下文 = System Prompt + Summary 摘要 + Buffer 最近几轮

读取路径（回溯场景）：
  按 session_id + 时间范围查询原始对话 → 临时注入上下文
```

**存储选型**：
- 对话原文存 PostgreSQL 或 MongoDB（需要按时间查询、按 session 过滤、支持全文搜索）
- 摘要向量存向量库（需要语义检索，如“用户之前提过什么偏好”）
- 两者互补：精确查找走关系数据库，模糊语义查找走向量库

**差距在哪**：面试官考的是对“信息不可逆丢弃”的认知——真正的系统设计不能只考虑模型侧。摘要是有损压缩，有损就意味着可能丢关键信息。持久化原始数据是兜底策略，确保任何时候都能“回到现场”。这和数据库设计中“永远不删原始日志”是同一个原则。

---

## Q：当用户对话零碎、跨轮次且意图发生跳跃时，如何结合上下文准确判断当前意图？

> 来源：某小厂FOSHO/AI应用开发二面

**新手答**：“用最近几轮对话判断意图。”

**高手答**：

意图跳跃的本质是：**用户心智模型是连续的，但表达是碎片化的**。用户脑中有一条清晰的思路，但说出来的话是断断续续、前后跳转的。只看最近几轮会误判——因为最新一轮可能是对三轮前某个话题的回溯。

**三层意图识别策略**：

| 层级 | 输入 | 输出 | 作用 |
|------|------|------|------|
| 即时意图 | 当前轮用户消息 | 关键词 + 初步意图分类 | 捕捉最新表达 |
| 会话意图 | 最近 3-5 轮对话 | 主题聚类 + 是否跳跃判断 | 判断延续 vs 跳转 |
| 长期意图 | 用户历史画像 | 稳定偏好 + 高频需求 | 消歧和补全 |

**跳跃检测机制**：

计算当前 query 与上一轮 query 的语义相似度：
- 相似度 > 0.7 → 延续当前话题，正常处理
- 相似度 0.3~0.7 → 灰区，结合历史判断是否是对更早话题的回溯
- 相似度 < 0.3 → 判定为跳跃，触发“话题重置”

**跳跃后的处理**：
- 清空工作记忆（当前话题的中间状态）
- 保留用户画像（长期偏好不受话题切换影响）
- 检查是否是对历史话题的回溯——如果是，从话题记忆中恢复该话题的上下文

**编程/Agent 场景的特殊处理**：

用户可能在多个文件间跳转，但底层任务是同一个（比如“修复一个跨模块的 bug”）。这时候需要维护的是**任务栈**而非话题栈——文件切换不是意图跳跃，而是同一任务的不同步骤。

```text
话题栈（对话场景）：聊天气 → 聊餐厅 → 回到天气 → 各话题独立
任务栈（Agent 场景）：改文件A → 改文件B → 跑测试 → 同一任务的不同步骤
```

**差距在哪**：面试官考的是对“意图不连续”这个真实工程难题的解题思路，不是教科书式的意图分类。只看最近几轮会在跳跃时误判，只靠语义相似度会在“同一任务不同步骤”时误触跳跃检测。三层融合 + 场景化判断才是完整方案。

---

## Q：session 里的临时文件存主服务还是 skill 进程服务，要不要删，什么时候删？

> 来源：阿里淘天/Agent开发一面

**新手答**：“存主服务，session 结束就删。”

**高手答**：

临时文件应该存在 **skill 进程侧**（谁生产谁管理），主服务只保留文件引用（URI/路径）。

**存储位置的设计原则**：

| 决策 | 方案 | 原因 |
|------|------|------|
| 存哪里 | skill 进程本地 | ① 避免主服务成为 IO 瓶颈 ② skill 进程重启时可以清理自己的垃圾 ③ 多 skill 并行时避免命名冲突 |
| 主服务存什么 | 只存文件引用 | URI/路径 + 过期时间，按需拉取内容 |
| 命名空间 | `/tmp/{session_id}/{skill_id}/` | 天然隔离不同 session 和 skill 的文件 |

**删除策略（三级）**：

| 级别 | 删除时机 | 适用对象 | 示例 |
|------|---------|---------|------|
| 即时删除 | skill 执行完、结果回传后 | 中间产物 | 格式转换的临时文件、解压缩的中间目录 |
| 延迟删除 | session 超时后（TTL 30min） | session 级资源 | 用户上传附件的解析结果、临时生成的图表 |
| 保留不删 | 永不自动删除 | 跨 session 资源 | 用户长期记忆文件、持久化配置 |

**工程注意点**：

1. **命名空间隔离**：`/tmp/{session_id}/{skill_id}/` 确保多 session、多 skill 并行不冲突
2. **进程异常退出兜底**：skill 进程 crash 后临时文件不会自动清理——靠 cron job 定时扫描 `/tmp/` 下超过 TTL 的目录并清理
3. **磁盘满报警**：临时文件积累可能撑满磁盘，设置报警阈值在 80%，触发时强制清理所有过期文件
4. **大文件特殊处理**：超过阈值（如 100MB）的临时文件不走本地磁盘，直接走对象存储（S3/OSS），skill 只拿到下载链接

**差距在哪**：面试官考的是微服务架构下的资源生命周期管理能力——看似小问题，但反映系统设计功底。“存主服务+session 结束删”有两个问题：主服务变成 IO 瓶颈，以及 session 异常断开时临时文件变成孤儿。skill 侧管理+分级删除+cron 兜底才是生产级方案。

---

## Q：Agent 做上下文压缩后，如何验证没有破坏当前任务？

> 来源：Coding Agent 面经/本地 Coding Agent

**新手答**：“压缩后让模型检查一下摘要是否完整。”

**高手答**：

不能用同一个模型凭感觉评价自己的摘要，而要先定义任务不变量：用户硬约束、当前计划与完成状态、文件和符号引用、工具调用结果、未解决错误、权限边界。压缩前后分别抽取这些结构化字段并做一致性校验。

验证分三层：

1. **结构校验**：必填约束、待办项、文件版本和 checkpoint 是否齐全。
2. **语义校验**：用 NLI 或独立 Judge 检查摘要是否遗漏、矛盾或新增事实。
3. **行为回放**：在隔离环境用压缩上下文执行下一步，比较工具选择、参数和测试结果。

原始历史不能立即删除，应保留可寻址的冷存储和 evidence id。校验失败时回退到上一版摘要，按缺失字段增量重压缩；高风险任务则宁可减少压缩比例，也不丢弃原始证据。

**差距在哪**：新手只做主观摘要检查，高手把“没破坏任务”定义为可验证的不变量，并用结构、语义、行为三层验证。面试官考的是上下文压缩能否安全进入生产链路。

---

## Q：大体积工具结果落盘后，为什么还要返回预览？预览内容应该如何选择？

> 来源：小红书 Agent 岗一面

**新手答**：“把结果开头截一段给模型，剩下的保存到文件。”

**高手答**：

“预览 + 路径”解决的是两个不同问题：路径保存**完整、可追溯的证据**，预览提供**下一步决策所需的最小信息**。如果只返回路径，模型不知道结果是否成功、文件是什么格式、是否值得继续读取；它往往会盲目追加一次读文件调用，增加延迟和 token。预览还能暴露错误页、空结果、字段结构和截断状态，让模型立刻决定重试、过滤还是继续。

但预览不能固定取前 N 行。日志的异常可能在尾部，搜索结果的关键命中可能在中段。更合理的是按工具类型生成**结构化采样**：

- 通用元数据：总字节数、行数、格式、生成时间、校验值和完整路径；
- 头尾采样：同时返回开头和结尾，日志默认偏向尾部；
- 关键片段：围绕错误码、查询命中、最高相关度记录返回上下文；
- 结构摘要：JSON 返回 schema 和代表性记录，表格返回列名、统计和异常行；
- 明确截断：标注省略范围，并提供按行号、游标或查询条件继续读取的方法。

预览应由工具适配器按结果语义生成，而不是让 LLM 任意截断。敏感字段在预览和落盘文件中都要按权限脱敏。

**差距在哪**：高手把预览视为“决策索引”，不是完整结果的随意开头；能根据数据价值分布选择头、尾、命中片段和统计摘要。

---

## Q：跨会话记忆如何从对话中提取？哪些信息值得写入长期记忆？

> 来源：小红书 Agent 岗一面

**新手答**：“每轮让 LLM 总结一下，然后存进向量数据库。”

**高手答**：

跨会话记忆写入应是独立管线，而不是把整段聊天原样长期保存：

```text
会话事件 → 候选提取 → 类型分类 → 价值/风险判定
        → 去重与冲突检测 → 用户确认（必要时）→ 结构化写入
```

候选信息通常分为：稳定用户事实、长期偏好与沟通风格、持续项目约定、明确纠正、可复用环境事实。临时任务进度、一次性验证码、模型猜测、敏感数据和容易重新获取的信息默认不写入。

LLM 负责从自然语言中提取候选和证据片段，输出受 JSON Schema 约束的字段，如 `type/content/evidence/confidence/scope/ttl`；系统规则再做硬过滤。写入前按实体键和语义相似度去重，发现“喜欢辣”和“不吃辣”这类冲突时保留时间与来源，不直接覆盖。高敏感或低置信度记忆要求用户确认，且应支持查看、纠正和删除。

检索时还要基于当前任务做相关性、时效性、可信度和权限过滤。能被存下来不代表每轮都应注入上下文。

**差距在哪**：新手只有“LLM 摘要 + 向量库”。高手说明了候选提取、规则门禁、证据、冲突、生命周期和可治理性。

---

## Q：如何用 Prompt 提取用户风格偏好？风格偏好应包含哪些内容？

> 来源：小红书 Agent 岗一面

**新手答**：“让模型总结用户喜欢什么风格。”

**高手答**：

风格偏好应描述**稳定、可执行且不越权的交互约束**，例如：语言、称呼、结论与解释顺序、详略程度、语气、格式、代码风格、文件交付方式，以及用户明确反感的表达。它不应包含人格臆测、情绪诊断或从一次对话推断出的永久标签。

提取 Prompt 可以约束为：

```text
你是用户偏好提取器。仅提取用户明确表达，或在多次交互中稳定出现的沟通与交付偏好。
不要提取临时任务要求、敏感信息、人格推断或模型自己的猜测。
每条输出：category、preference、evidence、confidence、scope、ttl。
如果证据不足，返回空数组；不得为了完整而补全。
```

工程上还应增加三道门：单次隐含行为只形成低置信度候选；用户的明确纠正优先级最高；新偏好与旧偏好冲突时按作用域和时间处理，而不是无条件覆盖。注入上下文时改写成简短声明，例如“用户偏好结论优先、少解释”，不要回放原始私密对话。

**差距在哪**：面试官在看你是否能把“风格”变成带证据、置信度、作用域和生命周期的数据，而不只是写一句宽泛 Prompt。

---

## Q：大模型生成会话摘要时，如何避免摘要内容污染用户偏好？新结论推翻旧结论时怎么保留？

> 来源：百度内容营销与广告日常实习一面（2026-08-12）

**新手答**：“把历史对话交给模型总结，用户说了新偏好就覆盖旧偏好。”

**高手答**：

问题的根因是把**任务摘要**和**用户偏好**混在同一段自由文本里。摘要里的一次性要求可能被误写成长期偏好；模型自己的归纳也可能被当成用户事实。生产系统应分槽存储：

```text
session_summary：当前目标、已完成步骤、未解决问题
explicit_preferences：用户明确表达的稳定偏好
temporary_constraints：仅当前任务生效的约束
facts_with_evidence：事实 + 来源 turn_id + 时间
conflicts：新旧结论、作用域、裁决状态
```

写入时先做证据门禁：只有用户明确表达，或多次稳定出现且达到置信度阈值的行为，才形成偏好候选；模型摘要中推断出的内容不能直接升级为偏好。读取时按**当前轮明确指令 > 当前任务约束 > 已确认长期偏好 > 模型推断**排序。

新结论推翻旧结论时不要物理覆盖，而是做版本化追加：旧记录标记 `superseded`，保留 `valid_from`、`valid_to`、`evidence_turn_id` 和被哪条新记录替代。这样当前推理只注入生效版本，审计和误判恢复仍能回看历史。若新旧说法作用域不同，例如“这次用 Java”与“平时偏好 Python”，则分别保存在 task 和 global scope，不视为冲突。

摘要生成后再做三类校验：结构字段完整性、NLI 矛盾检测、关键任务回放。校验失败就回退上一版摘要并保留原始对话指针，不能让有损摘要成为唯一事实源。

**差距在哪**：新手把摘要当成一段可反复覆盖的文本。高手将摘要、偏好、临时约束和事实分离，用证据、作用域和版本链解决污染与冲突。面试官考的是记忆系统能否审计、纠错和回滚。

---

## Q：金融 Agent 执行股价提醒等定时任务时，应该携带哪些历史上下文？

> 来源：顺极 Agent 开发二面（2026-08-23）

**新手答**：“把创建任务时的对话历史一起存下来，触发时再恢复。”

**高手答**：

定时任务应保存经过确认的结构化契约，而不是整段聊天：标的、阈值、方向、有效期、时区、通知渠道、频率、权限和创建时引用的规则版本。触发时加载当前行情、任务契约和仍然有效的用户偏好；闲聊、过期市场判断和创建时的临时推理不应自动带入。

历史可分三类：执行必需的事实进入任务状态；稳定偏好进入长期记忆并带来源、更新时间和撤销入口；原始对话只作为审计证据按需读取。若规则、权限或风险等级已变化，应重新确认，而不是沿用旧上下文执行。每次触发记录使用了哪些版本和证据，防止“历史语义漂移”造成错误提醒或交易副作用。

**差距在哪**：新手把聊天记录当任务状态，高手区分契约、偏好、实时证据和审计原文。面试官考的是长生命周期任务如何避免过期上下文污染。

---

## Q：上下文预算不足时，如何按任务依赖压缩，而不是按时间删除旧消息？

> 来源：腾讯互娱全栈开发（AI）二面（2026-08-13）

**新手答**：“保留最近几轮，把更早内容做摘要。”

**高手答**：先把上下文拆成目标、硬约束、决策、证据、工具结果、副作用状态和待办，并建立当前计划对这些节点的依赖。优先保留高依赖、高可信、与未完成步骤相关的信息；已否决方案只留结论和原因，大工具结果转为带来源的结构化事实。系统规则、权限和已发生副作用不得由模型摘要。压缩后用执行日志校验“已完成/未完成”和关键约束是否一致。

**差距在哪**：新手按消息年龄压缩，高手按任务因果关系管理工作集。

---

## Q：云端 Coding Agent 的容器迁移或重启时，如何恢复会话上下文、工作区和进行中的任务？

> 来源：腾讯 WXG 微信读书一面（2026-08-24）

**新手答**：“把聊天记录和代码目录挂载到持久卷，容器启动后继续运行。”

**高手答**：不能把容器当状态源，也不能把“恢复”简化为重新加载聊天记录。需要把三类状态分开持久化：会话层保存目标、约束、计划和关键证据；工作区层保存基线 commit、已应用 patch、未跟踪文件清单和依赖锁；执行层保存步骤状态、工具调用幂等键、进程/测试结果和副作用记录。大文件进对象存储，元数据和事件日志进入外部控制面，容器本地盘只作为可丢弃缓存。

每个安全步骤结束后写 checkpoint，并用单调递增的事件序号或版本号把三类状态关联起来。迁移时先将旧实例置为 draining，停止领取新步骤，等待当前原子操作完成或标记为状态未知，再刷新工作区快照并释放租约。新实例通过 fencing token 获取唯一执行权，按“恢复工作区 → 校验版本与依赖 → 加载结构化任务状态 → 查询未知副作用终态 → 继续未完成步骤”的顺序恢复，避免两个容器同时执行。

恢复后必须校验仓库 HEAD、文件哈希、模型/Prompt/工具 schema 版本和密钥权限。对于写文件、提交代码、创建 PR 等操作，使用幂等键和结果查询；不能看到上次没有成功响应就盲目重放。无法安全续跑的 shell 进程应终止并从最近可验证节点重建，同时向用户说明丢失的瞬时状态。

**差距在哪**：新手只有“持久卷 + 聊天记录”。高手区分会话、工作区和执行状态，用 checkpoint、租约、fencing、幂等和恢复校验保证一致性。面试官考的是有状态 Agent 在无状态容器基础设施上如何做到可恢复且不重复产生副作用。

---

## Q：按大纲分章节生成长文时，如何维持跨章节连续性与事实一致性？

> 来源：成都 Agent 实习面经（2026-02-10）

**新手答**：“每次生成新章节时，把大纲和前一章一起放进上下文，最后再让模型通读润色。”

**高手答**：

只携带前一章只能维持局部衔接，无法保证第一章定义的术语、第三章引用的数据和第十章的结论一致。更可靠的方案是把长文生成建模为**带外部状态的分阶段写作任务**，把正文和事实源分开管理。

生成前先建立版本化的 `document_spec`：读者、目标、语气、总字数、章节大纲、每章输入输出、禁止事项和验收条件。再维护一份结构化“写作账本”：

```text
glossary：术语、缩写和统一译名
facts：事实、数值、时间、来源和可信状态
claims：已提出的核心论点及证据
entities：人物、系统、对象及固定属性
decisions：已确定的写法与被否决方案
open_loops：待解释概念、伏笔和跨章节引用
chapter_summaries：每章已覆盖内容与状态增量
```

每章生成时不应全量回灌旧正文，而是输入全局契约、本章大纲、不可变事实、上一章的衔接摘要，以及按当前章节目标检索出的历史片段。模型输出“章节正文 + 引用的 fact/claim ID + 状态增量”，编排器只在校验后合并增量。这样模型不能通过一段新摘要悄悄改写全局事实。

校验至少分三层：规则检查标题层级、篇幅、术语和交叉引用；用 NLI 或独立 Reviewer 检查新章节与事实账本、已有结论是否矛盾；对数字、引用和关键事实回查原始证据。发现冲突时定位到具体 `fact_id` 或章节，不要让模型整篇自由重写。大纲确需调整时生成新版本，并重算受影响章节，而不是把新旧设定混在同一上下文里。

最后的全局审校负责消除重复、修复过渡和检查论证闭环，但它不是唯一防线。高风险事实、核心结论和跨章节改纲仍应设置人工门禁；否则 Reviewer 与生成器可能共享同一种误解，得到“文风统一但事实一致地错误”的长文。

**差距在哪**：新手靠扩大上下文和最终润色。高手把大纲、事实、论点和待办外置为版本化状态，用按需检索、状态增量和分层校验维持跨章节一致性，同时保留证据和可回滚能力。

---

## 这类题的答题模式

记忆与上下文题的核心是**多层次 + 产品思维**：

```text
1. Memory 不是一个组件，是一个多层系统——短期、中期、长期各有分工
2. 不要只说"存起来"，要说"存什么、怎么查、怎么融合"
3. 上下文管理的核心是"工程手段省 token"，而不是"换更大的窗口"
4. 模糊需求的处理思路是"先猜再问"，而不是"直接问"
5. 交互设计和技术方案同样重要——Agent 是用户产品
```

面试官听到“向量数据库”或“直接问用户”就知道你只想到了技术的一半。听到三段式记忆、NER 实体抽取、结构化摘要、先猜再确认，才会觉得你既懂技术也懂产品。

下一篇建议继续看：

- [评估与全局观：怎么量化 Agent 好坏、落地最大挑战](../05-eval-and-vision/index.html)
