Agent开发面试圣经8

14. 如何赋予 LLM 规划能力?

给 LLM 加规划能力主要靠这几种思路。

  • CoT 是让 LLM 把推理步骤写出来,线性地一步步推导到答案;

  • ToT 是让它同时探索多条推理路径,选最优的继续深入;

  • GoT 是图结构推理,推理节点可以复用和合并,适合更复杂的任务。

工程上我用 CoT 最多,因为实现成本最低,就是改个 prompt;ToT 效果更好但调用次数多,成本大概是 3 到 5 倍;GoT 目前还比较学术,生产环境我没见过有人真正落地用的。

要理解为什么需要规划能力,先看 LLM 在没有任何规划机制时是怎么运作的。

普通的问答模式下,LLM 接到一个问题,就直接「一口气」生成答案,中间没有任何推理过程。这对简单问题没啥大问题,但遇到需要多步推导的任务就很容易翻车。比如让它做一道需要 3 步推导的逻辑题,如果直接让它给答案,出错概率会远高于让它把每步都写出来。

背后的原因是 Transformer 的 next-token 预测机制,每个 token 是基于前面所有 token 生成的,推理链越长、隐式的跳步越多,误差就越容易在中间某一步悄悄累积,最后给出一个看起来很自信但其实是错的答案。

「规划能力」要解决的就是这个问题:把 LLM 隐式的推理过程显式化,让它不再是「一步跳到答案」,而是「一步一步推到答案」,每步都有迹可循。

CoT、ToT、GoT 是这个方向上依次演进的三种方案,每一个都在解决前一个的局限性。

CoT:最简单的激活方式,加一句话就够了

CoT 的全称是 Chain of Thought(思维链),核心思路极其简单:在 prompt 里加一句「请一步步思考」,LLM 就会把推理过程逐步写出来,而不是直接蹦出答案。

为什么这么简单的改变就有效?

本质是因为 LLM 的输出是顺序生成的,当它先输出推理步骤,这些推理内容会进入上下文,影响下一个 token 的生成。换句话说,「写下来的推理过程」本身就成为了后续生成的依据,帮助 LLM 不跳步、不乱想。就好比你在纸上演算数学题,把每一步写出来之后,下一步出错的概率会比在脑子里算要低得多,原理是一样的。

CoT 有两种触发方式。

  • 第一种叫 Zero-shot CoT,就是直接在 prompt 末尾加「让我们一步步思考」,LLM 自己展开推理,不需要额外例子;
  • 第二种叫 Few-shot CoT,给几个带有完整推理过程的例子,让 LLM 模仿这种推理格式来回答新问题,效果通常更稳定。

CoT 的局限很明显:它只有「一条推理路径」。如果一开始走错了方向,整条链就歪了,没有任何纠偏机制。

ToT:从「一条链」到「一棵树」,解决走错方向的问题

ToT 的全称是 Tree of Thoughts(思维树),针对的正是 CoT「一旦走错就全错」的问题。

核心改变是把「生成一条推理链」变成「同时探索多条推理路径,边探索边剪枝,最终选出最优路径」。用一个生活类比来理解:CoT 像你做题时只想了一个解法,一路做到底;ToT 像你先想了三种可能的解题思路,评估了一下哪种最靠谱,选了最好的那条继续深入,另外两条直接放弃。

ToT 的执行流程可以分三步来理解。首先是生成多个候选思路,让 LLM 针对同一个问题给出 3 个不同的初步方向,而不是只走一条路。然后是评估每个思路的可行性,用另一个 LLM 调用(或同一个 LLM 带上评估 prompt)给每个思路打分,判断哪个最有希望。最后是选优继续深入、剪掉差的,只保留分数高的思路,再展开下一层推理,反复循环直到得出最终答案。

这个「生成 -> 评估 -> 剪枝」的循环,让 LLM 不再是「一条道走到黑」,而是有了探索多条路、选好的走、发现走错了还能回头的能力。代价也很明显:原来 CoT 一次生成就搞定,ToT 需要多次 LLM 调用(多条路径 × 多层深度 × 每层还要评估),成本是 CoT 的 3-5 倍甚至更高。

GoT:从「树」到「图」,解决推理结果不能复用的问题

GoT 的全称是 Graph of Thoughts(思维图),是在 ToT 基础上再进一步的进化。

ToT 虽然引入了多路径探索,但它是树形结构,不同分支之间完全独立,两条推理路径上的中间结论无法互相借用。GoT 把推理结构换成了图,允许不同路径的中间结果合并、复用,也就是说一个推理节点可以接收来自多个前置节点的输出作为输入。

举个具体例子:如果任务是「分别研究竞品 A 和竞品 B,然后做综合对比分析」。ToT 里研究 A 和研究 B 是两条独立的路径,各自得出结论;但「综合对比分析」这一步需要同时用到两条路径的结论,在树形结构里很难自然表达,因为树的每个节点只有一个父节点。GoT 的图结构允许把「研究 A 的节点」和「研究 B 的节点」的输出,汇聚到「综合对比分析节点」,这种「多个中间结论合并输入到下一步」的操作在图里是一等公民,表达起来非常自然。

GoT 能建模的推理模式比 ToT 更丰富,也更接近人类实际处理复杂任务的思考方式。但落地复杂度很高,目前主要还是学术研究场景,生产环境里极少见到真正用起来的。

三者的演进关系

把这三者放在演进视角里看,逻辑非常清晰。

CoT 解决了「要不要把推理显式化」的问题,答案是要,把过程写出来就能显著减少跳步出错。ToT 解决了「走错方向怎么办」的问题,答案是先多探索几条路,边走边评估边剪枝。GoT 解决了「不同推理路径的中间结论能不能复用」的问题,答案是把结构从树换成图,自然支持结论汇聚与复用。每一步都是在前一步的基础上发现局限、针对性改进。

工程上怎么选?CoT 几乎是所有任务的标配,加一句话、零成本,直接加到 system prompt 里就行。ToT 在准确率要求很高、任务比较复杂的场景值得考虑,但要做好调用成本增加 3-5 倍的心理准备。GoT 目前工程落地不成熟,主要了解它的思想即可,真实项目里不必强行引入。

工程里真正常用的规划模式:Plan-and-Execute

CoT、ToT、GoT 说的都是「怎么让 LLM 把推理过程做得更好」,但在真实的 Agent 项目里,还有一种更贴近工程实践的规划模式,叫做 Plan-and-Execute(先规划再执行)。

这个模式的思路很直白:面对一个复杂任务,先让 LLM 制定一份完整的执行计划,把任务拆成若干步骤,然后一步一步执行,每完成一步就检查一下进度,必要时调整后续计划。你可以把它理解成「先写大纲再动笔」的写作方式,而不是拿到题目就开始一口气往下写。

为什么需要这种模式?因为 CoT 虽然能让 LLM 逐步推理,但它是「边想边做」的,走到哪算哪,没有全局视角。对于一个需要调用多个工具、经历多个环节的复杂任务来说,如果没有一个整体规划,LLM 很容易在某一步跑偏,后面的步骤全都白费。Plan-and-Execute 的核心价值就是:先用一次 LLM 调用建立全局视角,再用后续调用逐步落地,把「规划」和「执行」分成两个阶段来做。

具体执行流程分三步。

  • 第一步,Planner(规划器)接收用户任务,生成一份步骤清单,比如「第一步搜索相关资料,第二步整理关键信息,第三步撰写总结报告」。
  • 第二步,Executor(执行器)按照清单一步步执行,每步可能涉及工具调用或 LLM 推理。
  • 第三步,也是容易被忽略的关键,每执行完一步,会有一个 Re-planner(重新规划器)回顾当前进展,判断原来的计划还适不适用,如果中间发现了新的信息或者某步执行结果不符合预期,就动态调整后续步骤。

这个模式和 ReAct 是什么关系?ReAct(Reasoning + Acting)是一种让 LLM 在每一步都先「思考」再「行动」再「观察」的循环模式,它的特点是每步都是即时决策,没有提前规划。Plan-and-Execute 则是在 ReAct 的基础上加了一层全局规划,你可以理解成 ReAct 负责每一步怎么执行,Plan-and-Execute 负责这些步骤的整体编排和动态调整。两者不是替代关系,而是经常搭配使用的。

工程上 Plan-and-Execute 的好处很明显:规划和执行分离之后,规划阶段可以用更强的模型(比如 GPT-4)来保证方向正确,执行阶段可以用更快更便宜的模型来提高效率,成本和质量都能分别优化。LangGraph 里就内置了这种模式的支持,用起来相当方便。

答好这道题有几个层次。首先要说清楚为什么需要规划能力,LLM 默认「一口气」生成答案,没有显式推理过程,多步推理任务容易跳步出错,规划机制就是把隐式推理过程显式化。然后要说三种机制的演进逻辑:CoT 解决「要不要把推理写出来」,ToT 解决「走错了方向怎么纠偏」,GoT 解决「不同路径的中间结论能不能复用」,每一个都是针对上一个的局限性改进。最容易被忽略的考点是工程取舍:CoT 几乎零成本;ToT 效果更好但调用次数是 CoT 的 3-5 倍,要明确说出这个数字;GoT 目前学术阶段,生产环境没有成熟落地。面试里如果能把工程成本和适用场景说清楚,比只讲原理要加分得多。

15. 讲讲 Agent 的反思机制?为什么要用反思?具体怎么实现?

反思机制我的理解是:让 Agent 在完成一个步骤或整个任务后,自我评估输出质量,判断有没有问题,不达标就重试或调整策略。

用反思的原因是 LLM 第一次输出不一定是最优的,加一轮自我检查能显著提升质量,相当于人写完东西自己再看一遍。

代价是多至少一次 LLM 调用,token 消耗和延迟都会增加,所以我在工程里通常只在质量要求高的关键节点启用反思,不是每步都做。

LLM 也面临同样的问题。它每次生成输出,本质上是在「一口气」完成的,没有机会停下来检查。

第一次输出常见的毛病有这几类:逻辑跳跃(推理步骤不完整,中间少了关键推断)、遗漏细节(任务里要求了某些点,但没有全部覆盖到)、事实错误(模型幻觉导致的错误信息)、表达含糊(意思到了但说得不清晰)。

这些问题,如果给 LLM 一个「回头检查」的机会,它自己是有能力发现并修正的。反思机制就是给它加上这个环节。

核心循环:生成 -> 评估 -> 改进

反思机制的核心思路来自 Self-Refine 论文,整个流程就是「生成 -> 评估 -> 改进」的循环。

这个循环靠两个 prompt 来驱动。第一个负责评估,让 LLM 扮演「检查者」的角色,专门去找问题:

复制代码
任务:{task}

当前输出:
{current_output}

请评估以上输出:
1. 有没有事实错误或逻辑问题?
2. 有没有遗漏重要内容?
3. 表达是否清晰准确?

如果输出已经足够好,回复「PASS」;
否则指出具体问题并给出改进建议。

这个评估 prompt 的设计有几个值得注意的地方。

首先,它给出了明确的检查维度(事实、逻辑、完整性、表达),而不是让 LLM 自由发挥。这很重要,没有方向的评估往往流于表面,LLM 可能只是说「输出看起来不错」,没有真正找到问题。给出具体维度,它才会有针对性地逐项审查。

其次,「PASS」机制是必须有的,这是给 LLM 一个「足够好就停」的出口。如果没有这个机制,LLM 为了反思而反思,可能对一个已经很好的输出挑不必要的小毛病,反而把原本对的东西改错。

如果评估结果不是 PASS,就把评估意见喂进第二个改进 prompt:

复制代码
原始任务:{task}
当前输出:{current_output}
评估意见:{reflection}

请根据评估意见改进输出:

改进 prompt 有一个关键点:它同时传入了原始任务、原始输出、评估意见这三样东西,缺任何一个都会让改进变得盲目。只有任务没有原始输出,LLM 不知道在什么基础上改;只有原始输出没有评估意见,LLM 不知道改哪里;只有评估意见没有任务,LLM 可能改着改着偏离了原始目标。三者都在,它才能有针对性地修改,而不是把内容全部重写一遍。

两个 prompt 循环调用,直到 LLM 自己回复 PASS,或者超过最大轮次强制退出,整个外层逻辑不过是一个普通的 for 循环。

两个粒度:步骤级 vs 任务级

反思可以在两个粒度上触发,它们有不同的适用场景,代价也不一样,选哪种需要根据任务特点来判断。

步骤级反思是在每个工具调用或推理步骤完成后立即检查。它的好处是错误早发现早纠正,不会让一个小错误在后续步骤里层层放大。

想象一下 Agent 在做多步信息检索:第一步选了一个不精准的搜索关键词,后续所有步骤都在错误的信息上继续,到最后才发现,前面的工作全废了。

步骤级反思能在第一步就发现关键词的问题,马上纠正,后续步骤都建立在正确基础上。适合这种粒度的场景是步骤之间强依赖、前一步错了后面会全错的任务。代价是每一步都多一次 LLM 调用,整体延迟和 token 消耗会大幅增加,一个 10 步的任务可能实际要调用 20 次 LLM。

任务级反思是整个任务执行完之后做一次整体评估。好处是开销更小,整个任务只多一次 LLM 调用;而且从整体视角审视,能发现步骤级看不到的问题,各个步骤单独看都是对的,但整体结论前后矛盾,或者各部分之间衔接不自然,这种问题只有从整体视角才能看出来。

代价是如果任务中途某步出了大问题,到最后才发现,前面的执行都已经浪费了。适合步骤之间相对独立、最终输出的整体质量更重要的场景,比如生成一份报告。

多 Agent 互评:为什么「他人审视」比「自我检查」更好

除了单 Agent 的自我反思,还有一种效果通常更好的方式,多 Agent 互评:专门设置一个独立的 Critic Agent,让它来审查执行 Agent 的输出。

为什么独立的审查比自我反思效果更好?你可以类比代码 review 的场景:一个人写完代码自己检查,和让同事来 review,发现的问题质量往往不一样。自己写的东西自己看,容易「视觉疲劳」,会不自觉地补脑跳过问题,潜意识里倾向于认为自己的逻辑是正确的。

在 LLM 里同样如此:单 Agent 自我反思时,评估者和生成者是同一个模型,它在生成输出时形成的一套「内部逻辑」,做评估时也会沿用这套逻辑,对自己输出的错误不够敏感,容易陷入「自洽」。而独立的 Critic Agent 没有这种包袱,它的唯一职责就是「找问题」,视角更客观,更容易发现执行 Agent 自己看不出来的漏洞。

互评的具体流程是:执行 Agent 生成输出,Critic Agent 审查并给出具体批注,执行 Agent 根据批注修改,Critic Agent 再次确认。

什么时候值得用这种方式?质量要求非常高的场景,比如生成代码后让独立的测试 Agent 来验证、生成分析报告后让事实核查 Agent 交叉验证。代价是又多一个 Agent 的调用成本,系统复杂度也更高,所以并不是所有场景都需要互评,普通场景用自我反思就够了。

进阶:Reflexion 和 LATS,把反思做得更深

前面讲的 Self-Refine 是最基础的反思模式,学术界在此基础上还有更进一步的探索,了解这些能帮你在面试里展现更深的理解。

第一个是 Reflexion,这篇论文的核心思路是:不仅让 Agent 反思当前输出的质量,还要让它把「失败经验」存下来,下次遇到类似任务时直接参考,避免重蹈覆辙。

你可以理解成 Self-Refine 是「写完作文当场改」,Reflexion 是「把这次犯的错记在笔记本上,下次写作文之前先翻一遍笔记」。

Reflexion 引入了一个「经验记忆」的概念,每次反思产生的教训会被存储起来,作为后续任务的参考上下文。这个思路在需要重复执行类似任务的场景里特别有价值,比如一个代码生成 Agent,第一次写出了有 bug 的代码,反思后不仅修好了这次的 bug,还把「这类 bug 的成因和避免方法」记下来,下次生成类似代码时就不太容易犯同样的错。

第二个是 LATS(Language Agent Tree Search),它把反思和树搜索结合了起来。前面讲规划能力时提到过 ToT(思维树),LATS 的思路是把蒙特卡洛树搜索(MCTS)和反思结合起来:通过 MCTS 同时探索多条路径,每条路径执行之后都会做评估和反思,反思结果作为经验反馈给后续的路径探索。这样一来,Agent 不仅能同时探索多条路径,还能从已经走过的路径里学到教训,让后续的探索更有针对性。代价当然也更大,既有多路径的成本又有反思的成本,目前主要还是学术研究场景。

还有一种思路叫辩论式反思,不是让一个 Agent 自己审查自己,而是让多个 Agent 互相辩论。比如设置一个「正方 Agent」和一个「反方 Agent」,正方提出一个方案,反方专门挑毛病、提反对意见,正方再针对反对意见优化方案。这种对抗式的反思比单方面审查更能暴露深层问题,因为反方的「职责」就是找漏洞,它会比一个只是「检查一下有没有问题」的 Critic Agent 更积极地挖掘问题。工程上偶尔会在高质量要求的场景里用到这个模式,比如重要的商业决策分析、法律文本审查等。

工程权衡:怎么用才合理?

理解了反思机制的原理和进阶方案之后,还需要知道工程上怎么合理地用它,不然反而会让系统变慢、变贵、甚至陷入死循环。

什么场景值得开反思?输出质量要求高、错误代价大的关键节点,比如最终报告生成、重要决策的推理过程,以及任务比较复杂、LLM 容易遗漏细节的场景,这些是反思最能发挥价值的地方。

什么场景不值得开?简单直接的任务,比如格式转换、简单问答,加反思纯粹是浪费。实时性要求高的场景也一样,一次反思至少多一次完整的 LLM 调用,延迟可能从 1 秒涨到 3 秒,有些应用场景根本接受不了。

最重要的是防死循环,必须设最大轮次,通常设 2-3 轮,绝对不能依赖 LLM 自己判断停止。原因是 LLM 有时会陷入「为了改而改」的循环,每次评估都觉得还有地方能优化,改完又有新的「问题」,每轮改动都很小但实质没有进步,系统就一直在转圈。硬性的轮次上限是唯一可靠的退出机制。

最后要对整体代价有清醒认知:每轮反思包含一次评估和一次改进,3 轮反思意味着在原始生成之外额外增加 6 次 LLM 调用,延迟和成本都会大幅增加,这是工程上做取舍的核心数字。反思是提升质量的有效手段,但不是免费的,用在刀刃上才有价值,不是每步都做。

答好这道题有几个要点。

首先要说清楚反思的闭环结构:两个 prompt 各司其职,评估 prompt 专门找问题,改进 prompt 结合原始任务和批注做定向修改,缺任何一个环节都会失效。

其次,评估 prompt 的两个关键设计要能说出来:给出具体检查维度,以及设置「PASS」出口,否则 LLM 要么流于表面、要么无限挑毛病。

第三,步骤级和任务级反思的区别很容易被忽略:前者错误发现得早但开销大,后者能看到整体问题但前期做的无效工作难以挽回,要根据任务特点选择。

第四,最容易被遗漏的工程要点是防死循环:必须硬性设置最大轮次(2-3轮),不能依赖 LLM 自己停止。

最后,如果能提到多 Agent 互评比自我反思效果更好,并说出原因(同一模型对自己的输出有「自洽」偏见),会是一个加分点。

16. 如何设计多 Agent 的协作与动态切换机制?

协作靠两件事:消息传递和共享状态。消息传递是 Agent 完成自己的工作后把结果发出去,下一个 Agent 取用;共享状态是所有 Agent 共同读写一个状态对象,记录任务进展和中间结果。

动态切换靠 Orchestrator 来做,有两种方式:一种是静态路由,提前写好规则「任务类型 A 就找 Agent X」;另一种是让 LLM 动态决策,根据当前情况实时判断该把任务交给谁。

我的实践是两种混用,主流程用静态路由保证稳定,边缘情况才交给 LLM 动态判断。

在展开细节之前,先从全局视角理解一下多 Agent 协作的几种主要模式。工程实践中常见的协作模式大致分为三类:

  • 第一类是流水线模式,Agent 之间按固定顺序依次执行,前一个完成后交给下一个,像工厂的装配线;
  • 第二类是层级模式,有一个 Orchestrator(指挥者)负责分配任务、收集结果,其他 Agent 各自执行分配到的子任务;
  • 第三类是协商模式,多个 Agent 之间没有严格的上下级关系,通过互相沟通、辩论来达成一致。

这三种模式不是互斥的,一个复杂系统里经常会混合使用。理解了这个大分类之后,再来看具体的通信方式和路由策略就很清晰了。

先说协作:Agent 之间怎么传递信息

你可以把多 Agent 系统想象成一个公司里的多个部门:研究部、开发部、测试部各司其职。部门之间传递信息,有两种方式。

  • 第一种方式,像发邮件。研究部完成了资料整理,就把报告「发」出去,开发部收到邮件后再开始工作。这就是「消息传递」的思路,Agent 完成自己的工作后把结果发送到一个消息队列,下游的 Agent 订阅自己感兴趣的消息,取到了再开始处理。这种方式最大的优点是解耦,研究 Agent 不需要知道谁在等它的结果,只管发;接收方也不需要知道消息是谁发的,只管处理。缺点是需要一个「邮件服务器」,也就是消息中间件来维护这套机制,部署成本稍高一些。

  • 第二种方式,像共享白板。公司里所有部门都盯着同一块白板,上面写着「当前任务是什么、进展到哪一步了、各部门完成了什么」。研究部写上「资料整理完成」,开发部一看,知道可以开始了,于是接手并写上「代码开发中」。这就是「共享状态」的思路,所有 Agent 都读写同一个状态对象。LangGraph 就是用这个思路来设计的,它有一个贯穿所有 Agent 的 State,每个 Agent 执行完就往 State 里写入自己的结果,下一个 Agent 直接从 State 里读取前面的产出。

这两种方式怎么选?如果各 Agent 之间的依赖关系比较强,前一步的结果要直接传给后一步,用共享状态更直接。如果你希望 Agent 之间尽量解耦,互相不知道对方的存在,用消息传递更合适。

状态管理:多 Agent 共享状态的设计要点

既然提到了共享状态,这里有必要展开聊一下状态管理的设计,因为这是多 Agent 系统里最容易出 bug 的地方之一。

为什么状态管理这么重要?你想,多个 Agent 都在读写同一个状态对象,如果设计不好,很容易出现一个 Agent 写入的结果被另一个 Agent 意外覆盖,或者读到了一半更新的脏数据。这就像公司那块共享白板,如果没有任何规则,两个人同时往白板上写东西,写完之后谁也看不懂。

工程上设计共享状态时有几个关键点需要考虑。

首先是状态结构要分层,通常会把状态分成「全局状态」和「局部状态」两层。全局状态存放所有 Agent 都需要读取的信息,比如用户的原始请求、当前任务进展、最终输出,这些是共享的。

局部状态存放每个 Agent 自己的中间结果,比如搜索 Agent 找到的候选文档列表、代码 Agent 生成的草稿代码,这些在 Agent 内部使用,不会直接暴露给其他 Agent,避免信息污染。

其次是写入规则要明确。最简单也最可靠的做法是「只追加不覆盖」,每个 Agent 完成工作后把结果追加到状态里,而不是修改已有的字段。LangGraph 的 State 更新机制就是这个思路,你定义好 State 的 schema,每个节点返回的是一个「增量更新」,框架帮你合并到全局状态里,这样就不会出现互相覆盖的问题。

最后是错误状态的处理。如果某个 Agent 执行失败了,它的错误信息也应该写入状态,而不是悄悄吞掉。后续的 Agent 或者 Orchestrator 读到这个错误状态后,才能做出正确的决策,比如跳过这一步、换一个 Agent 重试、或者直接终止任务。

再说切换:Orchestrator 怎么决定叫谁

「切换」就是决定下一步把任务交给哪个 Agent,这个决策动作在系统里叫做「路由」。Orchestrator 就是那个负责做路由决策的角色。

路由有两种策略。

静态路由,就是提前把规则写死。比如任务描述里包含「搜索」就找 Researcher Agent,当前步骤已经是「代码写完了」就找 Reviewer Agent,找不到匹配规则就回到 Orchestrator 兜底。

这就像工厂流水线,每道工序完成后,下一步去哪个工位是固定的,效率高、可预测、好调试。但它覆盖不了你没预料到的情况,如果任务走了一条你没定义规则的路径,系统就不知道该怎么办了。

动态路由,则是把「下一步找谁」的决策权交给 LLM 来做。Orchestrator 把当前任务描述、已经完成了什么、还有哪些 Agent 可以调用,全部告诉 LLM,让它判断「现在应该叫哪个 Agent 来做下一步」。

这种方式的优点是灵活,能处理任何你没预先设计的路径,任务走到一个边缘情况时,LLM 也能做出合理判断。缺点是每次路由都要多一次 LLM 调用,增加了延迟和成本,而且 LLM 偶尔也会路由错,系统行为的可预测性就降低了。

两种路由策略的对比可以用一张图来理解:动态路由在代码层面是怎么实现的?其实核心就是让 LLM 做一次分类决策,把可用的 Agent 列表和当前上下文传给它,让它返回应该调用哪个 Agent。下面是一个简化的示例

复制代码
def dynamic_route(task_context: str, available_agents: list[str]) -> str:
    """让 LLM 根据当前上下文决定下一步调用哪个 Agent"""
    prompt = f"""当前任务状态:
{task_context}

可用的 Agent:
{chr(10).join(f'- {agent}' for agent in available_agents)}

请根据当前进展,判断下一步应该交给哪个 Agent 来执行。
只返回 Agent 名称,不需要解释。"""

    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
    selected = response.choices[0].message.content.strip()
    return selected  # 返回选中的 Agent 名称

实际项目里通常还会加一些保护措施,比如校验返回的 Agent 名称是否在可用列表中、设置默认的 fallback Agent、记录路由决策的日志以便后续分析等。

Handoff 模式:Agent 之间的「接力棒」

除了由 Orchestrator 集中做路由决策,还有一种更去中心化的切换方式叫 Handoff(交接),这个模式在 OpenAI 的 Swarm 框架里被用来演示和推广。需要注意的是,Swarm 是一个教育性/实验性框架,OpenAI 官方明确说它不是生产级工具,但它对 Handoff 模式的展示非常直观,很适合理解这个概念。

Handoff 的思路是:不需要一个中央的 Orchestrator 来决定「下一步找谁」,而是让当前正在执行的 Agent 自己决定「我做完了,接下来应该把任务交给谁」。你可以理解成接力赛跑,每个运动员跑完自己那一棒之后,直接把接力棒递给下一个人,不需要裁判在旁边喊「下一个是谁」。

这种模式的好处是每个 Agent 对自己的任务边界最清楚,它知道自己做完了什么、还缺什么,由它来决定下一步找谁,往往比一个外部的 Orchestrator 判断得更准确。而且没有中央节点的瓶颈,系统的扩展性更好。

缺点也很明显:没有全局视角。如果 Agent A 把任务交给了 Agent B,但 Agent B 又觉得这不是自己的活儿,再交给 Agent C,甚至 Agent C 又交回给 Agent A,就形成了死循环。

所以用 Handoff 模式时,必须设计好每个 Agent 的职责边界,并且加上防循环的机制,比如记录任务已经经过了哪些 Agent,如果发现重复经过同一个 Agent 就强制终止。

工程上怎么用

实践中最稳健的做法是两种路由组合用:主流程用静态路由,把确定性的节点切换都写成规则,保证绝大多数情况下系统行为稳定可预测;只在遇到没有匹配规则的边缘情况时,才交给 LLM 动态决策。这样静态路由负责「保底」,动态路由负责「兜住异常」,两者互补。

至于 Handoff 模式,它适合那种每个 Agent 职责边界非常清晰、任务流向相对确定的场景。如果你的系统里 Agent 数量不多、每个 Agent 的输入输出接口定义得很明确,用 Handoff 比用中央 Orchestrator 更简洁。但如果 Agent 数量多、任务流向复杂,还是建议用 Orchestrator 来统一调度,避免 Agent 之间的交接变成一团乱麻。

通信方式的选择同理:如果你的多 Agent 流程是一条相对清晰的流水线,各步骤之间有明确的前后依赖,就用共享状态,简单直接;如果你的系统需要让多个 Agent 独立并行、互相不感知对方的存在,就用消息传递,解耦清晰。

答好这道题有几个层次。首先,协作机制要说出两种通信方式的本质区别:消息传递的核心是解耦,发送方不需要知道接收方是谁,适合 Agent 之间需要独立运行的场景;共享状态的核心是直接,所有 Agent 读写同一个对象,LangGraph 就是这个思路,适合各步骤依赖关系明确的流水线型任务。

这两种选哪个,取决于 Agent 之间的依赖有多强。其次,动态切换要说出静态路由和动态路由各自的优缺点:静态路由稳定可预测,但覆盖不了没预料到的边缘情况;动态路由灵活,但每次多一次 LLM 调用,且行为不可预测。

最容易被忽略的点,也是最能体现工程经验的答法,就是说出「主流程静态路由保底,边缘情况才交给 LLM 动态决策」的混合策略。这个答法面试官一听就知道你真的做过多 Agent 系统。

相关推荐
kyriewen1 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
黄敬峰3 小时前
从零搭建 RAG 应用 —— 一个故事带你彻底搞懂检索增强生成
面试
众人皆醒我独醉4 小时前
etcd,其实不是你以为的"数据库"——Kubernetes 大脑的六个反直觉真相
面试·kubernetes
Hyyy4 小时前
Electron-Vite是什么,和Vite有什么区别
前端·面试
兰令水6 小时前
hot100【acm版】【2026.7.14打卡-java版本】
java·数据结构·算法·leetcode·面试
SamDeepThinking8 小时前
Java面向对象在JVM里怎么实现
java·后端·面试
恣逍信点8 小时前
《凌微经》通俗解读——哲学第一因
学习·职场和发展·创业创新·学习方法·业界资讯·交友·哲学
不简说10 小时前
JS 代码技巧 vol.1 — 10 个让代码少写 30% 的小套路
前端·javascript·面试
Mr_凌宇10 小时前
# AI 应用工程入门学习笔记 一
人工智能·面试·程序员
Mr_凌宇10 小时前
AI 应用工程进阶扩展学习笔记 二
前端·面试