什么是 Agent?与大模型有什么本质不同?
面试时答这道题,一定要点出三件事:一是 Agent 有自主规划能力,给它一个复杂目标它能自己拆解成多步;二是它能行动,通过工具调用跟外部世界真实交互;三是它有闭环,每步的结果会反馈回来指导下一步,而不是一次性生成完就结束。另外还要提一句容易混的点:模型本身只是「大脑」,工具的真正执行是你的代码,模型只负责决策。
我理解 Agent 本质上是一个能自主完成目标的 AI 系统,跟传统 AI 最核心的区别在于「自主性」和「能行动」。
传统 AI 是你问一个问题它回答一个问题,每次都是独立的,被动响应;而 Agent 有自己的规划能力,你给它一个复杂目标,它会自己把任务拆成多步,通过调工具、访问记忆、感知环境来一步步执行,直到完成。
它不只是输出文字,而是真的能做事
Agent 的基本架构由哪些核心组件构成
Workflow,Agent,Tools 这三个的概念和区别介绍一下?
Tools 是最小的能力单元,就是封装好的可调用函数,比如搜索、执行代码、发邮件,它只负责「执行」,本身没有任何决策能力。
Agent 是一个完整的决策系统,内部用 LLM 做大脑,自己判断什么时候调哪个 Tool、要不要继续、什么时候结束,是主动的。
Workflow 是更上层的编排框架,把 Agent、LLM、Tools 组织成一条确定性流程,每个节点做什么、按什么顺序流转都是开发者事先写死的。
三者最核心的区别就一句话:Tools 不做决策只执行,Agent 自己做决策,Workflow 是开发者替所有节点把决策提前写好。
Tools 没有决策能力,只负责被调用时执行;Agent 由 LLM 在运行时动态决策,同样的输入可能走不同路径;Workflow 的决策提前写死在代码里,行为完全可预测。
三者不是三选一的关系,而是可以相互嵌套的,面试时还要补一句:生产环境里最主流的不是纯 Agent,而是 Agentic Workflow,用 Workflow 固定主流程骨架,在需要灵活判断的节点嵌入 Agent,这样兼顾了可控性和灵活性。
三者怎么组合?Agentic Workflow 才是生产主流
完全靠 Agent 自主决策 的系统其实很少在生产环境里出现,原因很现实:行为太难控制,一旦出问题很难排查,成本也容易失控(LLM 调太多轮)。
完全靠 Workflow 写死 的系统又太脆,因为你没法把所有情况都穷举到代码里,遇到预料之外的输入就容易失败或者给出很差的结果。
所以目前生产环境里最主流的模式是**「Agentic Workflow」**:用 Workflow 固定主流程的骨架,在需要灵活判断的节点嵌入 Agent,其余固定节点直接用 LLM 或 Tools。 骨架是确定的,让你能控制整体行为、便于调试;关键节点是灵活的,让你能应对各种复杂情况。两个优点都有,两个缺点都被削弱了
总结了几种常见的 Workflow 编排模式:
- 第一种叫「Prompt Chaining」(提示链),就是把一个大任务拆成多个小步骤,前一步的输出作为后一步的输入,像流水线一样串起来。
- 第二种叫「Routing」(路由),先用一个 LLM 做分类判断,然后根据分类结果把请求分发到不同的处理分支,前面客服系统的例子就是典型的路由模式。
- 第三种叫「Parallelization」(并行化),把可以同时进行的子任务并行执行,最后汇总结果,这在需要多维度分析的场景下特别有用,比如同时从多个数据源检索信息。
- 第四种叫「Orchestrator-Workers」(编排者-工人),一个中央编排者负责分配任务,多个 Worker 各自完成子任务,适合任务可以分解但子任务之间相互独立的场景。
还有一种非常实用但经常被忽略的模式叫「Evaluator-Optimizer」(评估者-优化者)。
它的核心思路是:一个 LLM 负责生成输出,另一个 LLM(或者同一个模型换一个角色)负责评估这个输出的质量,如果评估不通过就把反馈给回生成者,让它改进后重新输出,如此循环直到评估通过或者达到最大重试次数。
了解哪些其他的 Agent 设计范式?Agent 和 Workflow的区别是什么?
常见的设计范式除了纯 Agent之外,还有ReAct、Plan-and-Execute、Reflection这几种。
我理解 Agent 和 Workflow 最核心的区别是「谁来决定下一步」。Workflow 是我提前把流程写死的,每一步怎么走都是固定的,确定性高、好控制;Agent 是让 LLM 自己决定下一步做什么,灵活但不可控。
我在实际工程里用得最多的反而是把两者混用,固定流程的部分用 Workflow,需要灵活决策的节点嵌入 Agent 能力,这样既保住了整体可控,又有局部的灵活性。
Agent 三种设计范式
ReAct(Reasoning + Acting)是最常见的一种。
它的名字直接说明了它的核心机制:把推理(Reasoning)和行动(Acting)交替进行。具体来说,ReAct 的每一轮循环由三个步骤组成,形成一个完整的 Thought -> Action -> Observation 循环。
Thought 阶段,LLM 先把当前的情况分析一遍,把推理过程写出来,比如「用户想查竞品信息,我应该先用搜索工具查一下竞品 A 的最新动态」;Action 阶段,LLM 根据思考的结论决定调用哪个工具、传什么参数;Observation 阶段,工具返回的结果被反馈给 LLM,它读取这个结果,然后进入下一轮 Thought,重新分析当前局面、决定接下来怎么做。
Plan-and-Execute
它把规划和执行彻底分开,先让一个 LLM 专门做规划,输出一个完整的步骤列表,然后由另一个 LLM(或同一个模型以不同角色)逐步执行。
成熟的 Plan-and-Execute 实现里,每执行完一步都会把结果反馈给规划器,规划器会判断:当前的执行结果和预期一致吗?后续的计划还适用吗?需不需要调整?如果发现某一步的结果和预期严重偏离,规划器会修改后续的步骤,甚至插入新的步骤来应对。
Reflection(反思)
它的做法是在 Agent 完成一步或者完成整个任务之后,再让一个 LLM(可以是同一个模型也可以是专门的评估模型)来判断做得好不好、结果是否符合预期。如果评估不通过,就重试或者换一种策略。这个机制能显著提升输出质量,尤其是在代码生成、文案写作这类「质量要求高但一次做对很难」的场景下效果特别明显。
Reflection 有一个非常值得关注的变体叫 Reflexion。它和基础 Reflection 的区别在于,Reflexion 不只是简单地说「这个结果不好,重做一遍」,而是会生成一段具体的「反思总结」,记录下这次失败的原因和改进建议,然后把这段总结作为额外的上下文传给下一次尝试。
第一个雷是设计范式不熟,ReAct 是最常见的,但 Plan-and-Execute(把规划和执行解耦)和 Reflection(执行后加自我评估环节)也是必须说出来的,三个范式各有适用场景。
第二个雷是把 Reflection 当调试手段,它是正式的运行时机制,内嵌在 Agent 的执行流程里,代价是增加 token 消耗和延迟,这个取舍在面试里经常被追问。
第三个雷也是最重要的一个:以为 Agent 是生产环境的首选。实际上纯 Agent 模式在生产里用得很少,因为行为不确定、难以调试、成本容易失控。
真正的工程答案是 Agentic Workflow:整体用 Workflow 框住主流程保证可控,在需要灵活判断的节点嵌入 Agent 能力。能主动说出「为什么纯 Agent 在生产里有局限」,是这道题拿高分的关键
Agent 推理模式有哪些?ReAct 是啥?具体是怎么实现的?
Agent 的推理模式我用过几种。
最基础的是直接输出答案,没有中间推理;CoT 是让 LLM 先把推理过程写出来再给答案,准确率更高;ReAct 是在 CoT 基础上加了「行动」,让 LLM 交替输出思考和工具调用,每次行动后再根据结果继续思考,形成一个循环。
我觉得 ReAct 是目前 Agent 用得最广的模式,因为它推理过程可见,又能动态利用外部工具,两个优点都有。
ReAct 是什么?
ReAct 是 Reasoning and Acting 的缩写,由 Yao 等人在 2022 年提出,核心思路是在 CoT 的推理链里,插入真实的「行动」。
它让 LLM 按照「思考 -> 行动 -> 观察」这个循环来推进任务:先思考当前该怎么做,然后调用一个工具去获取信息或执行操作,把工具返回的结果作为新的「观察」接收回来,再进入下一轮思考,直到 LLM 判断任务完成。
纯 CoT 的问题前面说过了,它只能在脑子里推理,推得再好也拿不到真实数据,遇到需要实时信息的场景就抓瞎,而且纯靠内部推理很容易产生幻觉,因为没有外部事实来校准。
纯 Act-only 走的是另一个极端,它让 LLM 直接输出工具调用序列,不写任何思考过程,看起来效率很高,但问题在于每一步行动之间没有推理链条来连接,就像一个人闷头干活但不动脑子,遇到需要调整策略的情况就容易出错。
ReAct 的实现原理,是通过 prompt 格式来约束 LLM 的输出结构,但这个循环不是 LLM 自己在转,而是由你的代码来驱动的。
ReAct 的优势在于灵活,每一步都能根据最新情况做决策,特别适合那些任务边界不太明确、需要探索性地获取信息的场景,比如开放式的问答、信息搜索这类任务。它的代价是容易漂移,而且每一步都要把完整历史带上调 LLM,步骤多了 token 消耗会线性增长。
Plan-and-Execute 的优势在于有全局视野,不容易跑偏,特别适合那些目标明确、需要多步骤协作完成的复杂任务,比如深度研究、长文写作、多工具协同的数据分析。它的代价是初始规划本身就需要一次 LLM 调用,如果任务很简单(一两步就能搞定),这个规划步骤反而是多余的开销。
面试官最想听到的核心点是两个:第一,ReAct 的本质是「思考 -> 行动 -> 观察」的循环,推理过程显式化,又能动态调用外部工具,解决了 CoT 只能纯文字推理的局限;第二,这个循环是由你的代码框架驱动的,模型每次只输出 Thought + Action,你的代码负责解析、执行工具、把 Observation 填回历史,再把完整历史传给模型进入下一轮。
把这两点说清楚之后,主动提一下 ReAct 的两个实战局限(循环漂移(每次输出的答案局部最优,但最后可能会偏移目标)和错误传播(中间某一步输出错误答案,会继续向下传播)),再顺带说一下 Plan-and-Execute 是怎么通过「先规划再执行」来解决 ReAct 的漂移问题的,以及实际项目中两者经常混合使用(规划用大模型、执行用小模型),整个回答就会很有深度。
ReAct、Plan-and-Execute、Reflection 三种范式有什么核心区别?实际项目中该如何选型?
ReAct
ReAct 最大的优势是实现简单、灵活度高、逻辑透明,出了问题好排查,新手入门零门槛。但它的短板也很明显:遇到长流程、多步骤的复杂任务,很容易走着走着就跑偏,忘了最初的目标,也容易在某一步陷入无效循环。所以它更适合流程不固定、复杂度适中的任务,比如日常信息搜索、简单问答助手、客服机器人,也是新手入门的首选。
Plan-and-Execute
Plan-and-Execute 和 ReAct 最核心的区别,就是把「规划」和「执行」完全解耦了:先有完整的执行计划,再分步执行,全程不会偏离最初的目标,而不是像 ReAct 那样边规划边执行、随时可能调整方向。和 Reflection 相比,它的核心是「先规划再执行」,没有强制的自我检查环节,但两者可以叠加使用。
优势正好补了 ReAct 的短板:整体结构清晰,执行链路可控,复杂度很高的长流程任务也不容易跑偏,还方便做并行优化,大幅降低整体耗时。
Reflection
Reflection 和前两者最本质的区别,是它不是一套独立的做事流程,而是可以叠加在 ReAct 或 Plan-and-Execute 之上的增强机制,互不冲突。前两者的核心是「把事做完」,Reflection 的核心是「把事做好」,专门解决输出质量不达标、有事实错误、逻辑漏洞的问题。
优势很直接:输出质量明显提升,幻觉、逻辑错误、细节遗漏都会减少,对严谨性要求高的场景效果尤其明显。代价是至少多一次 LLM 调用,token 消耗和延迟都会线性增加,如果没有轮次限制,还很容易陷入「为了改而改」的死循环。所以它适合对输出质量要求极高、不能出错的场景,比如写生产环境的代码、正式的商业报告、法律文书,但凡有错误就会出大问题的,都值得加上 Reflection。
进阶:动态 Replan 和 Reflexion
动态 Replan
动态 Replan 的做法是在每个步骤执行完之后,把当前结果和剩余计划一起交给规划模块,让它判断「原来的计划还合理吗,需不需要调整」。如果需要,就生成一份新的剩余步骤计划,替换掉原来的。
Reflexion
第二个是 Reflexion,它把 Reflection 的「自我反思」推到了更深的层次。普通的 Reflection 是「做完了检查一遍、发现问题就重做」,有点像考试做完检查一遍。
Reflexion 在这个基础上多做了一件关键的事:它不仅检查输出对不对,还会把每次失败的原因总结成一段「经验教训」,存进记忆里,下次再遇到类似任务时,这段教训会作为上下文传给 LLM,让它避免重蹈覆辙。
说完定位,再按维度对比三者的核心区别:ReAct 边想边干、灵活度最高但长任务容易跑偏;Plan-and-Execute 先规划再执行、结构清晰但灵活度不足;Reflection 专门解决输出质量问题,代价是增加 token 消耗和延迟。
如果面试官追问进阶内容,可以展开讲动态 Replan 是怎么解决「计划太僵硬」的问题,Reflexion 是怎么通过「错题本」机制实现跨任务经验积累的,再补充一下三种范式的 token 消耗差异。
最后给出选型口诀:任务简单用 ReAct,流程长且复杂用 Plan-and-Execute,输出要求高再加 Reflection,顺带提一句「别过度工程化、够用就好」,面试官会觉得你有实际项目经验,不是只会背概念
复杂任务怎么做的任务拆分?为什么要拆分?效果如何提升?
拆分方式主要有两种:一种是静态拆分,提前把步骤写死;另一种是动态拆分,让 LLM 自己根据目标规划步骤,更灵活但也更难控制。
我理解任务拆分的原因是 LLM 一次性处理太复杂的任务很容易出错,把大任务拆成小步骤,每步聚焦一件事,准确率会明显提升。
为什么?
把一个大目标切成多个小步骤,每个步骤只做一件事,LLM 的全部注意力都集中在这一件事上,桌面保持干净,质量自然高。
每一个步骤都是独立的输出,可以被单独检查和验证。某一步出了问题,重试那一步就行,不需要从头跑整个任务。
任务拆分两种思路
静态拆分是你提前把任务流程设计好,固定成一个确定的Workflow,每一步是什么、按什么顺序执行,全部事先写死。比如「写一篇技术博客」,固定拆成:搜索资料 -> 整理大纲 -> 逐段撰写 -> 润色校对,四步顺序执行。好处是行为完全可预测,出了问题知道是哪一步的问题,好排查;坏处是灵活性低,遇到你没设计进流程的情况就容易卡住。
动态拆分则是把「任务拆解」这件事本身也交给 LLM 来做。你给它一个目标,让它先输出一个执行计划,再按计划一步步执行,这是 Plan-and-Execute 模式的核心思想。
自适应拆分:做不好就继续拆
更好的做法是:不要在开始时就把所有步骤的粒度定死,而是在执行过程中根据每一步的实际难度动态调整。核心逻辑很简单:先让执行器尝试完成当前任务,如果做得好就继续往下走,不做多余的拆分;如果明显做不好,比如超过了最大步数还没完成,或者输出质量不达标,就把这个「做不好的任务」交给规划器,让规划器把它进一步拆成更小的子任务,然后对每个子任务重复同样的流程:先试,做不好就再拆。
第一层是「为什么拆」:LLM 的 context window 有上限,任务越大中间状态越多、越容易出错,而且拆开后每步可以独立验证和重试。
第二层是「怎么拆」:静态拆分适合流程固定的场景,直接写死步骤;动态拆分用 Plan-and-Execute 让 LLM 自己规划,灵活但规划质量不稳定。
第三层是「拆完还要做的事」:分析步骤依赖关系,把能并行的步骤并发跑,关键路径时间可以降 40% 到 60%。
最后再补一句「粒度把握很重要,以原子操作为标准,既不能太细也不能太粗」,这道题就回答得很漂亮了。
请你介绍一下 AI Agent 的记忆机制,并说明在实际开发中应该如何设计记忆模块?
记忆机制分四层:感知记忆(当前输入的原始内容)、短期记忆(context window 里的对话历史)、长期记忆(存在外部数据库、语义检索召回)、实体记忆(结构化提取的关键事实)。
四种记忆类型(从最短暂到最持久)
第一层:感知记忆(Sensory Memory)
这是最短暂的一层,就是「当前这次调用的原始输入」,用户发来的这条消息、上传的截图、传入的文档。它的生命周期只有一次调用,处理完就消失,不会主动保留。类比到人的话,就是你刚听到的一句话,如果没有主动去记,几秒后就忘了。感知记忆就是这个「刚进来还没处理」的原始感知,它存在的意义是给模型提供一个「入口」来接收外部信息。
第二层:短期记忆(Short-term Memory)
这是 context window 里的 messages 列表,维持着当前任务执行过程中的完整状态,包括用户说了什么、模型输出了什么、工具调用返回了什么。只要任务还在进行,这些信息就都在;任务结束(对话关闭),这块记忆就清空了。你可以把它想象成你的「工作台」,桌上摆着的都是正在处理的东西。工作台有大小限制(token 上限),放满了就得清一清。工作台的特点是「随时可见」,不需要去翻箱倒柜地「找」,直接读就行。
第三层:长期记忆(Long-term Memory)
这是跨任务保留的信息,存在外部数据库里,通常是向量数据库、关系数据库或 Key-Value 存储。任务结束了,信息不会消失,下次需要时去检索拿回来用。你可以把它理解成你的「档案室」,东西放进去不会丢,但要用的时候需要主动去翻。长期记忆的关键技术是向量数据库,它支持「语义检索」:你不需要知道存的时候用了什么关键词,只要意思相近就能检索到相关内容。这比精确匹配灵活得多,比如你存的是「用户不喜欢冗长的注释」,用「代码风格偏好」去查也能找到它。
长期记忆其实不是铁板一块,它还可以细分成三种子类型,每种存的东西和用途都不一样。
第一种是「情节记忆」(Episodic Memory),存的是具体的事件经历。比如「上周二用户让我写了一个 Python 爬虫,中间遇到了反爬问题,最后用 Selenium 解决了」,这是一段完整的任务经历,包含了时间、场景、过程和结果。情节记忆的价值在于,当 Agent 遇到类似的新任务时,可以检索出历史上的相似经历,参考上次是怎么解决的,避免重复踩坑。
第二种是「语义记忆」(Semantic Memory),存的是从多次经历中提炼出来的通用知识和规律。比如经历了好几次反爬问题之后,Agent 沉淀出一条规律:「当目标网站有 JavaScript 动态渲染时,requests 库抓不到内容,应该优先考虑 Selenium 或 Playwright」。这不再是某一次具体的事件记录,而是跨多次经验总结出来的抽象知识。语义记忆的信息密度更高,检索时也更容易命中,因为它直接存储的就是结论而不是过程。
第三种是「程序记忆」(Procedural Memory),存的是怎么做某件事的操作流程。比如「部署一个 Flask 应用的标准步骤:创建虚拟环境 -> 安装依赖 -> 配置 gunicorn -> 设置 nginx 反向代理 -> 启动服务」,这是一套可以直接复用的操作 SOP。程序记忆在处理重复性任务时特别有用,Agent 不需要每次都从头推理,直接调出对应的 SOP 执行就行,既快又稳。
三种子类型各有侧重,实际项目中通常会混合使用。情节记忆提供具体的参考案例,语义记忆提供抽象的知识规律,程序记忆提供可复用的操作流程,三者配合起来才能让 Agent 的长期记忆真正好用。
第四层:实体记忆(Entity Memory)
这层比长期记忆更精炼,它不是存原文,而是把对话中出现的关键实体和事实主动提取出来,存成结构化字段。比如「用户偏好 Python」「客户预算是 5 万」「项目截止日是 3 月底」,这些是从对话里提炼出来的「结论」,而不是原始对话本身。类比到人的话,就像医生的病历卡,不是把问诊录音存起来,而是结构化地记录「主诉:头痛三天;诊断:偏头痛;用药:布洛芬」。信息密度高,查询快,而且不受原始表述方式影响。
实际设计记忆模块的三个核心问题
第一个:存什么?
通常值得存的有三类:用户偏好和习惯(语言风格、技术栈偏好、工作习惯)、任务执行中产生的关键结论和决策(比如「调研发现竞品 A 的定价策略是按用量收费」)、以及外部知识(产品文档、FAQ、历史案例)。
第二个:怎么存?
需要语义检索的内容,比如文档知识、对话摘要这类非结构化的文本,适合存进向量数据库,用 embedding 编码后通过相似度检索。结构化的用户偏好和状态字段,比如语言偏好、项目配置这些可以精确查询的内容,更适合用关系数据库或 Key-Value 存储,查询速度快,不需要语义理解。整段文档或知识库则适合存进向量数据库,配合 RAG 流程做召回。
混合存储是主流做法:结构化的偏好字段用关系数据库精确查,非结构化的知识和历史用向量数据库语义检索,两者配合使用。
第三个:什么时候取出来用?
第一种叫「主动检索」,在任务开始前,用当前任务的描述去检索相关记忆,把结果注入 system prompt 作为背景知识。这样 Agent 一开始就带着「历史记忆」进入任务,不需要用户每次重新交代背景。第二种叫「被动触发」,Agent 在推理过程中,判断当前步骤需要某类特定知识时,主动发起检索。具体做法是把「查记忆」封装成一个 Tool,让 Agent 自己决定什么时候调。这种方式更灵活,但依赖模型判断什么时候该去查。
实践上两种结合效果最好:session 开始时做一次主动检索,把关于用户偏好和背景的记忆加载进 system prompt;任务执行过程中,遇到需要专业知识或历史数据的步骤,再让 Agent 按需检索
Context Window 管理:短期记忆的「工作台」不够大怎么办
最简单的是「滑动窗口」,只保留最近 N 轮对话,更早的历史直接丢弃。好处是实现简单,代价是早期的重要信息可能被丢掉。比如用户在第一轮就说了「所有代码用 TypeScript」,到了第十轮这条信息被滑出窗口了,Agent 又开始写 JavaScript,用户就会很崩溃。
进阶一点的做法是「摘要压缩」。当历史长度接近上限时,用 LLM 把早期的对话历史压缩成一段摘要,替换掉原始的冗长历史。比如把前面十轮的详细对话压缩成「用户要求用 TypeScript 编写一个 REST API,已完成数据库设计和路由定义,当前正在实现用户认证模块」,一段话就把关键信息保留了,token 占用从几千降到几百。代价是压缩过程本身会丢失细节,而且需要额外的 LLM 调用来做摘要。
还有一种做法是把不常用但重要的信息「卸载」到长期记忆里。执行过程中产生的中间结果,如果当前步骤不需要但后面可能用到,就先存到向量数据库里,从 context window 中移除,等后面某步需要时再检索回来。这相当于给工作台配了一个「抽屉」,桌面放不下的东西先收到抽屉里,要用的时候再拿出来。
知识图谱:让记忆之间产生关联
在 Agent 的记忆模块里引入知识图谱,通常是和向量数据库配合使用的。向量数据库负责处理模糊的语义检索(比如用户说「之前那个项目」,向量检索能找到最相关的项目记忆),知识图谱负责处理精确的关系推理(比如查某个用户的所有相关公司和角色),两者互补。具体做法是:对话过程中用 LLM 自动提取出实体和关系,存入知识图谱。检索时先用向量检索拿到一批候选记忆,再用知识图谱补充关联信息,最后把两部分结果合并后注入 context。
记忆整合:从碎片到知识
回答 Agent 记忆机制这道题,先把四层分类说清楚:感知记忆是当次调用的原始输入,最短暂;短期记忆是 context window 里的 messages,维持任务状态;长期记忆是存在向量或关系数据库里、跨任务持久化的内容;实体记忆是从对话中提炼出来的结构化事实,信息密度最高。
说完分类,再答三个工程核心问题:存什么(只存对下次任务有价值的内容,过滤噪音)、怎么存(语义内容用向量数据库,结构化偏好用关系数据库,混合存储是主流)、什么时候取(任务开始前主动检索加载背景,执行中按需检索特定知识)。
最后用「读 -> 用 -> 写」三阶段闭环收尾,整个回答结构清晰、有深度,面试官很难挑剔。
Agent 的长短期记忆系统怎么做的?记忆是怎么存的?粒度是多少?怎么用的?
短期记忆就是 context window 里的对话历史,存当前任务的中间状态,任务结束就清掉;
长期记忆用向量数据库存,把信息 embedding 后写入,用的时候做语义检索拿回来注入 prompt。
再多说一层:长期记忆其实还可以按「类型」细分成三种。
第一种是语义记忆(Semantic Memory),存的是事实性知识,比如「用户是 Python 开发者」「项目预算上限 5 万」,这些是不随时间变化的客观信息。
第二种是情节记忆(Episodic Memory),存的是具体事件的经历,比如「上周二用户让我写了一个爬虫,中间因为反爬策略改了三次方案」,它带有时间线和因果关系。
第三种是程序记忆(Procedural Memory),存的是「怎么做某件事」的方法论,比如「给这个用户写代码时,先确认风格偏好,再写主逻辑,最后加注释」,它更像是 Agent 积累下来的行为模式。
第一个雷是把长期记忆说成「存数据库靠关键词搜索」,这暴露了不了解向量检索,长期记忆的核心是 Embedding + 向量数据库,靠语义相似度而不是字符串匹配来检索,这一点一定要说清楚。
第二个雷是以为粒度越细越好,实际上粒度太细会导致记忆碎片化,检索时拿到不完整的信息,合理粒度是「一次完整交互」或「一个独立知识点」。
第三个雷是搞不清两层记忆各自的作用时机,短期记忆是任务执行中的「工作台」,任务结束就清空;长期记忆是任务前检索注入、任务后写入沉淀,两者分工不同,配合使用才能让 Agent 既不中途失忆、又能跨任务积累。
什么是 Multi-Agent?
Multi-Agent 之间的协作方式主要有三种模式。第一种是顺序流水线(Sequential Pipeline),Agent A 做完把结果交给 Agent B,B 做完交给 Agent C,就像工厂流水线一样,每个环节依次处理。第二种是并行扇出(Fan-out),一个调度者把多个独立子任务同时分发给不同的 Worker Agent,它们各自并行执行,最后由调度者收集汇总。第三种是辩论/评审模式(Debate/Review),多个 Agent 对同一个问题各自给出方案,然后由一个裁判 Agent 或者它们互相评审来筛选最优解,这种模式在需要高质量决策的场景特别有用,比如代码评审、方案选型
这道题的核心在于能不能说清楚「为什么需要 Multi-Agent」,而不是泛泛地说「多个 AI 一起工作效率更高」。
面试官最想听到的是两个具体的技术驱动因素:第一是 context window 的硬上限,单个 Agent 处理复杂任务时信息量一旦超出窗口,就开始「遗忘」,这是结构性的限制,不是努力优化能绕过去的;第二是专业度问题,让一个 Agent 身兼数职,每件事都做得不够专注,分工之后每个 Agent 的 context 是干净的,只装自己那块的信息,专业能力也更强。
回答时还要提到并行执行这个好处,多个 Worker 同时跑,整体效率有实质提升。把这三个点说清楚,这道题就答到位了。
说说 Single-Agent 和 Multi-Agent 的设计方案?
Single-Agent 适合任务流程清晰、复杂度适中的场景,实现简单、好维护;Multi-Agent 适合需要专业分工、任务量大或者需要并行执行的复杂场景。
Multi-Agent 架构上主要有两种拓扑:中心化的 Orchestrator 模式,由一个主 Agent 统一调度各个 Worker;去中心化的 Peer-to-Peer 模式,Agent 之间直接通信。
我在工程里用中心化用得更多,因为好控制、好调试,出问题链路清晰。
Single-Agent缺点:
Single-Agent 真正开始力不从心,是在遇到这几类任务的时候:任务太长、信息量太大,context 撑爆,Agent 开始遗忘;不同步骤需要完全不同的专业能力,什么都塞进一个 Agent,每件事都做得不够专注;任务中有多个独立子任务,理论上可以并行,但单 Agent 只能一个个来
Multi-Agent
Peer-to-Peer缺点:
总结下来,去中心化系统里这几类问题会频繁出现:任务分配没有协调、执行顺序没有保证、失败没有感知、没有人来确认「任务整体完成了」。类比一个没有项目经理的团队:每个人都很能干,但没有人协调时间节点和接口,最后交出来的可能是互不兼容的结果,而且没有人知道整体进度到底怎么样了。
这就是为什么去中心化方案更多停留在学术研究里探索,研究的是「AI 系统能不能实现自主协调」这个更宏观的问题。而生产环境里,几乎所有正经项目都选 Orchestrator 模式,因为可控、可追踪、出了问题能排查,这才是工程上真正需要的。
这道题最容易犯的错误有三个,对应开头对话里踩的三个雷。
第一,选型标准不能只说「任务复杂就用 Multi-Agent」,要说出具体的三类场景:context 要撑爆了、需要不同专业分工、有子任务可以并行,不属于这三类就用 Single-Agent,盲目引入 Multi-Agent 只会增加系统复杂度,带不来对应收益。
第二,Multi-Agent 架构方案要主动提中心化和去中心化两种,而且要明确说出工程里几乎都选 Orchestrator 中心化模式,因为可控、可追踪、出了问题能顺着调度链路排查。
第三,去中心化「听起来灵活」但要能说清楚它的实际问题:任务分配没协调、执行顺序没保证、失败没有感知,这才是它在生产环境里不可用的根本原因。
Agent 记忆压缩通常有哪些方法?
记忆压缩常见有四种方法:摘要压缩、滑动窗口、重要性过滤、结构化抽取。
摘要压缩是把长对话总结成简短摘要;滑动窗口是只保留最近 N 轮对话;重要性过滤是打分筛选,只留重要内容;结构化抽取是把关键信息抽成结构化数据存起来。
我在实际项目里最常用的是摘要压缩和滑动窗口,而且经常组合用,滑动窗口丢弃前先做一次摘要,尽量不丢重要信息
第一种方法:滑动窗口,最简单的方案,也是最粗糙的
滑动窗口是最符合直觉的做法,就像手机聊天记录默认只显示最近 200 条:超出就从最老的开始删,只保留最近 N 轮对话。
第二种方法:摘要压缩,丢之前先提炼一遍
不直接丢弃即将超出窗口的历史,而是先让 LLM 把这段历史总结成一段精华摘要,用摘要替换原始对话,再继续往前。
这个方案单独用时,通常的做法是「旧的压缩成摘要,近的保持完整」,最近几轮对话往往和当前任务关系最密切,保持原文;更早的历史相关性低,压缩成摘要。
进阶一点的做法是层级式摘要(Hierarchical Summarization)。不是对所有旧历史做一次性摘要,而是分层处理:最近 10 轮保持原文,10 到 50 轮的历史压缩成一份「中期摘要」,50 轮之前的历史进一步压缩成更精炼的「长期摘要」
最常见的工程组合:滑动窗口 + 摘要
在实际工程里,这两种方法通常一起用,而不是单独用其中一种。滑动窗口负责控制对话历史的总长度上限,摘要压缩负责在历史被丢弃之前做一次提炼,把关键信息留下来。这样既有长度控制,又不是直接硬截断,是目前最常见的工程方案。
第三种方法:重要性过滤,按价值筛选,不按时间筛选
按内容的实际价值来决定去留:给每条对话记录打一个重要性分数,低于阈值的淘汰,高分的保留。
还有一种更激进的重要性过滤思路叫观察遮蔽(Observation Masking)。它的做法不是删除低分内容,而是在构造 prompt 时选择性地「隐藏」某些历史条目(比如写代码,与需求相关的片段不会传入进来,只会把相关的信息传入进来)
主动压缩的思路是,Agent 在每一步执行完之后,主动判断哪些中间过程可以压缩。
第四种方法:结构化抽取,换一种载体存信息
把这些信息主动提取出来,存成结构化字段,后续注入 prompt 时直接用这些字段,比传一大段对话文本要高效得多,信息密度也高得多。
Prompt Caching:在「计算层」的互补手段
Prompt Caching 的思路是:如果 prompt 的前缀部分在多次请求之间是一样的,就把这部分的计算结果缓存起来,下次请求如果前缀匹配,直接复用缓存,不重新计算。费用和延迟都大幅降低,某些场景下能降到原来的十分之一。
回答时要覆盖四种方法,并且能说清楚它们解决的是不同维度的问题:滑动窗口和摘要压缩解决「历史太长怎么截」,前者直接硬截,后者截之前先提炼;重要性过滤解决「内容不等价怎么挑」,打破时间顺序按价值保留;结构化抽取解决「对话文本是不是最佳载体」,换一种信息密度更高的形式存储。
另外,Prompt Caching 要和记忆压缩区分清楚,它是「计算层」的优化,对已经决定带进去的内容减少重复计算,和「信息层」的压缩是互补关系,不是替代关系,这个区别如果能主动点出来,会给面试官留下很好的印象。
在工程实践中,为什么有时候选择「手搓」Agent,而不是直接用成熟框架?
第一是抽象层太多,调试的时候不知道哪步出了问题,得一层层往下扒;第二是版本升级经常有破坏性变更,线上稳定性难保证;第三是框架的通用设计往往和具体业务需求有偏差,定制起来反而更费劲。
手搓的代码完全在自己掌控之内,可观测性好、出问题好排查,也更方便做性能优化。所以我现在的策略是核心逻辑手写,只在边缘功能上用框架的工具
手搓的本质优势:完全掌控
首先是链路透明、可观测性好。手搓的每一行代码你都知道在干什么,可以在任意位置加日志、打断点、插入监控,没有任何黑盒。线上出了问题,靠日志复现故障是最快的方式,链路越清晰,定位根因越快。
第一,框架的价值是真实的,POC 阶段省时省力,不要一开口就否定框架。
第二,框架的痛点要说具体:抽象层太多导致排查困难、版本升级带来 breaking change、通用性设计产生隐性性能开销,这三个是实际生产中最常遇到的问题,泛泛说「框架有缺点」没有说服力。
第三,手搓的核心价值是「完全掌控」,可观测性好、稳定不受外部升级影响、性能可以精确裁剪,这些在生产环境里是真实的成本节省。
第四,最容易被忽略的是折中方案:核心逻辑手写,周边工具性功能借用框架,这才是实际项目里最常见也最务实的选择,面试官通常很认可这个答法。
最后要记住一句:框架不是问题,「不理解就依赖」才是。
如何赋予 LLM 规划能力?
给 LLM 加规划能力主要靠这几种思路。
• CoT 是让 LLM 把推理步骤写出来,线性地一步步推导到答案;
• ToT 是让它同时探索多条推理路径,选最优的继续深入;
• GoT 是图结构推理,推理节点可以复用和合并,适合更复杂的任务。
工程上我用 CoT 最多,因为实现成本最低,就是改个 prompt;ToT 效果更好但调用次数多,成本大概是 3 到 5 倍;GoT 目前还比较学术,生产环境我没见过有人真正落地用的
CoT:最简单的激活方式,加一句话就够了
CoT 的全称是 Chain of Thought(思维链),核心思路极其简单:在 prompt 里加一句「请一步步思考」,LLM 就会把推理过程逐步写出来,而不是直接蹦出答案。
第一种叫 Zero-shot CoT,就是直接在 prompt 末尾加「让我们一步步思考」,LLM 自己展开推理,不需要额外例子;
• 第二种叫 Few-shot CoT,给几个带有完整推理过程的例子,让 LLM 模仿这种推理格式来回答新问题,效果通常更稳定。
CoT 的局限很明显:它只有「一条推理路径」。如果一开始走错了方向,整条链就歪了,没有任何纠偏机制。
ToT:从「一条链」到「一棵树」,解决走错方向的问题
核心改变是把「生成一条推理链」变成「同时探索多条推理路径,边探索边剪枝,最终选出最优路径」。用一个生活类比来理解:CoT 像你做题时只想了一个解法,一路做到底;ToT 像你先想了三种可能的解题思路,评估了一下哪种最靠谱,选了最好的那条继续深入,另外两条直接放弃。
GoT:从「树」到「图」,解决推理结果不能复用的问题
ToT 虽然引入了多路径探索,但它是树形结构,不同分支之间完全独立,两条推理路径上的中间结论无法互相借用。GoT 把推理结构换成了图,允许不同路径的中间结果合并、复用,也就是说一个推理节点可以接收来自多个前置节点的输出作为输入。
CoT 解决了「要不要把推理显式化」的问题,答案是要,把过程写出来就能显著减少跳步出错。ToT 解决了「走错方向怎么办」的问题,答案是先多探索几条路,边走边评估边剪枝。GoT 解决了「不同推理路径的中间结论能不能复用」的问题,答案是把结构从树换成图,自然支持结论汇聚与复用。每一步都是在前一步的基础上发现局限、针对性改进。
工程里真正常用的规划模式:Plan-and-Execute
具体执行流程分三步。
• 第一步,Planner(规划器)接收用户任务,生成一份步骤清单,比如「第一步搜索相关资料,第二步整理关键信息,第三步撰写总结报告」。
• 第二步,Executor(执行器)按照清单一步步执行,每步可能涉及工具调用或 LLM 推理。
• 第三步,也是容易被忽略的关键,每执行完一步,会有一个 Re-planner(重新规划器)回顾当前进展,判断原来的计划还适不适用,如果中间发现了新的信息或者某步执行结果不符合预期,就动态调整后续步骤。
这个模式和 ReAct 是什么关系?ReAct(Reasoning + Acting)是一种让 LLM 在每一步都先「思考」再「行动」再「观察」的循环模式,它的特点是每步都是即时决策,没有提前规划。Plan-and-Execute 则是在 ReAct 的基础上加了一层全局规划,你可以理解成 ReAct 负责每一步怎么执行,Plan-and-Execute 负责这些步骤的整体编排和动态调整。两者不是替代关系,而是经常搭配使用的。
首先要说清楚为什么需要规划能力,LLM 默认「一口气」生成答案,没有显式推理过程,多步推理任务容易跳步出错,规划机制就是把隐式推理过程显式化。
然后要说三种机制的演进逻辑:CoT 解决「要不要把推理写出来」,ToT 解决「走错了方向怎么纠偏」,GoT 解决「不同路径的中间结论能不能复用」,每一个都是针对上一个的局限性改进。
最容易被忽略的考点是工程取舍:CoT 几乎零成本;ToT 效果更好但典型调用次数是 CoT 的 3-5 倍(具体看路径数和深度),要明确说出这个数字;GoT 目前学术阶段,生产环境没有成熟落地。