面灵AI→

蚂蚁 Agent 开发一面:ReAct 与 Plan-Execute、切块策略与上下文压缩

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

《面试题目》

  1. 请介绍一个你深度参与的 Agent 项目:它解决什么问题?你负责的部分是什么?遇到的主要技术难点是什么,你是怎样处理的?
  2. 判断一个 Agent 是否适合进入企业生产环境,你会重点检查哪些能力和指标?
  3. 当你拿到来源多样、格式不一的外部资料时,会怎样处理它们,让后续检索能稳定找到有效内容?
  4. ReAct 和 Plan-Execute-Replan 在任务拆解、执行和调整策略上有什么不同?你会怎样判断该用哪一种?
  5. 哪些知识适合通过 RAG 动态检索,哪些更适合整理为 Skill 供 Agent 使用?你会依据什么做选择?
  6. 请从用户提交问题开始,说明项目中的检索链路:问题经过哪些处理,最终怎样转化为 Agent 可用的上下文?
  7. 文档切块时,你会如何确定 Chunk 的长度和边界?哪些因素会影响这个选择?
  8. 如果某个 Chunk 虽然包含答案相关内容,但也混入了很多无关信息,你会怎样减少噪声对回答的影响?
  9. 同一问题采用关键词、向量等多种检索方式后,系统怎样合并、排序并选出最终结果?
  10. 你会通过哪些数据和测试证明检索质量达到要求?如何区分检索问题和生成问题?
  11. Agent 的记忆可以怎样分层?每一层适合保存什么、服务哪些场景,又有哪些读取或写入限制?
  12. 项目中的上下文压缩在什么条件下触发?压缩时会怎样整理历史内容,并保证关键事实与约束仍然可用?
  13. 哪些信息必须在上下文压缩后保留下来?你会怎样把这些保留要求落实为代码或流程约束?
  14. 你了解 Claude Code 的上下文压缩机制到什么程度?它会怎样处理对话历史,以及压缩后的内容如何继续影响后续工作?
  15. 如果要重新设计一个你参与过的 Agent 项目,你会先重构哪一部分?为什么它比其他部分更值得优先处理?
  16. 怎样比较 DeepSeek harness 和 pi 的设计思路?你会从哪些方面分析它们的执行循环、工具调用和扩展方式?
  17. 在一个实际开发任务中,你会怎样把 AI Coding 与 Agent 能力结合起来?从需求理解、实现到验证,哪些环节适合交给 AI,哪些需要额外把关?

《参考解析》

企业级 Agent 的准入检查看四类指标:效果(任务成功率、需要人工介入的比例)、可靠性(同类输入输出是否稳定、失败是否可复现)、成本与延迟(单任务 token 与时长、P95 延迟)、可运维性(每一步有没有留痕、出错能不能定位到具体工具调用)。最容易被忽略的是第二类:演示能跑通和稳定跑通之间隔着大量边界情况,准入检查要专门准备一批「刁钻输入」来看它是明确失败还是胡编。

异构资料的清洗顺序决定了后面所有环节的天花板。实践顺序是:统一格式(PDF/HTML/Word 抽文本,保留标题层级)→ 去噪(页眉页脚、导航、广告、重复段落)→ 去重(同一份文档的多个版本只留最新的,否则检索结果会被旧版本占满)→ 结构化(表格还原成表格、代码块标记语言)→ 保留出处(每段能回溯到原文位置,后面评估和引用都靠它)。如果不做去重,很多「检索质量差」的问题其实是同一内容的多份副本挤占了召回名额。

ReAct 与 Plan-Execute-Replan 的差别在「计划何时固定」。ReAct 是边想边做,每一步根据上一步的观察决定下一步,灵活但容易在长任务里跑偏、也容易重复劳动;Plan-Execute-Replan 先生成完整计划再执行,执行中发现问题才重规划,好处是全局视角、可并行、可把计划给人看,代价是计划质量依赖首轮理解,环境变化快时会浪费。判断依据是任务的可预测性:步骤固定、依赖清晰的选计划式;需要探索、每步结果都会改变后续策略的选 ReAct。实际系统里常见的是分层——顶层用计划式拆解,每个子任务内部用 ReAct。

RAG 与 Skill 的边界是「知识的体量与更新方式」。RAG 适合体量大、会变、需要精确引用出处的知识(产品文档、工单、代码库);Skill 适合体量小、需要模型「照着做」的操作规程(某类任务的步骤、输出格式、判据)。分界线可以这样问自己:这份内容是需要被检索出来的事实,还是需要被遵循的指令?前者进 RAG,后者进 Skill。

检索链路的完整路径:问题进来 → 改写(把口语化的追问补全成独立问题,多轮场景必需)→ 意图判断(要不要检索、检索哪个库)→ 多路召回(向量 + 关键词 + 结构化过滤)→ 融合排序(RRF 或加权,再上重排模型)→ 上下文装配(按预算裁剪、去重、加出处)。每一步都可能成为瓶颈,所以要有分步指标。

Chunk 长度没有通用最优值,看三件事:内容的自然边界(章节、段落、代码块,切断表格和代码是常见事故)、检索粒度(问题通常指向一个具体事实,chunk 太长会稀释相关性)、上下文预算(要放几个 chunk 进 prompt)。工程上的做法是分层:小的子块用于检索,命中后把它所在的父块送进上下文,兼顾召回精度和上下文完整性。重叠窗口用来避免边界处的答案被切断,但重叠太多会造成重复召回。

噪声抑制有几种手段可以组合:句子级过滤(把 chunk 里与问题无关的句子剔除,只留有支撑关系的)、重排(用交叉编码器对候选重打分,比向量相似度准得多)、引用约束(要求回答必须标注出自哪个 chunk 的哪一句,模型不容易编)、以及多 chunk 交叉验证(同一事实在多个来源出现才采信)。

多路检索融合的标准做法是 RRF(Reciprocal Rank Fusion):不看各路分数的绝对值(不同检索器的分数量纲不可比),只看排名,score = Σ 1/(k + rank),k 一般取 60。融合后再上重排模型取 top-k。这样做的稳健性来自「不同检索器都排在前面的结果大概率相关」。

区分检索问题和生成问题,靠分层评估。检索侧看 recall@k 和 MRR(标准答案所在的 chunk 有没有被召回、排在第几);生成侧在给定正确 chunk 的前提下看答案正确率(把正确的 chunk 直接喂给模型,如果这时还答错,就是生成的问题)。这两套指标要分开跑,否则一个「答错了」的 case 永远不知道该修检索还是修 prompt。

记忆分层的常见切法:工作记忆(当前任务的中间状态,随任务结束丢弃)、会话记忆(本次对话的历史,按轮次或摘要压缩)、长期记忆(跨会话的用户偏好与事实,需要显式写入和召回)、领域知识(不属于记忆,走 RAG)。每层的读写限制不同:长期记忆写入要慎重(避免污染),读取要按相关性召回而不是全量塞进去。

上下文压缩的触发条件通常是三条之一:token 数超阈值、轮次超阈值、或者任务阶段切换(比如从探索进入执行)。压缩的做法是保留最近若干轮原文 + 更早的内容做摘要,摘要里必须保留的是:用户明确给出的约束与偏好、已确认的事实与数字、已经做过的决定与理由、未完成的待办。把这些要求落实成代码的办法是结构化——压缩时不是让模型自由写摘要,而是按固定字段填(目标、约束、已完成、待办、关键事实),字段缺失就重试。

关于 Claude Code 的压缩机制:它在上下文接近上限时自动总结历史,把摘要作为新的起点继续;同时保留最近若干轮原始消息和文件读取记录,避免摘要丢掉刚用到的细节。压缩后的影响是双向的——省下了 token,但也可能丢掉早期约定的细节,所以重要的约束要在系统提示或项目配置文件里落地,而不是只依赖对话历史。

重设计的优先级排序:先改「错了会一路错下去」的部分,通常是上下文装配和验证环节,而不是模型或 prompt。理由是前者决定模型看到什么,后者决定错误能不能被拦住,这两处改动收益最确定。

DeepSeek harness 与 pi 的对比维度:执行循环的粒度(一步一调用还是批处理)、工具调用的协议与错误反馈方式、扩展机制(插件、配置文件、还是代码级接入)、以及上下文管理的策略。对比时不要只比功能列表,要看「同样的任务在两边跑,中间态长什么样、失败时能拿到什么信息」。

AI Coding 与 Agent 的分工:需求理解与方案评审留给人(这决定了做对的事),实现和重复性改造适合交给 AI,验证必须由程序兜底(测试、类型、lint)。把关点设在「产出可评审的中间物」——spec、diff、测试结果,而不是在最后一步才看整体效果。