得物后端一面:RAG 召回与生成归因、多轮意图与可观测性
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 详细说明物流客服智能助手的项目背景。
- 为什么选 Spring Boot + LangChain4j 这套技术栈?
- 文档切分参数和召回 top 5 是怎么定下来的?
- 怎么判断是召回不好,还是召回正确但模型答错?
- 文档已正确召回但模型回答仍有偏差,应该检查哪些项?
- multi-query 为什么能提升效果?它有什么副作用,怎么解决?
- 物流客服场景里,什么类型的问题最适合 BM25 而不是向量召回?
- 多轮对话自动生成摘要重建上下文时,怎么保留用户最终真实意图、过滤前期临时想法?
- 用户会修正早期订单意图,多轮长对话会不会意图偏移?用户自己摇摆不定时怎么处理?
- 每条消息和上下文都存在 MongoDB,这是全量信息吗?
- 为什么不存向量库?MongoDB 里存的是向量吗?
- 检索召回率从 90% 提升到 95%/97%,但最终答案准确率反而下降,可能是什么原因?
- AI 客服偶发响应变慢(常规 3~5 秒,部分超过 10 秒),现有 Actuator + TraceID 能不能直接定位?
《参考解析》
召回问题 vs 生成问题:做“证据回放”。固定同一批问题,先看检索结果里有没有包含标准答案所需的文档/片段:如果没有,是召回问题;如果有但回答错,是生成或编排问题。召回问题再拆查询改写、切分、索引、过滤、top-k、重排;生成问题拆上下文顺序、提示词、模型能力、输出解析、工具调用。可以人工标注“黄金证据”,计算 recall@k 和 MRR;生成侧用忠实度评分和人工抽检。不要只看最终答案对错。
切分与 top-k:切分按文档结构(标题、段落、表格)优先,块大小和 overlap 用评测集网格搜索;top-k 不是越大越好,太大引入噪声、增加延迟和 token。物流客服的文档有运单规则、赔付标准、时效说明,条款类适合小块 + 精确检索,流程类适合稍大块保留上下文。top 5 是基线,应该按问题类型动态调整,并用重排把真正相关的排前面。
multi-query:把原问题改写成多个不同表述分别检索,能覆盖同义词、口语化表达和隐含条件,提升召回。副作用是查询变多导致延迟和成本上升、召回结果重复或互相矛盾、可能引入噪声。解决:限制查询数量、并行检索、结果去重与融合(RRF)、加重排、对改写质量做校验,简单问题不走 multi-query。
BM25 适用场景:订单号、运单号、手机号、SKU、地名、专有名词、精确条款编号这类“字面必须匹配”的问题,向量容易把相似但不同的编号混在一起,BM25 更稳。反过来,口语化描述、同义表达、跨段语义匹配更适合向量。所以生产上用混合检索,按问题类型调权重。
多轮摘要与意图:摘要不能只压缩文本,要保留结构化状态:用户最终目标、已确认的订单/商品、时间范围、已排除的选项、待确认问题。每轮更新状态时用“新增/修改/删除”而不是重写整段摘要;让模型只做信息抽取,状态合并用确定性规则。恢复上下文时把“当前有效状态”放在最前面,历史摘要作为补充。用户摇摆时不要替用户做决定,列出选项和后果让用户确认;关键操作(退款、改地址)必须二次确认。
MongoDB 与向量库:MongoDB 适合存原始消息、会话元数据、工具调用记录,字段灵活、按会话查询方便;向量检索需要专门的向量索引和相似度计算,MongoDB Atlas 支持向量搜索,但自建场景常用 Milvus/pgvector/FAISS。存不存向量取决于检索需求:如果只是按会话回放,不需要向量;如果要做语义检索,向量库更合适。注意隐私和 TTL,聊天记录不能无限期全量保存。
召回率升但准确率降:常见原因是 top-k 变大后上下文过长,模型被无关或矛盾信息干扰;重排没做好,相关文档被淹没;召回的口径变了(比如把相似但过期的版本也召回);评测集泄漏或标注偏差。解决:控制上下文长度、按版本/权限过滤、加强重排、让模型引用来源、对长上下文做压缩,并分别评估召回和生成的指标。
偶发慢请求定位:Actuator + TraceID 只能告诉你“哪个 span 慢”,不能直接给根因。要看慢请求的分布:是否集中在某个模型、某个工具、某个文档、某个时段;对比 P50/P95/P99;检查模型侧限流/排队、检索侧慢查询、MongoDB 连接池、GC、线程池排队、网络重试。把 Trace 采样率提高,记录每步耗时和重试次数;如果是外部模型偶发慢,要有超时、降级和缓存。