面灵AI→

海康威视 AI Agent 一面:工具编排与上下文压缩

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍,然后讲讲你那个私人助理项目。
  2. Agent 如何完成一个完整任务?完整流程是什么?从用户输入到输出。
  3. 接收用户输入后,上下文怎么构造?包含哪些信息?怎么组织?
  4. 意图判断怎么做?什么时候需要调用工具?谁来决策?
  5. 工具调用参数怎么生成?结构化输出怎么保证?格式错了怎么办?
  6. 工具执行失败怎么处理?重试策略是什么?重试几次?
  7. 工具返回结果怎么注入上下文?放在哪个位置?为什么放那里?
  8. 怎么判断任务完成?终止条件是什么?谁来定义?
  9. 未完成怎么继续规划?谁来做决策?模型还是代码?
  10. 最终结果怎么做格式化和安全检查?有没有敏感词过滤?
  11. 如果用户说「我赶时间」,Agent 怎么快速响应?怎么降级?
  12. 如果用户说「帮我叫一辆车去机场」,需要调用哪些工具?怎么编排?
  13. 这些工具怎么编排?先后顺序怎么定?依赖关系怎么处理?
  14. 高峰期车辆紧张,Agent 怎么和用户沟通?话术怎么设计?
  15. 兜底方案怎么设计?有没有人工介入?什么时候转人工?
  16. 你怎么评估出行 Agent 的服务质量?除了准确率还有哪些指标?
  17. 如果让你设计行程规划 Agent,结合天气、路况、预算,你会怎么做?
  18. 多轮对话中用户改了需求,怎么处理?之前的计划怎么回滚?
  19. 上下文无限增长怎么控制?压缩策略是什么?压缩多少?
  20. 记忆压缩会丢信息,怎么评估损失?有没有量化方法?
  21. 多 Agent 协作时状态怎么同步?有没有共享状态机?
  22. 如果某个子 Agent 返回了错误结果,主 Agent 怎么发现?怎么纠正?
  23. 你怎么做链路追踪和可观测性?Trace 里记录哪些字段?
  24. 线上出问题怎么排查?先看什么?怎么定位到具体环节?
  25. 如果 Agent 调用外部服务超时,重试策略是什么?会不会重复操作?
  26. 重试会不会导致重复操作?幂等怎么做?key 怎么设计?
  27. 你怎么控制 Token 成本?有哪些具体手段?省了多少?
  28. 如果让你设计一个多轮对话状态管理,你会怎么做?状态存哪里?
  29. 你那个私人助理项目里,长期记忆怎么做的?存了什么?
  30. 用户偏好怎么抽取?怎么判断哪些值得长期存?谁来决定?
  31. 反问:团队现在做的是出行场景的哪一块?
  32. 手撕:给定一个数组,求最长子数组和为 k 的长度。

《参考解析》

上下文要按「用途分区、按重要性排序、可裁剪」来组织。 一段完整的上下文通常有五块:稳定的 system 段(角色、约束、工具清单摘要)、会话段(最近若干轮原文)、记忆段(长期偏好与已知事实,带来源与时间)、任务段(当前计划、待办、已完成的观察)以及检索段(外部知识,带出处)。这样分区的好处是压缩时能按优先级动手——system 与当前任务段不能动,会话段按新旧裁剪,检索段按相关性丢弃。工具返回结果的注入位置也有讲究:结构化数据(价格、时长、订单号)要提炼成短字段放在靠近模型决策点的位置,超长原始响应截断或落盘只留摘要与引用,否则关键结论会被淹没在噪声里。经验法则是「结论前置、证据可追溯」——模型更容易被它最近读到的内容影响,把要用的数字放到最后一段通常比埋在中间有效。

意图判断用分层路由,工具决策要区分「谁决策」与「谁兜底」。 推荐结构是:规则或小模型做最外层分类(闲聊、知识问答、需要工具的任务),再让主模型在缩小后的候选工具集里选择并按 schema 填参数。直接让大模型面对上百个工具做选择会显著抬高选错率。参数生成靠结构化输出保证——优先用厂商原生的 function calling 或受限解码,再叠一层 JSON Schema 校验;格式错时把校验错误的原文回灌一次让它改,第二次还错就用默认值、跳过该工具或转人工。这里要明确回答「最终谁兜底」:模型只负责生成候选动作,正确性的最终责任必须在代码这一侧,因为模型的输出是概率性的,把兜底交给它等于没有兜底。

失败要分类处理,重试的前提是幂等。 失败分三类:参数错(不该重试,回灌错误让模型改)、瞬时错(超时、限流、网络抖动,指数退避加随机抖动重试,通常两到三次封顶)、业务错(无车可派、余额不足,直接翻译成用户能懂的话术,重试一万次也没用)。超时时间按该工具的历史 P99 延迟设并留余量,不要用一个全局值;超时之后的正确动作是先查询状态再决定是否重发,而不是立刻重发。写操作必须带幂等键:由代码用稳定的业务字段生成(用户、操作类型、关键参数指纹),服务端用唯一约束或状态机去重,重试前先查上次结果。幂等键的生成规则和存储位置要能说清,否则「我们做了幂等」就是一句空话。

压缩与记忆的关键是「关键事实不能只存在摘要里」。 压缩策略通常是组合:保留 system 与最近几轮原文,更早的对话压成摘要,同时把订单号、地址、时间、金额、用户明确约束这些槽位抽成结构化字段独立保存,必要时用检索召回相关历史片段。评估损失要用回放集:拿一批长会话,比较压缩前后在任务成功率、关键槽位召回率、约束违反率三个指标上的差异;上线后靠 A/B 或灰度观察。多轮中用户改需求时,「回滚」这个词要拆开答:未执行的步骤直接改计划;已执行但可撤销的走补偿操作(比如取消已下的单);已执行且不可撤销的要显式告知用户当前状态并重新规划后续,同时所有写操作靠幂等键对账,避免补偿动作重复执行。长期记忆的写入由三类触发:用户显式要求、跨会话重复出现的偏好、任务结束的结构化总结;冲突时当前指令优先,长期偏好只当默认值。

出行场景的题考的是编排与「不要瞎承诺」。 「帮我叫一辆车去机场」的解法是先做槽位确认(起点、终点、时间、人数、车型偏好),缺什么问什么;然后按依赖图编排工具:先查路况估时与预估价,再查可用车型,最后才下单——下单这类有副作用的动作要用户确认,且只能在拿到确定结果后才算完成。高峰期无车时的话术设计原则是「给确定信息 + 给可选方案」,比如告知预计等待时间并给出加价、换车型、改时间三个选项,而不是让模型自由发挥说「马上就来」。降级路径要分层:换车型 → 改时间 → 换出行方式 → 转人工,并明确定义转人工的触发条件(用户明确要求、连续失败、涉及金额或纠纷、安全相关)。行程规划 Agent 的难点是多目标约束(时间、天气、路况、预算、偏好),实现上是先过滤硬约束,再对软约束打分排序,最后给出两三个方案让用户选择——把取舍摊开比给一个「最优解」更可信。

多 Agent 的状态同步与错误发现,靠状态机加证据校验。 共享内存只适合同进程的短任务,跨进程跨机的可靠做法是「状态落库 + 事件消息」:任务与步骤状态写在数据库里,Agent 之间只传事件,任何时刻都能从库中重建当前进度。子 Agent 的结果要带可验证证据(工具原始返回、引用、执行日志),主 Agent 不能只读它的自然语言结论;校验方式包括格式与 schema 校验、与已知事实的冲突检查(时间、地点、金额是否与已有槽位矛盾)、以及关键动作的二次确认。发现错误后的顺序是:重试该子任务 → 换工具或换子 Agent → 降级(跳过或简化)→ 转人工,并且每次降级都要打点。

可观测性决定线上能不能定位问题,字段设计比工具选型重要。 一条 Trace 至少要串起:请求 ID 与会话 ID、每一步的模型名与提示词版本、输入输出 token 数、工具名与参数摘要、工具耗时与错误码、以及最终任务状态。指标分三层:模型侧(时延、token、失败率、重试率)、工具侧(成功率、P95 时延、超时率、限流次数)、业务侧(任务成功率、平均轮次、人工介入率、用户放弃率)。线上排查的顺序是:先定位第一个异常环节(不是最后一个报错),再对齐时间线看是否有发布或配置变更,最后用固定输入换模型或换工具重跑来二分公司。成本控制分省 token 与省次数两条线:模型分层路由(意图识别用便宜模型)、前缀缓存、工具结果结构化与截断、并行工具调用减少轮次、中间结果缓存;「省了多少」这类问题必须有前后对照口径,否则不如说清策略与监控方式。

手撕:最长子数组和为 k,有负数时滑动窗口就失效了。 之所以不能照搬「最短无重复子串」那套双指针,是因为窗口右移时区间和不再单调,左指针不知道该往哪走。标准解法是前缀和加哈希表:遍历时维护 prefix,用哈希表记录每个前缀和最早出现的下标,查询 prefix - k 是否出现过,出现过就用当前下标减去它取最大长度;复杂度 O(n) 时间、O(n) 空间。常见追问方向:数组全为正时可以直接用双指针(右移扩张、超了左缩),空间更省;求「个数」时哈希表记录出现次数;求「最短」时要记录最近出现的下标而不是最早的;注意先查表再写入当前前缀和,且要预先放入 (0, -1) 处理从头开始的区间。写的时候把「为什么不能滑动窗口」讲在代码之前,是这道题最容易拿分的地方。