Skip to content

智能体核心面试题 ​

智能体不是“更聪明的聊天机器人”,而是一个会在模型、工具、状态、记忆之间循环的工程系统。

答题主线 ​

“帮我安排周末旅行”通常要先拆城市、交通、预算和预订;“北京现在几点”则直接查一次就够。这个对比能说明规划、记忆和 Agent 循环各自解决什么问题,也能提醒你别把所有请求都做成长流程。

回答智能体题时,建议按这条线展开:

text
目标输入 -> 任务拆解 -> tool loop 执行 -> 状态更新 -> 记忆/上下文裁剪
-> 终止条件判断 -> 输出结果 -> trace / eval / cost 复盘

面试官通常想确认你是否真的理解这些东西:

  • Agent 和普通聊天的区别。
  • ReAct / planning / memory 各自解决什么问题。
  • 为什么要有最大轮数、预算和终止条件。
  • 什么时候单 Agent 足够,什么时候该拆多 Agent。

一、什么是智能体 ​

Q1:什么是智能体?它和普通聊天机器人有什么区别? ​

回答脉络

先给定义,再讲差别,不要只背名词。

参考答案

智能体是一个能够围绕目标做多步决策,并调用工具影响外部世界或获取信息的系统。普通聊天机器人更多是在一次对话里直接生成回答,而智能体会把任务拆成多步:判断要不要查工具、执行工具、观察结果、再决定下一步。

两者的关键区别是:

  • 聊天机器人偏“单轮生成”。
  • 智能体偏“多步执行”。
  • 聊天机器人更多依赖模型内部知识。
  • 智能体会显式管理状态、工具、记忆、预算和终止条件。

所以面试里如果只说“智能体就是会调用工具的模型”,那太浅了。更准确的说法是:智能体是一个围绕目标进行循环决策和执行的工程体。

Q2:为什么说 Agent 不是“模型自己完成任务”? ​

回答脉络

把模型决策和程序执行分开,强调工程控制。

参考答案

Agent 不是模型“自己”完成任务,而是模型和代码协作完成任务。模型负责判断下一步该做什么,代码负责真正执行、校验、记录和兜底。

比如用户让系统“查一下订单状态并判断是否可以退款”:

  • 模型判断应该先查订单再查政策。
  • 代码去调用订单 API 和政策库。
  • 模型读取工具结果后做下一步判断。
  • 代码负责权限、日志、错误和确认。

如果没有代码控制,模型就会变成一个不受约束的生成器,稳定性和安全性都很差。

二、tool loop 与 ReAct ​

Q3:tool loop 是什么?为什么它是 Agent 的基本骨架? ​

回答脉络

把 Agent 的最小闭环说清楚。

参考答案

tool loop 就是“模型决策 -> 工具执行 -> 结果回传 -> 继续决策”的循环。一个最小的 Agent 通常是:

  1. 把用户输入和历史消息放进 messages。
  2. 调模型,看是否需要工具。
  3. 如果有 tool call,就执行工具。
  4. 把工具结果带着 tool_call_id 回写到 messages。
  5. 继续调用模型,直到得到最终回答或触发停止条件。

它之所以重要,是因为它把“思考”和“执行”拆成了明确步骤,模型不再一口气编答案,而是每次根据最新观察继续推进。

Q4:ReAct 和 tool loop 是什么关系? ​

回答脉络

说明 ReAct 是思想,tool loop 是工程实现。

参考答案

ReAct 的核心思想是 Reason + Act:先推理,再行动,再观察,再推理。现代工程实现里,最常见的落地形式就是 tool loop。也就是说,ReAct 是策略,tool loop 是执行骨架。

你可以这样讲:

text
ReAct 负责告诉我们 Agent 应该“边想边做”;
tool loop 负责把这个思路变成可运行代码。

面试官如果问“为什么不是一次性让模型把所有步骤写完”,你就可以回答:一步写完会丢失中间观察,工具结果变化也没法及时反映到下一步判断里。

Q5:tool loop 为什么容易失控? ​

回答脉络

讲出循环、上下文、错误和预算叠加的问题。

参考答案

tool loop 容易失控,主要有四个原因:

  • 循环没有上限:模型可能一直想继续查。
  • 上下文越来越长:工具返回和历史消息不断膨胀。
  • 错误会传染:某一步工具出错后,模型可能反复重试。
  • 预算没限制:token、时间、调用次数没有上限。

所以一个真正可用的 Agent,不只是“能循环”,而是要能在合适的时候停下来。最大轮数、重复检测、超时、预算和人工接管都是必须的,不是加分项。

三、规划、记忆与上下文工程 ​

Q6:planning 有什么用?什么时候需要规划? ​

回答脉络

不是“多想想”,而是把复杂任务拆成可执行单元。

参考答案

planning 的作用是把复杂任务拆成子任务,并且给每个子任务设置完成条件。它能减少模型一边想一边乱跑的情况,也能让长任务更容易追踪和复盘。

适合规划的场景包括:

  • 调研报告。
  • 多步信息抽取。
  • 需要先查证再总结的任务。
  • 多工具、多阶段任务。

不太需要规划的场景包括:

  • 单轮问答。
  • 简单分类。
  • 固定流程判断。
  • 一步工具调用就能完成的任务。

更像工程师的回答是:能不规划就不规划,只有当任务确实有多个阶段、且阶段之间有依赖关系时,规划才值得上。

Q7:memory 和 context engineering 有什么区别? ​

回答脉络

记住“memory 是记什么,context engineering 是这一轮放什么”。

参考答案

memory 解决的是“长期要记住什么”。比如用户偏好、历史摘要、关键事实、已完成步骤。它关注的是跨轮次保留信息。

context engineering 解决的是“这一轮给模型看什么”。它关注的是把哪些消息、摘要、工具结果、检索内容放进当前上下文,以及放多少、按什么顺序放。

两者的关系是:

  • memory 决定能长期保存哪些信息。
  • context engineering 决定当前这次调用怎么组装输入。

很多 Agent 失败不是因为“记忆不够大”,而是因为上下文组装不当:把太多无关历史塞进去,导致真正关键的信息被淹没。

Q8:一个长任务上下文越来越长,怎么处理? ​

回答脉络

按“裁剪、摘要、检索、状态化”四种办法回答。

参考答案

我会按任务性质选择几种办法:

  • 裁剪:只保留最近几轮和关键事实。
  • 摘要:把长历史压缩成可读的状态摘要。
  • 检索:把旧信息放到外部存储,需要时再取。
  • 状态化:把槽位、阶段、证据、结论单独存结构化状态。

如果一个任务已经进入后半段,就没必要把早期每句话都带着。更合理的做法是保留“目标、已做事项、已知事实、未解决问题、下一步动作”这五类状态。

Q9:memory 能不能自动让 Agent 变聪明? ​

回答脉络

澄清 memory 只是信息管理,不是能力增强器。

参考答案

不能。memory 只能让 Agent 更容易记住重要信息,不能自动提升推理能力或检索质量。真正让系统变好的,通常是:

  • 更清楚的任务拆解。
  • 更好的检索和工具。
  • 更稳定的上下文组织。
  • 更严格的评估和纠错。

memory 如果设计不好,反而会把过时信息、错误结论和噪声一直带在系统里。所以记忆不是越多越好,而是越相关越好。

四、状态、终止条件与工程控制 ​

Q10:为什么 Agent 一定要有终止条件? ​

回答脉络

把“能继续”变成“该停了”。

参考答案

Agent 必须有终止条件,因为模型会倾向于继续生成和继续尝试。没有终止条件,系统容易出现:

  • 无限循环。
  • 重复调用工具。
  • 成本失控。
  • 结果迟迟不收口。

常见终止条件包括:

  • 达到最大轮数。
  • 得到最终答案。
  • 连续错误超过阈值。
  • 工具调用已无法推进任务。
  • 用户要求停止。

工程上,终止条件不是“看感觉”,而是明确规则。这样系统才能稳定、可评估、可复盘。

Q11:状态机和简单循环有什么区别? ​

回答脉络

说明状态机更适合有明确阶段的流程。

参考答案

简单循环更像“问一下模型 -> 执行一下工具 -> 再问一下模型”。状态机则会明确当前处于哪个阶段,比如:

  • 规划阶段。
  • 检索阶段。
  • 生成阶段。
  • 复核阶段。
  • 收口阶段。

如果任务有明确阶段和分支,状态机比纯循环更清晰,也更容易调试和评估。比如客服、调研、审校这类任务,状态机通常比“自由循环”更稳。

Q12:什么时候该用单 Agent,什么时候该拆成多 Agent? ​

回答脉络

先给原则:能单 Agent 就别拆;只有职责清晰、可验收、可隔离时才拆。

参考答案

我会优先用单 Agent,因为它成本低、上下文简单、调试容易。只有在下面这些条件成立时,才考虑拆多 Agent:

  • 任务可以明确拆分。
  • 每个子任务都有独立输入输出。
  • 子任务可以独立验收。
  • 上下文隔离能减少互相污染。
  • 拆分后总体质量或可控性明显变好。

如果任务本来就不复杂,强行拆多 Agent 往往只会增加协调成本和故障面。

五、Agent 模式题与追问 ​

Q13:一个 Agent 系统通常由哪些核心组件组成? ​

回答脉络

不要只说“模型 + 工具”,要把控制流和工程配套讲出来。

参考答案

一个较完整的 Agent 系统通常包括:

  • 模型层:负责理解目标、生成下一步动作或最终答案。
  • 工具层:负责检索、计算、查库、写入、调用外部系统。
  • 编排层:负责 tool loop、状态流转、分支和终止条件。
  • 状态层:记录任务阶段、已知事实、工具结果、错误和预算。
  • 记忆层:保存跨轮需要复用的用户偏好、摘要和历史事实。
  • 安全层:做权限、参数校验、危险动作确认。
  • 观测层:记录 trace、usage、latency、cost 和错误。

面试里这样答,比“Agent = LLM + tools”更完整,因为它说明你知道 Agent 是工程系统,不是一个 prompt。

Q14:Workflow、Agent、Tools 三者有什么区别? ​

回答脉络

Workflow 控流程,Agent 做决策,Tools 做执行。

参考答案

三者可以这样区分:

  • Workflow:流程相对固定,代码决定下一步,比如“分类 -> 检索 -> 生成 -> 审核”。
  • Agent:下一步有一定不确定性,由模型根据上下文和目标判断。
  • Tools:被 Agent 或 workflow 调用的外部能力,比如搜索、数据库、文件、计算器。

真实系统里经常是组合关系:外层 workflow 控制边界和状态,内层 Agent 负责不确定决策,工具负责真实执行。这样既能利用模型灵活性,又不让系统完全失控。

Q15:ReAct、Plan-and-Execute、Reflection 分别适合什么场景? ​

回答脉络

把三种模式的目标、优点和代价说清楚。

参考答案

模式适合场景风险
ReAct需要边查边答、边观察边调整容易循环,需要终止条件
Plan-and-Execute复杂任务、阶段清晰、子任务可验收计划可能过度复杂或执行中失效
Reflection需要自检、改稿、代码审查、报告复核成本更高,可能反复修改

ReAct 更像“边做边看”,Plan-and-Execute 更像“先拆计划再执行”,Reflection 更像“做完后复盘并修正”。面试里不要把它们讲成互斥,很多系统会组合使用。

Q16:复杂任务拆分为什么能提升 Agent 效果? ​

回答脉络

讲信息密度、可验证性、错误隔离。

参考答案

复杂任务拆分有三个好处:

  • 降低单步难度:模型每次只解决一个更小的问题。
  • 提高可验证性:每个子任务都有中间结果,可以检查。
  • 隔离错误:某一步错了,能定位到具体阶段,而不是整段答案都散掉。

比如自动调研任务可以拆成“生成子问题 -> 检索证据 -> 归纳结论 -> 复核引用”。这样比让模型直接写完整报告更稳。

Q17:任务拆分失败会带来什么问题? ​

回答脉络

拆分不是越细越好,坏拆分会增加成本和丢上下文。

参考答案

任务拆分失败常见问题有:

  • 子任务太细,协调成本超过收益。
  • 子任务边界不清,多个步骤重复做同一件事。
  • 上游漏了信息,下游只能猜。
  • 计划过时,执行中没有更新机制。
  • 每一步都调用模型,成本和延迟暴涨。

所以拆分时要保证每个子任务都有清楚输入、输出和完成条件。拆分的目标是让任务更可控,不是制造更多步骤。

Q18:Reflection 机制怎么设计? ​

回答脉络

Reflection 不是“让模型再想想”,而是基于标准检查结果。

参考答案

我会把 Reflection 设计成一个受控复核步骤:

  1. 先生成初稿或初始结果。
  2. 用明确 rubric 检查,比如事实、格式、引用、遗漏、安全。
  3. 输出问题清单,而不是直接无限重写。
  4. 根据问题清单修改一次。
  5. 设置最大反思轮数。

适合 Reflection 的场景包括:报告复核、代码审查、答案引用检查、长文改写、安全复查。它的价值是提升质量,但必须限制轮数和范围。

Q19:Reflection 会不会让系统越来越好? ​

回答脉络

不一定。它能改善某些错误,但也可能带来新错误和更高成本。

参考答案

Reflection 能让系统发现遗漏和不一致,但不是万能。风险包括:

  • 反思模型也可能判断错。
  • 修改时引入新错误。
  • 成本和延迟增加。
  • 多轮反思会反复拉扯。

所以我会把 Reflection 放在高价值或高风险任务里,并用 eval 验证它是否真的提升质量。如果质量提升不明显,就不值得增加这个步骤。

Q20:短期记忆和长期记忆怎么设计? ​

回答脉络

短期记忆服务当前任务,长期记忆服务跨任务复用。

参考答案

短期记忆通常存在当前会话或当前任务状态里,记录目标、已完成步骤、工具结果、未解决问题。长期记忆则保存跨会话仍有价值的信息,比如用户偏好、历史项目摘要、长期约束。可以结合记忆机制中的数据模型回答来源、有效期、权限和删除问题。

设计时要注意:

  • 短期记忆要及时清理,避免上下文膨胀。
  • 长期记忆要可检索、可更新、可删除。
  • 重要事实要有来源和时间。
  • 不要把错误结论永久记住。

记忆系统最怕“什么都记”,真正重要的是筛选、压缩和失效策略。压缩运行内上下文与保存跨会话记忆是两条不同链路,不能混为一个“记忆库”。

Q21:记忆压缩有哪些常见方法? ​

回答脉络

先区分运行内上下文压缩和跨会话记忆外化,再按滑动窗口、摘要、结构化状态、按需检索和分层组合回答。实现细节见记忆压缩。

参考答案

运行内压缩常见方法有:

  • 滑动窗口:只保留最近几轮对话。
  • 摘要压缩:把长历史压成任务摘要。
  • 结构化状态:抽取目标、事实、约束、待办。
  • 外化检索:把暂时不放进上下文的旧信息存到外部,需要时按权限和相关性召回;这是上下文管理手段,不等于自动写入长期画像。
  • 分层组合:近期原文、中期摘要和远期外化信息分开管理,按任务需要换入。

压缩时要防止两个问题:压丢关键事实,或者把模型推测当成事实写进记忆。工具调用还要按完整消息组裁剪,保留 tool_call 与结果的配对、来源 ID 和可回滚版本。

Q22:Agent 如何动态决定下一步该做什么? ​

回答脉络

可以由模型路由,也可以由规则或状态机路由。

参考答案

常见做法有三类:

  • 规则路由:确定性强,比如检测到订单号就查订单。
  • 模型路由:意图复杂时,让模型选择下一步工具或子任务。
  • 状态机路由:阶段固定但分支较多,比如客服和审批流程。

我更倾向于把高风险、确定性强的分支交给代码,把开放判断交给模型。这样系统既有灵活性,也有边界。

Q23:一个 Agent 能不能自己改自己的 prompt? ​

可以做,但要非常谨慎。一般要把它限制在受控场景里,比如提示词优化实验、离线评估、固定模板更新。在线系统里如果让 Agent 自由改自己的规则,容易产生漂移和不可预测行为。

Q24:Agent 会不会越“会思考”越好? ​

不一定。复杂任务需要一定规划,但过多思考会带来更高成本、更长延迟和更多不稳定性。工程上追求的是“够用且可控”,不是“无限会想”。

Q25:Agent 和 workflow 的关系是什么? ​

workflow 更像明确的流程编排,步骤和分支比较固定;Agent 更像带决策能力的执行器。真实系统里经常是两者结合:外层 workflow 控流程,内层 Agent 做判断和工具调用。

本节常见扣分点 ​

  • 把 Agent 说成“带工具的聊天框”。
  • 说不清 ReAct 和 tool loop 的关系。
  • memory 和 context engineering 混在一起。
  • 没有终止条件和预算控制。
  • 看到复杂任务就想上多 Agent。
  • 只会讲概念,不会讲状态和失败模式。

六、深挖题:Agent 状态机与运行控制 ​

Q26:为什么生产级 Agent 需要显式状态机?状态应该保存哪些内容? ​

考察点

考察是否能把“模型上下文”与“可恢复的业务状态”区分开,并能设计可持久化的状态结构。

回答脉络

先解释自由循环的问题,再说明状态机的节点、边和持久化字段,最后给出一个长任务例子。

详细参考答案

只用一个 while 循环也能做出 Demo,但生产环境需要知道任务当前在哪个阶段、为什么进入下一阶段、失败后从哪里恢复。显式状态机把这些信息变成可观察、可校验的状态转移,而不是藏在一段不断增长的对话历史里。

状态通常至少包括:

  • run_id、用户、租户和权限上下文。
  • 原始目标、约束、输入引用和任务类型。
  • 当前节点、状态版本和下一步动作。
  • 计划及每个子任务的状态、依赖和完成条件。
  • 工具调用记录、幂等键、结果引用和错误分类。
  • 已确认事实、证据来源、待解决问题和人工审批状态。
  • 已用 token、工具次数、成本、deadline 和取消标记。
  • 重试次数、checkpoint、版本信息和审计元数据。

例如调研 Agent 可以有 INTAKE -> PLAN -> RESEARCH -> SYNTHESIZE -> REVIEW -> DONE。如果 RESEARCH 中途进程重启,系统从数据库读取当前节点、已经完成的子问题和证据引用,继续执行未完成部分,而不是让模型从头猜测。

状态机并不意味着所有决策都写死。状态转移可以允许模型提出候选动作,但代码要验证当前节点是否允许这条边。例如 DONE 状态不能再调用写入工具,WAITING_APPROVAL 只能接受审批事件或取消事件。

工程落地

使用持久化 checkpoint,状态更新带版本号或乐观锁。每次状态转移写入事件日志,至少记录 from_state、event、to_state、操作者和原因。状态对象和消息历史分开保存:消息用于模型理解,状态用于恢复、审计和业务判断。

常见追问及答案

  • 状态全部放在 messages 里可以吗? 不建议。消息不适合作为权限、幂等、预算和恢复的唯一数据源,长度和格式也不稳定。
  • 状态机是否会降低 Agent 灵活性? 会限制无边界探索,但可以把开放决策放在允许的节点内,换来更好的可控性和可测试性。
  • 状态更新失败怎么办? 不应宣称动作完成;使用事务、版本检查或事件重放恢复一致状态,并告警处理不确定结果。

扣分点

  • 只列几个状态名,不说明状态数据和转移条件。
  • 把完整聊天记录当成业务状态。
  • 没有 checkpoint、版本和重启恢复设计。

Q27:如何设计 Agent 的状态转移,避免模型跳过必要步骤? ​

考察点

考察是否理解状态机守卫、前置条件、不变量和代码侧转移控制。

回答脉络

回答“模型提出意图,编排器验证边,业务服务执行副作用”,并举审批或退款例子。

详细参考答案

我会把状态转移定义成带守卫条件的边,而不是允许模型任意填写 next_state。例如:

text
NEED_INFO --收到完整订单号--> READY
READY --只读查询成功--> ELIGIBILITY_CHECK
ELIGIBILITY_CHECK --策略允许且用户已确认--> EXECUTE
EXECUTE --工具返回成功--> VERIFY
VERIFY --业务状态已确认--> DONE

每条边有明确的事件、前置条件和副作用。EXECUTE 前必须检查身份、资源归属、审批 token 和幂等状态;VERIFY 必须读取真实结果,不能因为模型生成了“成功”就直接进入 DONE。

代码侧还要维护不变量,例如:

  • 未通过权限检查不能执行写入工具。
  • 未获得审批不能进入高风险节点。
  • 同一个逻辑步骤不能生成多个未决副作用。
  • DONE 状态必须有结果引用或明确的安全拒答。

模型可以根据上下文建议“下一步想查订单”,但编排器只接受当前状态允许的工具。若模型请求非法转移,记录违规事件,返回受控错误,必要时终止或转人工。

工程落地

为状态机写转移表和属性测试,覆盖正常路径、重复事件、乱序事件、过期审批、越权动作和重启恢复。高风险边尽量由代码和策略引擎决定,不让模型直接控制。

常见追问及答案

  • 模型选错状态怎么办? 不直接写入状态;由编排器依据当前状态和工具结果决定,模型建议只作为输入。
  • 状态机和规则引擎有什么区别? 状态机管理阶段和事件流转,规则引擎负责某个条件或策略的判定,两者可以组合。
  • 是否允许回退状态? 可以,但要定义哪些回退合法、是否产生补偿,以及如何防止回退造成副作用重复。

扣分点

  • 让模型直接决定并写入任意状态。
  • 没有前置条件和不变量。
  • 不考虑乱序事件、重复事件和回退副作用。

Q28:规划器应该输出什么?为什么计划不能只是一段自然语言? ​

考察点

考察是否能把计划设计为可执行、可校验、可更新的中间表示。

回答脉络

从计划字段、依赖关系、完成条件和动态重规划四方面回答。

详细参考答案

自然语言计划适合给人阅读,但不适合直接驱动编排器。一个可执行计划至少要有:

  • 子任务 ID 和目标。
  • 输入引用和预期输出 schema。
  • 依赖的子任务 ID。
  • 允许使用的工具或 Agent。
  • 成功、失败和跳过条件。
  • 风险等级、预算和截止时间。
  • 当前状态和结果引用。

例如“先找资料,再写报告”太模糊;结构化计划应明确为:collect_sources 输出带 URL 和发布时间的证据列表,draft_report 依赖该列表,review_report 检查每个结论是否有证据。这样执行器才能判断是否可以并行、是否完成以及失败后重试哪一步。

计划也不是一次生成后永远不变。工具返回空结果、外部数据变化或预算不足时,系统要暂停受影响节点,重新规划剩余部分。已完成且有副作用的步骤不能被重规划器随意重复执行,必须读取 checkpoint 和幂等状态。

工程落地

使用结构化 schema 表示计划,编排器对工具白名单、依赖是否成环、预算总量和输出契约做校验。复杂计划可以用 DAG 表示;涉及强顺序和人工审批的部分仍由状态机控制。

常见追问及答案

  • 计划越详细越好吗? 不是。计划过细会增加 token、延迟和过时风险,应细到可验收和可恢复即可。
  • 规划器和执行器用同一个模型吗? 可以,但不必相同;规划更重全局分解,执行更重工具参数和局部决策,按质量和成本选择。
  • 计划中允许模型自由增加工具吗? 不应自由增加,必须受当前任务的工具白名单和权限约束。

扣分点

  • 计划只是几句口号,没有输入、输出和完成条件。
  • 没有依赖关系和动态重规划。
  • 允许重规划覆盖已经执行的副作用。

Q29:如何判断一个 Agent 任务是否真的完成?为什么“模型说完成了”不够? ​

考察点

考察完成条件、事实验证和业务验收,而不是把自然语言当作执行证据。

回答脉络

区分模型层完成、工具层成功和业务层完成,最后给出多条件收口。

详细参考答案

一个任务至少有三种“完成”:

  1. 模型完成生成:模型产生了最终文本或结束意图。
  2. 工具调用成功:某个 API 返回成功,但可能只是受理了请求。
  3. 业务目标完成:真实资源状态已经达到预期,并通过了必要的验证。

例如“帮我创建会议并发通知”不能只看创建 API 返回 200。系统还要确认会议 ID 存在、时间和参与人正确、通知任务已受理或发送成功。如果通知是异步的,最终状态可能只能表述为“已提交,通知发送中”。

我会为每类任务定义验收条件:必需的工具结果、必需字段、状态查询结果、证据要求和允许的部分完成状态。自然语言最终回答只能引用这些已验证状态;没有证据就说未确认或失败。

工程落地

在状态中保存 completion_criteria 和 evidence_refs,由代码执行验收函数。对于报告类任务,验收可以检查引用覆盖率、必需章节和事实一致性;对于写操作,验收要查询资源状态。

常见追问及答案

  • 部分完成怎么回答用户? 明确已完成、未完成、失败原因和下一步,不把部分成功包装成全部成功。
  • 工具返回成功但数据没变化怎么办? 标记为业务未确认或一致性延迟,按策略重查,超过 deadline 转人工。
  • 最终答案需要再次调用模型吗? 可以由模型负责表达,但事实字段应来自已验证状态,必要时用模板或结构化结果约束。

扣分点

  • 把 HTTP 200 等同于业务完成。
  • 把模型的 final 标记当作事实。
  • 不支持部分成功、异步受理和未知状态。

Q30:Agent 的终止条件应该如何分层设计? ​

考察点

考察是否能同时控制正常结束、资源预算、风险和异常终止。

回答脉络

按成功终止、资源终止、安全终止、故障终止和用户终止回答。

详细参考答案

我会把终止条件分成几类,而不是只设置一个最大轮数:

  • 成功终止:目标和验收条件全部满足。
  • 资源终止:达到最大轮数、token、工具次数、时间或费用预算。
  • 安全终止:发现越权、提示注入、高风险未审批、敏感数据外泄风险。
  • 故障终止:连续相同错误、依赖服务不可用、状态不一致或无法确认副作用结果。
  • 用户终止:用户取消、会话过期或权限撤销。

条件之间还有优先级。安全终止应优先于“继续尝试”,deadline 到期后不能因为模型说再查一次就突破。达到预算后,可以尝试一次低成本收口,例如返回已验证的部分结果,但不能为了生成漂亮总结继续消耗预算。

重复检测也很重要:对工具名、规范化参数和相关状态做指纹。如果连续多轮没有状态进展,说明循环没有推进,应暂停、换路径或转人工。所谓“进展”应尽量由状态字段或完成条件衡量,而不是由模型自评。

工程落地

每次循环开始前检查 deadline 和预算,每次工具执行后更新计数器;把终止原因写成枚举,如 SUCCESS、BUDGET_EXCEEDED、SAFETY_BLOCKED、NO_PROGRESS。用户看到的是可理解的状态,内部 trace 保留详细原因。

常见追问及答案

  • 最大轮数设置多少? 按任务分布和 SLA 设定,通过线上 P95/P99、完成率和成本调优,不存在通用数字。
  • 达到最大轮数要不要自动重启? 通常不应无条件重启,否则只是把无限循环隐藏起来;应先总结状态、改变策略或转人工。
  • 如何判断没有进展? 比较结构化状态、工具参数指纹、未解决问题和完成条件,不只比较自然语言。

扣分点

  • 只有一个 max_iterations,没有 deadline、成本和安全条件。
  • 终止后自动无限重启。
  • 不记录终止原因,无法区分失败类型。

Q31:上下文压缩应该压缩什么、保留什么?怎样避免压缩造成事实丢失? ​

考察点

考察是否理解上下文窗口、摘要失真、事实与推测分离,以及压缩后的质量验证。

回答脉络

先区分消息历史和任务状态,再按优先级保留信息,并说明压缩验证和按需召回。可以参考记忆压缩中的预算、消息组、摘要 schema 和回滚流程。

详细参考答案

上下文压缩不是简单地把历史截断或让模型写一段摘要。首先应把信息分层:

  • 不可丢失:用户目标、硬约束、权限、已确认事实、关键 ID、审批结果、未完成事项和失败原因。
  • 可压缩:重复寒暄、已经解决的中间推理、冗余工具原文、重复检索片段。
  • 可外置:大文件、完整日志、长网页、原始搜索结果和历史对话全文。

摘要中要明确区分“事实”“来源”“推断”“待确认”,保留时间和版本。例如不能把“工具返回订单状态为处理中”压缩成“订单已处理”。对代码或数字,不能只保留自然语言结论,最好保留结构化字段和原始产物引用。

常见组合是:最近若干轮消息 + 任务状态摘要 + 关键事实表 + 按需检索的旧信息。压缩后可用独立校验器检查关键字段是否仍存在、数字是否一致、引用是否可追溯;高风险任务可以不压缩关键证据,只压缩表达层。

工程落地

给摘要设置 schema,例如 goal、constraints、facts、decisions、pending、evidence_refs、uncertainties。摘要版本化并保留来源消息 ID;发现摘要质量异常时可以重新从原始事件重建,而不是继续压缩错误摘要。

常见追问及答案

  • 摘要模型会不会幻觉? 会,所以只允许基于给定内容抽取,关键字段做程序校验,并保留原文引用。
  • 窗口越大是不是就不用压缩? 不是。成本、注意力分散、工具结果噪声和长期任务仍然存在。
  • 为什么不把所有历史放向量库? 向量检索可能召回相似但错误的内容,状态和精确事实不应完全依赖语义检索。

扣分点

  • 只说“做摘要”或“滑动窗口”,没有保留策略和验证。
  • 把推测压缩成事实。
  • 丢失审批、权限、金额、ID 和未完成事项。

Q32:Agent 的短期记忆、长期记忆和外部知识库如何分工? ​

考察点

考察记忆类型、写入门槛、时效性、删除权和检索策略。

回答脉络

先定义三者解决的问题,再说明哪些内容不应写入长期记忆。记忆的存储、权限和生命周期可结合记忆机制回答,压缩算法则看记忆压缩。

详细参考答案

我会按生命周期分为:

  • 短期记忆:当前 run 的目标、对话、工具结果和临时假设,服务当前任务,任务结束后可清理。
  • 长期记忆:跨会话仍有价值且经过确认的用户偏好、稳定约束、项目事实,必须可更新、可删除和可追溯。
  • 外部知识库:组织政策、产品文档、代码、业务数据等共享知识,通常由内容管理和索引流程维护,不应因为一次对话就直接写入。

写入长期记忆前应满足价值、稳定性、可信度和隐私条件。用户说“这次我想用深色主题”不一定是长期偏好;用户明确说“以后所有项目都使用 Python”才可能成为偏好,但仍应允许查看和修改。错误推断、敏感信息、一次性任务细节、未经授权的第三方数据和短期情绪不应自动持久化。

记忆召回也要带来源、时间和置信度;如果新信息与旧记忆冲突,不能静默覆盖,应按时间、来源可信度和用户明确确认处理,必要时向用户澄清。

工程落地

记忆记录包含 memory_id、内容、类型、来源、创建时间、更新时间、租户、可见范围、置信度、过期策略和删除标记。提供用户查看、纠正、删除和导出机制。召回后还要做权限过滤,避免把一个项目的记忆带到另一个租户。

常见追问及答案

  • 长期记忆要不要全部向量化? 不一定。偏好和语义事实可向量检索,权限、时间、状态和精确字段需要结构化存储。
  • 记忆冲突怎么办? 保留来源和时间,按策略合并或标记冲突;关键事项请求用户确认。
  • 删除记忆是否只删向量库记录? 还要处理缓存、摘要、备份、索引和下游副本,并记录删除完成状态。

扣分点

  • 认为“对话里出现过的内容都应该记住”。
  • 不讲来源、时效、权限和删除。
  • 把长期记忆和组织知识库混为一谈。

Q33:Agent 任务中断、服务重启或网络断开后,如何恢复? ​

考察点

考察 checkpoint、事件日志、幂等、未知结果和可恢复状态设计。

回答脉络

先保存什么,再恢复时如何判断最后一步,最后说明哪些情况必须人工接管。

详细参考答案

恢复的核心不是把模型重新调用一遍,而是从持久化状态判断任务进度。每个重要阶段都要写 checkpoint,至少包括当前状态、已完成子任务、工具调用 ID、幂等键、工具结果引用、预算和版本。

最危险的是“工具可能已经成功,但 Agent 在写 checkpoint 前崩溃”。恢复时不能直接再次执行副作用,而应:

  1. 使用同一幂等键查询执行记录或业务状态。
  2. 如果能确认成功,补写 checkpoint 并继续。
  3. 如果能确认失败且无副作用,按策略重试。
  4. 如果状态未知且动作不可逆,暂停并进入人工确认或对账流程。

恢复还要固定任务启动时的 prompt、模型、工具 schema、策略和知识版本,或显式执行迁移,否则新版本可能改变原任务的含义。恢复事件也要防重复消费,使用版本号、租约或幂等事件 ID。

工程落地

采用“事件日志 + 当前快照”或持久化状态表。后台 worker 用租约领取任务,租约过期后允许其他 worker 接管;接管前检查心跳和版本。长任务支持暂停、取消、恢复和过期清理。

常见追问及答案

  • 只保存最后一条消息够吗? 不够,无法知道副作用是否完成、预算用了多少、审批是否过期。
  • 恢复时要重新规划吗? 先恢复已有事实和未完成节点,再只对剩余部分重规划;不能覆盖已经确认的副作用。
  • 服务重启导致重复通知怎么办? 通知工具使用幂等键和发送记录;客户端也按事件 ID 去重。

扣分点

  • 只说“把历史存 Redis”。
  • 不处理“执行成功但 checkpoint 未写入”的未知结果。
  • 恢复时无条件重跑所有工具。

Q34:什么时候应该让 Agent 自动恢复,什么时候必须人工接管? ​

考察点

考察是否能按错误可逆性、风险、信息缺口和自动恢复置信度做分流。

回答脉络

用“可自动修复、可等待、必须审批、必须人工”四类划分,并说明人工接管的上下文设计。

详细参考答案

自动恢复适合确定性强、无副作用或可安全重试的问题,例如临时网络错误、分页参数错误、短暂限流。需要等待的情况,例如异步作业未完成、审批未返回,可以进入等待状态,而不是继续消耗模型调用。

以下情况通常应人工接管:

  • 不可逆动作的结果未知。
  • 资金、权限、隐私或生产系统出现不一致。
  • 多次重试没有状态进展。
  • 输入缺少关键事实且用户无法及时补充。
  • 模型提出超出工具白名单的动作。
  • 安全策略命中但业务又确实需要例外处理。

人工接管不是简单地把一句“请人工处理”返回给用户。应生成交接包:用户目标、已完成步骤、工具结果和证据、失败原因、风险、待决策项、建议动作、相关资源和审计链接。人工处理后,系统把结构化决定写回状态,由编排器继续或结束。

工程落地

配置人工队列的优先级、SLA、分配规则和超时升级;人工操作也要有权限和审计。交接前对敏感字段脱敏,人工只能看到处理该任务所需的最小信息。

常见追问及答案

  • 人工接管是不是说明 Agent 失败? 不一定。高风险动作保留人工确认是设计目标,关键是交接信息完整、可恢复且可量化。
  • 如何减少人工量? 统计人工原因,补工具能力、规则、提示词、校验和评估集,但不能为了降低接管率而放宽安全边界。
  • 人工拒绝后模型还能继续尝试吗? 默认不能绕过拒绝;只有新的授权、输入或策略事件允许时才能重新进入流程。

扣分点

  • 把所有错误都自动重试。
  • 人工队列没有上下文、权限和 SLA。
  • 用降低人工率作为唯一优化目标。

七、深挖题:规划、反思与 Agent 组合模式 ​

Q35:ReAct、Plan-and-Execute、Workflow 三种模式如何选择? ​

考察点

考察能否根据不确定性、步骤依赖、风险和成本做架构取舍。

回答脉络

先分别定义三种模式,再给选择矩阵和组合方案。

详细参考答案

  • Workflow:代码预先定义步骤和分支,适合审批、客服分流、固定格式转换等确定性流程,优势是稳定、可测、成本可控。
  • ReAct:模型根据当前观察选择下一步动作,适合工具结果不可预知、需要边查边调整的问题,代价是循环和路径不稳定。
  • Plan-and-Execute:先生成计划,再由执行器完成子任务,适合研究、报告、复杂数据处理等阶段清晰的长任务,代价是计划可能过时,需要重规划。

选择时看四个维度:流程是否固定、环境反馈是否频繁变化、动作风险是否高、任务是否需要全局协调。高风险和固定流程优先 workflow;开放探索使用受限 ReAct;复杂长任务使用结构化计划,并在执行层加状态机和工具校验。

一个成熟系统往往是组合的:外层 workflow 管权限、预算和人工审批;规划器生成受 schema 约束的 DAG;每个子任务内部用小范围 ReAct;结束前再做一次规则化验收。

工程落地

先用固定 workflow 建立基线,只有明确的质量缺口才引入 Agent 自由决策。对每个节点记录完成率、平均步骤、工具错误率、成本和人工接管率,比较增加智能程度后的净收益。

常见追问及答案

  • Agent 越自主越先进吗? 不是。自主性应与风险、可解释性和收益匹配。
  • Workflow 是否不能用 LLM? 可以,workflow 的控制流是代码定义的,节点内部仍可用模型做分类、抽取或生成。
  • 为什么不全用 Plan-and-Execute? 简单任务会平白增加一次规划调用,且计划可能比问题本身更复杂。

扣分点

  • 把三种模式当作互斥名词背诵。
  • 不谈风险、成本和流程确定性。
  • 任何需求都推荐多步自主 Agent。

Q36:Reflection、Critique 和 Verifier 应该如何设计,才能避免“自我复读”? ​

考察点

考察反思的检查标准、独立性、修改边界和停止条件。

回答脉络

先指出泛化的“再检查一遍”无效,再讲可验证 rubric、独立检查器和有限修复。

详细参考答案

反思的价值不在于让模型再生成一段更长的思考,而在于针对明确的验收标准找问题。设计时我会把它拆成:

  1. 生成初始结果。
  2. 使用结构化 rubric 检查事实、完整性、格式、引用、安全和业务规则。
  3. 输出问题列表,每条包含位置、证据、严重级别和修复建议。
  4. 只对可修复问题做一次或有限次修改。
  5. 重新验证,若关键问题仍存在则降级或人工接管。

Verifier 尽量使用确定性代码或独立数据源验证,例如 JSON schema、引用是否存在、代码是否通过测试、金额是否匹配、SQL 是否只读。第二个模型可以检查语义,但不能被要求“把原答案说得更好”就算通过。

为避免自我复读,要限制最大反思轮数、要求每轮必须产生新的问题或状态变化,并比较修改前后的关键事实。如果只是换措辞却没有质量增益,应直接结束。

工程落地

为每个任务定义 verifier 接口:输入结果和上下文,输出 pass、fail、uncertain 及证据。不同风险等级配置不同检查深度,高风险任务不允许仅凭同一个模型自评通过。

常见追问及答案

  • 反思模型和生成模型必须不同吗? 不必须,但关键任务最好引入独立规则、不同提示或不同模型,降低同源错误。
  • 反思失败要不要继续改? 由严重级别决定;连续失败说明需要外部信息或人工,而不是无限重写。
  • Verifier 说通过就一定正确吗? 也不一定。要评估 verifier 的漏检率,并对关键类别做人工抽检。

扣分点

  • 把 Reflection 等同于再调用一次模型。
  • 没有 rubric、独立证据和最大轮数。
  • 反思只看语言流畅,不看事实和业务结果。

Q37:如何判断是否应该拆成多个 Agent?拆分后如何定义 Agent 之间的接口? ​

考察点

考察多 Agent 的必要性、职责边界、上下文隔离和可验收接口。

回答脉络

先说明拆分条件,再说明角色、输入输出、共享状态和失败处理。

详细参考答案

我不会因为“多 Agent”听起来先进就拆分。满足以下条件时才有价值:任务存在相对独立的专业职责;每个职责能定义输入、输出和验收标准;不同上下文之间存在隔离收益;并行执行能显著降低延迟或提高覆盖;拆分后的协调成本可接受。

例如自动调研可以拆成检索 Agent、事实核验 Agent、综合 Agent 和审校 Agent,但每个角色不能只用一句“负责研究”描述。检索 Agent 输出带来源、时间和片段的证据;核验 Agent 输出事实状态和冲突;综合 Agent 只能使用通过策略的证据;审校 Agent 输出问题列表和验收结果。

接口最好是结构化消息,而不是互相转发完整自然语言上下文。字段包括任务 ID、子任务 ID、输入引用、输出 schema、状态、置信度、证据引用、错误码和截止时间。共享状态要有写入权限边界,避免两个 Agent 同时修改同一事实。

拆分后还要处理部分失败、重复消息、超时、版本兼容和最终仲裁。协调器负责收集结果和决定是否继续,不能让某个子 Agent 的自然语言直接覆盖其他 Agent 的结论。

工程落地

给每个 Agent 注册能力、输入输出 schema、工具白名单、预算和可访问数据范围。使用消息队列或任务编排器传递结构化事件,所有事件带 correlation_id、causation_id 和幂等 ID,便于追踪因果链。

常见追问及答案

  • 多 Agent 之间可以共享完整上下文吗? 尽量不共享,只共享完成任务所需的最小数据和引用;完整上下文会增加成本和信息污染。
  • 一个 Agent 失败,其他 Agent 要不要继续? 看依赖关系。独立任务可以继续,关键前置失败则暂停下游并进入重试或人工处理。
  • 谁负责最终结果? 协调器或专门的合成/验收节点负责,且必须基于结构化结果和证据。

扣分点

  • 只按“搜索 Agent、写作 Agent”列角色,没有接口和验收。
  • Agent 之间传递大量未经筛选的自然语言。
  • 没有协调器、版本、幂等和部分失败处理。

Q38:多个 Agent 同时编辑同一个文件或资源时,如何解决冲突? ​

考察点

考察是否理解共享资源并发写入、锁、版本控制、补丁合并和人工裁决。

回答脉络

先避免无必要的共享写入,再讲资源所有权、乐观并发控制、合并策略和冲突升级。

详细参考答案

多个 Agent 同时编辑同一文件,不能依赖“大家都小心一点”。我会按以下层次设计:

  1. 优先分区:按文件、目录、函数或任务块分配所有权,尽量让每个 Agent 只写自己的范围。
  2. 共享基线:每次修改基于明确的 commit、版本号或文件哈希,提交时带上基线信息。
  3. 乐观并发控制:写入前检查当前版本是否仍等于基线;不一致则拒绝直接覆盖。
  4. 补丁而非整文件覆盖:Agent 提交结构化 diff、行级补丁或 AST 变更,协调器尝试自动合并。
  5. 合并后验证:运行格式检查、类型检查、单元测试和冲突扫描;验证失败不能宣布合并成功。
  6. 冲突升级:语义冲突、同一函数的不同修改、测试互相破坏时,交给专门的合并 Agent 或人工处理。

文件锁适合短时间、范围明确的写入,但不能解决所有语义冲突,也不能把锁一直持有到模型完成长时间思考。更常见的是短锁保护提交,配合版本检查和重试。对于数据库资源要使用事务、条件更新和唯一约束;对于外部文档或配置还要保存审计版本和回滚点。

例如 Agent A 修改认证逻辑,Agent B 同时修改同一文件的错误处理。即使文本补丁能拼接,最终行为也可能冲突,所以合并后必须重新运行相关测试,并由协调器检查任务目标是否仍满足。

工程落地

共享文件编辑协议至少包含 resource_id、base_revision、patch、owned_ranges、tests 和提交者身份。冲突结果分为可自动合并、需重新基于最新版本生成补丁、需人工裁决三类。任何覆盖写入都要留存旧版本、diff、测试结果和审批记录。

常见追问及答案

  • 加一个全局锁是不是最简单? 能防止同时写,但会降低并发,而且长任务持锁会造成阻塞;应优先短锁提交加版本控制。
  • Git merge 成功就代表冲突解决了吗? 不代表。文本无冲突不等于语义无冲突,必须做构建、测试和业务验收。
  • 冲突时让一个模型总结两份文件可以吗? 可以作为辅助,但输入应是明确 diff 和约束,最终仍需代码检查和人工裁决高风险修改。

扣分点

  • 只说“加锁”,不讲锁粒度、超时和死锁。
  • 把文本 merge 成功当成业务正确。
  • 允许 Agent 用整文件覆盖其他 Agent 的修改。

八、综合场景题 ​

Q39:设计一个能够处理“查资料、执行操作并支持人工审批”的客服 Agent,你会怎么拆? ​

考察点

考察能否把模型、RAG、工具、状态机、权限、审批、恢复和可观测性串成完整系统。

回答脉络

按请求接入、意图识别、查询、决策、审批、执行、验证和收口描述端到端流程。

详细参考答案

我会把它设计成外层状态机加受限 Agent:

  1. 接入与身份:创建 run_id,读取用户、租户、渠道和权限;做输入脱敏和请求限流。
  2. 意图与信息收集:模型输出结构化意图,例如查询订单、解释政策或申请退款;代码检查必需字段,缺少订单号就向用户澄清。
  3. 只读阶段:只开放订单查询、政策检索和账户信息工具,结果带来源、时间和资源范围。
  4. 资格判断:模型可总结政策,但是否符合退款条件由规则服务或策略引擎给出,避免模型自行解释成授权。
  5. 审批阶段:若是高风险操作,展示金额、订单、原因和影响范围,生成绑定参数的审批请求,Agent 进入 WAITING_APPROVAL。
  6. 执行阶段:审批通过后调用幂等退款工具,工具服务再次校验权限、状态和幂等键;超时进入未知状态并查询,而不是生成新退款。
  7. 验证与通知:查询真实订单状态和退款记录,确认后再向用户说明;异步通知则展示已提交和任务 ID。
  8. 恢复与观测:每个阶段持久化 checkpoint,记录工具、版本、成本、延迟、错误和人工接管原因。

模型在其中负责理解用户意图、选择允许的只读工具、解释工具结果和组织回答;代码负责状态转移、权限、策略、审批、执行、幂等、超时和事实验收。

工程落地

为查询和副作用工具分离凭据与权限,默认只读;审批 token 绑定 run_id、用户、租户、动作和参数摘要。对话层不直接调用数据库写入,所有副作用通过受控服务接口完成。

常见追问及答案

  • 政策检索结果和规则服务冲突怎么办? 规则服务负责资格结论,检索内容用于向用户解释;冲突记录并进入人工或规则维护流程。
  • 用户说“刚才已经确认过了”怎么办? 查审批状态和绑定参数,不能只信对话历史。
  • 退款 API 超时怎么办? 查询同一幂等键或退款记录,状态未知时暂停,不重复扣款。

扣分点

  • 模型直接根据政策文本决定退款并执行。
  • 审批只体现在聊天记录里。
  • 没有真实状态验证、幂等和未知结果处理。

Q40:如何给 Agent 做线上监控?哪些指标能帮助定位问题? ​

考察点

考察是否能从最终成功率下钻到节点、工具、模型和用户体验。

回答脉络

按业务结果、模型行为、工具链路、资源消耗、安全和人工运营六类指标回答。

详细参考答案

线上监控不能只看接口 200 或模型响应时间。我会至少关注:

  • 业务结果:任务完成率、部分完成率、真实验收通过率、用户重试率。
  • Agent 行为:平均和 P95 步骤数、循环率、重复工具调用率、规划失败率、终止原因分布。
  • 工具链路:各工具调用量、成功率、超时率、参数校验失败率、权限拒绝率、下游延迟和未知结果数。
  • 模型质量:结构化解析通过率、工具选择准确率、拒答准确率、引用支持率和人工抽检分数。
  • 成本体验:输入/输出 token、缓存命中情况、每任务成本、P50/P95 延迟、排队时间和流式首 token 延迟。
  • 安全运营:注入命中、敏感信息拦截、高风险审批量、越权尝试和审计缺失。
  • 人工运营:接管率、接管原因、人工处理时长、升级 SLA 和重复问题。

这些指标要能通过 trace_id 串起来,从一次失败任务下钻到具体 prompt 版本、模型、状态节点、工具参数和外部错误。监控应区分版本和流量切片,避免新旧版本混在一起掩盖回归。

工程落地

采用 trace/span 记录一次 run、模型调用、工具调用、状态转移和人工事件。敏感输入做脱敏或只记录哈希;成本使用 provider 返回的 usage 与内部价格表计算,异步工具把等待时间和执行时间分开统计。

常见追问及答案

  • 任务完成率由谁定义? 由业务验收条件定义,不由模型是否返回文本定义。
  • 平均成本有意义吗? 有,但还要看 P95/P99 和按任务类型、模型、租户的分布,异常长任务可能被平均值掩盖。
  • 发现循环率上升先改 prompt 吗? 先定位是工具错误、状态不推进、模型版本、上下文压缩还是 prompt 变化,再决定修哪一层。

扣分点

  • 只监控 QPS、响应时间和 HTTP 错误。
  • 没有 trace 关联模型、工具和状态。
  • 日志记录完整隐私内容,或成本只按请求次数估算。

本节新增题的作答主线 ​

面对 Agent 设计题,可以用下面的顺序快速组织答案:

text
先判断任务是固定流程还是开放决策
-> 定义状态、计划和工具边界
-> 规定每一步的输入、输出和验收条件
-> 加上权限、审批、沙箱和副作用保护
-> 处理超时、重试、幂等、checkpoint 和恢复
-> 设计终止条件、人工接管和可观测性
-> 用完成率、质量、成本和安全指标验证取舍

真正有分量的回答,应该能说明“某一步为什么由模型做、为什么由代码做、失败时状态如何变化、恢复后如何避免重复副作用”。

持续学习,持续实践。