跑通RAG+Agent Demo后,我被问得最多的10个面试题——深度拆解与避坑指南 📅 2026/6/30 4:48:49 这些题不是从教科书上扒的是我把项目写进简历后面试官顺着项目一路挖到底的真问题。每个题我都标注了常被追问的方向和我答错过的坑。题一为什么用RecursiveCharacterTextSplitterchunk_size和overlap怎么定的题二BGE Embedding为什么要归一化如何部署成独立服务题三Chroma、FAISS、Milvus选型差异与适用场景题四Rerank的原理是什么CrossEncoder和Bi-Encoder区别题五对话记忆爆Token怎么办总结记忆和滑动窗口怎么实现题六防幻觉提示词设计思路还有哪些更彻底的技术方案题七Agent选ReAct还是Function Calling解析失败如何处理题八增量添加文档时怎么保证向量空间一致题九整个系统从输入到输出的延迟瓶颈在哪里题十如果知识库和工具返回冲突信息Agent如何抉择前言之前我把那套RAGAgent Demo写了之后我把被问得最多、也最容易答岔的10个问题重新整理了一遍连同当初做Demo时踩过的坑、面试官顺藤摸瓜的追问还有我个人觉得能拿分的回答方式全部摊开写在这里。建议看完之后别直接背而是结合你自己的项目经验去消化——面试官想看的不是标准答案是你做技术取舍的思考过程。题一为什么用RecursiveCharacterTextSplitterchunk_size和overlap怎么定的面试官常这么问“你切文档用了什么策略分块大小怎么选的”我在Demo里没用固定字数硬切而是选了LangChain的RecursiveCharacterTextSplitter分隔符给了中文标点优先级先按段落换行再按句号、问号最后才到逗号和空格。这么做的逻辑其实很朴素——我想保证每一块尽量是完整的语义单元。如果用固定512字硬切很容易把一句话从中间劈开比如“员工每年享有五天带薪年假”被拆成“员工每年享有五天带”和“薪年假”向量检索时相似度会被严重稀释。追问深挖方向“这个chunk_size到底怎么定出来的你做过实验吗”“overlap为什么设50太小或太大会怎样”我当时真的跑过几组对比。chunk_size试了256、512、768最后落在512是权衡了两件事一是BGE-small的Embedding训练时上下文窗口大约512 tokens过长会超出模型处理习惯相似度反而下降二是公司制度类文档单条条款大多在300500字512刚好能覆盖一条完整规则。overlap设50大概占chunk_size的10%这样相邻两块可以共享开头或结尾的关键信息比如“详见附件二”这种跨块引用不会被切断。设太大会导致冗余多、检索效率低设太小或0则容易出现答案刚好卡在边界上的情况。容易栽的坑有人直接把chunk_size设成和模型最大长度一致比如1024觉得“越大越不容易丢信息”。但向量检索里长文档的语义会被平均掉短查询匹配时反而找不到。另外就是忽略中文分隔符用默认英文分隔符切中文切出来全是乱断句。题二BGE Embedding为什么要归一化如何部署成独立服务面试官原话“你代码里encode_kwargs里写normalize_embeddingsTrue这有什么用不归一化行吗”这个问题在面试里中招率特别高。答案是归一化之后两个向量的余弦相似度等于它们的内积。Chroma默认用余弦相似度做检索但底层计算如果要先归一化再算会多一步开销如果直接存储的就是归一化向量后续计算直接做内积速度更快而且数值稳定。更关键的是如果不归一化向量的模长会携带文本长度信息长文档天然模长大会导致相似度排序被长度因素污染短而精准的片段反而排不上号。追问那你怎么把Embedding部署成独立服务我通常的回答思路是Demo里直接用HuggingFace本地加载但到多人调用或微服务场景肯定会把BGE封装成HTTP接口。具体做法是用FastAPI加一个/embed端点背后用单例模式加载模型支持批量请求。还可以用TorchServe或者Triton Inference Server做GPU推理加速。这里我会强调一个细节——模型输出层要手动加L2归一化因为有些serving框架不保证这一步。踩坑点有些人换了模型但忘了改normalize_embeddings参数或者新模型默认不归一化结果Chroma的检索结果完全乱套。另一个坑是服务化后客户端和服务端的归一化逻辑不一致两边向量对不上。题三Chroma、FAISS、Milvus选型差异与适用场景面试官追问逻辑“你Demo用Chroma那如果数据量大了会换什么FAISS你用过吗什么时候上Milvus”这个问题其实在考察你有没有做过生产评估。我的回答通常会分层Chroma零配置、本地持久化、自带元数据过滤非常适合Demo和原型验证。我在项目里文档量不超过5000条时检索响应都在毫秒级完全够用。FAISSFacebook出的纯向量索引库不存原始文档不持持久化需自己序列化但索引算法极其丰富IVF、HNSW调优后可以在百万级向量上做到亚毫秒级检索。我一般会说“如果对延迟极度敏感且不需要元数据过滤我会换FAISS但需额外搭个DB存原文”。Milvus分布式向量数据库天然支持横向扩展、混合查询、数据持久化适合十亿级别的大规模线上服务。我一般补一句“咱们Demo这个体量用Milvus相当于杀鸡用牛刀但我在公司内部POC里确实用过主要是看中它和K8s的集成比较方便。”容易答岔的地方单纯说“Chroma简单就用这个”不讲出FAISS和Milvus的核心差异。面试官会追一句“那你怎么不直接用FAISS”如果你答不上来FAISS没有持久化能力、需要自己管理元数据那基本就凉了。题四Rerank的原理是什么CrossEncoder和Bi-Encoder区别面试官高频问法“你明明已经用向量检索了为什么还要加一步Rerank这个Rerank模型和前面的Embedding模型有什么区别”我这里一定要把Bi-Encoder和CrossEncoder的本质差异讲透Bi-Encoder双塔模型就是前面的BGE Embedding。Query和Document分别独立编码成向量然后算余弦相似度。好处是速度飞快可以离线把海量文档全量向量化检索时只算一个查询向量。但问题在于Query和Document在编码时没有交互全靠各自向量映射后的空间距离对语义的精细捕捉不够。CrossEncoder交叉编码器把Query和Document拼成一对[CLS] Query [SEP] Document [SEP]输入Transformer从头到尾充分交互最后输出一个相关性分数。效果好得多但缺点也明显——每一对都要过一次完整模型计算量巨大完全没法对全库做。所以我的设计思路就是粗排用Bi-Encoder快速召回Top-K精排用CrossEncoder对少量候选做重排序兼顾效率和效果。在我的Demo里召10条然后用Rerank截取前3把最相关的片段塞给LLM比直接给10条的最终回答质量提升非常明显幻觉率肉眼可见下降。追问“你能讲讲Rerank模型具体怎么打分吗”这时可以补充CrossEncoder输出层一般是一个线性头把[CLS]位置的隐藏状态映射成一个logit再用sigmoid得到相关性分数。更细的还可以提一下训练数据的构造方式正负例采样。踩坑提醒有些人直接把Rerank用在全部文档上整个流程巨慢却不知道问题出在哪。另外就是Rerank模型的最大输入长度通常也是512长文档要先截断。题五对话记忆爆Token怎么办总结记忆和滑动窗口怎么实现面试官追问路径“你的Demo用ConversationBufferMemory如果用户连续聊了50轮会发生什么”老实说我在Demo里根本没处理这个问题因为演示场景对话很短。但这个追问几乎是必考题。我会这么答BufferMemory本质上就是把所有历史消息全量拼进Prompt聊多了肯定超模型上下文窗口要么被截断丢信息要么直接报错。解决方案从简单到复杂有几种滑动窗口记忆ConversationBufferWindowMemory只保留最近K轮对话简单粗暴。缺点是早期重要信息会丢比如用户一开始说过“我叫张三”窗口一滑就忘了。摘要记忆ConversationSummaryMemory用一个额外的LLM调用定期把长对话压缩成一段摘要把摘要和最近几轮一起放进Prompt。这样能保留关键信息又能控制Token数。但摘要质量依赖模型且多一次LLM调用有延迟开销。Token限制记忆ConversationTokenBufferMemory直接按Token数硬截断确保不超限。我一般在生产里会把摘要和Token限制混合用。踩分点能清晰描述每种方案的适用场景和代价比如“摘要记忆适合长对话但需要额外算力滑动窗口适合简单问答但会丢全局信息”。如果还能说出记忆和检索的结合——比如把历史摘要存入向量库每次检索也召回相关历史片段那就是高阶回答了。题六防幻觉提示词设计思路还有哪些更彻底的技术方案面试官经常这样问“你在System Prompt里写‘不知道就说不知道’真的能防住模型瞎编吗”我的真实反馈是有用但不够。提示词约束本质是软约束模型在生成概率分布时仍然可能输出看似合理但文档里没有的内容尤其是一些数值、日期它会“脑补”。在Demo里我主要靠提示词压低幻觉率但同时也准备了更高阶的思路。追问那有没有更彻底的手段我一般会展开讲这三个方向强制引用标注要求模型在回答的每一句后标注[来源文档3-第2段]。这样至少能溯源用户自己能核对。落地时配合前端高亮体验很好。NLI校验用一个自然语言推理模型比如RoBERTa微调的NLI对生成答案做事实一致性检测。具体做法是把答案拆成原子事实每个事实和检索原文做蕴含判断矛盾的过滤掉或标记。严格约束解码在生成阶段限制解码词表只允许从原文片段中抽取或限定词汇比如使用constrained beam search。不过通用性较差一般只在特定领域用。易错点很多人会以为提示词里写一句“不要编造”就万事大吉面试官一追问“如果模型还是编了你怎么监控”就答不上来。所以一定要把软约束和硬校验的组合思路表达清楚。题七Agent选ReAct还是Function Calling解析失败如何处理面试官爱问“你为什么用ReAct而不用OpenAI的Function CallingReAct的观察-思考-行动循环具体怎么保证不跑飞”选ReAct的一个重要原因是我当时Demo里想兼容任意LLM包括本地ChatGLM这些模型不一定支持原生Function Calling。ReAct本质上是通过Prompt引导模型输出特定格式文本再通过正则解析出Action和Action Input属于纯工程化的方法对模型本身没有特殊要求可迁移性强。但代价也明显——解析非常脆弱。模型稍微输出格式不规范比如Final Answer后用了中文冒号或者少一个空格正则就匹配失败。我Demo里加了两道防线一是Prompt里反复强调格式并用示例强化二是开启handle_parsing_errorsTrue解析失败时把原始输出和错误信息喂回模型让它重新输出。实测重试一次成功率能到90%以上。追问那跟Function Calling比到底什么时候用哪个我的判断是如果你用OpenAI、DeepSeek这类强模型且工具调用逻辑简单Function Calling更稳定因为它直接约束模型输出结构化JSON几乎没有解析错误。但如果要换模型、或者Agent推理链比较复杂、需要模型显式展示思考过程便于调试ReAct的可解释性优势就出来了。坑点ReAct的max_iterations设太小任务完不成设太大可能无限循环。另外工具描述写得不清晰模型会选错工具或重复调用同一个工具这是Prompt工程的问题面试官最喜欢顺着这个聊“你优化过Agent的Prompt吗”。题八增量添加文档时怎么保证向量空间一致面试官一般先确认“你Demo里新上传了一份文件是怎么加到向量库的”我代码里是直接用vector_store.add_documents()增量加的没有重建索引。这时面试官通常会追一句“那你怎么保证新文档的向量和旧文档在同一个向量空间里如果换了Embedding模型怎么办”答案核心就一句话保证Embedding模型包括模型文件、参数、归一化设置完全不变。因为向量的几何空间完全由模型参数决定只要你加载的是同一个BAAI/bge-small-zh-v1.5normalize_embeddingsTrue也一样新生成的向量就会落在同一个空间里和旧向量直接比较内积是有意义的。追问如果不得不升级模型呢那就必须全量重建索引。把所有原始文档重新走一遍Embedding流程生成新的向量并替换旧库。这里有个工程技巧可以用新旧两套库并行跑一段时间逐步切流量验证效果没问题后再下线旧库。踩坑最常见的错误就是偷偷改了模型版本或者normalize参数自己都忘了。结果检索越来越差排查时才发现向量空间早就不一致了。我在Demo里专门在初始化时加了日志打印模型路径和参数就是为了防止这种“不知道什么时候变了”的情况。题九整个系统从输入到输出的延迟瓶颈在哪里面试官现场会问“你这个Demo用户问一个问题平均多长时间出结果你觉得最慢的环节是哪个”我实测的结果本地CPU无GPU大致这样向量检索10条约80-120msRerank重排10对约200-300msLLM生成gpt-3.5-turbo API约1500-2500msAgent决策额外开销可能1-2次LLM调用再加1500-3000ms所以瓶颈明显在LLM调用上占了端到端延迟的70%以上。如果Agent路径比较长多次Thought-Action循环延迟会成倍增加。追问你会怎么优化我一般分三层回答推理层换用更快的模型比如gpt-3.5-turbo比gpt-4快很多或者把LLM部署到本地用vLLM加速推理。架构层能并行的就并行。比如检索和用户意图分类可以同时做Agent如果第一步就命中知识库直接回答而不启动工具搜索。工程层加缓存常见问题直接返回缓存答案对检索做预加载把Embedding模型常驻内存等。但最后我都会补一句在Demo阶段延迟其实不是首要关注点把流程跑通、理解每个环节的耗时占比更重要。题十如果知识库和工具返回冲突信息Agent如何抉择面试官最后一个追问经常是开放性的“假设知识库里写着‘员工年假5天’但联网搜出来说‘法律规定最少5天公司可以给更多’Agent会怎么回答”这个题没有标准答案它考察的是你如何设计冲突消解逻辑。我的Demo里其实没有专门处理这个场景但在面试时我会结合思考过程这样回答现状Agent只会把两个来源的结果都塞给LLM让模型自己判断。后果可能是模型随机选一个或者混乱。改进思路我会在Prompt里加入优先级规则“当知识库和网络搜索结果冲突时以知识库内部规定为准因为那是公司的正式制度。但仍需提醒用户外部信息供参考。”这样就把冲突处理变成了显式的规则约束而不是模型自由发挥。更系统的方法引入一个“仲裁者”组件对多来源结果做一致性检查。可以简单的基于来源可信度打分内部知识库 官方API 通用搜索也可以用NLI模型判断两个陈述是否存在矛盾矛盾时告警或触发人工审核。面试加分点能意识到这是一个非确定性系统下的“信源可靠性排序”问题并且能举出实际业务中类似的例子比如内部定价和外部行情冲突比直接说“我会修改Prompt”要深刻得多。最后的个人总结把这十个问题重新梳理一遍我最大的感受是面试官真正在意的不是你有没有用到某个技术而是你选择这个技术时脑子里走过的权衡过程。RAG和Agent的组件选型很少存在绝对的最优解都是根据场景在效果、延迟、成本之间取平衡。Demo可以小但你在上面花过多少思考时间面试时几句话就能体现出来。我建议你把这份解析当成一个“自查清单”每一条都试着用自己的项目经验重新组织一遍语言甚至可以主动引导面试官去问你最熟悉的那个模块——比如我当时特别想聊Rerank就故意在介绍项目时说“我们在检索后加了一个重排序步骤效果提升很明显”面试官马上就会顺着这个问下去整场节奏就被带着走了。如果你对某个题目还有更细节的疑问或者想知道面试时具体怎么把这些话术自然地说出来欢迎在评论区留言我看到会接着聊。这些踩过的坑、总结出来的经验希望能帮正在准备大模型岗面试的朋友们少走一点我走过的弯路。