面灵AI→

蚂蚁集团大模型算法岗面经 01:多模态与 Agent 合集

时间
2026-09
来源
牛客网

《面试题目》

面经 01 · 多模态算法(2026-08-20)

  1. 介绍项目
  2. 为什么多模态模型在票据场景中容易出现「看起来正确但实际错误」的结果?
  3. 多模态训练中,为什么需要区分图像级、区域级和 token 级监督?
  4. SFT 和偏好优化阶段的 batch size 过大或过小,会造成什么问题?
  5. 为什么某些多模态训练会使用反向 KL,而不是正向 KL?
  6. GRPO 和 DAPO 的核心差异是什么?多模态场景如何改造?
  7. 多模态模型做 RL 训练时,如何防止奖励黑客?
  8. 多模态模型中的视觉 token 压缩为什么可能损失关键字段?如何改进?

面经 02 · 智能体与大模型应用工程(2026-06-11)

  1. 项目中本地缓存和 Redis 二级缓存的设计,你认为哪些链路会使用这个本地缓存?
  2. 缓存的更新是怎么想的?
  3. 本地缓存的过期时间大概是多久?
  4. 你认为用户量多少、什么场景下会用到两级缓存这种复杂的方案?
  5. 你用 MQ 去做异步订单,是怎么在自己的电脑上测试这一块的?
  6. 怎么保证 MQ 的消息只被接收一次?
  7. 什么场景下只处理一次?
  8. 秒杀的时候你 Redis 中的集合是一直都有效的吗?
  9. 假如你想要删这个 set,但在你要删的时候服务挂掉了,这种情况怎么办?
  10. 对于个人订单的数据,你认为应该持久化在 DB 中还是 Redis 中?
  11. Redis 的持久化有研究过吗?
  12. 智能体项目为什么使用 Spring AI 框架,而不用 Python 的那些框架?
  13. 你去比较过用 Java 以及其他语言实现同一个模块之间的复杂度吗?
  14. 你认为 Java 跟 Python 比起来,它的优势是什么?
  15. 项目中 RAG 是怎么设计的?
  16. 对于 RAG 知识库,一般情况下你是怎么往里面导入数据呢?是在另外一个入口吗?
  17. 智能体多轮对话的循环框架用的是哪个?
  18. 你觉得用 Java 做的话,怎么让 CPU 的利用率提高?Spring AI 这个选型你觉得它的优势在哪?
  19. 你这个项目里调用的模型是什么?
  20. 国内的大模型厂商和大模型都有哪些?

面经 03 · AI 应用研发(2026-05-30)

  1. agent 架构选用 LangGraph 或 LangChain 的原因是什么?核心考虑了框架的哪些优点?
  2. 工具链的具体流程主要是哪些节点?
  3. 工具会不会有响应比较慢的情况?这种异常情况如何处理?
  4. 日志查询如果时间跨度大或关键词没包括,怎么处理?
  5. RAG 里面的 TOPK 是什么样的?为什么是这个设置?
  6. TOP3、TOP5 哪个效果好一点?好在哪里?
  7. 检索或召回阶段有没有做哪些优化或不同方案的比较?
  8. 混合检索设计了哪些检索模式?各自是怎么样的排序或占比?
  9. 评测主要是评测什么维度(除了语料相关性)?
  10. 语料库大概是怎样的一个大小?涉及哪些文档或格式?
  11. 如果再做一套企业级的类似技术栈项目,大概要花多久?
  12. 模型训练项目主要做什么内容?
  13. 奖励模型主要在哪个训练阶段用?
  14. PPO 和 GRPO 是用在哪个阶段?
  15. 经过几个训练阶段各都有哪些提升?有没有效果的衡量指标?
  16. 对 GQA、kvcache 这些专业名词哪个印象比较深?可以稍微展开一下吗?训练过程中都有用到这些技术吗?
  17. 手撕:数组中满足其总和大于等于 target 的长度最小的子数组的长度

面经 04 · 智能体与大模型应用(2026-05-26)

  1. 如何解决大模型幻觉?
  2. 对模型微调那些算法了解吗?
  3. 项目的 skills 是怎么实现的?你是怎么写 skills 的?
  4. Spring AI 框架的 skills 调用更像 Claude Code 还是其他 Harness Agent?
  5. 你说看过 Claude 源码,Claude Code 学习经验总结?
  6. Claude Code 是给模型用 grep 检索,没有用 RAG 检索,这俩有什么区别?为什么没用 RAG?
  7. 讲讲 RAG 的混合召回
  8. URL 解析过程
  9. TCP 三次握手、四次挥手
  10. MySQL 的数据结构,讲讲 B+ 树
  11. Spring 的控制反转、AOP
  12. 你平时用什么做 AI coding?

面经 05 · 大模型算法(2026-05-08)

  1. 介绍第一个项目,追问实现细节
  2. 脑机接口是如何做的?如何处理时序数据?
  3. AI coding 一般怎么用?
  4. 介绍 DPO、PPO、GRPO
  5. 介绍 Dify 平台
  6. 介绍 Ms-swift 平台
  7. Flash Attention 原理
  8. 手撕:对着屏幕用 PyTorch 实现一个神经网络
  9. 如何训练模型学会论文翻译的风格?
  10. 第二个项目的 query 和论文总结是如何匹配搜索的?
  11. 开放题:如何训练一个信贷系统,输入个人信息,可以输出意见和额度?

面经 06 · 大模型算法(2026-05-03)

  1. 实习拷打:实习项目具体做了哪些内容?
  2. 依次介绍项目
  3. 当时大家都在做 RL,为什么我们还在 SFT?
  4. 这里面最大的问题是什么?有什么困难?
  5. 你觉得还有其他亮点可以说说吗?

面经 07 · 大模型推理 AI Infra(2026-05-02)

  1. 做过哪些相关工作?看过哪些经典文章?参与过哪些开源项目?
  2. 为什么要做 Prefill 和 Decode 分离?追问:PD 到底争夺什么资源?和「直接多给卡、资源翻倍」相比本质差异是什么?
  3. AF 分离的好处和坏处?
  4. 常见并行模式怎么看?怎么根据具体场景选择合适的并行模式?选择因素有哪些?
  5. 追问:Prefill、Decode 与 Attention、MOE 这四种组合,分别更适合什么并行策略?
  6. 你觉得一个优秀的大模型推理框架,核心技术点有哪些?追问:量化选择策略
  7. GEMM 核心优化方法,ncu 怎么用?
  8. 拷打算子项目,MLIR / LLVM 理解

面经 08 · AI 应用研发(2026-04-30)

  1. 你做的两个小项目分别是什么?
  2. 你之前做的这个高并发 AI 聊天系统,具体是一个什么产品?
  3. 它和 ChatGPT 这类聊天产品相比,有什么不同?
  4. 你当时在设计这个聊天系统时,上下文管理和 prompt 注入时机是怎么设计的?
  5. 你用过 Claude Code、Codex 这类 AI IDE 或者 AI 编程工具吗?
  6. 你主要是用它们的 CLI、桌面端,还是网页版?

《参考解析》

1. 票据场景「看起来正确但实际错误」的成因:多模态模型有很强的版面与语义先验,容易顺着「一张像发票的图应该长什么样」去补全,而不是逐字段核对图像内容,于是金额大小写不一致、税号或日期错一位(8 看成 3、O 与 0、1 与 7)、明细合计对不上、购方销方串位这类错误非常常见,而且输出读起来完全通顺。根因有三层:视觉编码器分辨率与 patch 粒度不足以看清小号字与印章;端到端损失里关键字段的字符级正确率没有被直接优化;训练数据以「格式正确」的合成票据为主,模型学到的是模板而不是校验。治理手段对应三层:关键区域高分辨率切图或先定位再识别,做字段级结构化监督,关键数字加 token 级 loss 权重,最后再叠一层规则校验(大小写金额互验、合计等于明细加总、日期与税号格式校验)并把校验失败回退到人工或重新识别。评测也要换成字段级准确率,而不是整串完全匹配。

2. 图像级、区域级与 token 级监督的分工:图像级监督(整图对应一段描述、一个问答答案或一个偏好排序)便宜、覆盖任务语义与指令跟随,能约束全局正确性,但信号太粗,局部错一个数字照样拿高分。区域级监督(bbox、版面元素、字段框)把监督对齐到实体,教模型「哪个像素区域对应哪个字段」,是 grounding 能力的来源,对票据、文档、GUI、图表这类结构化场景几乎是必需的。token 级监督最细,直接决定字符准确率与坐标回归精度,也是抑制「数字幻觉」的唯一有效粒度。三者的正确关系是分工而不是替代:图像级给任务定义和偏好排序,区域级给空间对齐,token 级给细粒度准确率。只在图像级上做偏好优化,几乎必然训出「描述全面、关键字段乱写」的模型。

3. SFT 与偏好优化阶段的 batch size:SFT 阶段 batch 太小,梯度噪声大、loss 剧烈抖动、对学习率敏感、吞吐低,多模态样本还容易出现长答案或高分辨率图主导一个 micro-batch;batch 太大则泛化变差(大 batch 倾向收敛到尖锐解),等效学习率需要同步放大,显存也扛不住,通常要靠梯度累积、序列 packing、序列并行来折中。多模态还要特别注意不同分辨率的样本显存峰值差异大,梯度累积时按 token 数加权而不是按样本数平均,否则长答案样本的梯度被稀释。偏好优化阶段的问题正好相反:DPO 这类方法靠对内的相对差构造隐式奖励,batch 太小则这个差值的估计方差极大、梯度不稳;GRPO 的组内均值方差归一化在组大小太小时 advantage 偏差明显。batch 太大又会让同一 prompt 上的 on-policy 分布变化过快、重要性采样比失真,需要配合 clip、更小的学习率和更频繁的校正。实践上 SFT 用大 batch 加 warmup 与 token 级加权,RL/偏好优化用小 batch 加组内多次采样。

4. 反向 KL 与正向 KL 的区别:RLHF 类目标通常是最大化期望奖励再减去对参考模型的 KL 约束,方向选哪个决定了策略的行为。反向 KL(π 对 π_ref 的 KL)是 mode-seeking,惩罚的是「策略在参考模型概率很低的地方放质量」,会把分布收拢到参考模型的少数高概率模式上,生成更尖锐、更不容易发散;正向 KL(π_ref 对 π 的 KL)是 mass-covering,要求策略覆盖参考模型的全部模式,会把概率质量摊平,在多模态生成里容易变成「什么都有可能」的平庸描述。偏好优化普遍选反向 KL,是因为它天然对应信任域:只允许在参考模型本来就不错的模式里挑更好的那个,训练更稳、不容易为了刷奖励跑到分布外,同时保留一定熵。正向 KL 更适合蒸馏和变分推断那种要求覆盖面完整的场景。多模态场景还有一个额外好处:视觉输入模糊时,反向 KL 会抑制模型「发散地编造」多种互相冲突的描述。

5. GRPO 与 DAPO 的核心差异:GRPO 去掉了 PPO 的 value network,对同一个 prompt 采样一组 G 个回答,用组内奖励的均值和标准差归一化得到 advantage,省掉 critic 的显存与训练成本。它的两个已知毛病是:组内全对或全错时标准差为零,advantage 全为 0、梯度消失,训练被简单题和废题吃掉;以及按样本长度平均会系统性偏向长回答。DAPO 在这两点上做了四组改动:解耦上下裁剪系数(clip-higher),抬高上界以维持熵、避免策略过早坍缩;动态采样,过滤掉全对和全错的 prompt 组,只保留中间难度以保证有效梯度;token 级 loss,按 token 而非按样本长度归一化,缓解长度偏差;超长与软长度惩罚,处理被截断的样本、不给「写得长就分高」留口子。多模态改造的要点是:奖励要换成视觉相关且可验证的信号(字段准确率、OCR 交叉核对、坐标 IoU、工具执行结果),rollout 时的图像分辨率与预处理必须和训练一致,token 级归一化要把视觉 token 排除在文本 loss 之外,长度惩罚还要防住「用大段无关文字描述图片」这种刷分方式。

6. 多模态 RL 中的奖励黑客与防御:奖励模型学到的往往只是相关性——回答更长、术语更多、格式更整齐、出现某些关键词就被判为好答案,策略很快会找到这些漏洞:堆长度、复述图片内容、把格式写得漂亮但内容错,甚至完全不看图也能拿高分。防御的第一原则是尽量用可验证奖励替换学出来的奖励:规则与程序化校验(字段格式、金额互验、代码单元测试、工具执行成功)、OCR 或另一模型做交叉核对、多奖励模型集成投票。第二是持续审计:定期用新标注数据检查奖励模型与策略的一致性,监控奖励曲线与真实评测集的分化。第三是约束优化空间:长度分箱归一化与长度惩罚、KL 或信任域约束、保留 held-out 真实评测。多模态还必须做「图像扰动测试」:遮住关键区域或改掉一个数字,如果奖励不下降,说明模型根本没在依赖视觉输入,此时无论 reward 多高都是假的。

7. 视觉 token 压缩为什么会丢关键字段:高分辨率图像切成 patch 后 token 数随面积增长,推理成本难以承受,所以普遍用 pooling、pixel-shuffle、Q-Former 或 Perceiver 重采样把视觉 token 压到几百个。问题是压缩对高频细节是无差别抹平的,而票据的关键字段往往只占一两百像素(小号数字、密集表格线、印章、手写签名),压缩后这些区域的信息先被平均掉,模型只能靠语言先验猜,于是出现「看图也对、答得也顺,就是数字错」。改进方向:自适应压缩率,按版面检测、文本密度或 OCR 置信度给区域分配 token 预算,关键字段区域保留原分辨率、背景纯色区域多压;多尺度特征并存,全局低分辨率加局部高分辨率裁剪;把 OCR 文本作为旁路 token 与视觉 token 拼接,让模型至少有精确文本可用;训练时对关键字段的 token 级 loss 加权,让优化目标明确惩罚压缩带来的信息损失;压缩后位置编码要做相应的坐标映射,否则 grounding 会整体错位。

8. 本地缓存与 Redis 二级缓存的设计:本地缓存(Caffeine、Guava)适合「读多写少、变更不频繁、能容忍秒级不一致、热点集中」的数据,典型如商品详情、库存快照、用户基础资料、字典与配置、权限元数据;订单、余额这类强一致数据不该放本地。更新策略以 Cache-Aside 为主:写库成功后删缓存而不是更新缓存,避免并发写导致新旧值乱序覆盖;本地缓存的失效靠 MQ 广播失效消息给所有实例,或者带版本号(缓存值里编码 version,读时对比 Redis 中的最新版本,落后就回源)加短 TTL 兜底。TTL 分层:本地 5 到 30 秒(安全要求高就压到秒级),Redis 几分钟到几十分钟,并加随机抖动防雪崩。是否值得引入两级缓存要看 QPS 是否已经让 Redis 网络往返成为瓶颈、热点是否足够集中:只有当少数 key 承担大部分读流量时,本地缓存的收益才盖得住多实例不一致带来的排查成本,否则单层 Redis 更省事。

9. MQ 幂等与「只消费一次」:主流 MQ 只承诺至少一次投递,所以「只被消费一次」必须在业务侧靠幂等实现,而不是指望中间件。做法是用唯一业务键(订单号加状态版本)建去重表或唯一索引,插入冲突即视为重复投递直接 ACK;或用 Redis SETNX 加状态机 CAS,把「判断是否处理过」和「更新状态」放在同一个事务或 Lua 脚本里保持原子;消费成功后再手动 ACK,失败进重试队列、超过次数进死信并告警。真正需要「只处理一次」语义的是有副作用的操作——扣款、扣库存、发券、发通知,纯查询可以重复执行。本地测试这一块,实用做法是用 Testcontainers 或 Docker 起真实的 RocketMQ / Kafka,直接调用消费者方法并人为制造重复投递、乱序、消费者中途抛异常和 broker 重启,用拦截器或日志统计实际处理次数;只测 happy path 是测不出幂等 bug 的。

10. 秒杀场景 Redis set 的有效期与容灾:秒杀用的用户去重集合不能简单地「永不过期」,否则内存随活动数量线性增长;设 TTL 又要小心活动跨零点或提前预热时 key 消失导致重复下单。常见做法是 key 按活动维度命名(活动 ID 入 key),活动结束后异步清理。至于「删到一半服务挂了」,本质原因是删除不是原子的:集合元素多时 SREM 只能分批,可能删掉一部分后进程退出,状态就变成「有的用户能再买、有的不能」。真正的兜底是不把 Redis 当真相源:用户是否已下单以 DB 的唯一索引(用户 ID 加活动 ID)为准,Redis 只是前置拦截层,库存扣减用 Lua 保证原子、订单异步落库,重启后按 DB 对账重建集合。工程上还常用「先改名再后台删」避免大 key 阻塞主线程,或用 UNLINK 异步删除,并对大 key 做拆分。

11. Java 与 Python 的选型,以及 Spring AI 的取舍:Java 的优势在工程侧:Spring 的事务、依赖注入、AOP、配置中心、Micrometer 可观测性、成熟的线程池与 JUC、JVM 的 JIT 与 GC 调优、长稳运行的运维工具链,加上团队存量系统和公司内网权限、审计、网关的接入成本低,类型系统也利于长期重构。Python 的优势在模型侧:PyTorch、Transformers、vLLM、评测工具与最新论文实现基本都首发在这里,迭代速度快。智能体项目选 Spring AI 通常是「必须与既有 Java 微服务同栈」的结果,好处是复用 Spring 的 HTTP 客户端、重试、熔断、指标与灰度能力,代价是模型生态和社区示例明显落后。多轮对话的循环框架,Python 侧主流是 LangGraph 的显式状态图加 checkpoint 持久化与中断恢复;Java 侧则多是 Spring AI 的 advisor 机制加自研状态机。要提高 CPU 利用率,思路是 IO 密集任务用虚拟线程或异步化、把模型流式输出与工具调用并行、对工具做批量化与结果缓存,而不是盲目加线程数。

12. RAG 的 TOPK 与混合检索:TOPK 不是越大越好:召回变多会引入噪声、拉长上下文、推高成本,还会因为关键信息落在中间位置而被稀释。常见起点是单跳事实型问答 k 取 3 到 5,多跳或汇总型问题取 5 到 10,更稳的做法是两段式——粗召回 20 到 50 条,再用 rerank 模型(cross-encoder 或 LLM 打分)截到 3 到 5 条。TOP3 与 TOP5 谁更好取决于问题类型和 rerank 质量,应该在自己的评测集上扫一遍再定,而不是凭感觉。混合检索的模式一般包含:BM25 或稀疏向量负责精确术语、编号、报错码,稠密向量负责语义改写,外加结构化过滤(时间、权限、标签);融合常用 RRF(按排名倒数相加,不需要归一化、跨检索器可比)或加权线性融合(需要先归一化分数)。评测维度除语料相关性外,还要看召回率与命中率、上下文相关性、忠实度(答案是否有引用支撑)、答案相关性、幻觉率,以及业务维度(格式正确、可直接执行、引用可点开),通常用 LLM-as-judge 大规模跑、再人工抽检校准评委。

13. Prefill 和 Decode 分离到底在争什么资源:Prefill 是计算密集型(长序列的大 GEMM,打满算力,能效高,对显存带宽相对不敏感),Decode 是访存密集型(每步只生成一个 token,却要反复读 KV cache 和权重,算术强度极低,瓶颈在 HBM 带宽和 KV cache 显存占用)。两者混布在同一张卡上会互相干扰:长 Prefill 任务把 Decode 的 TPOT 拖出抖动、尾延迟不可控,而它们各自最优的并行策略也不一样(Prefill 适合张量并行或序列并行放大算力,Decode 适合按 KV 分片或数据并行摊带宽与显存)。PD 分离就是把两类负载拆到不同实例池,各自按自己的瓶颈扩缩容,中间传 KV cache(此时 KV 传输带宽成为新瓶颈,要靠 RDMA / NVLink、分层传输和 prefix cache 复用来摊薄)。和「直接多给卡、资源翻倍」的本质差异在于:加卡只是把同一份混合负载摊到更多硬件上,干扰和尾延迟依然存在,通信占比上升后甚至更差,利用率也不会变好;PD 分离改变的是资源配比与调度粒度,让算力和带宽各自按需分配,本质是异构负载拆分加池化调度。

14. GQA 与 KV cache:KV cache 是自回归解码时缓存历史 token 的 K、V,避免每步重算历史,显存占用正比于层数 × 头数 × head_dim × 序列长度 × batch × 数据类型字节数,长上下文大 batch 下它会比模型权重还大,直接决定吞吐上限。MQA 让所有 query head 共享一份 K、V,最省显存但质量掉得明显;GQA 是折中,把 query head 分成若干组、组内共享一份 K、V,显存与带宽降到 MHA 的 1/G 而质量接近,解码阶段每步要读的 KV 变少,收益直接体现在带宽瓶颈上,同时允许更大 batch。训练侧 GQA 影响的是 attention 参数量与前反向计算,通常从头训练,或把 MHA 的 K、V 头做均值池化初始化再继续预训练。压成本还有一整套配套:KV cache 量化到 INT8 或 FP8、PagedAttention 按块分配减少碎片、prefix cache 复用公共前缀、投机解码提高每步产出。训练过程中一般不使用 KV cache,靠 FlashAttention 的分块计算加反向重算避免物化整个注意力矩阵,省的是显存而不是带宽。

15. 大模型幻觉,以及为什么代码检索用 grep 而不是 RAG:幻觉的来源是训练目标只优化似然、不区分「不知道」,加上长尾知识不足、上下文缺失时仍要输出流畅答案。工程手段是按层叠加:检索增强把答案锚定在证据上并强制给出引用,用「资料中没有」类样本做 SFT 允许模型拒答,工具调用与代码执行做事实校验,结构化输出加规则校验,解码侧用受限解码和引用回链。至于 Claude Code 这类编程 Agent 用 grep 检索而不用向量 RAG,是因为代码里的关键线索是精确符号——函数名、变量名、报错码、路径——精确匹配比 embedding 相似度更准;grep 零索引成本、随工作区实时变化、结果可解释可验证,而 RAG 需要维护索引与失效逻辑,还会把「最相关」变成概率性的近似匹配,往往漏掉真正的那一处调用点。二者并不互斥:超大规模代码库通常先做粗召回(符号索引或向量),再用 grep 精确定位,实际 Agent 更多是「grep 加读文件加迭代」的循环,把检索决策交给模型自己。