字节常问的 Agent 题,面试官到底在追什么?
这类 Agent 面试题常把知识库、工具调用和线上指标串起来追问。准备时别背单点名词,要能从需求判断、检索证据、状态恢复一路讲到延迟、成本和灰度。
本篇阅读顺序 · 三遍读法
一篇文章,读出三种能力。
先弄懂它为什么这样工作,再把条件换一换,看方案还能不能站住,最后用代码和证据复盘一遍。顺序固定,读完才知道自己是真的会了,还是只记住了名词。
沿着直觉、公式和边界读正文,看到变量就问输入、状态、复杂度分别是什么。
把面试官的追问当作小型设计评审:更大流量、更少上下文、外部失败或安全约束出现时,局部如何重算。
沿代码、表格和证据卡复盘,最后用文末的 60 秒回答确认自己没有只记住名词。
“你们的 RAG 召回率多少?”答完这句,面试官往往马上把问题追到线上:
回答完,面试官可能马上接着问:“线上 P95 呢?如果工具超时呢?为什么不用缓存?用户看到的引用是哪一版?”这类题的难点不在于每个知识点都讲得很深,而在于能否把一个 Agent 从离线数据一路讲到线上行为。
先给一个能复述的答案
面对综合型 Agent 面试题,可以沿五段讲:需求与成功口径、数据和检索链路、工具与权限边界、状态和故障恢复、线上指标与成本。先给最小闭环,再按追问展开。每个数字都要带数据集、分母、版本和代价,不能只报一个漂亮的 Recall。
第一段:先判断需求是不是 RAG
不要把“知识库”当成默认答案。先判断:
| 问题特征 | 首选路径 |
|---|---|
| 私有且经常更新的文档 | RAG + 版本与权限过滤 |
| 实时库存、订单、推荐结果 | 工具或数据库查询 |
| 需要固定输出格式 | 结构化 schema,必要时微调 |
| 稳定常识、低风险闲聊 | 直接回答 |
面试官如果追问“为什么不用 Fine-tune”,可以说:微调改变行为和格式,不能替代实时事实和权限过滤;两者可能组合,但解决的是不同问题。
第二段:把 RAG 讲成一条链路
文档接入 -> 清洗与版本 -> 结构化切分 -> 索引
问题改写 -> 混合召回 -> 元数据过滤 -> 重排
证据组装 -> 生成 -> claim / citation 校验 -> 反馈回流
不要只讲“向量相似度”。当面试官问“为什么正确文档没被用上”,要能拆成召回漏掉、过滤错误、重排错位、上下文截断、生成未引用五种可能。
指标至少分层:
Recall@k:相关证据有没有进候选集
MRR / nDCG:相关证据排得靠不靠前
citation_coverage:回答结论是否被片段覆盖
faithfulness:结论是否超出证据
P95 / cost:系统是否能在线承受
第三段:工具调用要从协议讲到副作用
一个工具不是“函数名 + 参数”。至少说清:
{
"name": "refund.create",
"input": {"order_id": "...", "amount": 0, "idempotency_key": "..."},
"preconditions": ["same_tenant", "approved"],
"result": {"status": "accepted|rejected|unknown", "refund_id": "..."}
}
只读工具和写工具要分权限。未知结果不能自动重试,必须先对账;重复提交必须靠幂等键而不是提示词提醒。
第四段:线上性能不是只看模型延迟
一次 Agent 任务的 P95 可能来自:模型排队、输入上下文、检索、重排、工具网络、重试和人工升级。先用 trace 把耗时拆开,再决定优化顺序。
total = queue + model_prefill + retrieval + tool + model_decode + retry
常见优化顺序是先减少无效步骤,再压缩上下文和工具结果,之后做模型路由、缓存与并发控制。高风险写操作不能为了追求 P95 绕过审批或校验。
第五段:用线上指标结束回答
任务:成功完成率、拒答率、人工接管率
过程:步骤数、重试率、工具错误率、尾延迟
证据:引用覆盖率、版本命中率、越权率
运营:P50/P95、单位成功任务成本、缓存命中
稳定:新版本回归、长尾分布、灰度差异
如果只报“线上准确率 92%”,面试官会继续追问“准确是什么”。把口径说清,才能把问题从背诵带回工程。
一个可复述的系统设计示例
用户问题
-> 认证与租户上下文
-> 意图路由:检索 / 实时工具 / 直接回答
-> 检索前 ACL 与版本过滤
-> 召回、重排、证据组装
-> 生成与引用校验
-> 只读返回;写操作进入审批、状态机和审计
-> trace、指标和失败样本进入回归集
把综合题拆成一张“证据卡”
字节类综合题经常连续追问同一个数字。准备时可以为每个项目做一张证据卡,而不是只记组件名:
| 追问方向 | 必须说出的证据 | 不能越过的边界 |
|---|---|---|
| 数据 | 文档版本、租户、更新时间、删除策略 | 不把旧索引当实时事实 |
| 检索 | Recall@k、过滤命中率、重排增益 | 不用平均分掩盖长尾 |
| 工具 | schema、权限、幂等键、状态机 | unknown 不等于失败 |
| 线上 | P95 分解、单位成功成本、人工接管率 | 不为降延迟绕过审批 |
面试官要的是“你如何知道它工作”,不是“你使用了哪些框架”。每张证据卡再附一个失败样本:输入、实际轨迹、错误层级、修复动作和回归用例。这样被追问时可以从抽象设计落到一次真实请求。
设计一条可回放的失败路径
综合题最有区分度的回答,往往是把失败写成状态转移:
retrieval_miss -> clarify_or_refuse
tool_timeout -> bounded_retry -> fallback_or_handoff
unknown_result -> reconcile -> confirm_or_compensate
policy_denied -> stop -> audit
每次转移都记录 trace_id、输入版本、策略版本和下一步原因。回放时先重放检索和策略决定,再选择是否重放模型;写操作默认只做模拟执行,避免为了复现事故再次产生副作用。若同一失败样本在新版本变成成功,仍要检查是不是放宽了权限或改变了问题分布。
面试题不要只背“标准答案”
可以把题目分成四张卡来练:
- 判断卡:什么时候用 RAG、工具、微调或直接回答?
- 定位卡:答案错在召回、过滤、重排、上下文还是生成?
- 恢复卡:超时、重复提交、旧版本和越权分别怎么停?
- 指标卡:成功率、引用覆盖率、P95、成本和安全如何同时解释?
每张卡都用“结论—依据—反例—验证”四句完成。不会的细节可以声明假设,但不能用一个模糊的“线上会监控”替代验证动作。
追问顺序要从“能不能做”走到“敢不敢上线”
综合题不是把所有组件一次讲完。更稳的回答顺序是先确认边界,再逐层暴露证据:
需求与硬约束
-> 数据 / 版本 / 权限
-> 召回与引用证据
-> 工具状态与副作用
-> P95、成本与人工接管
-> 灰度、回滚和剩余风险
每一层都准备一个“如果失败怎么办”的反例。例如检索无结果时拒答或澄清,工具返回 unknown 时对账而不是重试写入,P95 超预算时先减少无效上下文而不是直接换更大的模型。这样面试官继续往下追问,你是在展开一条真实系统,而不是切换到另一个背诵答案。
可以给每道题准备一张追问矩阵:
| 层级 | 面试官在判断什么 | 你的证据 |
|---|---|---|
| L1 | 是否理解基本链路 | 一句话结论 + 组件职责 |
| L2 | 是否做过工程取舍 | 前后对照、失败样本、指标口径 |
| L3 | 是否能处理线上边界 | 状态机、回滚、权限和成本 |
| L4/L5 | 是否能承担系统责任 | 证据包、剩余风险、复查条件 |
把一次线上请求压成可交接的回放包
综合题讲到最后,面试官往往会问:“你怎么证明这次不是偶然?”可以把一条真实请求压成一个最小回放包,既能解释指标,也能交给下一位同学继续排查:
request-pack/
├── manifest.yaml # 模型、Prompt、工具、知识库和策略版本
├── input.json # 脱敏后的输入与租户/意图标签
├── trace.jsonl # 每一步状态、耗时、重试和工具回执
├── evidence/ # 命中的片段、引用和版本有效期
├── replay.sh # 只读或模拟执行入口
└── diff.md # 与基线的第一处分歧和剩余风险
入口脚本先做三件事:校验版本是否存在、把写工具切到 dry-run、检查证据是否仍在有效期内。回放结果不要只写“成功/失败”,而要记录 first_divergence:第一次和基线不同的状态、输入或决策。这样定位问题时,先查分歧层,再决定是否需要重跑模型,避免把整条链路重新跑一遍。
四个常见坑
把字节题当成“背组件题”
真正的追问会从组件跳到数据、延迟、成本和稳定性。按链路准备,不按名词准备。
只报离线指标
离线高分不代表线上没有分布漂移、缓存污染和工具尾延迟。至少补一条线上观测。
忽略引用和版本
知识库答案最容易在旧版本和无依据结论上翻车。引用片段和有效时间要进入数据契约。
写操作没有状态和对账
工具返回 accepted 不等于业务完成,unknown 也不等于失败。把状态和恢复路径讲出来。
L1 / L2 / L3 追问
L1: 你会怎么设计一个企业知识库 Agent?
先做认证和租户上下文,再做版本与 ACL 过滤、混合检索、引用生成;写操作单独走审批、幂等状态机和审计。
L2: RAG 召回率高,为什么答案仍然错?
可能是过滤、重排、上下文截断或生成未引用;用 claim、证据片段和 trace 分层定位,而不是只看 Recall。
L3: 如何把线上 P95 降下来?
按 trace 拆队列、模型、检索、工具和重试耗时,先减少无效工作,再做上下文压缩、路由、缓存和并发控制,同时守住安全与成功率。
L1: 什么时候应该拒答而不是继续检索?
证据版本过期、权限过滤后没有足够支持,或问题要求实时事实但系统没有对应工具时,应明确说明缺口并引导用户补充,而不是用相似文本凑答案。
L2: 为什么混合检索仍可能漏掉正确文档?
关键词、向量和元数据过滤可能在不同阶段丢失候选;要记录各阶段候选数、过滤原因和重排分数,区分“没召回”和“召回后没用上”。
L2: 工具返回 unknown 时怎么处理?
先查询业务状态或对账接口确认是否落库;确认前禁止重复写入,超过时限则转人工并保留 provider reference。
L3: 如何证明缓存没有泄露租户数据?
缓存键必须包含租户、权限、查询版本和敏感过滤条件;命中前再做策略校验,并用跨租户回归样本验证拒绝路径。
L3: 线上指标互相冲突时怎么取舍?
先按风险设置硬门槛,例如越权率和副作用错误不可用平均成功率抵消;在安全门槛满足后,再用单位成功成本和 P95 做优化。
L2: 为什么只报 Recall@k 不够?
Recall 只说明候选集里有没有证据,还要看重排位置、引用覆盖、版本命中和最终答案是否超出证据。
L3: 如何把一次线上事故变成面试中的工程证据?
脱敏保存输入、轨迹、版本、失败层级和修复前后指标,再补一条回归用例和灰度结果;不只说“后来修好了”。
L4: 面试官要求你给出一个数字,但你没有完整线上统计怎么办?
先说已有样本和口径,再给范围或方向性结论,明确不能外推的边界;随后说明会怎样补齐版本化评测和灰度对照。不要用“印象里大约”伪装精确。
L4: 为什么你的设计没有直接用更大的模型?
把模型能力、延迟、成本、数据新鲜度和工具约束放在同一张决策表里。更大的模型可能只改善表达,未必解决版本过滤、状态恢复或证据缺失。
L5: 如果面试官连续否定你的方案,怎样保持回答有结构?
先确认对方改变了哪个约束,再只修改受影响的一层;保留已经验证的边界和证据,明确哪些结论需要重新实验。不要为了迎合而把整个架构推倒重讲。
L5: 综合题怎样体现你能负责上线?
除了主流程,主动给出硬失败、监控、灰度、回滚、人工接管和剩余风险;并说明谁拥有开关、复查日期和关闭条件。能把风险说清,比堆更多组件更重要。
L5: 如果只能保留一个线上样本给下一位同学,你会保留什么?
保留一个脱敏的 request-pack:包含版本 manifest、输入、完整 trace、命中的证据片段、工具回执和第一处分歧。写工具只保留 dry-run 或对账结果,并明确哪些外部状态无法复现,不能只留下截图或最终答案。
综合题用一张 request-pack 把答案讲完整
面试官追问“如果线上出了问题怎么办”时,不要重新从头讲架构。拿一条脱敏 request-pack,按输入、版本、证据、工具和处置动作展开,答案会自然落到工程细节:
request_id: req-784
goal: "从私有知识库生成带引用的合同摘要"
version_tuple: model@r8 + index@r17 + tools@v3
trace:
retrieval: 42ms / candidates=80 / accepted=6
generation: 1.8s / tokens=920
tool: draft.save / dry_run=true
evidence: [doc-17:p4, doc-22:p8]
failure: "claim-3 与旧版本冲突"
action: "阻止发布,转人工复核"
这张包同时回答了“用了什么”“为什么相信”“哪里失败”“有没有副作用”。如果面试官改变约束,只替换对应字段:实时数据改变工具层,扣款写操作改变审批和幂等层,租户隔离改变检索过滤和缓存键,不需要把整个方案推倒重来。
综合题最后要给一张容量与成本估算
讲完链路和失败出口后,再补一张粗粒度容量卡,面试官才能判断方案是否能上线。估算不需要假装精确,但要声明流量、上下文、工具次数和预算假设,并说明哪个变量变化会触发降级:
capacity_note: cap_20260820_04
traffic:
requests_per_minute: 1200
peak_multiplier: 3
per_request:
model_calls: 4
tool_calls: 6
input_tokens: 4200
output_tokens: 900
budget:
p95_latency_ms: 1800
cost_per_success: 0.018
degrade:
- "超过 2k rpm:切换小模型做路由与摘要"
- "工具队列 > 70%:只读任务进入排队"
- "预算超阈值:关闭非必要 rerank"
evidence: "replay-pack-0042 + canary-10%"
估算的重点是暴露取舍:想把上下文扩大一倍,就要说明成本和时延怎么变;想增加一个 verifier,就要给出成功率提升是否值得。把“能不能做”推进到“在什么预算下敢不敢做”,答案才完整。
容量估算之后还要做一次“降级回放”
容量表里写了降级动作,不代表线上真的能在压力下切过去。面试或项目验收时,再拿一条峰值 request-pack 走一遍:人为抬高并发、工具队列和上下文长度,观察路由、缓存、只读队列和人工接管是否按顺序生效。重点记录“什么时候切换”和“切换后丢掉了什么”,而不是只报一个平均延迟。
degrade_replay: dgr_20260820_48
baseline:
rpm: 1200
p95_latency_ms: 1640
stress:
rpm: 3600
tool_queue_ratio: 0.78
context_tokens: 8400
observed:
router: small_model
write_actions: queued_for_review
rerank: disabled
p95_latency_ms: 1890
decision: within_budget_with_degrade
evidence: "request-pack-0042 + trace-diff-17"
降级回放要把功能损失写出来:关闭 rerank 后证据新鲜度是否下降,只读排队后用户是否得到明确等待状态,小模型路由是否误把写任务当读任务。能在压力下说明“保住了什么、牺牲了什么”,比背一套静态组件图更像真实系统设计。
L5:为什么容量估算一定要配降级回放?
估算只回答“可能会超预算”,回放才回答“超预算时系统怎么活下来”。没有回放,降级动作可能没有开关、没有权限 owner,或者切换后把证据完整性一起丢掉。
L5:为什么面试中的容量估算可以不精确,但不能不写?
因为估算的价值是暴露变量和决策,而不是猜中生产峰值。没有任何数字,架构取舍就无法比较;有了假设,即使数字后来变化,也能快速重算并说明哪些降级动作仍然成立。
L5:为什么一条脱敏请求比十张架构图更能证明你做过?
架构图只能说明组件存在,request-pack 才能说明它们在一次真实约束下如何协作:哪一步耗时、哪条证据被采用、哪个工具被拒绝、什么动作触发人工。它还保留了可回放入口,面试官继续追问时,你能沿同一条证据链回答,而不是临时编一个理想流程。
综合题最后要补“灰度—回滚—复盘”三件套
面试里的系统设计如果只停在架构图,通常还差最后一公里。一个能上线的回答要说明如何小流量验证、什么信号触发回滚,以及回滚后怎样保留现场。特别是 RAG 和工具调用,线上变化可能来自知识库、权限和第三方接口,不一定是模型版本。
release_plan:
change: "reranker_v2"
canary: {traffic: 0.05, slices: [long_query, fresh_docs]}
guardrails:
- "grounding_coverage >= 0.92"
- "tool_error_rate <= baseline + 0.5%"
- "p99_cost <= baseline * 1.1"
rollback: "route_to_reranker_v1"
preserve: [request_pack, retrieval_snapshot, trace_digest, decision_log]
review_after: "24h or 10k requests"
这组内容能把“我会监控指标”变成具体动作:指标达到什么阈值、切哪条路由、保存哪些证据、多久后复盘。面试官继续追问成本或安全时,也能沿着同一张 release plan 展开,而不是临时再加一堆孤立组件。
L5:为什么回滚也要保存 retrieval snapshot?
因为只切回旧模型并不能恢复旧世界。知识库可能已经更新,第三方工具的返回也可能变化;没有请求包和快照,团队无法判断问题来自模型、数据还是外部依赖。保存最小证据链,才能在不复制敏感正文的前提下复盘同一条决策路径。
灰度计划还要写“谁有权按下回滚”
很多发布方案只写阈值和回滚命令,却没有明确 owner:指标触发后,谁确认是模型问题,谁负责切路由,谁核对正在进行的写操作。我的 request-pack 会把告警、决策、执行和复盘角色写成最小 RACI,并记录每一次手动覆盖的理由。这样回滚不是一句口号,而是一条在压力下仍能执行的流程。
rollback_raci: rri_20260820_84
change: reranker_v2
trigger: grounding_coverage < 0.92 for 10m
roles:
detect: oncall-agent
decide: ml-owner
execute: platform-owner
reconcile: data-owner
actions:
freeze_new_writes: true
route_to: reranker_v1
preserve: [request_pack, retrieval_snapshot, trace_digest]
manual_override_requires: incident_id
decision: canary_ready
L5:为什么写了回滚命令仍然不算可回滚?
线上事故需要在分钟级完成判断和动作,若没有 owner、冻结策略和证据保存,命令可能没人敢执行,或回滚后无法对账。可回滚性既是技术能力,也是责任链和现场证据的组合。
60 秒面试回答
综合型 Agent 题我会按五段回答:先确认需求和成功口径,再讲数据接入、版本、权限、召回、重排和引用的完整 RAG 链路;工具调用说明 schema、幂等、错误和写操作审批;线上部分用 trace 拆模型、检索、工具和重试的 P95,最后给任务、证据、安全、成本和稳定性指标。这样从离线到线上是一条闭环,面试官继续追问某一段时,也能沿证据展开。
交付前检查清单
- 能判断问题该走 RAG、工具、微调还是直接回答
- 能讲清召回、过滤、重排、组装和引用校验
- 工具契约包含权限、幂等和未知结果
- 性能按 trace 拆到模型、检索、工具和重试
- 指标包含任务、证据、安全、成本和稳定性
- 设计里有灰度、回归和人工接管边界
相关阅读
资料来源
- Agent 岗面试宝典 v3(AgentAlpha 飞书文档)
- ARIS in AI Offer:系统设计追问地图与分层回答结构