32 · 面试实战:系统设计、手撕题、项目讲述与速查清单
「AI-Agent 面试深度指南」· 模块八 · 后训练、RL 与面试实战 · 第 32 篇 / 共 32 篇
引言
知识储备与面试表现之间隔着一堵墙:你懂的东西,未必能在 60 秒内有条理地说出来。本篇是整套指南的"输出层"——把前面 31 篇的知识,转换成面试现场能直接使用的答题框架、代码模板与讲述结构。
三部分:系统设计题的通用解法、三道高频手撕题的可运行骨架、以及项目经历与速查清单。
一、系统设计题:五步法
1.1 Step 1:澄清需求(2 分钟)
必问的六项:用户量级与并发、可接受延迟与成本、成功率目标、是否需要人工兜底、是否涉敏感数据与合规、知识来源与更新频率。
不要急着画架构——先问清边界。面试官考察的第一件事就是你会不会问问题。
1.2 Step 2:总体架构(画出来)
接入层(HTTP/SSE)
→ 意图路由(小模型)
→ 编排层(计划/状态机)
→ 执行层(工具集:检索、业务 API、工单、人工转接)
→ 验证层(约束检查 + 评委)
→ 输出层(引用、结构化结果)
旁路:日志/trace、评测、成本统计、权限与审计
1.3 Step 3:挑三个点深挖
不要平均用力,选三个能体现深度的点展开:
- 上下文:稳定前缀、压缩、按需加载、缓存命中;
- 可靠性:危险操作 HITL、幂等、失败分类重试、降级路径;
- 评估:自建集、pass^k、失败归因、CI 回归。
1.4 Step 4:权衡与演进(体现功力)
- 先单 Agent + 好提示词做基线,再按需加规划/反思/多 Agent;
- 多 Agent 只在有信息增量时使用,且要用 A/B 证明值得;
- 成本:小模型路由 + 缓存 + 减轮数;
- 冷启动:先用规则与模板兜住高频问题,逐步让 Agent 接管。
1.5 Step 5:准备三个追问
- “怎么保证不胡说?” → 只基于检索内容回答 + 引用 + 无证据时拒答;
- “怎么防止越权?” → 工具权限分级 + 用户身份贯穿 + 执行层校验;
- “怎么评估?” → 三层:组件级(recall@k)、任务级(pass^k + 成本)、业务级(人工介入率)。
加分动作:主动讲一个你踩过的具体坑(工具爆炸、上下文膨胀、评估造假)与解决办法。
二、手撕题一:ReAct 主循环
def run_react(question, tools, llm, max_steps=8):
messages = [{"role": "system", "content": SYSTEM},
{"role": "user", "content": question}]
trace, seen = [], {}
for step in range(max_steps):
reply = llm(messages, tools=tools.specs())
call = reply.tool_call
if call is None:
return reply.content, trace # 收尾
if call.name not in tools: # 工具不存在
messages.append(tool_msg(call.id,
f"错误:无此工具。可用:{list(tools)}"))
continue
key = (call.name, json.dumps(call.args, sort_keys=True))
if key in seen: # 重复调用
messages.append(tool_msg(call.id,
"已用相同参数调用过,请换方法或说明无法完成"))
continue
seen[key] = 1
try:
result = tools[call.name](**call.args)
except Exception as e: # 结构化错误回传
result = f"执行失败:{type(e).__name__}: {e};请修正参数重试"
messages.append(tool_msg(call.id, truncate(str(result))))
trace.append({"step": step, "call": call, "result": result})
return "达到最大步数,已知信息如下:", trace # 部分回答
评分点:轮数上限、重复检测、错误回传(而非抛异常)、结果截断、轨迹记录、耗尽时的部分回答。
三、手撕题二:检索与重排
def rrf_fuse(rank_lists, k=60):
scores = {}
for ranks in rank_lists:
for i, doc_id in enumerate(ranks):
scores[doc_id] = scores.get(doc_id, 0) + 1.0 / (k + i + 1)
return sorted(scores.items(), key=lambda x: –x[1])
def retrieve(query, vec_index, bm25, filters, topk=50):
dense = vec_index.search(embed(query), topk, filter=filters) # 语义
sparse = bm25.search(tokenize(query), topk, filter=filters) # 关键词
return [d for d, _ in rrf_fuse([dense, sparse])][:topk]
def rerank(query, docs, cross_encoder, topn=5):
scores = cross_encoder.predict([(query, d.text) for d in docs])
ranked = [d for _, d in sorted(zip(scores, docs), key=lambda x: –x[0])]
return dedup_by_parent(ranked)[:topn]
必须补的细节:过滤要在召回阶段做(pre-filter);去重相邻块;控制 token 预算;召回为空时降级。
四、手撕题三:并发、限流与重试
class TokenBucket: # 限流
def __init__(self, rate, capacity):
self.rate, self.capacity = rate, capacity
self.tokens, self.ts = capacity, time.time()
def acquire(self, n=1):
now = time.time()
self.tokens = min(self.capacity,
self.tokens + (now – self.ts) * self.rate)
self.ts = now
if self.tokens < n:
time.sleep((n – self.tokens) / self.rate); self.tokens = 0
else:
self.tokens -= n
def retry(fn, retries=3, base=0.5): # 退避重试
for i in range(retries):
try:
return fn()
except RetryableError: # 超时/限流/5xx
if i == retries – 1: raise
time.sleep(base * 2**i + random.uniform(0, .1)) # 抖动防惊群
except FatalError: # 参数错/权限不足
raise
必答要点:区分可重试与不可重试;加抖动;设超时;写操作用幂等键;并发结果按原顺序回传;连续失败要熔断。
五、项目经历:四段式讲述
5.1 结构:背景 → 难点 → 方案 → 数据 → 复盘
背景(30 秒):业务是什么、谁用、原来怎么做、为什么需要 Agent。
难点(决定含金量):不要说"模型不够聪明",要说具体工程问题。例如:工具从 20 涨到 200 个后调用准确率从 93% 掉到 71%;长任务刷新页面就丢状态;检索召回差导致业务方不敢用。
方案(分层讲):架构图 + 四要素(上下文怎么组织、工具怎么治理、怎么保证可靠、怎么评估)。
数据(最有说服力):成功率(说明口径与样本量)、成本/延迟变化、业务指标(人工介入率、处理时长)。
复盘(展示深度):做错了什么、重做会怎么改、还差什么。
5.2 简历写法对照
反例:“负责智能客服 Agent 开发,使用 RAG、ReAct、多智能体技术。”
正例:“主导智能客服 Agent 从 0 到 1 上线。针对 300+ 工具导致调用准确率仅 72% 的问题,设计分组按需加载 + 语义检索的工具治理方案,准确率提升至 93%,单轮工具选择 token 下降 40%;构建 420 条生产回流评测集与失败归因流程,平均排查时长从 2 小时降至 20 分钟。”
检验标准:每一条都能被追问三句而你答得上来。
六、速查清单(考前自查)
能答出 80% 即可上场:
七、行为面试与反问
STAR 结构:情境(一句话)→ 任务(目标与约束)→ 行动(你做的决策与取舍)→ 结果(量化 + 复盘)。每个故事都要有一个具体决定和它的代价。
反问环节(加分项,不是走过场):团队现在 Agent 系统最大的瓶颈是什么?评测体系怎么建的、失败案例如何回流?新同学前三个月负责什么?业务上 Agent 是降本还是增收、人工兜底比例多少?技术栈自研还是开源、为什么?
问"评测体系"的人和问"加班多不多"的人,给面试官的印象完全不同。
小结
技术决定下限,表达决定上限。把这套指南的知识练成"60 秒讲清一个知识点"的能力,就是秋招最稳的护城河。最后一件事:遇到不会的问题,用三步应对——承认边界 → 给出分析框架 → 说明你会怎么查证。这比硬编体面得多,也更像一个真正的工程师。


