RAG interview

know-engine面试通关指南(更新中)

问题改写具体做了哪些事情,举个例子说明下 在我们的汽车智能客服场景中,问题改写(Query Rewrite)的核心定位是 “前置理解层” 。它的本质是在不改变用户核心意图的前提下,将用户口语化、模糊或带有情绪的原始提问,转化为系统向…

TL;DR

问题改写具体做了哪些事情,举个例子说明下 在我们的汽车智能客服场景中,问题改写(Query Rewrite)的核心定位是 “前置理解层” 。它的本质是在不改变用户核心意图的前提下,将用户口语化、模糊或带有情绪的原始提问,转化为系统向…

问题改写具体做了哪些事情,举个例子说明下

在我们的汽车智能客服场景中,问题改写(Query Rewrite)的核心定位是“前置理解层”。它的本质是在不改变用户核心意图的前提下,将用户口语化、模糊或带有情绪的原始提问,转化为系统向量数据库、关系型数据库更容易理解和匹配的标准化查询语句。 具体而言,我们的改写主要做了以下三件事: 1. 语义归一化与简洁化:删除无意义的语气词、修饰词,将口语化的疑问句转化为陈述句,使其更符合搜索引擎的检索习惯。 2. 抽象概念提炼:将用户描述的具体故障现象或细节问题,转化为更基础、更专业的抽象概念。 3. 术语标准化与纠错:纠正用户输入中的错别字、拼音,并将非标准的车型昵称统一转化为官方标准名称。 举例说明:假设用户提问:“我如果想买一辆特斯拉Model 3的话,大概需要多少钱啊”。如果直接拿这句话去检索,向量库可能会匹配到大量关于“购买流程”、“Model 3体验”等无关文档。经过我们的改写器处理后,它会输出:“Tesla Model 3官方指导价”。在这个例子中,改写器去掉了“我如果想买”、“的话”、“大概需要...啊”等冗余信息,并将“特斯拉Model 3”进行了术语标准化,最终让检索系统能精准命中价格相关的核心文档。

有没有遇到改写之后检索效果更差的情况

在实际落地过程中,确实遇到过改写后效果反而变差的情况,这通常是由以下两种原因导致的: 第一种情况:过度抽象导致关键信息丢失。在初期调试“抽象概念改写”策略时,如果提示词(Prompt)的约束不够严谨,LLM可能会过度发挥。例如用户问“我的Model Y冬天在东北掉电快怎么办”,如果改写器将其过度抽象为“电动汽车冬季续航衰减”,虽然语义正确,但丢失了“Model Y”和“东北”这两个极其关键的检索限定词,导致召回的文档过于宽泛,无法解决用户的特定问题。 第二种情况:专有名词被错误泛化或改写。有时LLM会将一些特定的技术术语或车型代号进行“自作聪明”的改写。比如用户查询“ChatGPT的System Prompt长度限制”,改写后变成了“大语言模型的提示长度限制”,虽然意思相近,但“System Prompt”这个专有名词被泛化,导致在向量库中无法匹配到包含该精确术语的技术文档。 我们的应对方案:针对这些问题,我们在Prompt中增加了严格的约束,明确要求“保留所有专有名词、产品名、技术术语不修改”。同时,在工程实现上,我们的 KnowEngineQueryTransformer 返回的是一个集合 List.of(compressedQuery, query),即同时返回改写后的查询和原始查询。在检索阶段,我们可以采用多路召回或降级策略,如果改写后的查询召回效果不佳,系统可以静默回退到使用原始查询进行检索,从而保证系统的鲁棒性。

怎么监控和运维发现是问题改写导致的结果变差

在AI Agent系统中,传统监控(如请求量、延迟、错误率)往往会失效,因为改写节点即使把问题改错了,HTTP请求依然会返回200成功,这属于典型的“静默失败”。为了发现和定位这类问题,我们采取了以下监控与运维手段: 1. 建立全链路的数据留存与关联(可观测性基础)正如代码中实现的,我们在 transform 方法中通过异步线程将 原始问题 和 改写后的问题 持久化保存到数据库(chatMessageService.updateTransformContent)。这是排查问题的基石。当业务侧收到“答案不对”的投诉时,运维人员可以通过 assistantMsgId 快速拉取当时的改写记录,判断是“改写错了”还是“检索/生成错了”。 2. 设立Bad Case专项反馈闭环我们不仅仅依赖自动化指标,还建立了用户反馈机制。当用户对回答点“踩”或进行人工客服转接时,系统会自动标记该会话。运维团队定期抽检这些Bad Case,如果发现大量问题的根因都是“改写后的Query偏离了原意”,这就触发了改写策略的优化警报。 3. 监控改写节点的“异常模式”虽然不能直接监控“改写质量”,但我们可以监控一些间接指标。例如,监控改写前后的文本长度差异、或者改写后检索出的文档相似度分数分布。如果某段时间内,大量查询被改写成了极度简短或极度抽象的词汇,且伴随检索召回率的断崖式下跌,系统应能触发告警。

上线之后你怎么动态的发现整体的得分下滑,这一块线上的监控你是怎么做的?

1、评测自动跑,起个定时任务,定时把线上的真实问题用评测框架跑一遍。然后把一些异常得分的case告警出来,人工跟进。 2、定义基线,线上的测评持续跑了一段时间之后,可以根据历史数据做一个基线,比如把过去10天的平均分数作为基线值。实时评测低于这个基线,或者有一定的数量低于这个基线则告警。

混合检索和重排序,如何进行加权

在我们的项目中系统中,混合检索和重排序是两个核心步骤,它们共同决定了最终提供给LLM的上下文质量。其实,我们项目中没有用加权的方案做,而是采用检索阶段的分数融合+重排序阶段的阈值过滤。 第一层:混合检索的分数融合(RRF算法) 在混合检索阶段,我们通常会同时使用多种检索器,例如向量检索(语义相似)和关键词检索(精确匹配)。不同检索器返回的分数(Score)量纲和分布都不同,无法直接相加。因此,LangChain4j的DefaultContentAggregator默认采用RRF(Reciprocal Rank Fusion,倒数排名融合)算法来解决这个问题。 RRF的核心思想是:“不关心原始分数,只关心排名位置”。它将不同检索结果的原始分数转换为基于排名的权重,然后进行融合。

✅RAG优化技术:重排序

什么是重排序? 重排序(Reranking)是在通过混合检索(或其他方式)获得初步检索结果(候选文本块)后,再通过更强的模型(通常是 Cross-Encoder 或专用 Reranker 模型)对这些候选文本块进行重新打分和排序,将真正最相 LLMentor RRF算法巧妙地通过排名来“加权”,避免了不同检索器分数不可比的问题,让在多个渠道都表现优秀的文档脱颖而出。 第二层:重排序的精准打分与过滤(ScoringModel) RRF融合后的结果列表虽然综合了多种检索方式的优点,但可能仍然包含一些相关性不高的文档,或者数量过多。这时就需要重排序登场。 LangChain4j的ReRankingContentAggregator在RRF融合的基础上,引入了ScoringModel(我们的方案中的BGE-Reranker)进行二次精排。这一步的“加权”体现在两个方面: 1. 精准相关性打分ScoringModel(通常是Cross-Encoder模型)会将查询(Query)和每一个文档(Document)拼接在一起,输入模型进行深度交互计算,输出一个全新的、更精准的相关性分数。这个分数比向量检索的余弦相似度或关键词匹配的BM25分数更能反映语义上的相关性。 2. 阈值过滤(Min Score):设置一个最低分数阈值(minScore)。所有低于这个阈值的文档都会被直接过滤掉,不会被送给LLM。

✅通过 minScore 解决召回准确率低的问题

现象 部分 Query 即便经过查询改写、混合检索(KNN + 全文)、BGE-RERANKER 重排序,仍会把语义相关度极低的分片喂给 LLM。不仅可能出现错误回答,还会导致召回准确率降低。 比如我们在测试的时候发现,经过重排序后有分数小 LLMentor

用混合检索的必要性,只用向量检索或者只用关键词检索会有什么问题,有实际case吗

1、只用了向量检索效果不行 核心问题:向量检索依赖语义相似度,对专有名词、精确短语、编号等缺乏精确匹配能力;且在面对极短查询时,因语义上下文有限,容易导致召回内容过于宽泛。 比如我们课程讲的内容中,针对『超级桌面』这个内容的检索。超级桌面本身就是一个汽车领域的专有名词,而和他相似的词有很多,比如典型的3D桌面,手机桌面,车机桌面,桌面。 单纯靠向量检索的话,包含这些关键词的文档得分都挺高的。使得检索效果差。比如这个case:

✅解决中文分词不准确导致召回效果差的问题

我们虽然在ES中安装了IK分词器,但是并没有用上,所以导致中文分词是每个中文字单独作为一个分词了,就导致召回结果不好,明明相关的内容却召不回。 所以我们需要让IK分词器生效。 创建组件模板 创建索引模板 LLMentor 2、只用bm25关键词检索效果不行 核心问题:关键词匹配是死板的字面匹配,无法理解同义词、语义表达变化或复杂的自然语言意图。 这个就很好理解了,关键词检索要求一定要字面匹配,比如我们想要问关于手机能否启动汽车等问题的时候,其实在问的是汽车如何做启停、如何无钥匙进入、智能座舱功能等。 单纯按照分词后的关键词检索的话,就会检索不到想要的内容,就算检索到,得分也不高。

Ragas如何使用的,如何使用,用到了哪些测评指标

见前面评测章节

答案相关性高,答案召回率低你觉得是什么原因

  1. 召回阶段:检索策略过于单一或参数过严 - 仅依赖单一语义匹配:如果系统只使用了纯向量检索,而没有结合关键词检索(BM25),很容易因为语义理解的偏差导致漏召回。例如,用户提问“微服务熔断”,但知识库权威文档中使用的是“服务降级”或“故障隔离”,纯向量检索可能无法覆盖这些同义表达,导致召回率下降。 - 过滤条件过严:在检索前或检索过程中,如果设置了过于严格的权限预过滤、时间过滤或元数据过滤,会直接把部分正确答案排除在候选集之外。
  2. 排序与重排阶段:阈值设定过高(最常见原因) - 重排序(Rerank)阈值过高:在引入Reranker模型进行精排时,如果设置的最低相关性分数阈值(minScore)过高(例如设置为0.8或0.9),系统会过滤掉所有得分略低但实际上包含关键信息的文档。这虽然保证了留下的文档“绝对相关”,但牺牲了整体的召回率。 - 排序质量导致“伪证据”挤占位置:有时候真正相关的证据其实已经被召回到了Top-50中,但由于排序算法的问题,前面挤满了看似相关但实际无用的噪声Chunk。如果最终只截取Top-10给大模型,真正的答案就被截断了。
  3. 切块阶段:语义边界损坏 - 切块(Chunk)太小:如果文档被切分得过细,会导致上下文不完整。例如,某个问题的定义在上一段,而例外条件在下一段,如果它们被切分到了不同的块中,检索时可能只命中了其中一个碎片,导致其他包含完整逻辑的相关块无法被有效召回。 - 结构化信息被破坏:对于表格、代码块或层级分明的制度文档,如果按固定长度硬切,会导致语义断裂。系统可能检索到了“有点相关”的碎片,但真正能直接回答问题的完整证据块不在召回结果中。
  4. 查询阶段:改写导致语义偏移 - Query Rewrite 改偏:如果使用了LLM对原始问题进行改写,改写过程可能过度抽象或丢失了关键实体。例如,将“2024年Q2营收”误改写为“2024年Q2利润”,或者丢失了具体的车型编号、产品代号,导致检索器无法在知识库中命中那些包含精确术语的文档。

讲讲你在项目中使用RAG遇到哪些技术难点,以及你是怎么解决的?

✅讲讲你的RAG项目遇到哪些技术难点,以及你是怎么解决的?

(这部分的难点,可以等面试官主动问,但是建议把他们提前写到简历上,等着面试官) 分块语义被截断的问题 最开始我们用固定长度切分文档,但很快发现汽车知识库里大量内容是按 Markdown 标题层级组织的(比如「车型 → 配置 → 保养手册」) LLMentor

RAG项目有做测评吗?你是怎么做的?

我们项目是做了系统性测评的,而且用的是 RAGAS 框架。之所以引入这套测评,是因为我们在早期发现,RAG 系统上线后很容易遇到‘高分低能’的情况——比如模型明明检索到了正确答案,却依然在闭眼瞎编。而且只看最终答案对不对,根本没法定位到底是检索环节出了问题,还是生成环节出了问题。 为了解决这个问题,我们引入了 RAGAS 来做自动化的组件级评估。具体做法是: 第一,构建评估数据集。我们整理了一批覆盖业务核心场景的问答对,包含 question(用户问题)、ground_truths(标准答案)、contexts(检索到的文档片段)和 answer(模型生成的回答)。 这些问题一部分来自于之前的线上客服在用的Q&A手册,还有一部分是运营同学整理出来的,这些是带有标准答案的,这些数据大概有100多条,我们有用大模型,针对问题做了扩展,用的是GPT 5模型,这样幻觉比较小,并且只针对问题扩展,他看不到答案,所以也不会有隐私问题,让大模型给出不同的问法。 还有一部分数据是人工测评的时候打标的比较好的QA对。 第二,利用 RAGAS 的核心指标进行拆解评估。我们主要关注三个维度: 1. 检索质量(Context Relevancy & Recall): 评估检索回来的文档片段是否真的和问题相关,以及是否包含了回答问题所需的全部信息。这能帮我们判断是不是 Embedding 模型选得不对,或者分段(Chunk)策略有问题。 2. 生成质量(Faithfulness,忠实度): 这是 RAG 最核心的指标,用来衡量模型生成的答案有多少是基于检索到的上下文的。如果这个分数低,说明模型在产生幻觉、胡编乱造。 3. 回答质量(Answer Relevancy): 评估最终生成的答案是否完整、准确地回应了用户的问题。 第三,通过测评驱动优化。RAGAS 的好处在于它能实现‘无参考评估’,不需要大量人工标注,可以直接用大模型当裁判打分。通过监控这些指标,我们能精准定位瓶颈。 比如,如果发现 Context Relevancy 低,我们就去调优向量检索的 Top-K 或者引入重排序(Rerank)模型;如果发现 Faithfulness 低,我们就去优化 Prompt,强制模型严格基于上下文回答。 总结来说,引入 RAGAS 让我们的 RAG 系统从‘凭感觉调优’变成了‘看数据调优’,极大地提升了我们迭代系统的效率。

RAG优化的时候,有遇到哪些典型的bad case么?

【持续更新】know-engine评测问题与优化(bad case)

智界R7的超级桌面如何开启?——召回率低 相似度检索到的分段: BM25检索到的分段: LLMentor

MinerU的实现原理是什么?

MinerU 的实现原理非常扎实,它不是简单地调用现成的 OCR 接口,而是构建了一套完整的、基于深度学习的“高精度 PDF 模型解析工具链”。简单来说,它的工作流程可以分为以下几个核心步骤: 1. 文档分类与预处理 在处理 PDF 之前,MinerU 会先对文档进行“体检”,自动识别它是文本型、图层型还是扫描版 PDF,并进行相应的预处理(比如检测乱码),为后续解析打好基础。 2. 核心模型解析(四大金刚) 这是 MinerU 最核心的技术壁垒,它集成了多个先进的深度学习模型来精准“看懂”文档: - 布局检测:使用基于深度学习的 LayoutLMv3 模型,精准识别文档中的图像、表格、标题和文本等不同区域。 - 公式检测:利用基于 YOLOv8 的自研模型,专门用来识别数学公式,并区分行内公式和行间公式。 - 公式识别:通过自研的 UniMERNet 模型,将识别出的公式精准转换成 LaTeX 格式。 - 文字识别 (OCR):使用 PaddleOCR 等先进技术,负责识别文档中的文本内容,支持多语言。 3. 智能管线处理 (Pipeline) 模型识别出各个元素后,MinerU 会通过一个处理管线进行后处理。这一步非常关键,它会确定块级别的顺序、删除无用的页眉页脚、根据版面进行内容排序和拼装,并进行坐标修复和公式替换,最终保证输出的正文是通顺且符合阅读逻辑的。 4. 灵活的架构模式 MinerU 在架构设计上提供了两种模式: - Pipeline 模式:采用模块化设计,将 OCR、布局分析等任务划分为独立阶段,灵活且适合本地开发。 - VLM 模式:基于多模态深度学习架构,结合视觉与语言模型,适用于需要语义理解和上下文推理的复杂任务。 5. 结果质检与输出 最后,MinerU 会将处理后的数据转化为统一的中间态格式(middle-json),并根据需求输出为 Markdown、JSON 等格式。同时,它还引入了人工标注的自测评测集和可视化质检工具,通过不断反馈来进一步提升模型的解析能力。 这套原理确保了 MinerU 在处理包含复杂表格、公式和多模态元素的 PDF 时,能够保持极高的准确率和结构化还原度。

文档如果要更新怎么办?

这个问题来自一个真实的业务痛点:知识库文档更新时,不能让用户搜不到东西。比如一份保养手册要出新版,如果先把旧版删了再处理新版,中间有几个小时的空窗期,客服那边就完全查不到保养相关的内容了。 核心设计思路是新旧共存、最后切换。我们有一个三层实体模型:KnowledgeDocument(文档)→ KnowledgeDocumentVersion(版本)→ KnowledgeSegment(分块)。一个文档可以有多个版本,每个版本有自己独立的分块和向量数据。 上传新版本时,整个流程是这样的: 首先获取分布式锁(基于 Redisson,waitTime=0 非阻塞模式,拿不到锁直接报错,防止排队堆积)。然后做版本号校验(必须严格递增)和 SHA-256 内容去重(跨文档、跨版本全局查重)。通过校验后,把新文件上传到 MinIO,创建新的 Version 记录,开始走转换 → 切块 → 向量化的流水线。 关键在于:整个处理过程中,旧版本的 Segment 和 ES 向量数据完全不动。 代码里的注释写得很明确:"不清理旧版本数据,保证处理期间旧版本仍可查询"。检索时通过 metadata 里的 DOC_ID + VERSION 过滤,旧版本的数据一直在正常服务。 只有当新版本全部处理完成(状态推进到 VECTOR_STORED)之后,才会把 document.currentVersionId 这个指针切到新版本的 ID。这一步是在一个 @Transactional 里做的,是个数据库层面的原子操作。切换完成后,embedAndStore() 方法里还有一个检查逻辑:发现同一文档有其他 VECTOR_STORED 状态的旧版本,会调用 deactivateVersion() 清理旧版本的 ES 向量,把旧版本的 Segment 状态从 VECTOR_STORED 降级回 STORED。

版本提示

模型、框架与接口会持续变化。涉及版本号、参数与生产配置时,请在实践前对照对应官方文档。

LLMentor系统化学习大模型应用工程

内容来自个人课程知识库备份,并经过结构化整理。技术版本持续演进,生产使用前请结合官方文档验证。