Agent开发面试题

Agent开发面试题

一、工具调用与能力协议

1. 项目中把skill塞进system prompt,如果skill太多占用上游窗口太大怎么处理?

  • 核心原则:不能将所有skill常驻system prompt,否则会导致三个问题:上下文窗口被占满后旋转噪音过大;模型选择skill时容易混淆。更合理的方案是将skill做成外部注册表,system prompt仅保留最小规则和调用协议,真正的skill描述按需动态注入。
  • 具体实现:
    1. 先做一层skill路由(skill routine),可通过规则、分类模型或向量检索筛选出主题相关的skill(topic skill),再将几个skill的描述、关键参数和少样本示例(few-shot)拼入prompt。
    2. 若skill本身很长,将其拆分为招标版(精简版)完整版:先注入招标版让模型确认要调用后,再加载详细的完整版说明,可显著压缩token消耗。

2. 如果两个skill功能不同但description相似,导致Agent频繁加载错skill,怎么解决?

单靠自然语言匹配易出现误召回,解决思路是给skill增加更强的判别信息,而非堆砌模糊描述,具体分四步:

  1. 将skill从纯文本描述升级为结构化定义,包含适用场景、禁用场景、输入参数、返回格式、前置条件、失败条件和调用示例。
  2. 采用两阶段选择机制:先召回topk候选skill,再让模型根据参数约束和示例做二次筛选。
  3. 加入负样本,明确告知模型哪些问题不应该调用该skill。
  4. 执行前做schema校验和根因检查,即使模型选错也能阻止误执行。
  • 补充:若两个skill功能长期接近,建议在系统设计层面合并为一个skill,再通过内部参数路由,否则后续会持续出现误调用问题。

3. MCP、A2A、普通FunctionCalling,它们三个有什么本质区别?在工程里怎么选?

  • 本质区别:抽象层级和解决的核心问题不同
    • FunctionCalling:模型与宿主应用之间的单机式工具调用协议,模型输出结构化调用意图,宿主进程负责执行函数并返回结果,重点解决”模型如何调用本地/受控工具”的问题。
    • MCP:标准化的上下文和能力暴露协议,将资源、工具、提示模板等能力统一封装,解决”外部能力如何以标准方式被多个模型客户端/IDE发现和调用”的问题。
    • A2AAgent与Agent之间的协作协议,重点不是单个模型调用函数,而是多个智能体之间如何交换任务状态、转派任务和汇总结果。
  • 工程选型建议
    • 单应用内工具调用:用FunctionCalling足够
    • 多客户端共享一套工具/资源能力:选MCP
    • 多Agent分工协作、任务转派和结果汇总:选A2A

4. ToolCalling的本质是什么?工程上一般有哪几层?

  • 本质区别:普通函数调用是程序写死的(开发者控制调用者、函数和参数);ToolCalling是模型根据任务上下文自主输出工具名和参数,因此必须加一层校验和调度,不能把工具执行权直接交给模型。
  • 工程四层架构
    1. 工具注册层:统一管理所有可用工具
    2. 参数schema层:定义每个工具的输入输出规范
    3. 执行器层:负责实际调用工具并处理结果
    4. 审计日志层:记录所有工具调用的完整链路
  • 服务端必做校验:白名单校验、参数校验、超时控制、幂等控制和错误包装

二、上下文与记忆管理

5. 你觉得Agent设计里最重要的部分是什么?为什么?

Agent设计中最重要的部分是上下文工程

  • 根本原因:Agent不是单轮问答系统,而是持续决策系统。模型能看到的信息、信息的顺序和优先级、规则/证据/历史状态的区分,都会直接影响Agent的稳定性。
  • 效果对比:
    • 上下文工程做得好:模型会成为受控执行器,清晰知晓当前目标、约束条件和工具调用历史,输出准确的决策。
    • 上下文工程做得差:即使模型能力再强,也会出现目标漂移、工具误调用、对话污染和推理跑偏。
  • 核心结论:Agent设计的核心不是给模型最多的信息,而是给模型正确的信息

6. 上下文构成有哪些需要注意的要点?

  1. 角色隔离:system、developer、user、tool output、memory的优先级和边界必须清晰,不能将外部文本与系统规则混在一起。
  2. 信息裁剪:仅保留与当前任务相关的内容,避免堆砌所有历史对话、检测结果和工具说明。
  3. 格式控制:结构化上下文比纯自然语言更稳定,例如工具结果尽量用JSON格式,任务状态单独分段,历史对话做摘要而非保留原文。
  4. 来源清晰度分层:优先级顺序为「系统规则 > 用户输入 > 工具结果 > 模型猜测 > 无依据生成」。
  5. 长任务处理:长任务需做上下文压缩和过期淘汰,否则越到后期越容易发生状态漂移和旧信息污染新决策。

7. 你怎么设计Agent的长期记忆?

长期记忆≠存储所有历史,真正可用的长期记忆必须解决三个核心问题:什么值得写回、什么时候应该忘、冲突信息怎么处理,对应三大策略:

  1. 写回策略:仅保存高价值稳定信息(如用户偏好、身份属性、长期任务目标、反复出现的业务事实),而非每一句对话都入库。写回时优先做结构化抽取(例如将”用户更喜欢用Python”存为专门字段),而非整段存储原文。
  2. 衰减策略:记忆需设置时效性和权重,短期热点信息可设高权重并随时间衰减;长期稳定偏好可低频刷新,但不轻易删除。
  3. 冲突消减:结合时间戳、来源、可信度和置信度处理冲突,高可信度的新事实可覆盖旧事实,低可信度内容仅作为候选。更严格的设计可采用事件流+物化视图模式:所有记忆先写入事件流,再异步聚合成事实,既方便审计也支持回滚。

8. Memory通常分成哪几类?真正落地时怎么处理?

  • 三类核心记忆
    • 短期记忆:保留最近几轮对话和当前任务状态,保证会话连贯性
    • 长期记忆:保存稳定事实(用户偏好、身份属性、长期目标)
    • 摘要记忆:压缩长对话历史,提炼关键事实,减少token占用
  • 落地最佳实践
    不会把所有对话原文都塞进上下文,而是采用”分层存储+按需召回”策略:
    • 保留最近N轮对话原文
    • 将更久远的内容压缩成summary
    • 抽取关键字段单独存储
    • 生成时按需召回相关记忆,而非无脑全量拼接

9. 如果一个Agent需要同时读知识库、调外部API、结合用户历史偏好回答,怎么处理这3类上下文的优先级?

  • 核心优先级顺序(从高到低):
    1. 系统规则(最高优先级,不可被任何信息覆盖)
    2. 当前轮用户明确输入
    3. 外部工具返回结果和知识库证据
    4. 用户历史偏好(最低优先级)
  • 补充规则
    • 实时API返回的状态优先于知识库中的静态知识
    • 用户历史偏好只能影响表达方式或默认选择,不能覆盖当前轮的明确约束(如用户历史偏好Python,但本轮明确要求用Java,必须以本轮为准)
  • 实现建议:prompt组装时按槽位拼接,将当前目标、实时证据、历史画像分开,不要混成一段自然语言

10. 你怎么理解Agent里的”状态”而不是”上下文”?

  • 本质区别
    • 上下文:模型看到的输入材料,是大段的自然语言对话历史
    • 状态:系统对任务推进过程的结构化刻画,是机器可理解的结构化数据
  • 状态通常包含:当前阶段、已完成任务、失败次数、已调用工具、关键中间结果、待确认信息等
  • 核心价值
    很多Agent不稳定的本质不是上下文不够,而是没有显式的状态管理。有了显式状态,模型不用每次从自然语言里猜任务进度,系统可以明确告知当前节点,大幅提升执行一致性。

三、Agent核心架构设计

11. 了解主流的Agent设计吗?主流Agent设计一般分成几类?

主流单Agent设计主要分为四类:

  1. ReAct模式:最经典的边推理边行动模型,通过「思考→调用工具→观察结果→继续思考」的循环完成任务。
  2. Plan and Execute模式:先做整体规划,再按步骤执行,比纯ReAct更稳定,适合长任务。
  3. 路由(Router)模式:先做任务分类,再由路由分发到不同的Agent或工具链。
  4. Workflow+Agent模式:在固定流程中嵌入局部自主决策,是线上业务中应用最广泛的模式。

多Agent场景的常见协同模式:

  • 编排者(Orchestrator)模式:主Agent拆解任务并派发给多个子Agent执行。
  • 黑板(Blackboard)模式:多个Agent通过共享状态协同工作。
  • 纯点对点自由协同模式:线上应用极少,因为难以管控。

12. 如果让你设计一个Agent的规划器,怎么避免它每一步都重新规划导致路径震荡?

路径震荡的根源是规划器无状态且每次都整体重算,解决方案是分层规划+状态约束+重规划阈值

  1. 分层规划:将规划分为全局计划和局部调整两个层面
    • 全局计划:只定义阶段目标(如信息收集→证据校验→结果生成)
    • 局部调整:只允许在当前阶段内微调具体动作,不允许跨阶段修改全局计划
  2. 显式状态表示:给规划器明确的状态信息(当前子目标、已完成步骤、失败原因、剩余预算等),避免模型将新observation当成全新任务
  3. 重规划阈值:只有在关键前提失效、连续失败或用户目标明确变化时,才允许重新规划

13. 如何实现并行工具调用,既提升吞吐又保证一致性和可回放?

并行工具调用的核心不是同时调用多个接口,而是解决依赖关系、状态一致性、结果合并和失败回滚问题:

  1. 依赖关系处理:只有互不依赖的工具才能并行(如天气查询和汇率查询);若后一个工具依赖前一个的结果,必须串行执行。
  2. 一致性保证:禁止多个工具直接修改共享状态,采用「工具结果先写入临时观察区,再由调度器统一合并」的方式,避免并发写导致的状态污染。
  3. 可回放要求:每次工具调用必须携带trace id、type id、输入参数、输出结果和耗时,最终组成完整的执行DAG(有向无环图)。
  4. 失败处理:按工具粒度重试,不因单个工具超时丢弃全部结果。涉及副作用操作(如发信息、创建订单)时,并行执行前必须加幂等键,防止重复重试导致业务重复写入。

14. 在长任务场景里,怎么避免Agent无限推理或者死循环?

核心是靠状态机+明确的终止条件

  1. 硬性限制:设置最大推理步数、最大工具调用次数、最大token开销和最大执行时长
  2. 状态定义:明确定义”任务完成”、”任务失败”和”需要用户补充信息”的标准
  3. 重复动作检测:如果连续多步调用同一个工具且得到相似结果、没有产生新证据,强制终止并返回阶段性结论

15. 如果模型特别擅长生成,但不擅长严格遵守流程,怎么把它放进强约束工作流里?

核心方法是拆分生成自由度和流程控制权

  • 流程推进由外部状态机完全控制,模型不能跳步
  • 模型只负责当前节点下的局部判断和内容生成(如检索关键词改写、证据总结)
  • 线上稳定的Agent大多不是纯模型自治的,而是”系统控流程,模型控局部智能“的混合模式

16. 怎么设计Agent的失败恢复机制?

失败恢复不能简单等同于报错后重试,需按失败类型分类处理,且必须与状态机绑定:

  • 临时性错误(如接口超时):限次重试
  • 参数缺失:回到追问节点,向用户请求补充信息
  • 模型连续选错工具:触发降级策略(如改成规则路由或人工兜底)
  • 外部系统不可用:及时终止任务,返回清晰的失败原因
  • 禁止让模型自主决定是否重试,否则容易进入无限重试模式

17. 怎么判断一个Agent该做成单个Agent还是多个Agent?

判断标准不是任务听起来复不复杂,而是能力边界、上下文污染和天然并行性

  • 适合单Agent:任务虽然长,但上下文高度统一,单个状态机足以管理
  • 适合多Agent:任务包含明显不同的专业能力(如代码编写、合规审查、数据分析),拆分会让职责更清晰
  • 多Agent的权衡:好处是上下文隔离、局部优化方便;缺点是成本更高,需要处理通信、调度和一致性问题
  • 核心结论:不是Agent越多越高级,很多场景单Agent反而更稳定

四、RAG与Agent融合

18. RAG进入Agent后一般怎么设计?

  • 核心原则:RAG不应是固定的”先查再答”流程,而应作为Agent的一个决策节点
  • 具体设计:
    1. 模型自主判断:先判断问题是否真的需要外部知识,再决定query rewrite、query decomposition、rerank和生成的顺序
    2. 工具化封装:将RAG打包成一个标准工具,由Agent自己决定何时调用
    3. 检索结果预处理:不要原封不动扔给模型,需做去重、切片、排序和来源标注
    4. 生成约束:要求模型只根据检索到的证据回答,没有证据时明确说明”不确定”,从根源降低幻觉

19. 如果RAG召回了很多相互矛盾的文档,Agent应该怎么处理?

不能直接把矛盾文档丢给模型让它自己总结,否则容易生成看似圆滑但毫无依据的答案。正确做法是Agent作为证据调解器

  1. 先做证据归一化和冲突检测:按来源、时间、可信度对文档分组
  2. 冲突消解规则:
    • 时间敏感信息:新版本优先
    • 来源权威性不同:官方文档优先于第三方内容
  3. 无法消解时:明确告知用户存在冲突,并说明目前更可信的依据是什么

20. 如果工具调用成功但返回结果语义不完整,模型容易误判,怎么设计中间层?

这是工程中非常常见的问题(如接口只返回code无解释、字段含义不清),解决方案是增加工具适配层(Tool Adapter/Semantic Wrapper)

  • 不要把外部API的原始脏数据直接喂给模型
  • 中间层统一处理:字段补全、错误码翻译、单位归一、空值处理和置信度标注
  • 最终给模型的是标准化、可推理的中间表示,而非原始接口垃圾

五、安全与防护

21. Prompt Injection在Agent场景里怎么防?

Agent场景下Prompt Injection危险性更高,可能导致工具误调、越权执行甚至触发真实业务操作。核心防护思路是靠系统设计,而非仅靠prompt

  1. 角色和优先级隔离:外部知识绝对不能覆盖系统规则
  2. 检索文档定位:将检索文档视为”证据”,而非”命令”
  3. 工具调用管控:所有工具调用都要经过白名单和参数校验,高风险操作必须显式用户确认
  4. 全链路可追踪:输出和调用链路必须可追踪,出问题能完整回放
  5. 输入预处理:做输入清洗和风险分类,拦截明显越权或诱导内容

六、评估与监控

22. 怎么评估一个Agent系统的效果?

评估不能只看回答像不像人,而要看任务完成情况,一般分为四层:

  1. 回答质量:准确性、完整性、是否基于证据
  2. 工具质量:工具选择是否正确、调用是否成功、参数是否准确
  3. 任务质量:一次会话是否完成目标、是否需要额外追问、是否需要人工接管
  4. 系统质量:耗时、token消耗、错误率、稳定性
  • 补充:若包含RAG,需单独评估召回命中率、rerank效果和答案引用质量
  • 核心结论:Agent的效果是整条链路的分数,而非单个模型的分数

23. 如果发现Agent经常选错工具,怎么排查?

排查需从上游到下游逐步定位,不能只看最后一步:

  1. 检查工具描述和schema设计:边界是否模糊、参数是否能区分不同场景
  2. 检查skill routing层:是否一次性喂了太多候选工具,造成噪声竞争
  3. 检查prompt和few-shot示例:是否给了错误引导,或最近是否修改了system prompt
  4. 回放完整trace链路:检查模型选工具前看到的上下文、历史记忆是否污染判断、用户输入是否存在严重歧义
  5. 确认执行前是否有二次校验机制

24. 你觉得Agent最难监控的指标是什么?

最难监控的不是延迟、成功率等传统系统指标,而是表面成功但实际决策失误的问题:

  • 例如:工具调用成功但选错了工具、用了次优证据、本来应该追问却没有追问
  • 这类问题不会直接体现在传统监控上,但会严重影响用户体验
  • 必须增加决策质量指标:工具选择正确率、动作重复率、无效步数占比、应追问未追问比例、答案证据覆盖率

25. 如果让你做一个可以审计的Agent,你会保留哪些信息?

可审计的目标不是简单存档,而是能追责、能定位、能复现,至少需要保留:

  • 基础链路:用户输入、系统prompt版本、工具选集、最终工具选择、调用参数、工具返回、状态变迁、模型输出、最终结果
  • 完整审计:模型版本、知识库版本、检索到的文档ID、rerank结果、全局trace_id

七、工程化与稳定性

26. 在Agent系统里,什么时候应该追问用户,什么时候应该自己继续推理?

判断标准是信息缺口的影响程度和可补充性,本质是在体验和风险之间做平衡:

  1. 必须追问
    • 缺失执行任务的必要参数(如查订单必须要订单号)
    • 虽然能猜,但猜错的代价很高(如支付、发送、删除等副作用操作)
  2. 可以自行推理
    • 缺失的信息可通过工具或外部知识补齐(如天气查询中的城市可从用户画像获取)
    • 信息不影响核心决策,仅影响细节表达

27. 为什么很多Agent的demo挺惊艳,但一上线就不稳定?

  • Demo的理想环境:理想输入、有限工具、单次任务、短上下文,模型只要看起来会做事就行
  • 线上的复杂环境:输入脏、任务长、工具多、状态复杂、异常频繁,还要考虑权限、安全、性能和成本
  • 核心原因:Demo能跑通只能说明方向可行,而线上稳定需要把模型的不确定性关进工程的笼子里
  • 大多数团队后期遇到的问题,都不是模型不够强,而是来自状态管理、工具设计、上下文污染和缺少回放能力