Sunday 的面试指南

Agent 的 Context、Memory 和 State 有什么区别?为什么聊久了会“忘事”?

🧑‍💻 面试官:用户让 Agent 排查线上故障,特别交代了一句:“只查原因,不要修改生产数据。”聊了十几轮后,Agent 却准备调用修改配置的工具。你觉得问题出在哪里?

🙋‍♂️ 我:可能是对话太长,前面的要求没进入这一轮的上下文。可以把重要信息存进 Memory。

🧑‍💻 面试官:存进 Memory 就够了吗?如果存着,但这次没有取出来,模型能知道这条限制吗?

🙋‍♂️ 我:不能。还要在调用模型前,把当前任务相关的限制放进 Context。

🧑‍💻 面试官:那任务做到一半,服务重启了。已经查过哪些日志、接下来要做什么,应该从哪里恢复?如果模型还是请求修改工具,最后由谁拦住它?

这道题不要把三个词背成三个盒子。关键是看一条信息如何被保存、怎样进入本轮判断,以及执行危险动作时有没有独立的校验。

面试速答(60 秒版)

Context 可以理解成这一轮真正交给模型看的信息。用户刚说的话、任务目标、最近的工具结果,都可能放进去;但系统保存过的内容,不代表模型这一轮一定看到了。

State 记录的是任务现在进行到哪里。例如用户要排查什么、已经查了哪些日志、工具返回了什么,以及当前有哪些不能越过的限制。任务需要中断后继续,就要把这些关键状态持久化。

Memory 说的是信息如何被保留下来、以后再取用。它不是和 State 完全分开的东西:同一段对话里的短期记忆,可以存在任务 State 里;跨会话的偏好或长期事实,则可能放在单独的存储里,按需要取回。

所以,Agent 聊久了“忘事”,不一定是系统把原话删了,也可能是整理上下文时漏掉了,或者存进 Memory 却没取出来。像“不能修改生产数据”这种任务限制,不能只靠模型记住:每轮判断都要让模型看到,真正执行写操作前,工具层还要再检查一次。

知识点详解:一条关键信息怎样穿过 Agent 的每一轮?

先分清:系统存着什么,模型这一轮看到了什么

咱们继续用前面的线上排查任务。用户说“不要修改生产数据”,随后 Agent 查了监控、翻了日志,还读到一大段工具输出。

到了下一轮,应用要重新组织一次模型请求。它不一定把过去十几轮的原始消息全部发进去:一方面有上下文窗口和成本的限制,另一方面,过多无关内容也会干扰当前判断。应用可能只保留最近消息、压缩早期对话,或者从存储中挑选相关内容。

如果“不要修改生产数据”在这一步被裁掉了,即使数据库里还能找到原话,模型这一轮也未必知道。这就是 Context 与“历史记录”最大的区别:Context 是本轮实际输入,不是所有曾经出现过的信息。

因此,不能只问“这句话有没有存下来”,还要问“模型准备做决定时,这句话有没有被带进去”。

State 和 Memory 又分别负责什么?

我们可以把任务信息按用途放到不同位置:

信息更合适的处理方式为什么
当前任务是排查订单接口;禁止修改生产数据作为当前任务的关键 State 保存,每轮决策时带上相关约束它决定本次任务能做什么,不能在压缩聊天记录时顺手丢掉
已查过的日志、工具返回的大文件State 里记录结论、状态和原始结果的引用;需要细节时再读取下轮要知道进度,但没必要每次都把整份日志塞给模型
用户长期偏好“先给结论,再给排查过程”经用户授权后,可作为跨会话 Memory 保存,相关时取回它可能影响以后的任务,不只服务于本次排查

这里的 State 是任务运行时的记录,重点在“现在做到哪一步、当前限制是什么”。它可以放在数据库或检查点中;如果只放进进程内存,服务重启后就无法指望它继续存在。

Memory 则是“为了以后还能用,把信息留下并取回”的能力,范围比一个存储表更宽。很多框架把同一会话的历史消息称为短期记忆,同时又把它们存在 State 里;跨会话的用户偏好、已确认事实,才通常会进入单独的长期记忆存储。所以这三个词有交集,不是三套互不相干的数据库。

手绘图:任务 State 中的短期记忆与跨会话长期记忆按需进入本轮 Context,模型只看到本轮输入

还有一个细节:不是所有信息都应该写成长期记忆。“这次不要改生产数据”属于当前任务的限制;下一次任务是否仍然只读,需要重新看用户要求和权限配置。把它当成永久偏好,反而可能制造新的误判。

真正容易漏的,是从保存到执行的这段路

一条关键限制要发挥作用,至少要经过下面几步:

  1. 记录。 用户提出限制时,应用把它转成当前任务的明确字段,例如 read_only = true,同时保留原始消息,避免后续摘要改错原意。
  2. 组装。 每次调用模型前,运行器从任务 State 取出目标、限制和当前进度,再补充必要的工具结果。长日志可以只给摘要和引用,但“只读”这种硬条件不能依赖摘要碰巧提到。
  3. 执行。 如果模型仍然请求写工具,后端根据实际用户权限、环境和本次任务的只读标记拒绝调用。模型看见限制只是帮助它少犯错,不是权限控制本身。
  4. 核对。 用执行记录检查:限制有没有被存下、每轮模型请求有没有带上、工具调用最终有没有被放行。只看 Agent 最后说“我没有修改数据”,证明不了这条链路安全。

手绘图:只读限制写入任务 State、带入模型本轮 Context,写工具请求仍由服务端门禁拒绝

这里的 read_only 只是示意字段,不是某个 Agent 框架自带的标准写法。实际系统里,权限还要以服务端可信的身份与策略为准,不能让模型或未经验证的聊天内容自己决定能否写生产环境。

你会发现,Context、State 和 Memory 解决的是不同环节的问题。把上下文窗口调大,只是给本轮输入更多空间;如果关键限制没有被正确保存、选入和执行校验,窗口再大也不能保证安全。

面试官继续追问

服务执行到一半重启,哪些东西必须恢复?

至少要恢复这次任务的身份、目标、关键限制、已完成步骤、等待中的动作和工具结果的引用。否则 Agent 可能从头重复查询,甚至重复执行写操作。

但恢复 State 不等于把所有旧消息和大文件原样塞回模型。先还原系统中的真实进度,再根据当前这一步挑选需要给模型的内容。如果是高风险动作,重启后也要重新核对权限和审批状态,不能因为检查点写着“准备执行”就直接放行。

已经做了对话摘要,为什么 Agent 还是漏掉了限制?

摘要是有损的。它可能把“只允许查询,不得修改生产数据”压成“排查生产问题”,结果把最重要的否定条件丢了。

因此,任务目标、禁止事项和待审批动作最好用结构化字段保存,不只藏在一段摘要里。测试时可以专门准备长对话:先给限制,再插入大量无关日志,最后诱导 Agent 使用写工具,检查模型输入和工具层是否都守住了边界。

用户下一轮又说“现在可以修改”,是不是把只读标记改掉就行?

先确认这条新指令来自有权限的人,而且确实对应当前任务。即使用户改了主意,生产写操作还可能需要独立审批。

确认以后,任务 State 可以更新,并记录是谁、在什么时候改变了限制;后续模型请求也要使用新版本。旧的 Memory、旧摘要和未执行的工具请求不能继续按原样使用。最后是否执行,仍由工具层依据最新权限和审批结果决定。

面试速记卡

  • Context:这一轮真正交给模型的信息,不等于全部历史记录。
  • State:当前任务的目标、进度、结果和限制;需要恢复就要持久化。
  • Memory:让信息以后还能被取回;短期记忆可以存在 State 中,长期记忆通常跨会话。
  • 忘事排查:先查有没有保存,再查有没有选入本轮 Context,不只怪上下文窗口。
  • 安全边界:关键限制要反复带入判断,写操作还必须由工具层独立校验。
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历