面灵AI→

字节跳动 AI Agent 开发二面面经

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

《面试题目》

项目深挖

  1. 讲一个你做过的 Agent 项目,它在真实业务里解决了什么问题?
  2. 那套系统整体架构长啥样,模块之间怎么通信?
  3. 项目里最让你头疼的一个坑是什么,怎么填上的?
  4. 为什么选 Agent 而不是写一堆规则脚本,收益到底在哪?
  5. 如果让你重做一遍,哪块你会直接换方案?

Agent / RAG 核心

  1. 给对话 Agent 加长期记忆,你打算怎么设计存储和读取?
  2. 当轮上下文和长期记忆怎么分工,什么值得落库?
  3. 上下文超出窗口了,你有几种压缩手段,各自会丢什么信息?
  4. 摘要压缩时你保留哪些关键信息,怎么判断哪些能扔?
  5. 多个 Agent 一起干活,怎么防止它们互相打架、卡死循环?
  6. 单 Agent、多 Agent、Workflow 编排,你什么场景选哪种?
  7. 走一步看一步和先列计划再执行,你更倾向哪种,为什么?
  8. Agent 调工具,工具挂了你怎么兜底,失败信息怎么回传给模型?
  9. RAG 为什么要用父子切块,小块检索大块返回解决了啥?
  10. 向量检索和关键词检索怎么结合,重排放在哪一步?
  11. 你用过的向量库,增删数据后索引怎么更新,缓存怎么失效?

八股基础

  1. HTTP 和 RPC 在内部调用上你怎么选,为什么?
  2. HTTPS 怎么保证传输加密,根证书起什么作用?
  3. 进程和线程的区别,Go 的协程你理解到哪一层?
  4. 垃圾回收你了解哪几种策略,分别适合什么负载?
  5. 缓存击穿、穿透、雪崩,你线上遇到过哪个,怎么处理的?

手撕

  1. 【手撕】给一串工具调用的日志,统计每个工具的成功率,并找出失败次数最多的那个工具名。要求时间复杂度尽量低。

工程与场景

  1. 你做的 Agent 上线后怎么评测效果,有没有离线评测集?
  2. 模型推理成本高,你从哪些维度去压?
  3. 你们模型是自己部署还是调 API,部署踩过什么坑?
  4. Agent 输出怎么防止跑偏、产生幻觉,你有哪几道闸?
  5. 需求方说「要快上线」但评测还没过,你怎么权衡?

反问与软素质

  1. 反问环节你会问什么,为什么这么问?
  2. 你觉得自己做 Agent 最大的短板在哪?
  3. 入职后第一个月只让你做工具调用稳定性,你会从哪入手?

《参考解析》

长期记忆与上下文的分工。设计记忆先分清三类信息的生命周期:会话内的当轮上下文、会话级的任务状态(已完成步骤、待办、中间结果,任务结束即丢)、跨会话的用户长期记忆(偏好、身份、历史结论,必须落库)。落库的门槛是「下次会话还需要且能从外部确认」——用户明确表达的偏好、可复用的结论、稳定的实体属性值得存;模型自己推断的中间结论、可能过期的临时数据不存,否则记忆库会变成垃圾场。存储形态按用途分:结构化事实放关系表或 KV 按 user_id 精确取;非结构化的经历与结论放向量库按语义召回。读取时不要把记忆全塞进 prompt,而是按当前 query 召回 Top-3~5 条、带时间戳注入,并在回答里可追溯;同时要有写入去重与冲突处理(同一事实有新旧两条就以新的为准,覆盖而不是追加)。

上下文压缩的几种手段与代价。常见有四类:滑动窗口(丢最老的对话,代价是早期设定的目标、约束可能被丢掉)、摘要压缩(把历史压成一段总结,代价是细节和精确值丢失、且有生成开销)、结构化抽取(把历史拆成实体/事件/结论/待办分开存,实体与结论保原文,代价是要维护 schema)、以及外部化(把长内容写文件或状态表,上下文里只留指针,代价是模型需要多一次读取动作)。判断哪些能扔的准则是「可重新获取的可以扔、不可复现的必须留」:原始工具返回的大 JSON、base64 图片属于可重新取回的,扔掉没关系;用户的原始表述、关键数字、ID、已经做出的决策不可复现,必须原文保留;压缩效果要用评测集看任务成功率,而不是只看 token 降了多少。

多 Agent 协作、选型与执行模式。多 Agent 打架通常有三种形态:互相等待(活锁)、反复推翻对方结论(震荡)、重复执行同一动作。治理靠显式的共享状态与硬约束:维护任务级的「已执行动作」集合做去重,给每个子任务设最大重试与总步数预算,用超时把对称等待打破成明确的失败状态,Critic 打回时必须给出结构化的缺失项、执行方只能按缺失项补而不能自由换方向。选型上:单 Agent 适合工具少、任务线性的场景,成本最低、调试最容易;Workflow 适合路径可穷举的稳定流程;多 Agent 只在「子任务真的可并行或需要独立视角校验」时才划算,否则只是把一次推理拆成多次、成本翻倍。执行模式同理:任务明确、步骤可预测用 Plan-and-Execute,任务模糊、需要探索用 ReAct,实践里常用「Planner 出粗计划 + 每步内部 ReAct」。

工具兜底、父子切块与混合检索。工具挂了要分错误类型:超时、限流、网络抖动可重试(指数退避 + 全局限流 + 幂等键);参数错误、权限错误不可重试,直接把结构化失败信息回传模型(工具名、错误码、可操作提示),让它换方案或如实告知用户。父子切块解决的是「检索精度」与「上下文完整性」的矛盾:小块参与向量化与相似度计算,命中率高、噪声小;命中后返回它所属的大块给模型,避免答案被切在半句话里。混合检索是 BM25 与向量各自取 Top-K 后融合(常用 RRF),重排放在融合之后、进模型之前——先用便宜召回拿广度,再用精排提精度。向量库增删后按 doc_id 做幂等覆盖,删除要同时清向量与元数据索引,缓存 key 带上文档版本号,版本一变旧缓存自然失效;全量重建用双缓冲切换,新索引建好再切流量。

进程线程协程、GC 与缓存三兄弟。进程是资源分配单位(独立地址空间),线程是调度单位(共享进程内存),所以线程切换成本更低、通信更简单,但一个线程崩了会带走整个进程。Go 的 goroutine 是用户态协程,由 runtime 的 GMP 调度器复用到少量内核线程上,创建成本只有几 KB、切换不陷入内核,因此能开几十万个;代价是阻塞系统调用、共享状态竞争与 GC 压力仍需自己处理。GC 策略按负载选:标记-清除简单但有碎片,标记-整理无碎片但停顿长,分代收集利用「大部分对象朝生夕死」,并发/增量收集把停顿压到毫秒级适合大堆与低延迟服务,Golang 用并发三色标记加写屏障把 STW 压到亚毫秒。缓存三兄弟的解法很固定:穿透用布隆过滤器或短 TTL 空值缓存,击穿用互斥重建,雪崩用过期时间随机化加多级缓存与限流兜底。内部调用优先 RPC(二进制省带宽、有 IDL 强类型、支持流式与超时熔断治理),对外接口与调试场景用 HTTP+JSON;HTTPS 握手用非对称加密协商密钥并验证身份、传输用对称加密加 AEAD,根证书是信任锚,少了它中间人就能自签证书冒充站点。手撕日志统计用一次遍历加哈希表:以工具名为 key 维护总次数与失败次数,再扫一遍求最大失败数,时间 O(n)、空间 O(工具种类数),注意先确认日志格式与失败次数的口径。

评测、成本与上线权衡。上线前要有离线评测集,按难度分层(单跳、多跳、对抗与长尾),指标分两层:检索层看 Recall@K、MRR、NDCG,生成层看答案准确率、引用正确率、以及「该说不知道时有没有编造」;上线后补线上指标(追问率、转人工率、负反馈率、P99)并做 A/B。降推理成本有五个维度:按难度路由到更小的模型、压缩上下文与裁剪 prompt、命中缓存直接复用、批处理与并行工具调用、量化或蒸馏后的自部署。防跑偏的闸门是分层的——prompt 约束、检索素材约束、输出结构与事实核查、高风险动作的人工确认,任何一层都不能单独承担。至于「要快上线但评测没过」,合理的答法是把标准显式化:先看影响范围与可回滚性,能灰度、能回滚、有护栏指标的可以带条件上线并约定观测窗口;不可逆或直接影响资金与用户数据的宁可推迟——决策权交给业务方,但风险与代价要讲清楚。