面灵AI→

京东 AI Agent开发一面:架构、上下文与超时重试

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

《面试题目》

  1. 自我介绍,重点介绍你做过的最有技术含量的 Agent 项目。
  2. 你这个 Agent 项目整体架构是怎么设计的?画一下架构图,讲清楚每一层负责什么。
  3. 你刚才提到用了 ReAct 模式,具体是怎么实现的?Thought、Action、Observation 这三个环节在你的代码里怎么体现?每一步的输入输出格式是什么?
  4. 如果 LLM 返回的 tool call 格式不合法,或者参数类型不对,你的系统怎么处理?有没有做校验和重试?
  5. 你这个 Agent 在执行长任务的时候,如果中间某一步工具调用了 3 秒还没返回,你怎么处理?超时时间怎么设?
  6. 上下文管理是怎么做的?如果对话超过 100 轮,你怎么控制 token 消耗?
  7. 你说做了上下文压缩,具体怎么压缩的?压缩提示词怎么写的?压缩后丢失关键信息怎么办?
  8. Agent 执行过程中,工具调用失败或者任务被中断,应该如何设计恢复机制?比如失败重试、状态保存、任务恢复等。
  9. 如果 Agent 分析出的故障根因存在错误,后续如何重新触发诊断流程?在 LangGraph 工作流中,如何设计节点之间的跳转条件和边界判断?
  10. 为什么告警系统选择定时任务轮询,而不是通过 MQ 消息触发?两种方案各自有什么优缺点?
  11. 当定时轮询任务数量快速增长时,如何避免大量任务同时执行造成服务压力?分批执行、任务调度应该如何设计?
  12. 在 ReAct Agent 调用外部工具时,如果工具服务启动较慢(例如 Pod 启动需要 30 秒),你怎么处理?
  13. 你的 Agent 系统怎么处理分布式事务?Saga 模式?TCC?还是别的方案?
  14. 如果让你设计一个「智能客服 Agent」来处理退换货,你会怎么设计?涉及哪些工具?
  15. 你们的 Agent 和传统 API 服务有什么区别?在部署、监控、运维上有什么不同?
  16. 你怎么做 Agent 的监控和告警?关注哪些指标?告警阈值怎么设置?
  17. 如果 Agent 服务挂了,怎么保证用户无感知?有没有做熔断、降级、限流?
  18. 你怎么做 Agent 的灰度发布?怎么保证新版本不出问题?
  19. 如果 Agent 生成了违规内容,你怎么检测和拦截?
  20. 多模态在 Agent 中能做什么?比如用户上传截图,Agent 怎么理解?
  21. 如果让你设计一个企业知识问答 Agent,对接飞书、钉钉、邮件,整体方案怎么做?
  22. 你怎么理解 Agent 和普通大模型调用的本质区别?除了工具调用,Agent 还多了哪些能力?
  23. 如果 Agent 调用外部服务超时了,你的超时时间怎么设置?重试策略是什么?重试会不会导致重复操作?
  24. 在电商场景下,Agent 如何保证库存扣减的准确性?幂等怎么设计?
  25. 手撕题:实现一个简单的 Agent Loop,要求支持接收用户输入、调用 LLM、解析 tool call、执行工具、把结果返回给 LLM、判断是否结束。追问:如果 LLM 返回的 tool call 是多个并行的,怎么处理?如果工具执行需要异步,怎么设计?

《参考解析》

架构先分层,再谈每层的职责:讲架构图不要从 Spring Boot 启动流程讲起,而是按「接入层(会话、鉴权、限流)— 编排层(Planner、ReAct 循环、状态机)— 能力层(工具注册与执行、MCP Client、沙箱)— 记忆层(短期窗口、长期存储、检索)— 支撑层(可观测、评测、配置与灰度)」五块画,每块一句话说清输入输出和边界。面试官接下来一定会挑一层往下钻,所以每层都要准备一个「为什么这么切」的理由,比如工具协议统一成 schema 注册表是为了让新增工具不改编排代码,记忆层独立是因为它要被多个 Agent 复用。把「我的职责」说清(哪部分是我设计的、哪部分是团队既有能力)同样重要——被问到细节答不上来时,这决定了你是扣分还是被理解。

ReAct 的实现要落到数据格式:ReAct 在工程上就是「模型输出结构化动作 → 宿主执行 → 把观察结果拼回上下文 → 再问模型」的循环。要能讲出每一轮的消息结构:system 里的工具清单与约束、assistant 的 thought 与 tool_calls、tool 角色的返回(工具名 + 结果或错误)。tool call 的健壮性有三道闸:一是用 JSON Schema / Pydantic 做参数校验,不合法就把校验错误原文回灌给模型让它重发(限制重试次数);二是格式兜底,模型偶尔会输出包裹在 markdown 里的 JSON,需要容错解析并记录一次「格式修复」指标;三是语义校验,比如查订单的工具要求订单号存在,不存在就直接返回可读错误而不是抛异常。所有失败都要带上可判定的错误码回给模型,否则它只会换个说法反复重试。

超时、重试与幂等是一道题的三面:超时不能只设一个全局值,要分层:单次 LLM 调用(几十秒)、单次工具调用(读操作 1~5 秒、写操作可放宽但要设上限)、整个任务(分钟级,超过就转异步并通知用户)。超时后先判断「这个动作可不可以重试」——读操作可自由重试;写操作必须带幂等键(会话 ID + 步骤 ID + 工具名 + 参数哈希),服务端以唯一索引去重,重试时返回首次结果而不是再执行一遍。重试策略用指数退避加抖动,并限制次数(比如 3 次),超过就熔断该工具并降级(走备用通道或转人工)。对慢启动的服务(Pod 冷启 30 秒),正确做法不是拉长超时,而是限流加预热、就绪探针排除未就绪实例、把长耗时调用改成异步任务 + 轮询状态,等结果就绪再回到 Agent 循环。

上下文管理:分层压缩,而不是等超了再删:控制 token 的基本框架是分层——最近 N 轮原文保留;更早的历史做摘要(按主题分段总结,保留决定、约束、未完成的待办和关键实体 ID);大块工具输出(日志、代码、检索结果)只存引用与摘要,需要时再按 ID 取回;稳定知识(工具说明、系统规范)走前缀缓存。压缩提示词要结构化:让它输出「已完成的事、当前状态、待办与约束、必须保留的实体」,并明确要求不要臆测。压缩最大的风险是丢关键信息,所以要做两件事:一是把关键事实(订单号、文件路径、用户明确要求)单独抽成结构化状态存在对话之外,不依赖摘要保真;二是压缩后做一次自检,比如让模型复述当前任务与约束,答不上来就回退到上一个检查点重新压缩。

恢复机制:状态机 + 检查点 + 一致性校验:长任务要随时可中断可恢复,前提是每一步的状态都落库。做法是给任务定一张状态机表(task_id、当前步骤、步骤输入输出、外部副作用单号、状态、重试次数、版本号),每个步骤开始与结束各写一次检查点;服务重启后按状态机找未完成任务,从最后一个成功的检查点继续。恢复时最怕重复副作用,所以对外部写操作坚持幂等键;跨服务的多步操作可以用 Saga(每步配一个补偿动作,失败时反向补偿)或 TCC(Try 预留、Confirm 提交、Cancel 释放),对一致性要求不高的场景用「先预留后确认 + 对账」也够。恢复失败要有兜底:重试预算用尽后落死信表并告警,而不是静默放弃;一致性校验可以在恢复时比对本地状态与外部真实状态(查订单、查库存),不一致以外部为准再继续。

监控、灰度与内容安全,顺带把运维视角补齐:Agent 的观测比传统 API 多三类信号:轨迹(每一轮的 thought、工具名、参数、耗时、成败,建议用 OpenTelemetry 的 trace 串起来)、成本(token 与调用次数按会话维度统计)、质量(任务成功率、人工介入率、工具调用被拒率)。告警阈值按分位数设而不是按均值(P95 延迟、连续失败次数),并区分「模型侧抖动」和「工具侧故障」两类根因。灰度发布用提示词版本 + 模型版本 + 工具版本三个开关做组合,先小流量再全量,同时用固定的评测集跑回归;服务挂了要靠熔断、限流、降级兜住,至少给用户一个「任务已受理、稍后通知」的确定性答复。违规内容要走输入与输出双向检测(敏感词 + 分类模型 + 规则),命中就拦截并按策略转人工,全程留审计日志。