ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

微服务与RAG融合实战:在线教育AI助教架构设计复盘

微服务与RAG融合实战:在线教育AI助教架构设计复盘 面试结束三天了我还在反复回想那场对话。岗位是我比较看中的一家在线教育公司的AI助教后端负责人JD里写得很清楚要懂微服务架构要有 RAG 智能问答落地经验最好做过知识库方向。坦白说微服务和 RAG 都是这几年比较热门的方向单独挑出来聊很多候选人能聊一下午。但面试官没有按套路出牌他几乎没问“你会不会用 LangChain”而是让我把“十万学生同时提问”这个场景从服务拆分到检索链路白板推演一遍。整场下来我最大的感受是微服务架构与RAG智能问答单独看都不算难但把它们放进同一个在线教育AI助教场景里怎么融合、怎么取舍、怎么排查故障才是真正拉开差距的地方。这篇文章我打算把那场面试的问题、我的回答思路、被追问后修正的方案以及我实际项目里踩过的一些坑完整复盘一遍。适合几类人看正在准备AI应用开发或大模型后端岗位面试的人做微服务但想往RAG检索方向延伸的传统后端以及已经在做RAG知识库但被线上问题折磨过的朋友。我会尽量把“为什么这么做”也讲清楚而不是只给一堆结论。1. 先交代一下这是一场什么样的面试1.1 岗位背景与业务场景在线教育公司的AI助教业务上要做的事情并不复杂学生看视频课时可以随时提问助教要能基于当前课程内容给出回答学生做完题后可以拍照或者粘贴题目进来助教要能做错题分析学期末还能根据学生的学习记录生成复习建议。这些功能的背后牵扯到的技术点却不少——课程数据是结构化的数据库记录加非结构化的讲义PPT、视频字幕、题库Excel学生提问是口语化、错别字多、还经常带着指代比如“它为什么等于零”回答必须基于课程上下文不能瞎编同时还要保证调用大模型的成本在可控范围内。这样的业务场景决定了技术选型上绕不开两件事第一系统后台是典型的多端接入、多模块协作用户、课程、问答、知识库、学习记录各自都有独立的生命周期用微服务按领域拆分开是合理的第二回答要对得上课程内容不能完全依赖大模型的内部知识所以RAG检索增强是必须的。面试官从这两个大方向切入几乎是把候选人往实战场景里按。1.2 面试流程和我的整体感受整场面试两个小时节奏安排得很紧凑。开场先让我介绍自己做过的AI助教项目这部分算是热身然后面试官顺着项目里的“知识库构建”深挖问切分策略、向量化模型怎么选、检索效果怎么衡量接着跳到微服务问服务怎么拆、拆完以后数据一致性怎么保证最后抛了一道系统设计题让我现场设计一套支持十万学生的AI助教架构。整场没有一道八股题全是贴着业务场景往下问的。面完以后我反而觉得这种形式很值得写出来因为哪怕不为面试把这些问题想清楚对做AI应用落地的人也很有价值。2. 第一轮深挖AI助教的微服务怎么拆2.1 服务拆分不是拍脑袋而是顺着业务链路走面试官的第一个问题很朴素你们做AI助教服务是怎么拆的很多候选人听到这个问题第一反应就是“按功能拆”用户服务、课程服务、问答服务——这么答也不能说错但如果只是把原来的单体接口按Controller拆开拆完反而更慢。我当时的回答思路是顺着AI助教的请求链路走学生发起提问先经过网关做鉴权和限流然后进入问答主流程问答处理器要判断这是一个课程内容问题还是闲聊如果是课程内容问题就要去知识库里拿上下文再把“问题上下文用户历史”组装成Prompt交给大模型最后把回答流式返回给学生。链路中有几个天然的角色用户、课程、问答、知识库、学习记录这五个角色就是我拆分服务的最小集合。实际拆分还要再细化一层。知识库内部要分“管理”和“检索”管理侧负责上传课件、解析文档、切片、生成向量、写入向量库检索侧负责接收问答服务的检索请求完成向量查询和重排序。这两块虽然都叫知识库但一个是低频写操作一个是高频读操作放在同一个服务里就会互相影响。所以我拆成了knowledge-admin和knowledge-rag两个独立部署单元数据库也分开管理侧用MySQL检索侧用向量数据库加缓存。其他几个服务也类似用户服务和课程服务偏传统CRUD问答服务是核心编排层学习记录服务负责埋点和行为汇总。服务清单大概是下面这样服务名职责数据存储备注gateway统一入口、鉴权、限流、SSE透传无所有请求必经user学生账号、登录态、会员权益MySQL Redis与助教权限无关course课程、章节、课时、讲义的元数据MySQL文档文件走对象存储qa问答主流程、会话管理、Prompt组装Redis会话AI助教核心编排knowledge-admin文档上传、解析、切分、向量化MySQL 对象存储异步消费消息knowledge-rag向量检索、混合检索、重排序向量库 ES高QPS独立扩缩容feedback回答点赞/点踩、错题记录MySQL也是RAG效果评估的数据源2.2 服务间通信HTTP够用什么时候上MQ和gRPC拆完服务下一个问题必然是“服务之间怎么通信”。我直接说了结论内部的绝大多数查询走HTTP接口用OpenFeign做客户端文档解析、向量构建这种耗时操作走消息队列异步完成如果后续问答服务对内部检索的延迟要求变得很苛刻再考虑把knowledge-rag的检索接口改成gRPC。这么选的逻辑其实很简单。通信方式的选型必须回到业务特征上。AI助教的核心链路里问答服务调知识库检索、调学习记录汇总这些一次调用就结束不需要维护长连接HTTP足够。但知识库文档处理的链路不同——学生或者老师上传一份50页的课件PDF之后后续要执行解析、清洗、分段、向量化、写入索引这一长串操作如果同步调用一次上传请求可能要等几十秒如果上传量一大直接拖垮用户请求线程。这里必须引入消息队列解耦上传接口只负责把文件扔到对象存储然后发一条“文档待解析”的消息就返回。解析服务消费消息去构建知识库构建完成后回写状态。我当时的选型是RocketMQ原因也很实际团队Java技术栈Kafka虽然吞吐更高但运维成本略重RabbitMQ功能上也够但事务消息不如RocketMQ顺手。面试官接下来追问了流式输出对通信方式有没有影响这个问题其实问得很细。大模型回答是流式返回的客户端是一个EventSource连接服务端持续往连接里写数据。如果内部用的是HTTP同步调用qa服务调LLM网关时也要保持流式读取不能把整个响应缓冲在内存里等全部生成完了再返回那样首token延迟会高得没法看。网关层也要记得关闭响应缓冲我见过有同事在Nginx层忘了关proxy_bufferingSSE的字符全部攒在一起一次性flush前端的效果就是等了半天突然整段文字蹦出来交互体验完全是灾难级的。2.3 分布式事务在AI助教里其实没那么可怕微服务面试逃不掉分布式事务的问题。面试官问一门新课程上线了课件也上传了学生立刻去提问他为什么会检索不到刚上传的内容这就是典型的一致性场景。我的回答是这个场景不需要强一致更不需要跨服务分布式事务。课程创建和知识库构建天然可以接受秒级甚至分钟级的延迟学生的提问是发生在“课件上传之后”的行为中间隔的时间足够索引构建完成。实现上我用的是事务消息加状态机。课程服务在创建课程后发送一条半消息本地事务提交后才真正投递到解析队列knowledge-admin消费消息开始构建知识库构建期间课程状态保持“备课中”知识库索引全部构建完成后再把课程状态更新为“已发布”。学生看到的是课程状态要么未发布要么已发布不会出现课程显示已上架但提问时检索不到任何内容的情况。至于真正的分布式事务像跨服务扣库存那种场景在AI助教业务里基本遇不到。最多存在一个“学习记录落库加上助教回答写日志”的双写这种我也处理成只保证最终一致先写本地日志表异步发送到分析队列日志表里记录发送状态定时任务补偿重试。面试官对这个答案比较认可因为我没有扯一堆Seata AT模式或者TCC框架而是先判断业务是否真的需要。3. 关键一问RAG智能问答怎么落地3.1 RAG的核心链路与在线教育数据形态聊完微服务面试官话锋一转直接问RAG链路怎么搭。这部分我准备得比较足回答得也比较顺。RAG的本质是给大模型外挂一个可以随时更新的知识库整个链路可以拆成五个环节加载、切分、向量化、存储、检索。加载阶段要面对的是在线教育里多种格式并存的数据形态有课程讲义PDF、视频字幕SRT、题库Word/Excel还有不少是老师直接录制的音视频需要先转文字。我们当时的处理方式是统一走一个解析管道PDF和Word先用格式解析工具抽文本字幕文件做时间轴清洗音视频先转写再按段落对齐时间码。这些解析结果全部保留原始来源标识到了检索阶段可以通过来源反查定位到具体的课件页码或者视频时间点这对学生体验很重要因为他要的不只是一个答案最好还能回到原视频位置核实。3.2 切分和元数据决定检索质量的第一步切分策略我特意强调了一下这是很多RAG项目栽跟头的地方。字符串固定切分最简单按500个字切一刀切出来的块语义残缺学生问“牛顿第二定律和动量定理有什么区别”内容被切开散落在两个chunk里召回效果非常差。我们改用结构感知切分优先按章节、小节、知识点标题切标题和正文必须保留在同一块这里有个实用经验——markdown文档可以在切分前先用layout算法解析出标题层级再按标题层级切PDF课件的效果略差因为很多PDF没有真实文本层级只能退一步按“标题样式识别段落边界”切。代码和数学公式也要单独处理在线教育题库里充斥着LaTeX公式和代码块通用切分器很容易把公式从中间劈开所以我们针对代码用专门的parser公式则整体作为一个不可分割的文本单元。元数据设计在知识库构建阶段经常被忽略但它非常关键。每一块切分文本至少要记录课程ID、章节ID、知识点标签、文档类型、来源URL有些场景还要记录创建时间。为什么因为学生提问天然带有范围限定一个学生问“拉格朗日定理”他只想问高等数学课里的拉格朗日定理不想看到其他课程里的同名理论。检索阶段必须用元数据做预过滤把查询限制在“当前用户正在学习的课程范围内”。如果知识库里没有保存这些元数据过滤就无从谈起只能在查询层面做语义限定效果远差于结构过滤。我在这个环节还给面试官讲了一个调优细节——重叠窗口。相邻两个chunk之间保留50字左右的重叠可以明显降低换行和标题导致的语义割裂问题。3.3 混合检索与重排序把精确匹配和语义匹配都留下来面试官接着问检索策略这个问题我展开了讲。只做向量检索虽然能解决“同义改写”“口语化表达”这类语义匹配问题但会遇到另一类尴尬学生问“动量守恒定律的适用条件”向量检索召回的内容可能满是“冲量定理”“碰撞”这些语义相近但没有直接答案的文本反过来因为课件里可能明明白白写着“动量守恒条件”这几个字传统倒排索引一查就中。所以我在项目里用的是混合检索向量检索和BM25关键词检索同时执行各自取Top K个结果然后用RRFReciprocal Rank Fusion算法把两路结果合并排序。RRF公式很简单每个文档的得分等于它在两路结果中排名倒数之和的累计值用代码表示就是下面这个样子def rrf_score(doc_id, rankings, k60): score 0.0 for rank_list in rankings: if doc_id in rank_list: rank rank_list.index(doc_id) 1 score 1.0 / (k rank) return scoreRRF不需要对向量相似度和BM25分值做归一化对量纲差异天然免疫工程上非常省事。合并出Top 50结果之后还要过一次重排序。重排序模型我用的是Cross-Encoder结构的BGE-reranker它把查询和每个文档拼接在一起过模型打分比双塔向量模型的打分精度高很多但速度慢所以只对前50个候选做重排取Top 5进入最终Prompt。加了重排序以后回答准确率体感提升非常明显这一点强烈建议所有RAG项目都加上。3.4 多轮对话下的查询改写与意图路由面试官没有就此打住而是问了一个很现实的场景学生在课程问答里连续追问“那它和这个有什么区别”——这个“它”和“这个”指代什么单独拿这句话去检索肯定什么都查不出来。这是RAG做多轮对话绕不开的查询改写问题。我当时的方案分两步。第一步是意图识别判断当前用户这句话是不是真的依赖上下文如果消息里出现“那它”“这个公式”“为什么这样”等指代词几乎可以确定需要改写如果是一个完整的新题比如“请解释傅里叶变换的物理意义”就不需要改写直接检索。第二步是改写用小参数模型对“最近三轮对话当前问题”做一次压缩改写把指代消解成完整的实体词生成一个独立可检索的query。这里有个取舍值得说清楚改写一定要用便宜快速的模型因为它是检索的前置步骤本身增加了一次模型调用如果又慢又贵整个链路延迟就绷不住了。我实际用的改写模型是本地部署的一个6B模型单次调用大约150毫秒线上效果可接受。意图路由是我的另一个加分项。在线教育AI助教面对的问题不只课程知识问答学生可能会问“今天作业什么时候交”这种事实性问题也可能会问“这道积分怎么求解”这种计算题还可能会闲聊。如果所有问题都灌给RAG有一部分会检索出无关内容反而干扰回答。我在qa服务里内置了一个意图分类器把问题分成四类知识问答走RAG链路、事实查询走课程服务API、计算推理走“检知识推理链”组合、闲聊直接走通用对话。这个设计回答完之后面试官明显提了兴趣因为这个方案回答了一个很核心的问题——RAG架构并不是所有问题的银弹它需要和业务路由结合才是完整的产品逻辑。3.5 检索质量怎么评估hit rate、MRR、RAGAS面试官问到一个特别实际的问题“你刚才说重排序有效果你拿什么证明”这其实是在考做RAG工程的人有没有建立评估体系。我平时的离线评估靠三组指标。第一是hit rate也就是检索结果Top K里有没有包含能回答这个问题的正确文档它衡量的是知识库被“捞出来”的能力K通常取5到10。第二是MRR取第一个正确答案的排名的倒数它衡量的是“正确结果是不是排在最前面”对最终回答质量影响很大。第三是NDCG它考虑了候选文档的相关性分级适合判定有部分相关文档时的排序质量。这三组指标都是离线算的我会准备一个覆盖各学科、各类问法的评测集每次调整切分参数、embedding模型、重排序阈值都要跑一遍对比避免凭感觉做优化。在线上的指标则是用户的点赞、点踩和追问率如果AI助教频繁被追问大概率是回答没有命中要害需要回溯检索链路。RAGAS框架我也用过它提供faithfulness、answer relevancy、context relevance三类指标分别衡量生成内容是否忠于检索片段、回答是否对得上问题、检索片段是否有冗余信息做回归测试时很有参考价值。3.6 顺带聊透了“知识库存图片”的问题这个问题是面试官随口引申的问得很有意思学生问他课件第24页的电路图里那个电容型号是什么知识库能存图片吗单纯说“能”或者“不能”都显得浅。我的理解是向量库本身可以存储图片经过多模态模型编码后的特征向量支持按图搜图但AI助教场景里真正的需求不是搜图而是“引用图片内容回答问题”。要让学生在问答里获得图片上的信息需要两条路并行一是对图片做OCR把电路图中的文字标注提取出来进入文本索引二是给图片写一段描述文本和图片路径一起作为chunk存进知识库。检索返回后Prompt里带着OCR文本和描述回答中还能附上图片的访问链接学生点开就能看到原图。这比直接上多模态embedding更可控成本也更低。面试官点头显然对“按场景选方案”而不是“什么新用什么”的思路比较认可。4. 融合段位微服务如何把RAG跑稳4.1 会话状态与无状态服务的矛盾聊完了RAG本身面试官开始加码问题全部指向微服务和RAG的结合部。他抛出的第一个问题是问答服务是无状态的但对话明明又依赖上下文这两件事不矛盾吗矛盾确实存在但解法并不复杂。我的做法是把会话状态剥出来放在Redis里问答服务本身保持无状态每次请求都携带sessionId问答服务根据自己的业务需要从Redis读取“最近N轮问答记录”。N的选择是个关键参数它直接决定Prompt长度和token成本。我线上用的是最近10轮大概能覆盖一个连续追问的完整上下文窗口。这里有一个隐性问题——微服务实例扩容缩容时如果有状态数据存在本地内存实例一重启对话就断了这也是为什么要强调“服务无状态化状态下沉到Redis”的根本原因。对话变长后Redis里只保留原始内容还不够我还会在每轮结束时生成一个轻量的会话摘要存起来。学生问了几十轮之后历史全量传给大模型既不经济也不准确早期的闲聊对当前学术问题基本没有帮助这时候把摘要塞进Prompt会更高效当前轮问题、最近10轮记录、长期摘要三层拼装。4.2 缓存、降级与LLM成本控制面试官接着问十万学生如果同时用AI助教你的成本扛得住吗这个问题我专门算过。一次AI助教问答假设输入1200 token输出400 token单次成本大概是几分钱量级。如果完全不走缓存和限流十万学生每人每天问三个问题一个月的成本就会被拉到很高。成本控制有几个抓手我按优先级做了排序。第一是热点问题语义缓存。在线教育有很强的热点效应期末前“求线性代数复习重点”这类问题会被几千个学生同时问这些问题embedding出来的向量相似度极高。我可以在问答入口先对问题做向量化接着拿这个向量去缓存库里搜索如果相似度大于0.95直接返回缓存里的历史回答全程不调用大模型。第二是相同问题短时间内的token级缓存比如同一个学生反复问同一道题直接命中。第三才是成本意义上的限流对非付费用户的每日免费提问次数做一个额度限制。缓存设计里有个隐藏门槛相似度阈值调太高命中率上不去调太低语义相近但问题不同的问题会拿到牛头不对马嘴的答案。我通常取0.93到0.96之间并且对缓存命中结果加一条“回答缓存时间”说明避免学生误以为AI在敷衍。降级链路则是一层层向下的正常情况下是RAG完整链路LLM服务不可用就退化为“纯检索返回课件原文片段”向量库不可用就退化为ES的BM25检索全部不可用就对用户提示“助教暂时打盹”。这套降级链在面试时很加分因为它一下把做单体功能的人和做系统的人区分开了。4.3 链路追踪和线上疑难问题定位面试官最后问了一个运维向的问题全链路有十几个微服务线上出现一次“慢回答”你怎么定位是哪一环出了问题这个问题的标准答案是全链路追踪。我当时在项目里给每个请求都生成一个TraceId从网关入口注入在日志、Redis会话、RAG检索结果里全部带上一份。问答服务在处理时会在关键节点记录耗时包括网关时间、查询改写耗时、检索耗时、重排序耗时、Prompt组装耗时、LLM首token耗时。排查慢请求时打开日志按TraceId过滤一段完整的时间线立刻就出来了哪一个环节慢了基本一目了然。实际排查中我遇到过最诡异的一种情况是“时快时慢”——最后定位到是向量数据库的HNSW索引并发查询时CPU争抢加上ES和向量库用了同一台物理机导致资源互相挤兑。这个教训让我后来坚持一个原则向量数据库这类IO密集和计算密集组件一定要独立部署不能为了省机器和ES挤在一起。5. 现场系统设计题十万学生同时问AI助教5.1 题目与容量估算面试环节进行到一半面试官在白板上写下了题目你现在要为这家公司设计一套面向十万学生的AI助教系统要求支持高峰期的并发问题并且回答必须基于课程知识库。请给出总体架构、关键链路和容量估算。这种题不能上来就画图先估容量。我当时的推算如下十万注册学生正常情况下同时在线大约一万人每人在线期间平均每小时产生一次提问的话峰值QPS在几十到一百多之间但如果赶上考前冲刺、老师临时通知刷题这种突发流量峰值可能冲到平时的五到十倍就需要按500到1000 QPS设计。接着估算大模型的访问压力一次问答的完整流程里查询改写可能要一次小模型调用缓存未命中时主问答又要一次大模型调用峰值时如果每秒500次完整问答就需要模型服务端扛住每秒几百次的并发这要求必须要有多级缓存和队列削峰。容量和成本在这里是一回事不是事后算账而是设计架构前就要确定的硬约束。向量化环节每秒也会产生几百次embedding请求如果都用同一个本地模型跑会成为瓶颈解决方案是embedding模型单独部署一份并且支持批量推理。5.2 落地方案的主线设计容量估算完我开始讲方案主线。整体架构我按请求链路和异步链路两条线组织。请求链路是这样的学生从App或者网页发起提问请求先进入边缘网关做鉴权和限流网关把请求路由到qa问答服务问答服务先做意图识别和查询改写然后从Redis里捞会话上下文接着调用knowledge-rag检索服务检索服务内部并行执行向量检索和BM25检索合并后重排序取出Top 5问答服务把“问题、知识片段、会话上下文”组装成Prompt调用LLM网关获取流式响应前端边生成边展示。异步链路则处理知识库的持续更新老师上传课件文件先到对象存储然后发消息到MQknowledge-admin服务消费消息完成解析、切分、向量化后写入向量库和ES同时更新课程状态。为了保证热点问题能够快速返回我还在问题入口加了一层Redis热榜缓存把近期高频问题直接缓存起来。这一套方案的价值不在于每个组件有多新颖而在于它把“学生提问”这条主链路和“知识更新”这条副链路清楚地区分开各自扩缩容互不干扰。5.3 知识库更新和流式体验的细节处理面试官对方案里的两个细节做了追问。第一个问的是知识库更新期间检索是否会有不一致。我说知识库版本号解决了这个问题每次更新完成以后才切换版本号正在执行的查询永远绑定一个固定的版本号不会查到“切了一半”的索引。第二个问的是流式体验在重试场景下的表现。流式接口最怕中途断连如果大模型已经输出了一半网络断了重连再从头生成一遍既浪费成本又浪费时间。我的方案是在qa服务里做短暂的流式响应缓冲把已经输出的片段存起来断线重连时先补发缓冲内容再从断点继续请求LLM生成。这个方案并不复杂但确实有很多做RAG的团队忽略了流式断点续传这个体验细节面试官在这一点上给了我正向反馈。6. 常见问题与排查技巧实录6.1 检索结果不准的排查路径做RAG项目最头疼的就是“检索结果不对”我总结了一套排查路径在项目里反复用。第一步先把检索结果打出来看Top 5里到底有没有正确答案。如果连正确答案都没出现问题大概率出在切分或者向量化阶段——要么是内容被切碎语义丢失要么是embedding模型对领域术语不敏感要么是元数据过滤条件写得太严把正确内容过滤掉了。如果Top 5里能看到正确答案但回答依然不正确问题就出在排序或者生成阶段上正确答案排名太靠后重排序模型没有把它提到前面或者Prompt里的指令不够明确模型没有优先使用检索片段。这一步排查看似简单很多人却跳过“直接看检索原始结果”直接乱调参数改半天都找不到症结。除了检索结果还要看查询改写之后的内容是否失真。有一个经典翻车案例学生问“洛必达法则是什么”改写模型自作聪明把“洛必达”改成了“罗必达”检索结果立刻全错。后来我在改写模块里增加了一个实体词保护逻辑把课程知识库里的高频专有名词维护成白名单改写时禁止改动这些词。6.2 问答响应慢的优化思路潜伏得很深的一个性能问题是重排序太慢。Reranker是Cross-Encoder结构一次要对几十个候选做打分候选一多延迟立刻上去。最常见的优化手段是把重排序的候选列表从Top 50缩到Top 20并且确保向量库和ES都先做元数据预过滤减少无效候选的进入。更进一步可以把向量检索和BM25检索从串行改成并行用两个线程同时跑最后再合并排序能省掉一半左右的时间。还有一个优化很有意思查询改写本身其实也会引入延迟纯指代词改写如果规则能覆盖就先走规则规则的准确率足够高能省一次小模型调用规则无法覆盖的疑难指代再走模型改写。这再一次验证了架构上的一个原则技术方案里加模型不是万能的能用规则解决的就别用模型解决能用缓存的就别让模型硬算。6.3 知识库更新后表现不一致面试官没有直接问但这是我在项目里踩过的最实际的坑知识库文档明明更新了但学生提问时得到的还是旧答案。逐一排查后发现问题常常出在缓存层。热点语义缓存的命中逻辑只做了“问题向量相似度匹配”根本没有考虑“知识库文档版本是否变化”旧回答就一直被拿出去了。解决方案很简单缓存条目里带上知识库版本号每次建索引之后递增版本号新版本一旦生效旧版本的缓存全部按版本过期。另外一个原因是写入的顺序问题向量库和ES如果写入时序不一致检索结果会出现两边缺数据这种问题没有银弹我现在的做法是在两个存储前面加同一个版本号日常巡检里对比两边的最新版本号发现不一致就触发重建任务。这些都是做RAG工程时极少被写进技术博客、但线上运维时一定会遇到的细节。7. 面试复盘与个人建议7.1 这次面试暴露出的不足整场面试我自己心里有个评分——技术主线答得比较扎实但有几个地方准备得还不够细。一是向量数据库底层的索引参数面试官问了一句“HNSW的M值和efConstruction对召回率的影响”我只答出了大致方向没有给出实际调参经验这块是我做项目时直接用了默认参数、没有深挖导致的。二是Agentic RAG面试官给了一个开放题如果学生问的是一道复杂的综合题多个知识片段拼接才能回答RAG怎么做这个问题我答得偏保守只是说可以做多跳检索或者思维链处理但没有给出一套清晰的Agent设计。面试结束后我复盘才想明白这种场景需要的是把检索结果拆成多个子任务每一步检索后判断“信息是否足够回答”不够就继续检索或者查询改写本质上是从单轮RAG往多轮Agent演进的过程。第三是安全层面考虑得不够全面在线教育场景也一样存在提示注入风险比如用户在提问里夹带私货诱导系统忽略检索片段这个我确实还没有一套完整的防控策略。7.2 对后来者的准备方向如果有人现在正在准备这类型岗位的面试我会给出三条比较实在的建议。第一一定要动手搭一套完整的RAG项目哪怕用的是本地部署的Ollama加一个简单的向量库也好端到端跑通一次文档上传、切分、向量化、检索问答的流程很多问题只有亲手跑过才会遇到。第二学会用数据说话调检索效果时不要靠感觉准备几十个评测问题每次修改都要让hit rate、MRR、faithfulness这些数字告诉你到底有没有变好。第三面试前重点梳理“微服务和RAG在哪里交叉、在哪里冲突”这个主题服务怎么拆、会话状态怎么存、检索链路怎么追踪、知识库更新怎么异步化这些交叉点才是AI应用后端工程师真正的价值所在。技术会迭代模型会升级但“怎么把一个业务问题拆成可落地的系统架构”这个能力始终是核心。面完的当天晚上我又把白板上的架构重新画了一遍把面试时没答好的Agentic RAG补了一段设计。一个很深的体会是无论微服务还是RAG工具本身都给不了产品竞争力关键在于拿到一个真实的业务场景时能不能把链路捋顺、把边界划清。这篇复盘写下来也算是在正式拿到offer之前给自己的一份交代。最后再分享一个小技巧面试官问系统设计题的时候先别急着画架构图把容量估算和业务假设先讲清楚这张图自然会从你的话里长出来。
返回列表