面灵AI→

字节跳动 AI Agent 开发一面:RAG 排查、Tool 编排与后端基础

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

《面试题目》

  1. 先来做一段自我介绍。
  2. 详细聊一聊你的实习经历,以及负责过的项目。
  3. 讲一下你对 RAG 整体流程的理解。
  4. 如果 RAG 检索出来的内容相关性很差,你会怎么排查?
  5. 实际做 RAG 项目时,遇到过什么问题,最后是怎么解决的?
  6. 你怎么理解 Agent 和 Workflow 的区别?
  7. 如果一个 Agent 需要调用多个 Tool,你会怎么设计?
  8. 多 Agent 之间怎么进行任务分配和信息共享?
  9. 哪些场景会导致索引失效?
  10. MySQL 索引底层采用什么数据结构?
  11. 为什么 MySQL 索引主要使用 B+ 树?
  12. Redis 常见的数据结构有哪些?
  13. 缓存击穿、缓存穿透、缓存雪崩分别怎么解决?
  14. 在你平时学习或者做项目的时候,AI 大模型工具起到了什么样的作用?有没有借助它解决过实际问题?
  15. 你平时是怎么评估一个模型效果好不好的?
  16. MCP 底层使用的是什么协议?
  17. 你认为 Skills 的本质到底是什么?
  18. 如果从零设计一款 AI IDE,整体思路和方案是什么?
  19. RocketMQ 出现消息积压时,你会怎么排查和处理?
  20. 算法题:二叉树的层序遍历,请讲解思路并手写代码。
  21. 为什么想做 AI Agent 方向?你后面有什么职业规划?

《参考解析》

RAG 检索相关性差的排查顺序

不要一上来就换模型。按链路从后往前拆更省时间:先看评测口径——相关性是人工判的还是模型判的,抽样几十条看看「差」到底是召回不到、还是召回了但排序靠后。然后是查询侧:用户问题口语化、含指代或隐含前提时,原始 query 直接向量检索命中率必然低,需要做 Query Rewrite(补全指代、抽取关键词)、多查询扩展或 HyDE。接着看召回侧:召回数量是不是太少(top-k 被截断)、是否只用单路向量(叠一路 BM25 做混合检索并按 RRF 融合通常立竿见影)、切块粒度是否与问题尺度不匹配——问题问的是整体结论却切成了碎段,或者一段里塞了多个主题导致向量被平均掉,可以用「子块召回、父块返回」的两段式。再往后是重排:加 Cross-Encoder 或 LLM Rerank 把真正相关的顶上来,比换 Embedding 模型便宜得多。最后才查数据侧:文档解析是否丢内容(PDF 表格、扫描件)、元数据过滤是否把该命中的筛掉了、增量更新是否导致旧版残留、切片是否和索引时的版本不一致。落地时把每一步的命中率分段打点,问题出在哪一段一目了然,也便于回归。

Agent 与 Workflow 的区别,以及多 Tool 的设计

Workflow 的路径是人预先编排好的——节点、分支、调用顺序都写死在代码里,模型只负责某些节点里的判断,优点是可控、可测、成本可预估,适合流程稳定、合规要求高的业务。Agent 把「下一步做什么」的决策权交给模型,靠循环逐步逼近目标,适合步骤无法预判、需要根据中间结果换路子的任务。工程上常见的是混合:外层用 Workflow 划定阶段与边界(比如「先检索、再生成、后校验」),阶段内部放一个小循环让模型自己决定工具顺序,这样既有可观测性又保留灵活性。多 Tool 的设计要点:工具数量先做收敛(语义重叠的合并、低频的收进「工具目录 + 按需取详情」的两段式),按域分组并限定每轮可见的工具集合;每个工具的出入参要有 schema,错误语义要分类(参数错 / 业务错 / 系统错),让模型能据此自纠;并行无依赖的调用要一起发出去省轮次,有副作用的写操作必须幂等并加确认;最后统计每个工具的成功率与误触发率,长期无人调用的工具就下架。

多 Agent 的任务分配与信息共享

拆多 Agent 的理由通常只有一个:上下文窗口和关注点需要隔离(子任务各带各的材料,互不污染),而不是「多个 Agent 一定比一个强」。分工上按职责切(规划者、检索者、执行者、校验者)或按数据域切(各自负责一批文档/一批工具),关键是把接口定死——每个子 Agent 有明确的输入契约、输出结构和失败语义,主 Agent 只通过这些结构化产物做汇总。通信机制上,共享内存(同一进程内的状态对象/blackboard)最快但耦合重;消息传递(队列、事件总线)解耦好、可跨机、便于审计,代价是延迟和状态一致性要自己处理。防幻觉放大靠两道:一是要求子 Agent 的结论必须带出处(原始片段 ID / 工具返回原文),主 Agent 只允许在证据范围内汇总;二是对关键结论做交叉验证——让另一个 Agent 独立复算或反证,分歧时回退到人工或保守答案。另外要防死锁与互相等待:超时、最大往返轮数、以及「谁负责终止」都必须显式定义。

MySQL 索引与 Redis 缓存三件事

索引失效的典型场景:对索引列做函数或运算(date(created_at)、id+1)、隐式类型转换(字符串列传数字)、like '%x' 前导通配、违反最左前缀(联合索引跳过首列)、or 两侧有非索引列、!=/not in 导致优化器放弃索引、以及优化器估算回表代价高于全表扫描时主动不走索引。B+ 树的胜出原因:非叶子节点只存键、扇出大所以树矮(三到四层能撑千万级),查询路径稳定且都落在叶子层(不像 B 树的数据分散在各层导致波动),叶子之间用链表串联,天然支持范围扫描和排序,同时避免了红黑树/AVL 那样频繁旋转、也不像哈希索引那样只能等值查询。

Redis 的三大缓存问题要能区分「数据在不在」和「数据到期」:缓存穿透是查一个数据库里也不存在的键(恶意或误用),解法是缓存空值加短 TTL、布隆过滤器前置拦截、以及参数校验;缓存击穿是某个热点键过期瞬间大量请求同时压到数据库,解法是互斥锁/单飞(singleflight)、热点键逻辑过期不物理删除、或提前异步续期;缓存雪崩是大量键同时过期或者缓存整体不可用,解法是 TTL 加随机抖动打散、多级缓存(本地 + Redis)、以及限流降级预案。再往上一层就是一致性:更新数据库后删缓存(配延迟双删或 binlog 订阅兜底)比先删再更新更常用,但任何方案都要有 TTL 作为最终兜底。

MCP、Skills 与 AI IDE 这类开放题

MCP(Model Context Protocol)底层是 JSON-RPC 2.0,跑在标准输入输出(stdio)或 HTTP + SSE / Streamable HTTP 之上,把「工具、资源、提示模板」抽象成客户端—服务端两端的标准能力,所以换模型、换工具生态不用改胶水代码;代价是多一层进程与协议开销、工具描述本身仍占上下文,以及版本和鉴权要自己治理。Skills 的本质是把「怎么做一件事」的流程知识、脚本与模板打包成可按需加载的能力单元——它解决的不是模型能力,而是上下文预算和一致性:平时不占 token,用到时才把这一套约定和工具链注入,让同一个 Agent 在不同任务里表现出稳定的专业度。从零设计 AI IDE 的思路:底层要有代码索引(符号级 AST + 向量检索,别整仓塞上下文)和可回滚的编辑原语(apply diff、撤销栈);中间是动作层,把「搜代码、改文件、跑命令、跑测试」做成有权限边界的工具,命令执行放沙箱;上层是循环与验证,改完必须自证(编译、lint、测试、运行结果),失败要能把报错回灌重试;工程上还要有上下文预算管理、多文件改动的事务性、以及人机分工的确认点(高风险操作显式确认)。这类题的得分点不在名词,而在你能说清每一层的取舍与失败处理。

消息积压与模型效果评估

RocketMQ 积压先分「消费者不够快」还是「生产突然暴涨」:看消费 TPS、单条消费耗时分布、消费组是否有实例掉线或 rebalance 卡住、是否被下游慢接口拖住。处理上短期可以扩消费者实例(注意队列数限制了并行度上限,队列不够要加队列并同步扩实例)、提高批量拉取与批量消费、把耗时逻辑异步化或降级(先落库再慢慢处理);如果是某类消息反复重试导致的堆积,检查重试队列和死信,必要时先隔离问题消息止血,再补数据;根治靠压测容量规划、消费幂等与监控告警。评估模型效果要分场景:有标准答案的任务看准确率、F1、结构化输出合法率;开放生成任务用「规则指标 + LLM Judge + 人工抽检」三层,人工抽检用来校准 Judge 的偏差,样本要覆盖典型与长尾;线上再看业务指标与成本(成功率、平均耗时、单次调用成本、用户采纳/追问率),离线涨了线上没动,多半是评测集与真实分布不一致。