跳到主要内容
SUN / 笔记
← 全部文章

智能体记忆面试速记

本页保留问答式复习材料;系统原理请阅读 上下文工程 与 智能体记忆系统。

1. 如何设计一个高效的 Agent 上下文维护方案?

参考口述答案:

核心思路是分层管理。我会把上下文分成三层:

  • 最上面是固定信息,比如系统角色、安全规则,一直放在 system prompt 里不变。
  • 中间是近期对话,保持完整原文,保证多轮连贯。
  • 更早的历史则定期让模型自己做摘要,用一两句话替换掉原始大段对话。

除此之外,真正重要的跨对话知识(比如用户偏好)会存到向量数据库,新会话开始时按需检索再注入上下文。这样既省 token,又不丢关键信息,很多框架比如 LangChain 的 ConversationSummaryBufferMemory 就是这个思路。

python
messages = [
    {"role": "system", "content": "你是专业助手,偏好表格回答。"},
    {"role": "user", "content": "[历史摘要] 前面聊了 Python 性能优化。"},
    {"role": "user", "content": "那具体怎么用 cProfile?"},
    {"role": "assistant", "content": "你可以这样导入..."},
]

### Token 超限时,把旧消息压缩为摘要
if token_count(messages) > 6000:
    old = messages[1:6]  # 跳过 system,取旧消息
    summary = llm.summarize(old)
    messages = [messages[0]] + [
        {"role": "user", "content": f"[历史摘要] {summary}"}
    ] + messages[6:]

2. 主流模型上下文长度

参考口述答案:

目前 GPT-4 o、GPT-4 Turbo 一般是 128 k token,Claude 3 系列 200 k,谷歌 Gemini 1.5 Pro 可以到 100 万甚至 200 万 token。国内 Kimi 主打 200 万字上下文,通义千问有 100 万 token 版本,DeepSeek-V 2 是 128 k。

虽然窗口越来越大,但有效注意力在中后段会衰减,而且长文本调用又贵又慢,所以上下文管理仍然是工程里的刚需。

3. 讲一下 Agent 中的“长短期记忆”

参考口述答案:

可以类比人:

  • 短期记忆就是当前对话窗口里的全部交互历史,存在内存或 Redis 里,会话结束就可丢弃。
  • 长期记忆是跨会话持久化的,通常存向量库或关系数据库。下次新对话时,根据当前问题去检索相关记忆,再拼进上下文。

所以短期记忆解决“这次聊得连贯”,长期记忆解决“下次见你还记得你”。

python
### 存储
memory_store.add(
    user_id="u1",
    content="用户喜欢表格回答",
    embedding=embed("用户喜欢表格回答"),
)

### 检索
query_emb = embed("怎么展示数据")
results = memory_store.search(user_id="u1", embedding=query_emb, top_k=3)
system_prompt += "\n已知用户偏好:" + results[0].content

4. 什么样的信息应该放在长期记忆,什么样的信息放在短期记忆?

参考口述答案:

  • 短期记忆放当前任务强相关的即时信息:用户刚问的问题、工具返回结果、中间推理步骤、临时状态。
  • 长期记忆放跨对话还有价值的东西:用户画像(喜好、身份)、历史任务总结、经验教训、用户主动告知的事实(如公司名、deadline)。

判断标准很简单:如果下次新对话时你还得知道这些,就应该进长期记忆。

5. 长期记忆与短期记忆的压缩方案

参考口述答案:

短期记忆压缩,常用摘要+滑动窗口:每隔 N 轮让模型把前一段对话总结成简短摘要,替换掉原始长消息;或者只保留最近 K 轮完整消息,更早的用一句话概括。

长期记忆压缩,更多靠结构化和去重:存的时候只保留核心信息和摘要;后台定期聚类去重,合并相似记忆,淘汰低价值信息。

6. 长期记忆需要保存的核心内容

参考口述答案:

我会重点保存这几类:

  1. 用户画像:身份、偏好、习惯、技能栈。
  2. 任务成果:完成过的目标、产出的文件、重要结论。
  3. 反思与教训:从失败中总结的经验。
  4. 用户明确告知的事实:比如服务器地址、项目节点。

存的时候一定会带上时间戳、重要性评分和类型标签,方便后续检索和过期清理。

python
memory_entry = {
    "id": "mem_001",
    "user_id": "u1",
    "type": "preference",  # preference / fact / lesson
    "content": "用户要求代码示例用 Python",
    "importance": 0.9,
    "created_at": "2026-07-17T10:00:00Z",
}
vector_db.upsert(memory_entry)

7. 如果要进行记忆压缩,通常有哪些方法?

参考口述答案:

常见方法有:

  • LLM 摘要法:让模型把长文总结成几句。
  • 关键信息提取法:抽取人物、事件、决策等结构化字段。
  • 滑动窗口法:只保留最近 N 条完整消息,其余用摘要。
  • 聚类去重法:把嵌入相近的记忆归为一类,只保留最有代表性的一条。
  • 遗忘曲线法:按重要性+最近访问时间打分,低分自动淘汰。实际系统一般组合使用,比如“摘要 + 滑动窗口 + 重要性过滤”。

8. 长期记忆的压缩触发条件是什么?是基于 Token 阈值还是基于语义重要性?

参考口述答案:

我会采用混合策略:

  • Token 阈值是硬底线:当上下文使用率达到 70%-80% 时,强制压缩短期记忆防止溢出。
  • 语义重要性是质量过滤:存储时就打分,只有重要性超过阈值的才存;记忆库超量时优先淘汰低分记忆。另外还会设时间触发,比如每天定时整理记忆库,合并重复、清理失效信息。阈值保底,重要性过滤,两者互补。

9. 当对话轮数很多,上下文窗口不足时,有哪些处理策略?

参考口述答案:

我会按优先级用这几招:

  1. 滑动窗口 + 摘要:保留最近几轮完整对话,更早的用摘要替代。
  2. 向量检索召回:把历史存进向量库,每轮只根据当前问题检索最相关的几句,不全量携带。
  3. 阶段性主动总结:任务阶段切换时,生成进度总结,然后重置上下文,只带总结继续。
  4. 分层处理:近期用原文,中期用摘要,远期靠检索。
  5. 小模型压缩:用便宜模型先做摘要,大模型读压缩版。
python
def compress_context(messages, keep_recent=6):
    if len(messages) <= keep_recent:
        return messages

    to_summarize = messages[:-keep_recent]
    summary = llm.invoke("总结以下对话要点:" + str(to_summarize))
    return [
        {"role": "system", "content": f"[历史摘要] {summary}"}
    ] + messages[-keep_recent:]

10. 如果用户的 Prompt 特别长,导致上下文窗口溢出,除了截断,你有哪些简化上下文的策略?

参考口述答案:

直接截断太粗糙,我会用这几个方式:

  • 摘要预处理:先用小模型把长 Prompt 压缩成结构化摘要,Agent 基于摘要工作。
  • 分块处理:把长文本切成几块分别提取关键信息,汇总后再放上下文。
  • 外部文件模式:长文本先存成文件,只把摘要和文件 ID 放上下文,需要细节时调“读文件”工具。
  • RAG 式检索:提前给长文本建好向量索引,只把最相关的片段放进上下文。

核心思路就是把长文本变成可检索的外部知识,而不是全塞窗口。

11. 多 Agent/多异步任务下,如何防止上下文污染?

参考口述答案:

防止污染关键是隔离。

  • 会话级隔离:每个 Agent 或任务有独立的 messages 列表,绝不共享。
  • 消息总线通信:Agent 之间通过结构化消息传递结果,不直接拼接聊天记录。
  • 记忆库分区:长期记忆按用户 ID 或 Agent ID 做命名空间隔离。
  • 来源标注:引用其他 Agent 信息时,明确标记“据 Agent-A 反馈…”,避免模型误以为是自己经历。

这样能从根本上避免信息串扰和幻觉扩散。

12. Agent 是怎么实现上下文记忆的?

参考口述答案:

大模型本身是无状态的,记忆全靠工程层维护。

简单说就是维护一个 messages 列表,每次请求把整个列表带上,模型就能“记得”之前说过什么。

长期记忆则是另一套:在对话开始时或需要时,从外部数据库检索与该用户相关的历史信息,注入到系统提示或消息列表开头。

本质就是:短期记忆靠“消息历史拼接”,长期记忆靠“外部检索+注入”。

13. 上下文管理是怎么做的,如何进行记忆?

参考口述答案:

我会做一个上下文管理器模块,负责:

  1. 维护当前会话消息列表。
  2. 监听长度,超阈值时生成摘要替换旧消息。
  3. 识别并提取重要信息,异步写入长期记忆库。
  4. 新会话初始化时,根据用户 ID 从长期记忆库检索相关记忆,拼入系统提示。

这样就形成了一个“感知 → 存储 → 检索 → 注入”的完整闭环。

14. 如何构建工具实现 memory 记忆,让大模型在长期对话中学习用户习惯?

参考口述答案:

我会给 Agent 配置一套记忆管理工具,比如 remember_info、recall_info、forget_info。

在系统提示里明确告诉模型:“当你发现用户说了以后可能需要的信息,请调 remember 存下来;回答前可以先调 recall 查看相关画像。”

这样模型就能在对话中自发学会并记住用户习惯,下次自动应用。

python
tools = [
    {
        "name": "remember_info",
        "description": "存储一条需要长期记忆的信息",
        "parameters": {
            "content": "string",  # 要记住的内容
            "category": "preference / fact / lesson",
        },
    },
    {
        "name": "recall_info",
        "description": "根据关键词检索相关记忆",
        "parameters": {"query": "string"},
    },
]

15. 对 Cursor 记忆管理机制的了解

参考口述答案:

Cursor 的记忆管理和聊天 Agent 不太一样,它更偏向项目级静态上下文。

主要通过 .cursorrules 文件存储编码规范、项目约定、常用指令,每次 AI 请求都会带上。同时它会自动索引项目代码,生成向量嵌入,当你提问时检索相关代码片段。

最近版本也加了全局 Memory 设置,能记住一些全局偏好,比如默认语言、代码风格。

核心是“规则 + 代码索引”,而不是动态的长短期对话记忆。

16. Memory 上下文记忆功能的处理逻辑

参考口述答案:

整体处理逻辑是一个循环:

  1. 存储:对话中识别到重要信息,生成记忆条目,计算嵌入,存入向量库。
  2. 检索:新会话开始或需要时,用当前意图做查询,搜索相关记忆。
  3. 注入:将检索到的记忆拼接进上下文。
  4. 维护:后台定期清理过时、低价值或矛盾记忆。

这个闭环跑通后,Agent 就能表现出不错的“记性”。

17. 如何进行记忆管理,怎么处理长上下文,怎么进行持久化,后续怎么读取和关联?

参考口述答案:

我会这样设计:

  • 短期上下文用 Redis 存消息列表,带会话 ID 和过期时间,读写极快。
  • 长上下文处理:超长时做摘要,保留近期完整消息,远期用摘要替代,仍放短期存储。
  • 长期记忆持久化:向量库存嵌入,关系库存元数据(用户 ID、时间、类型)。
  • 读取和关联:短期直接用会话 ID 取;长期用用户 ID + 问题嵌入做向量检索,按相似度和时间排序取 Top N 注入。
python
### 持久化长期记忆
def save_long_term(user_id, content, embedding):
    db.insert(
        "memories",
        {"user_id": user_id, "content": content, "embedding": embedding},
    )


### 读取
def load_relevant_memories(user_id, query_emb, top_k=5):
    all_mems = db.query(
        "SELECT * FROM memories WHERE user_id=?",
        user_id,
    )
    scored = sorted(
        all_mems,
        key=lambda m: cosine_sim(query_emb, m.embedding),
        reverse=True,
    )
    return scored[:top_k]

18. 你的向量记忆库是如何更新用户画像的?如何区分短期记忆和长期记忆?

参考口述答案:

画像更新我分两条线:

  • 实时小更新:当识别到画像类信息,直接增/改对应的画像记忆条目。
  • 定时大聚合:后台任务定期对同一用户的所有记忆做聚类和总结,提炼成一份精炼的“用户画像文档”。

区分短期和长期记忆很简单:短期记忆就是消息列表里的内容,存在 Redis,不向量化;长期记忆一定进向量库并标记 type: long_term,生命周期完全不同。

19. 记忆更新时能否精准替换指定片段,还是需要全量清空重建?

参考口述答案:

完全可以精准替换,不需要全量重建。

给每条记忆分配唯一 ID,更新时带上 ID 和新内容,后端找到对应记录,修改内容和嵌入向量,向量数据库大多支持 upsert 操作。

全量重建只在极少数情况使用,比如索引结构改变或出现严重逻辑冲突需要重新梳理时。

20. 存储时如果出现前后不一致的情况如何解决?

参考口述答案:

矛盾有两种,处理方式不同:

  • 随时间更新(如“用 Python”→“用 Go”):以时间戳为准,新覆盖旧,因为用户偏好可能改变。
  • 逻辑直接冲突(如同时存“喜欢详细”和“喜欢简洁”):检索时把矛盾两条都提示给模型,让模型反问用户确认。

每条记忆加版本号和时间,冲突时保留历史版本但标记失效,做到可追溯。

21. 多轮对话的实现方案

参考口述答案:

多轮对话本质就是把历史消息带回去。大模型无状态,所以我们维护一个 messages 数组,按 user/assistant 交替存储,每次请求全量发送。

持久化方面,把数组存到 Redis 或数据库,用户下次回来加载出来就能无缝续聊。

再配合上下文压缩和长期记忆机制,就能支撑超长多轮对话而不会爆窗口或丢失重要信息。

python
session = load_session(user_id)  # 从 Redis/DB 恢复
messages = session["messages"]
user_input = "帮我看看这个报错"
messages.append({"role": "user", "content": user_input})

response = llm.chat(messages)
messages.append({"role": "assistant", "content": response})
save_session(user_id, messages)

作者:爱吃肉的棒男孩 1
链接:https://www.nowcoder.com/
来源:牛客网

短期记忆 vs 长期记忆如何配合

核心思路

  • 短期记忆(Working Memory):当前任务上下文(对话历史、当前计划、工具调用结果)
  • 长期记忆(Long-term Memory):跨任务沉淀(用户偏好、知识库、历史经验)

协作方式

分层设计

  • 短期记忆:放在 prompt / state(如 LangGraph state)
  • 长期记忆:放在向量数据库(如 FAISS / Milvus / Chromadb)

工作流程

  1. 用户输入 → 触发任务
  2. 从长期记忆中 检索相关信息(RAG)
  3. 注入到短期记忆(prompt)
  4. 推理 + 工具调用
  5. 重要信息写回长期记忆(可筛选)

工程关键点

  • 长期记忆不是全存,而是:
    • 用户偏好
    • 成功案例(few-shot)
    • 高价值知识
  • 短期记忆要控制长度(token budget)

来源拆分自:高德 Agent 研发面,记忆和评测问很细;以下保留原整理中的工程补充与校正。

如何设计 Agent 的记忆写入机制?

视频要点:旁路提取,而不是把所有对话都存进向量库

主对话模型继续服务用户,后台挂一个较便宜的小模型做异步记忆提取。视频以 8B 小模型为例,让它承担实体提取、分类和价值判断,从而降低主链路延迟与成本。

记忆是否准入,按三个维度判断:

维度 要问的问题 处理示例
持久性价值 下周或下次会话还能用到吗? “下周三去北京出差”应持久化;“刚才很小声”只进短期上下文或直接丢弃
结构化程度 是自由文本,还是明确的实体、属性和关系? “我和张三是同事”应抽成实体关系;普通对话可保留为文本记忆
个性化价值 能否帮助系统更懂用户? 反复要求“说人话、别啰嗦”可归纳为表达偏好,而不是机械保存每句原话

存储层按查询模式分工:

  • 向量库:保存可语义检索的文本、事件摘要和历史经验。
  • 图数据库 / GraphRAG:保存实体关系,支持关系约束和多跳查询。
  • 关系库或结构化 Profile:保存需要精确读写、去重、版本控制的事实与用户画像。
  • 冷日志:保留低频事件,设置 TTL 或衰减规则,不占用高成本热存储。

写入后还需要生命周期管理:

  • 按重要性、时效性、使用频率和置信度评分。
  • 合并重复记忆,发现新旧冲突时保留来源与版本,而不是简单覆盖。
  • 定期做 Reflection:把一周内的零散事件提炼为更高层洞察。
  • 对日志做衰减或归档;核心画像长期保存,但必须支持用户更正和删除。
flowchart LR
    A["用户对话"] --> B["旁路小模型:提取与分类"]
    B --> C{"持久性 × 结构化 × 个性化"}
    C -->|自由文本与经验| D["向量库"]
    C -->|实体与关系| E["图数据库"]
    C -->|精确事实与画像| F["关系库 / Profile"]
    D --> G["评分、去重、衰减与反思"]
    E --> G
    F --> G
    G --> H["按当前任务检索并注入上下文"]

可直接口述的回答

我不会把所有对话直接写入向量库,而是用旁路小模型做异步提取,先按持久性、结构化程度和个性化价值做准入筛选。自由文本与经验进入向量库,实体关系进入图存储,需要精确更新的用户画像进入结构化数据库。写入后再做重要性评分、去重、冲突处理、冷热分层和定期反思;召回时按任务类型路由,并保留来源、时间和置信度,避免过期或错误记忆污染后续决策。

补充与校正

  • “长期记忆”不等于“向量数据库”。更完整的分类是语义记忆(事实)、情景记忆(过去经验)和程序性记忆(规则与行为方式);它们的写入、更新和召回策略应不同。CoALA 论文、LangMem 官方概念文档
  • GraphRAG 适合实体关系丰富、多跳推理或全局主题分析,但索引成本更高。微软官方文档估计,标准 GraphRAG 中图抽取约占索引成本的 75%,所以不能默认所有记忆都建图。GraphRAG 索引方法
  • Reflection 只能基于可追溯证据做合并和归纳,不能把模型猜测直接升级为“用户事实”。敏感信息还要有最小化收集、授权、删除和审计机制。

相关笔记

相关文章

强化学习笔记 →上下文工程 →Mission: 掌握多模态 LoRA 与 QLoRA →