面试面经 · 第四范式
【第四范式】【Agent 开发】【暑期实习三面】面经(八股+大模型项目+手撕)
第四范式 Agent 开发 暑期实习三面(技术终面)面经
背景:海外一年制硕士,本科国内 211,投递时无正式实习,但有 2 个自己的 Agent 开源项目和 1 段实验室 RAG 落地经历。
题目摘要
- Go 语言基础:goroutine 与 channel 的底层实现,GMP 模型中调度器如何避免 goroutine 饥饿,以及
sync.Pool在什么场景下使用、有什么坑。 - MySQL 与 Redis 八股:MySQL 的
RR隔离级别下如何用MVCC + Next-Key Lock解决幻读;Redis 的zset底层跳表与哈希索引的取舍,以及缓存穿透/击穿/雪崩的应对策略。 - Agent 项目深挖:围绕一个基于 Function Calling 的客服 Agent,追问工具调用的错误恢复、上下文窗口超限处理、多轮对话中的状态管理。
- RAG 优化追问:检索质量差时如何诊断?重排(Rerank)的引入时机与代价?
- 推理成本优化:如何估算一次 Agent 交互的 token 成本?有哪些具体降本手段?
- 手撕算法题:「设计一个支持插入、删除、随机获取元素的集合(允许重复元素)」,即 LeetCode 381。要求写出核心思路与时间复杂度分析。
项目深挖
面试官对项目细节的追问非常猛,基本不聊框架,全在抠边界条件和工程取舍。
追问 1:你的 Agent 在 Function Calling 中,如果模型调用了错误的工具参数(比如日期格式不对),系统怎么处理?
参考回答方向:首先,在工具定义时用 JSON Schema 严格约束参数类型,并给每个参数写 description 提示模型。其次,在执行层加一层参数校验,如果校验失败,不会直接报错,而是把错误信息格式化为“工具返回的错误消息”回传给模型,让模型自行修正后重新调用。最后,设置最大重试次数(比如 2 次),超过后切换为兜底话术。面试官追问“如果模型连续两次修正都失败呢”,我补充了降级策略:放弃工具调用,走预设的 FAQ 流程,并记录日志用于后续优化 prompt 或工具描述。
追问 2:上下文管理怎么做?长对话中如何避免 token 爆炸?
参考回答方向:我的项目里用了双缓冲策略——短期记忆(最近 5 轮完整消息)和长期记忆(通过摘要提取关键信息,存到向量库)。具体实现是:当对话轮次超过阈值时,调用一次轻量模型(如 GPT-4o-mini)对历史对话做摘要,只保留用户的核心诉求和已确认的实体信息。同时,在每次工具调用时,只把与该工具相关的历史消息拼入上下文,而不是全量拼接。面试官追问“摘要会不会丢失关键信息”,我补充了“摘要后保留原始消息的索引,如果模型需要查细节,可以主动调一个 get_message_detail 工具”。
追问 3:如何评估你的 Agent 效果?A/B 测试怎么做?
参考回答方向:我用了离线评估(基于标注的测试集,算工具调用准确率和任务完成率)和在线评估(真实用户会话的 CSAT 评分、平均轮次、兜底触发率)。A/B 测试时,我按用户 ID 哈希分流,确保同一用户只进入一个实验组,同时用 t-test 检验指标差异的显著性。面试官追问“如果在线指标波动大怎么判断”,我回答会先看兜底触发率和工具错误率这两个过程指标,如果它们稳定,再去看最终的任务完成率,避免被随机噪声干扰。
手撕算法题
题意:设计一个数据结构,支持在平均 O(1) 时间内完成 insert(val)、remove(val) 和 getRandom(),其中 val 可能重复,getRandom() 需要按元素的实际数量等概率返回某个元素。
关键思路:这是 LeetCode 381 的变体。核心难点在于 remove 时如何保持 O(1) 且不破坏随机等概率。
- 用
map[int]map[int]struct{}记录每个值对应的索引集合(用哈希集合存索引,保证 O(1) 插入/删除)。 - 用一个
slice存所有元素值,getRandom直接随机索引取slice中元素。 remove(val)时,从val的索引集合中随便取一个索引i,把slice末尾元素last移到i位置,更新last的索引集合(删除末尾索引,加入i),然后删掉slice末尾,最后从val的索引集合中删除i。如果val的索引集合空了,就删掉这个 key。
时间复杂度:insert 和 remove 平均 O(1),getRandom 严格 O(1)。空间复杂度 O(n)。
我写完代码后,面试官追问“如果 remove 时 i 正好是最后一个索引怎么办”,我答“直接 pop 即可,不需要移动元素,因为 last 就是 val 本身”,面试官点头。
准备建议
- 把项目里的每个技术选型都准备一个“为什么不用 X”的答案。比如我用 Redis 做缓存,一定要能说清为什么不用本地内存或 Memcached;我用 Function Calling 而不是直接让模型输出 JSON,得能对比两者的可靠性、成本、延迟。面试官几乎每个问题都在试探你是否真正做过取舍,而不是照着教程堆技术。
- 手撕题不要只刷高频题,要刷“数据结构设计类”。第四范式的面试风格明显偏向工程设计,LeetCode 380/381、LRU、LFU、Trie、并查集这类题出现概率极高。建议把每道题的时间复杂度推导写清楚,特别是“为什么均摊 O(1)”这种细节。
- 准备一个“成本优化”的硬核案例。Agent 方向必问推理成本。提前算清楚:你的项目一次完整对话平均消耗多少 token?其中系统 prompt、历史消息、工具返回各占多少?你用什么手段降本(模型降级、缓存、摘要、动态上下文裁剪)?最好能给出一个具体数字,比如“引入摘要后,长对话的 token 消耗降低了 62%”,这种数据非常加分。
结果反馈
三面结束后 3 天收到 HR 电话,确认通过,约了 5 天后的 HR 面,后续顺利拿到 offer。整体感受是:第四范式的技术面非常务实,不考偏题怪题,但每个问题都会往工程落地上深挖,准备时务必以“能跑通、能量化、能对比”为标准。
想系统备战大厂大模型/Agent 开发?NiceOffer 提供 SDE+LLM 双轨 1v1 陪跑,合同保底 40w 年薪,文末扫码咨询。