🎯 参考回答 · 核心模块篇(B+ 级 · 16 题)
🎯 参考回答 · 核心模块篇(B+ 级 · 16 题)
📅 生成/更新:2026-06-16(新增 RAG 补充 × 2、MCP 协议补充 × 1、工程异常补充 × 1)
📚 数据来源:工作区面经 + 秋招复习笔记 + 网络搜索补充
🎯 适用:AI 应用开发 / Agent 开发 面试核心模块
【RAG 检索增强 · 6 题】
题1:RAG 的 chunking 策略有哪些?怎么选?
参考回答(面试口语化):
Chunking(分块)是 RAG 系统里决定检索上限的环节——你分块分得不好,后面的 embedding、检索、生成再优化也救不回来。
三种主流策略:
① 固定大小滑动窗口 最简单,设定一个固定 token 数(比如 512),按这个大小切,相邻 chunk 之间有重叠(比如 overlap 128 token)。优点是实现容易、通用性强;缺点是会切断语义完整的段落,导致检索到的片段”前言不搭后语”。
② 语义分块 按文档的自然边界(段落、章节、标题)来切,尽量保持语义完整性。适合结构化文档(PDF、Markdown、技术文档)。实现稍微复杂一点,需要做文档结构解析,但检索质量明显更好。
③ 递归分块 大块→小块逐级拆分。先按章节切大块,大块太长再按段落切中块,中块还长再按句子切小块。适合长文档,不同层级的 chunk 可以配合不同的检索策略。
怎么选? 核心方法是用评估集跑不同策略的效果对比。建一套标注好的 QA 数据集,跑不同 chunking 策略的召回率、答案准确率对比,选最优的。通用场景先用固定大小+语义分块做 baseline,逐步优化。
面试加分:Chunking 没有银弹,最好的策略取决于你的文档类型和用户提问方式。关键是用数据说话,不是靠感觉。
🔗 补充:父子块关联方案(中科曙光/长文档高频追问)
参考回答(面试口语化):
父子块关联是为了解决”大 chunk 丢精度、小 chunk 丢上下文”的矛盾。核心思路是建两层索引:
父块:按章节/大段切分(比如 1024 token),存到向量库,用于粗召回。 子块:在父块内部再切小段(比如 256 token),存的时候关联父块 ID。
检索流程:用户 query 先匹配到子块 → 通过子块找到父块 → 把父块全部内容作为上下文注入。这样LLM拿到的是完整的上下文片段,不是碎片化的几个句子。代价是检索要多一次关联查询,但上下文质量提升明显。
面试加分:如果面试官追问”那父块太大不也浪费token吗”——所以父块大小需要结合你的文档结构做调优。我自己在项目中实测,父块 1024 + 子块 256 的组合在召回率上比单一固定 512 chunk 高大概 7-8 个点。
🖼️ 补充:双栏 PDF 解析方案(西安新蛋高频追问)
参考回答(面试口语化):
双栏 PDF 是 RAG 文档处理里的一个”坑”。直接按文本流解析会把左右两栏的内容混在一起——比如第一行读左栏第一行,第二行读右栏第一行,用户 query 检索时驴唇不对马嘴。
正确做法:用 Layout-aware 的解析方案。
- 版面分析(Layout Detection):用 PDF 解析工具(如 PyMuPDF、Unstructured.io、Marker)识别页面中的文字块位置坐标
- 栏位分割:根据文字块的 x 坐标聚类,区分左栏和右栏
- 阅读顺序还原:按”先左栏从上到下,再右栏从上到下”的顺序拼接文本
- 语义块整合:跨栏的内容(如图表标题、表格跨栏)需要做合并判断
面试加分:实际做的时候要注意——扫描件 PDF 需要先 OCR(PaddleOCR / Tesseract),再做版面分析。纯文本 PDF 可以直接用 PyMuPDF 提取文字块坐标。不要用 pdfplumber 这种直接按行提取的工具处理双栏文档。
题2:RAG 检索优化有哪些手段?是 6 大手段展开说
参考回答(面试口语化):
RAG 检索优化,业界常用的六大手段:
① 分块策略优化:上文说了,用评估集对比不同分块策略的效果。不赘述。
② 多路检索:不只做向量检索,同时跑关键词检索(BM25/Elasticsearch)、混合检索(向量+关键词加权)。向量检索擅长语义匹配但可能忽略精确关键词,关键词检索正好互补。多路召回后合并排序,能显著提升召回率。
③ 重排序(Rerank):检索出 Top-K 候选后,用专门的 Rerank 模型(比如 BGE-Reranker)对候选进行二次排序。因为向量检索的排序不一定最优,Rerank 可以更精细地计算相关性,把真正有用的排在前面。需要理解的是,Rerank 的计算成本比向量检索高,所以一般只对 Top-50 或 Top-100 做 Rerank,不从头做。
④ 上下文压缩:检索到的文档片段可能很长,但和问题相关的部分只有几句话。用 LLM 或专门的压缩模型,只保留和问题最相关的部分再注入上下文。这样能省 token、减少噪音干扰。
⑤ 查询改写(Query Rewrite):用户的原始问题可能表述模糊,不适合直接检索。比如用户问”那个框架的上下文怎么管”,改写器把它改成”OpenClaw 的上下文管理策略是什么”,检索效果会好很多。改写可以用轻量 LLM 完成,也可以用规则模板。
⑥ 反馈循环:根据用户对回答的反馈(点赞/点踩/是否采纳),反向调整检索策略——降低低质量 chunk 的权重、调整检索参数、给高频问题做缓存。这是持续优化的闭环。
面试加分:这些手段不是一股脑全上,是逐步叠加的。先从分块和检索做起,baseline 稳定后再加 Rerank、查询改写,最后做反馈闭环。每一步都配评估,确保加对了而不是”感觉好了”。
题3:RAG 常见失败原因有哪些?
参考回答(面试口语化):
实实在在做过的都知道,RAG 不是搭起来就能用的,有四个最常见的翻车点:
① 召回不足(Recall 不够)——Top-K 设得太小,或者 chunk 切得太粗,最相关的内容根本没进候选。表现出来的症状是 LLM 说”根据提供的资料,未找到相关信息”。
② 检索结果相关性低——召回了但排在前面的都是噪音,真正有用的沉在底下。这是 chunking 不当 + 检索模型不够强 + 缺少 Rerank 的共同结果。
③ 注入的上下文干扰了模型判断——有时候检索到了一些看似相关但实际上无关或错误的内容,塞进 prompt 后反而把模型带偏了。这时候还不如不检索。
④ 用户问题表述不规范——问题太短、太模糊、或者领域术语用得不对,导致检索和问题对不上。
题4:怎么确认 RAG 召回数据的准确性?(政策文件场景)
参考回答(面试口语化):
政策文件场景下,准确性是命门——不能有”看起来差不多”的情况。
我的做法分两层:
第一层:离线验证。 建一个标注好的 QA 测试集,每个问题标注了标准答案和对应的原文出处。跑一遍 RAG 流程,检查:① 召回是否命中了原文出处(recall);② 命中的 chunk 是否包含正确答案所需的信息(precision);③ 最终生成答案是否和标准答案一致。
第二层:在线验证。 ① 让生成答案附带引用来源(原文 chunk ID + 段落引用),用户可以点击查看原文;② 用 LLM-as-Judge 对输出做事实一致性检查——“请判断以下回答是否有依据,没有依据的输出’无依据生成’并标红”;③ 人工抽检 + 反馈收集。
数据结构化: 政策文件场景还要注意一点——每条政策有发布时间、适用范围、效力等级。检索时需要加入时效性过滤(比如已废止的政策不能作为依据),匹配时按效力等级排序(法律 > 法规 > 规章 > 规范性文件)。
题5:RAG 评估方案有哪些?
参考回答(面试口语化):
RAG 的评估要分两部分——检索评估和生成评估。
检索评估(看召回好不好):
- Recall@K:前 K 个结果里是否包含了相关文档
- MRR(Mean Reciprocal Rank):第一个相关结果排在第几位
- NDCG@K:综合考虑排序位置和相关性等级
生成评估(看回答好不好):
- 答案准确率:人工标注或 LLM-as-Judge 评分
- Faithfulness(忠实度):生成答案是否严格基于检索结果,没有编造
- Answer Relevance:答案和问题的相关程度
- Context Relevance:检索结果和问题的相关程度(RAGAS 框架的三个核心指标)
评估方法:
- 离线评估:建 QA 测试集,跑 benchmark,对比不同策略的指标变化
- 在线评估:A/B 测试,看用户采纳率、留存率、反馈率
- LLM-as-Judge:用 GPT-4/Claude 等强模型给答案打分(需要校准,防止偏好偏差)
核心认知:RAG 评估不能只看最终答案,要拆开看”检索”和”生成”两段。检索不好,答案是 no-how;检索好但生成不好,是白费功夫。
题6:Embedding 模型怎么选?需要考虑哪些因素?
参考回答(面试口语化):
选 Embedding 模型不是越贵越好,要从几个维度综合考虑:
① 维度(Dimension):维度越高信息越丰富,但存储和检索成本也越高。常见的比如 768 维、1024 维、1536 维。文档量少用低维也行,海量数据维度高效果更好。
② 语言支持:中文还是英文为主?如果是中英文混合,要看模型是否双语支持。M3E 对中文好,OpenAI text-embedding-3 双语都行,BGE 系列也有中文版。
③ 成本:OpenAI 的 embedding 是按 token 计费的,量大成本不可忽视。开源的 BGE、M3E 可以本地部署,零推理成本但需要自建服务。
④ 领域适配:通用领域用通用 embedding 就行。如果是垂直领域(法律、医疗、代码),建议在领域数据上对比测试 —— 很多模型看起来很强,到了你具体场景可能反而不如小模型。
⑤ 性能与延迟:有些 embedding 模型推理慢(特别是大模型),在高 QPS 场景下要测延迟。可以考虑用更轻量的模型或者做缓存。
常用模型一览:
- OpenAI text-embedding-3-small/large:效果好但付费
- BGE(BAAI):开源,效果好,中文友好
- M3E:国产,性价比高
- Cohere Embed:企业级,多语言
面试加分:选型不只看指标,要看”在你的数据上”的效果。建议拿自己的 QA 数据集跑个对比,用 Recall@K 说话。
【MCP 协议与工具 · 4 题】
题7:MCP 的通信协议有哪些?有什么区别?
参考回答(面试口语化):
MCP 目前支持两种主要的传输方式:
① STDIO(标准输入输出) MCP Server 作为子进程和 Client 在本地通信,通过标准输入输出传 JSON-RPC 消息。优点是最简单、延迟最低、无需网络配置;缺点是只能本地用,Server 和 Client 必须在同一台机器上。适合个人开发环境、本地 Agent 工具。
② SSE(Server-Sent Events) MCP Server 跑在远程,Client 通过 HTTP SSE 连接和服务端通信。SSE 是单向推送(服务端→客户端),客户端用 POST 请求发送消息。优点是远程可访问、可以部署在云端;缺点是有网络延迟,需处理连接管理和重连逻辑。适合生产环境、多用户共享服务。
未来可能的第三种:WebSocket —— 社区有讨论,全双工通信比 SSE 更灵活,但目前还没标准化。
区别总结:
| 维度 | STDIO | SSE |
|---|---|---|
| 通信方式 | 进程管道 | HTTP 推送 |
| 部署位置 | 本地 | 本地/远程 |
| 延迟 | 最低 | 有网络开销 |
| 适用场景 | 开发调试、个人使用 | 生产环境、多用户 |
题8:MCP 怎么处理并发调用?
参考回答(面试口语化):
MCP 的并发处理分几个层面:
Server 侧:MCP Server 通常是单进程服务,请求在内部并行处理。Server 需要自己管理并发——比如用连接池限制最大并发数,用队列做请求排队,用超时机制防止死锁。
Client 侧:对于不会被修改的工具调用(比如只读的文件查询、搜索),Client 可以并行发送多个请求,不用等前一个完成再发下一个。但对于有状态的操作(比如写入文件、执行命令),需要串行化,防止竞态。
工具级别:工具本身的定义要说明是否幂等、是否安全并发。Client 根据工具的”只读/读写”属性决定是否并行调用。
OpenClaw 的做法参考:在 context 管理里会记录工具调用的并发策略,同时对工具返回的大结果会做截断处理,防止一个慢工具阻塞整条链路。
题9:A2A 协议和 SSE 协议了解吗?
参考回答(面试口语化):
**A2A(Agent-to-Agent)**是 Google 2025 年推出的 Agent 间通信协议。解决的问题是:不同 Agent 系统之间怎么发现对方、怎么协作。A2A 定义了 Agent Card(能力声明)、任务管理、消息传递的标准格式。和 MCP 的区别——MCP 是 LLM↔工具,A2A 是 Agent↔Agent。
**SSE(Server-Sent Events)**是 HTTP 协议基础上的一层,让服务端可以向客户端推送消息。特点:单向(服务端→客户端)、基于 HTTP 长连接、自动重连。在 AI 应用里最常用的场景是流式输出——LLM 一个字一个字往外蹦,用 SSE 推给前端,用户能看到逐字出现的回答。
两者的关系:不冲突。A2A 是 Agent 间的通信协议,底层传输可以用 SSE、WebSocket 或 HTTP。SSE 只是传输层的一个选择。
题10:你还知道哪些工具协议,除了 MCP?
参考回答(面试口语化):
除了 MCP,常见的工具/协议还有:
① Function Calling(原生方案) 各家模型厂商在 API 层提供的私有方案——OpenAI 的 function calling、Claude 的 tool use、Google 的 function call。本质都是传 Schema 让模型决策。不标准、换模型要适配。
② OpenAPI / Swagger 传统的 RESTful API 描述标准。MCP 出现前,有人用 OpenAPI 规范来描述工具接口,然后转成 LLM 能理解的格式。
③ A2A(Agent-to-Agent) Google 提出的 Agent 间协议,补充了 MCP 没覆盖的 Agent 协作场景。MCP 管工具调用,A2A 管 Agent 通信。
④ SSE / WebSocket 传输层协议。SSE 用于服务端推送,WebSocket 用于全双工通信。AI 应用里流式输出标配 SSE,实时交互用 WebSocket。
⑤ gRPC 高性能 RPC 框架,有些工具调用链路会用它做内部通信,延迟比 HTTP + JSON 更低。
面试加分:不是协议越多越好,看场景选。MCP 解决”工具怎么暴露”的问题,A2A 解决”Agent 怎么协作”的问题,Function Calling 解决”模型怎么调工具”的问题。三个不同层次,可以组合使用。
🔗 补充:MCP / Function Calling / Skill 三层次关系(中科曙光/美团高频追问)
参考回答(面试口语化):
面试中经常被问”MCP、Function Calling、Skill 这三者到底什么关系?是不是重复了?“——其实三个根本不在一个层次,是一个协议层 → 实现层 → 抽象层的递进关系。
第一层:协议层(MCP) MCP 定义的是工具”怎么暴露”——它是一套标准化的通信协议,规定了 LLM 怎么发现工具、怎么调用工具、工具怎么返回结果。就好比 USB-C 接口标准,不管你是硬盘还是充电器,插上就能用。MCP 的价值在于解耦:工具开发者按 MCP 标准写 Server,LLM 按 MCP 标准去调,两边都不用互相适配。
第二层:实现层(Function Calling) Function Calling 是模型厂商在 API 层提供的模型侧决策机制——把工具 Schema 传给模型,让模型判断”该不该调、调哪个、传什么参数”。它解决的是模型端的”怎么调”。MCP 不关心模型怎么决策——它只管”你要调了,我帮你把调用发出去并返回结果”。两者是互补的:MCP 做传输,Function Calling 做决策。实践中你可以用 MCP 暴露工具,用 Function Calling 让模型决定调哪个。
第三层:抽象层(Skill / Tool 编排) Skill 是对工具的更高层封装。一个 Skill 可能包含多个工具的组合调用 + Prompt 模板 + 执行逻辑。比如”代码审查 Skill”里面定义了:① 读取代码(工具)→ ② 搜索相关文档(工具)→ ③ 生成审查意见(LLM 调用)。Skill 解决的问题是——单个工具太细碎,需要把”怎么做一件事”的完整流程封装成一个可复用的单元。在 LangGraph、CrewAI 这类框架里,Skill 就对应一个可编排的 Agent 节点。
三者的协作关系图解:
Skill(抽象层)—— 组合多个工具+逻辑,封装成「能力」 ↓ 内部调用Function Calling(实现层)—— 模型决策「调哪个工具、传啥参」 ↓ 传输调用MCP(协议层)—— 标准化「工具怎么暴露、怎么通信」面试加分:面试官问这块,本质是在考察你有没有真正搭过 Agent 系统。很多人把这三个概念混在一起谈,你能理清楚这三个层次的职责划分,再加上你项目中的具体选择(比如”我们在协议层没用 MCP,因为团队小直接用 FC 够了;但抽象层我们自己做了 Skill 注册中心”),就很加分。
【工程实践与可靠性 · 6 题】
题11:API 超时和报错怎么排查解决?
参考回答(面试口语化 — 字节高频题):
API 超时报错的排查分几步走,核心思路是分层排查:
第一层:重试。 瞬时故障(网络抖动、服务短暂不可用)加重试就能解决。重试要指数退避(第一次等 1s,第二次 2s,第三次 4s…),防止雪崩。
第二层:工具级别降级。 如果某个工具连续失败(比如超过 3 次),切换到备用方案。比如主模型挂了换备用模型,主搜索工具挂了换关键词搜索。
第三层:Agent 级别的容错。 让 LLM 自己做判断——“工具调用失败了,尝试换一个方式/换个参数再试”。比如读文件失败,模型可以换成”先列出目录再确定文件路径”。
排查方法: ① 看工具调用日志(入参、出参、错误码、耗时);② 区分是模型问题(调用了不存在的工具)还是工具问题(工具本身挂了)还是网络问题;③ 分类统计失败原因,找出高频故障点针对性优化。
面试加分:关键是有系统性的兜底方案,不是只有一个”try again”。
题12:Token 消耗过快怎么排查和优化?
参考回答(面试口语化 — 字节高频题):
Token 消耗是钱的问题,也是性能的问题。排查步骤:
第一步:定位大头。 拿一次完整任务,统计三块的 token 占比——System Prompt 占多少、工具定义占多少、对话历史占多少。通常对话历史是大头,工具返回结果里的超大文本是元凶。
第二步:针对性优化。
- 上下文压缩:用摘要替换原始历史,最有效。平均能压 20-40%。
- 缓存:常用技能、工具定义、重复的知识不每次加载。语义缓存——相同问题的检索结果直接复用。
- 批处理:独立的小请求合并成一次大请求,减少重复的 prompt 固定开销。
- 模型选择:简单任务用轻量模型(比如 GPT-4o-mini),复杂任务才上重模型。
- 工具结果截断:设置工具返回结果的 token 上限,超了就截,保留头尾+摘要。
第三步:监控。 每个请求记录 token 消耗,设置告警阈值。发现异常增长的 case 做根因分析。
题13:Agent 优化后有什么可量化的效果?
参考回答(面试口语化 — 小厂/中厂高频题):
这个题的核心是——不能靠”感觉”,必须用指标说话。一般从四个维度量化:
① 准确率/任务完成率:优化前 70%,优化后 85%。比如通过 benchmark 的 pass rate 衡量。
② 响应速度:平均响应时间从 5s 降到 3s。包括模型推理时间和工具调用时间。
③ Token 成本下降:通过上下文压缩和缓存,单次请求平均 token 消耗减少 30%。可以换算成钱——“每月省了 500 刀”更有说服力。
④ 用户满意度:NPS 评分、人工评估打分、用户回访记录。
面试加分举例:“我们做了上下文压缩后,平均 prompt 长度从 6964 降到 5418(压缩率 18%),任务正确率从 66.7% 提升到 100%,重复读文件从 8 次降到 3 次。” 每一句都有数据。
题14:Agent 任务恢复/断点续跑怎么做?
参考回答(面试口语化 — 字节高频题):
Agent 执行过程中可能中断——报错、超时、用户暂停。断点续跑的核心是记录每一步的执行状态 + 存快照。
怎么做:
- 状态记录:每运行一步,把当前的上下文快照(用户输入、系统 prompt 版本、工具候选集、工具调用结果、Agent 输出)存下来。每步一个”检查点”。
- 中断检测:Agent 重启时,检查是否有未完成的任务(检查点存在且状态不是”已完成”)。
- 恢复执行:加载最近的检查点,重新初始化 Agent 状态,从中断的地方继续执行。恢复时需要把历史上下文摘要注入,让 Agent 知道”到哪了”。
关键设计:
- 检查点文件要结构化(比如 JSON),包含足够的元数据(任务 ID、步骤号、时间戳)
- 恢复时要告诉 Agent “这是恢复执行,不是新任务”——防止它从头开始
- 检查点定期清理,太旧的要淘汰
题15:Agent 的鲁棒性设计有哪些要点?
参考回答(面试口语化):
鲁棒性设计就是——系统不会因为一次异常直接崩掉。从输入到输出全覆盖:
输入校验 → 意图识别 → 敏感词过滤 → 上下文截断 → 错误兜底 ↓ 二次校验与格式解析每个环节的要点:
① 输入校验:先检查用户输入有没有问题——是不是恶意指令、是不是无关问题、参数是否合法。校验通过了才调用模型。
② 意图识别:判断用户到底想做什么——是查询、操作、还是闲聊?不同意图走不同处理路径,防止误操作。
③ 敏感词过滤:显式禁止的内容(政治敏感、黄赌毒、个人隐私)在入站时拦截。
④ 上下文截断:上下文太长时要不就压缩、要不就截断,不能让它溢出报错。
⑤ 错误兜底:所有环节出问题都有 fallback——重试、降级、给用户友好提示、转人工。
⑥ 二次校验:模型输出的关键内容做格式检查、内容校验,不完全信任模型输出。
关键原则:不是为了”好看”,是为了系统稳定跑下去。
题16:怎么节约 AI 成本?做了哪些优化?
参考回答(面试口语化 — ML/YC 公司高频题):
AI 成本大头在模型调用费。能优化的点很多:
① 上下文压缩(效果最明显):把几万 token 的对话历史压成几千 token 的摘要,直接省 40-60% token。这是成本大头。
② 缓存策略:语义缓存——相同/相似问题的检索结果直接复用;技能缓存——常用工具定义不重复加载;模型缓存——Prompt 复用相同的前缀(prompt caching 功能)。
③ 模型选择:简单任务用轻量模型(GPT-4o-mini/Claude Haiku),复杂任务才用重型模型。80% 的请求可以用轻量模型处理,成本能省 70%+。
④ 批处理:独立工具调用可以并行,减少来回调用的次数。
⑤ 降低重试次数:优化 Prompt 和工具 Schema 让模型一次调用就成功,减少重试的 token 浪费。
⑥ 流式输出 + 提前终止:模型输出到一半已经确定答案了,可以提前终止节省 token。
⑦ 本地部署:量大且对延迟不敏感的场景,用开源模型本地部署(比如 BGE embedding 本地跑、Qwen 本地跑),推理成本降到接近零。
面试加分举例:“我们通过上下文压缩省了 30% token,缓存省了 20%,轻量模型替代重型模型省了 50%,三叠加综合成本下降了 60% 以上。”
🔧 补充:Agent 系统异常处理体系(熔断 / 限流 / 补偿事务 / 死信队列)
参考回答(面试口语化):
Agent 系统一旦上了生产,异常处理就不能只靠”try-catch 重试”了。真正要对付的是级联故障——一个工具挂了导致整个 Agent 卡死,或者流量突增把所有服务打垮。我在项目中沉淀了一套异常处理体系,分四个层次:
第一层:熔断(Circuit Breaker) 某个工具或下游服务连续失败超过阈值(比如 5 秒内失败 3 次),自动熔断——后续请求直接返回 fallback 结果,不再真实调用。熔断后的状态流转:关闭(正常)→ 打开(熔断)→ 半开(试探恢复)→ 关闭或继续熔断。熔断能防止故障扩散,避免一个慢调用耗尽所有线程池。在 Agent 场景下,熔断阈值要设置得比传统微服务更保守——因为一次工具调用失败可能让整个 Agent 任务重跑。
第二层:限流(Rate Limiting) 不是所有请求都需要 AI 处理。高并发时对非关键请求降级(比如”用户查天气”走缓存不走模型),对关键请求(比如支付相关)保证可用。实现上可以用令牌桶/漏桶算法,在 API 网关层做。Agent 场景下还有一个特殊麻烦——循环调用:Agent 代码写 bug 了,同一工具无限循环调。限流策略要能检测这种”同一个任务无限重试”的异常模式。
第三层:补偿事务(Saga Pattern) Agent 的多步操作通常不是原子性的——比如”下单→支付→通知发货”,如果支付成功但通知发货失败了,不能简单回滚(支付已经扣钱了)。这时候需要补偿:发送一个”取消订单”的补偿操作来抵消已执行的操作。Saga 有两种实现方式:① 编排式(一个协调者告诉每一步该干啥或补偿啥);② ** choreography 式**(每个服务监听事件,自己决定补偿)。Agent 场景下更推荐编排式,因为 Agent 的执行路径通常是动态的、非线性的,需要中央协调者记录执行轨迹。
第四层:死信队列(DLQ) 重试多次仍然失败的消息不进垃圾箱,而是进死信队列。DLQ 的作用不是”丢弃”,而是兜底保留 + 人工介入。死信队列里的每条消息都包含:完整的调用上下文(入参、出参、错误堆栈、时间戳)、重试历史(重试了几次、每次失败原因)、处理建议。运维同学可以手动分析死信、修正问题后重新入队。Agent 场景下还要注意——死信里的工具调用上下文可能包含敏感信息,DLQ 要有一套脱敏机制。
面试加分:面试官问异常处理,不是在考概念定义,而是在看你有没有真正上过生产。不要说教科书上的熔断限流,要说”我们熔断阈值设的多少、为啥设这个值、实际踩过什么坑”。比如:“我们一开始熔断阈值设的 5 次/10 秒,结果一个弱网环境下频繁触发,后来改成了自适应阈值——根据工具的平均响应时间动态调整熔断 window。”
🔗 补充:RAG 检索精排流程详解(中科曙光高频追问)
参考回答(面试口语化):
面试官问”检索结果的精排依据是什么”——精排(Rerank)不是可有可无的锦上添花,是决定RAG最终质量的关键环节。
完整排序流程是三层递进:
第一层:粗排(向量检索)
- 用向量检索(cosine similarity / inner product)从海量文档里召回 Top-K
- 目标:高召回,不追求精度,追求”该有的都进来了”
- 这一层可能是 Milvus/Pinecone 在做的,通常是 Top-50 或 Top-100
第二层:精排(Rerank)
- 对粗排结果用 Cross-Encoder 模型重排,计算 query 和每个候选的精确相关性
- Cross-Encoder 的计算方式是 query + 候选文本一起编码,直接输出相关性分数
- 目标:高精度,把真正有用的排前面,噪声排后面
- 一般只对 Top-50 做 Rerank(因为计算成本高),取 Top-5 或 Top-10 进下一层
第三层:规则/业务层重排(可选)
- 根据业务规则调整排序:时效性加权(最新的排前面)、权威性加权(官方来源优先)、多样性去重(避免多个同类结果占据前排)
- 比如政策文件场景:已废止的政策降权,最新政策加权
精排的一般性结论:
- 粗排召回率可达 80-85%,加上精排后最终相关性能到 90-95%
- 精排 + 时效性加权,用户满意度能再提升 5-10%
面试加分:面试官问”精排你们用了什么方案”——通用方案用 BGE-Reranker 或 Cohere Rerank。如果你是做中文场景,BGE-Reranker-v2-m3 效果很好。如果面试官追问”为什么不用向量再做一次检索代替精排”——因为向量检索和精排的粒度不同,向量是双编码器(query和doc分别编码),精排是交叉编码(一起算),精度更高但速度更慢,所以精排只做最后一关。
🔗 补充:RAG 知识库文档版本管理与更新策略(Cider高频追问)
参考回答(面试口语化):
“RAG 知识库文档更新后,怎么保证用的是一个最新版本?“——这是 RAG 工程化落地时一定会遇到的真实问题。
我的方案分四层:
① 版本控制层
- 每个文档入库时记录
version_hash(基于内容 hash)+updated_at时间戳 - 文档更新时重新生成 embedding,写入新版本,旧版本标记为”过期”但不立即删除
- 新旧版本共存一段时间(过渡期)
② 增量更新层
- 全量重建知识库太贵了,一般用增量更新:只重新计算变更文档的 embedding
- 增量更新的触发条件:文档内容变更(git commit/webhook)、定时扫描(比如每 6 小时检查一次)
③ 读写分离
- 更新期间不做”停服更新”——新旧知识库双跑
- 查询走新版知识库,但查询时可以加
version_tag参数,需要回溯旧版本时可以切回去 - 切换后有观测期(比如 30 分钟),发现新版本导致检索质量下降立即回滚
④ 兜底策略
- 即使新版上线了,旧版知识库保留至少一个窗口期(比如 7 天)
- 极端情况下用户要求”用上次的结果”——能从旧版本召回
- 定期做 ghost 检测:检测旧版本中已被删除但新版本还在的文档
面试加分:我实际踩过的坑——“有一次我们更新了文档,增量 embedding 的时候出现了数据竞争,导致新增文档的向量和旧文档混合在一起,用户搜索某些关键词时返回了新旧混杂的结果。后来我们改成每次更新都分配一个批次号(batch_id),查询时只返回最新批次的数据。“
【Agent 系统工程 · 3 题(新增)】
题17:Agent 安全体系怎么设计?怎么防止 Agent 失控?
频次:⭐⭐⭐⭐ | 难度:A | 来源:字节/腾讯/CVTE/阿里淘天
参考回答(面试口语化):
面试官问”系统为什么不会失控”——不是要你保证”Agent 永远不会出错”,而是要看你有没有想清楚安全边界。
三层安全设计:
第一层:入口限制——Agent 没有”想做就做”的自由度 Agent 所有的能力都是显式注册的。你在 tool registry 里注册了什么,Agent 才能用什么。没有注册的工具,Agent 没法凭空调用。每个工具的 description 里会说明使用限制(比如”文件删除工具只允许删除工作区目录下的文件”)。
第二层:执行隔离——Agent 在”沙箱”里干活
- 文件系统隔离:Agent 只能访问工作区目录,不能碰系统文件。用 Docker 挂载卷 + 用户映射实现
- 网络隔离:非必要的网络请求会被拦截
- 操作审计:每一步工具调用都记录完整的入参、出参、时间戳
第三层:人在回路——关键操作永远有人确认 对于有破坏性的操作(删除文件、执行高危命令、写数据库),Agent 不能直接执行——它只能生成操作方案,等用户确认后才执行。等于说 Agent 的自主权不是无限的,它其实是一个”聪明但需要上级签字的下属”。
额外还要考虑的安全风险:
- Prompt 注入攻击:用户输入试图覆盖系统指令→输入侧做指令检测 + 权限分离
- 沙箱逃逸:Agent 生成的代码试图突破沙箱→seccomp 过滤危险 syscall + cgroup 资源限制
- 循环调用:Agent 的代码写 bug 了导致无限循环→限流检测 + 最大步数限制
面试加分:从”代码生成”角度——“我们在工具定义里加了’只读/读写’属性标注。只读工具(搜索、阅读文件)Agent 可以自主调用;读写工具(修改文件、执行命令)必须先产生操作方案,用户确认后才执行。这个设计让我们敢给 Agent 更多自主权——因为关键的写操作永远有人兜底。“
题18:Agent 任务恢复/断点续跑怎么做?
频次:⭐⭐⭐ | 难度:B+ | 来源:字节高频
参考回答(面试口语化):
Agent 执行过程中可能中断——报错、超时、用户暂停。断点续跑的核心是记录每一步的执行状态 + 存快照。
怎么做:
- 状态记录:每运行一步,把当前上下文快照(用户输入、system prompt 版本、工具候选集、工具调用结果、Agent 输出)存下来。每步一个”检查点”。
- 中断检测:Agent 重启时,检查是否有未完成的任务(检查点存在且状态不是”已完成”)。
- 恢复执行:加载最近的检查点,重新初始化 Agent 状态,从中断的地方继续。恢复时需要把历史上下文摘要注入,让 Agent 知道”到哪了”。
关键设计:
- 检查点文件要结构化(JSON),包含足够元数据(任务 ID、步骤号、时间戳)
- 恢复时要告诉 Agent”这是恢复执行,不是新任务”——防止从头开始
- 检查点定期清理,太旧的淘汰
对比实际落地经验:用 SQLite 做检查点存储比文件系统好——支持事务写入、查询、清理,而且不需要自己处理并发问题。LangGraph 的 Checkpointer 就是基于 SQLite 做的。
题19:Agent 意图识别不准怎么优化?
频次:⭐⭐⭐ | 难度:B+ | 来源:Cider/滴滴
参考回答(面试口语化):
意图识别不准是 Agent 项目里最让人头秃的问题之一——用户说的话千奇百怪,模型理解歪了,后面所有步骤都错了。
优化策略从浅到深:
① CoT 引导
- 让模型逐步推理而不是直接跳结论。加一句”请先分析用户想做什么,再决定下一步行动”
- 实测 CoT 引导后意图识别准确率能提 5-10%
② 反问澄清
- 模型对用户意图置信度低于阈值时,不要猜,直接反问用户确认
- “您是想查询天气还是设置提醒?“——反问能避免 80% 的错误意图推断
③ 多轮修正
- 允许用户纠偏,把纠偏记录存入 few-shot 示例
- 比如用户说”查北京天气”→ 模型以为是查北京旅游攻略 → 用户纠正”我说天气” → 记录这个纠偏对,下次类似场景参考
④ 轻量分类器兜底
- 用 BERT 级别的分类模型做第一道意图预检(意图分 5-10 个大类)
- 分类器置信度高的走特定处理路径,低的走 LLM 通用推理
- 好处:简单请求(查天气、算算术)不走 LLM,省成本也更快
面试加分:要让人感觉你真的挨过意图识别的打——“我们有一次上线了新工具,结果用户说’帮我看看这个’,模型直接调了 4 个不同工具各尝试了一次,浪费了好多 token。排查后发现是工具 description 里没有加’什么时候用’的说明,模型面对多个可选工具时只能挨个试。加上说明后这个问题就解决了。”
🎯 下篇预告:各厂特色题篇(30+ 题) — 字节/阿里/腾讯/滴滴/中小厂独家考点 + 项目话术题
Share Article
If this article helped you, please share it with others!