大模型面试题

📅 2026/7/12 19:37:57
大模型面试题
Agent面试题什么是 Agent与大模型有什么本质不同本质上是一个能自主完成目标的AI系统和传统AI最核心的区别在于自主性和能动性传统AI是你问一个问题他回答一个问题独立、被动响应Agent有自己的规划能力给一个复杂目标能把任务拆成多步通过调工具、访问记忆、感知环境一步步执行直到完成。工具调用记忆机制多步推理和自我纠错Agent 的基本架构由哪些核心组件构成LLM整个系统的大脑负责理解任务和做决策推理模型的代价是延迟更高、token 消耗更大常见的工程做法是用推理能力强的大模型做核心决策比如任务规划、关键判断用更快更便宜的小模型做简单任务比如意图分类、格式提取根据不同环节的需求来搭配。工具Agent能跟外部世界交互搜索、执行代码调用API模型负责「决定做什么」程序负责「真正执行」这里还有一个非常容易被忽略的点工具描述的质量直接影响 Agent 的表现。MCP JSON-RPC三类能力 Tools会改变外部世界的操作比如发邮件、Resources只读的数据源比如文件内容、Prompts预定义的提示词模板比如代码审查模板。HOST SERVER CLIENT记忆让Agent在任务执行过程中保持状态短期记忆 装在context window记住任务中间状态摘要压缩滑动窗口长期记忆 向量数据库记忆衰减记忆衰减的做法是给每条记忆加一个时间权重越久远的记忆权重越低检索的时候自然就排在后面了。规划模块把复杂目标拆解成可执行的步骤COTChain of Thought,思维链让模型把思考过程写出来而不是直接输出最终答案LLM 的 token 生成是逐步进行的每一步推理的输出会成为下一步推理的输入把中间步骤写出来等于给了模型更多的「思考空间」先规划再执行好处是整体结构清晰你能在执行前就看到完整计划方便人工审核缺点是如果中间某一步的结果和预期不一样原来的计划可能就不合适了需要重新调整。动态 重规划策略边执行边规划好处是灵活性极高能根据实际情况随时调整缺点是容易「走偏」因为每一步都是局部最优决策有时候会忽略整体目标Reflection反思Agent完成一步或者完成整个任务后再让一个LLM来判断做的好不好结果是否符合预期。评估不通过就重试或者换一种策略。这个机制显著提升输出质量。代码生成、文案写作。Reflexion会生成一段具体的反思总结记录失败原因作为额外的上下文写个下一次输出WorkflowAgentTools 这三个的概念和区别介绍一下这三个概念是粒度从小到大的三层结构Tools是最小的能力单元封装好的可调用函数比如搜索执行代码、发邮件只负责执行没有决策能力Agent是一个完整的决策系统内部用LLM做大脑自己判断什么时候调用哪个Tool要不要继续什么时候结束、是主动的Workflow是更上层的编排框架把Agent、LLM、Tools组织成一条确定性流程每个节点做什么、按什么顺序流转都是开发者事先写死的tools 封装函数说明书好的工具设计核心原则职责单一描述要精确错误信息要清晰常见的停止条件LLM主动判断任务完成输出最终答案设置最大循环次数返回当前已有的结果并告知用户设置总token预算上限超时机制Agentic Workflow用Workflow 固定主流程的骨架在需要灵活判断的节点嵌入Agent其余固定节点直接用LLM或Tools几种常见的Workflow编排模式提示链路由并行化编排者-工人了解哪些其他的 Agent 设计范式Agent 和 Workflow的区别是什么两者最核心的区别是谁来决定下一步。Workflow是我提前把流程写死的每一步固定确定性高好控制Agent让LLM自己决定下一步做什么灵活但不可控常见设计范式纯Agent还有ReactPlan-and-Execute、Reflection如何选步骤不多每步比较独立React就够简单直接灵活每一步都能根据最新情况做决策特别适合那些任务边界不太明确、需要探索性地获取信息的场景任务复杂步骤之间有依赖关系需要全局统筹Plan-and-Execute适合那些目标明确、需要多步骤协作完成的复杂任务比如深度研究、长文写作、多工具协同的数据分析输出要求高允许花一些时间和tokenReflection两者混用固定流程的部分用Workflow,灵活决策的接待嵌入Agent能力先从最简单的workflow开始只有当发现某个节点确实需要灵活决策、写死的逻辑无法覆盖所有情况时才把那个节点升级为AgentAgent 推理模式有哪些ReAct 是啥具体是怎么实现的?最基础的就是直接输出答案没有中间推理COT是让LLM先把推理过程写出来再给答案准确率更高COT是纯文字推理没有办法和外部世界交互ReAct是在COT基础上加了行动让LLM交替输出思考和工具调用每次行动后再根据结果继续思考形成一个循环。ReAct是目前Agent用的最广的的模式因为推理过程可见又能动态利用外部工具存在循环漂移问题错误传播Plan-and-Execute做全局规划能力强的大模型用ReAct做每一步的执行便宜的小模型。ReAct的本质是思考-行动-观察的循环推理过程显示化调用外部工具循环由代码框架驱动模型每次只输出Thought、Action代码负责解析执行工具、把Observation填回历史进入下一轮ReAct、Plan-and-Execute、Reflection 三种范式有什么核心区别实际项目中该如何选型ReAct是边想边干走一步看一步单步迭代实时调整灵活度最高Plan-and-Execute是先想全再干先定完整计划再分步执行适合长流程任务不容易跑偏Reflection不是独立的完整流程么人是给前两者加的检查修正buff用来提升输出质量选型指南任务不复杂、流程不固定、需要实时调整的直接用 ReAct够用就好别搞复杂的。任务很长、容易跑偏、需要整体结构清晰的上 Plan-and-Execute先把计划定清楚再执行。如果执行过程中经常遇到意外需要调整计划就加上动态 Replan。输出要求高、不能出错的在前两者基础上叠加 Reflection 做自我检查。如果还需要跨任务积累经验、避免重复犯错就用 Reflexion 把失败教训沉淀下来。复杂任务怎么做的任务拆分为什么要拆分效果如何提升任务拆分的原因是LLM一次性处理太复杂的任务很容易出错把大任务拆成小任务每次聚焦一件事准确率会明显提升。LLM的工作台 context window 是有大小限制的能同时处理的信息量是有上限的分成两种静态拆分提前将步骤写死由人决定动态拆分让LLM自己根据目标规划步骤更灵活但也更难控制由模型决定给它一个目标让它先输出一个执行计划再按计划一步步执行这是 Plan-and-Execute 模式的核心思想拆完之后步骤之间可能有依赖关系我的经验是能并行的步骤并发跑端到端延迟可以降很多有时能降40%到60%自适应拆分拆的太细也不行步骤太多LLM调用次数越多总toke消耗上升步骤太碎每步只做一件很小的事情LLM看不到全局产出的各部分也容易衔接生硬原子操作作为划分单步的标准这个步骤只做一件独立的事情边界清晰做完有明确的输出和其他步骤不互相依赖不要在开始时就把所有步骤的力度定死而是在执行过程中根据每一步的实际难度动态调整。先让执行器完成当前任务做得好就继续往下走不做多余的拆分。先试做不好再拆分动态重规划讲当前步骤的结果和剩余的计划一起交给规划模块实践中设置触发条件比如当某部的输出和预期差异很大时或者某步骤执行失败才启动Replan.拆分结果的验证标准完整性、独立性、可验证性请你介绍一下 AI Agent 的记忆机制并说明在实际开发中应该如何设计记忆模块Agent需要记忆才能在多步任务中保持状态、跨任务积累知识感知记忆当前输入的原始内容短期记忆context window 里的对话内容长期记忆外部数据库、语义检索找回语义记忆存的是事实性知识回答是什么情节记忆存的是具体时间的经历回答之前怎么处理过类似情况程序记忆存的是怎么做某件事的方法论回答按什么流程来用户偏好和习惯、任务执行中产生的关建结论和决策、以及外部知识实体记忆结构化提取的关键事实混合存储结构化的偏好字段用关系数据库精确查非结构化的知识和历史用向量数据库语义检索两者配合使用。什么时候取出来用第一种叫「主动检索」在任务开始前用当前任务的描述去检索相关记忆把结果注入 system prompt 作为背景知识。这样 Agent 一开始就带着「历史记忆」进入任务不需要用户每次重新交代背景。第二种叫「被动触发」Agent 在推理过程中判断当前步骤需要某类特定知识时主动发起检索。具体做法是把「查记忆」封装成一个 Tool让 Agent 自己决定什么时候调。这种方式更灵活但依赖模型判断什么时候该去查。实践上两种结合效果最好session 开始时做一次主动检索把关于用户偏好和背景的记忆加载进 system prompt任务执行过程中遇到需要专业知识或历史数据的步骤再让 Agent 按需检索Context Window 管理短期记忆的「工作台」不够大怎么办滑动窗口摘要压缩把不常用但重要的信息卸载到长期记忆里面[知识图谱让记忆之间产生关联]在 Agent 的记忆模块里引入知识图谱通常是和向量数据库配合使用的。向量数据库负责处理模糊的语义检索比如用户说「之前那个项目」向量检索能找到最相关的项目记忆知识图谱负责处理精确的关系推理比如查某个用户的所有相关公司和角色两者互补。具体做法是对话过程中用 LLM 自动提取出实体和关系存入知识图谱。检索时先用向量检索拿到一批候选记忆再用知识图谱补充关联信息最后把两部分结果合并后注入 context。记忆整合从碎片到知识去重 冲突消解最新的时间戳 抽象提炼整合的节奏也很重要完整记忆模块的配合方式第一阶段任务开始前先「读」记忆用户发来一个新请求Agent从实体记忆里取出用户的结构化偏好语言偏好、风格要求、过往决策再用任务描述作为查询词去长期记忆里做一次语义检索拿回最相关的历史背景。把这两部分信息拼进 system prompt 的开头Agent 进入任务时就已经带着完整的「用户画像」不需要用户重复交代背景。第二阶段任务执行中持续「用」记忆任务开始执行短期记忆messages 列表全程工作用户的每一条消息、模型的每一次输出、工具调用返回的每一个结果都追加进 messages。每次调用 LLM 都把这份完整历史带上Agent 始终知道自己做到哪一步、前面发现了什么。如果某个执行步骤需要特定的专业知识比如查某个 API 的文档、回想某次历史决策Agent 可以临时发起一次长期记忆检索把「查记忆」封装成一个 Tool用当前上下文作为查询词把检索结果注入到这一步的 context 里用完即走不需要永久保留在 messages 中。第三阶段任务结束后主动「写」记忆任务完成进行最后一步把本次任务产生的新知识写回持久化存储。具体来说如果用户在对话中表达了新的偏好「以后写函数都要加类型注解」就更新实体记忆的对应字段如果任务产生了有价值的结论「竞品 A 的定价是按用量收费」就把这条摘要写入长期记忆embedding 后存入向量数据库供下次检索。最后短期记忆messages 列表清空工作台恢复干净等待下一个任务。Agent 的长短期记忆系统怎么做的记忆是怎么存的粒度是多少怎么用的记忆系统分两层。短期记忆就是context window里的对话历史存当前任务的中间状态任务结束就清掉长期记忆用向量数据库存把信息embedding 后写入用的时候做语义检索拿回来注入prompt粒度上通常按一次完整交互或一个关键事件为单位存太细碎检索碎片化检索时拿到不完整的信息太粗糙又丢失细节噪声多需要根据业务实际调整比较合理的粒度是按「一次完整交互」或「一个独立的知识点/事件」来存。前者是用户的一个具体请求加上 Agent 处理结果信息完整性好后者是把「用户偏好Python简洁风格英文注释」打包成一条结构化记录检索时一次拿到完整偏好不会碎片化。过程中的每一步细小中间结果通常不需要存长期记忆短期记忆够用。存的时候把内容转成向量和原文一起存取的时候把当前问题也转成向量找向量空间里最近的几条记忆。「语义相似 向量距离近」这个特性让你不需要精确匹配关键词靠意思相近就能把相关记忆检索出来。什么是 Multi-Agent多个 Agent 协作完成任务每个 Agent 各有分工有的负责搜索、有的负责写代码、有的负责做评审。单个 Agent 主要受两个限制一是 context 窗口大小复杂任务信息量一多就撑爆了就开始遗忘这是结构性的限制二是单点能力什么都让一个 Agent 做每件事都是泛才。并行执行多个worker同时跑整体效率有实质性提升通过专业分工和并行执行能处理更复杂、更长流程的任务这是在实际项目里选择多智能体的原因三种选型顺序型并行扇出辩论/评审目前组织主要有两种一种是去中心化有一个由一个统一的调度者来分配任务收集结果另一种是去中心化Agent之间自行协商、直接通信说说 Single-Agent 和 Multi-Agent 的设计方案Single-Agent适合任务流程清晰复杂度适中的场景实现简单、好维护Multi-Agent适合需要专业分工、任务量大或者需要并行执行的复杂场景去中心化用的更多因为好控制、好调试、出问题链路清晰Single-Agent真正力不从心任务太长、信息量太大context撑爆Agent开始遗忘不同步骤需要完全不同的专业能力任务中有多个独立子任务中心化方案核心是一个叫Orchestrator的特殊角色负责三件事读懂用户的大目标、把他拆成一个个子任务判断每个子任务交给哪个Agent去做收集产出把他们拼成最终答案。静态路由预先定义好的动态规划根据用户输入动态生成任务计划自适应编排实时调整后续计划去中心化系统会遇到这几类问题任务分配没有协调执行顺序没有保证失败没有感知没有人确认任务整体完成了面试总结第一选型标准不能只说「任务复杂就用 Multi-Agent」要说出具体的三类场景context 要撑爆了、需要不同专业分工、有子任务可以并行不属于这三类就用 Single-Agent盲目引入 Multi-Agent 只会增加系统复杂度带不来对应收益。第二Multi-Agent 架构方案要主动提中心化和去中心化两种而且要明确说出工程里几乎都选 Orchestrator 中心化模式因为可控、可追踪、出了问题能顺着调度链路排查。第三去中心化「听起来灵活」但要能说清楚它的实际问题任务分配没协调、执行顺序没保证、失败没有感知这才是它在生产环境里不可用的根本原因。Agent记忆压缩通常有哪些方法摘要压缩滑动窗口重要性过滤打分筛选只选重要内容不按时间筛选结构性抽取把关键信息抽成结构化数据数据存起来换一种载体存信息常见的工程组合滑动窗口摘要滑动窗口负责控制对话历史的总长度上限摘要压缩负责在历史被丢弃之前做一次提炼把关键信息留下来。Prompt Caching的思路如果 prompt 的前缀部分在多次请求之间是一样的就把这部分的计算结果缓存起来下次请求如果前缀匹配直接复用缓存不重新计算。这和前面的记忆压缩是两个不同层次的优化。记忆压缩在「信息层」工作决定哪些内容值得被保留在对话历史里Prompt Caching 在「计算层」工作对已经决定要带进去的内容减少重复计算的开销。两者解决的不是同一个问题可以同时使用是互补关系不是替代。在工程实践中为什么有时候选择「手搓」Agent而不是直接用成熟框架框架用起来快但有几个实际痛点第一抽象层太多调式的时候不知道哪步出了问题得一层层往下扒第二版本升级经常有破环性变更线上稳定性难保证手搓没有多余开销第三框架的通用设计往往和具体业务需求有偏差定制起来反而更费劲折中方案核心手写周边工具性性能借用框架框架适合的时机POC阶段快速验证idea目标是跑通而不是优化团队刚接触Agent开发用框架能少踩基础性的坑手搓的时机准备上生产稳定性成为核心关切性能和成本百年的敏感业务逻辑高度定制团队需要高可观测性工程实践很多真实项目的演进轨迹是这样的先用框架快速跑通验证了方向遇到第一批线上问题之后开始把排查困难的关键部分替换为手写流量上来之后把性能敏感的核心逻辑全部手写最后框架只保留做得很好的周边工具。这条路走下来既享受了早期框架的速度又在生产阶段拿回了掌控权。如何赋予 LLM 规划能力为什么需要规划能力LLM默认一口气生成答案没有显示推理过程多步推理任务容易跳步出错规划机制就是把隐式推理过程显示化COT是让LLM把推理步骤写出来线性地一步步推导到答案要不要把推理写出来Zero-shot COT Few-shot COTTOT是把它同时探索多条推理路径选最优的继续深入,边探索边剪枝边评估走错了方向怎么纠偏GOT是图结构推理推理节点可以复用和合并适合更复杂的任务不同路径的中间结论能不能复用讲讲 Agent 的反思机制为什么要用反思具体怎么实现生成-评估-改进反思机制给我的理解让Agent在完成一个步骤或整个任务后自我评估输出质量判断有没有问题不达标就重试或调整策略用反思的原因是LLM第一次输出不一定是最优的逻辑跳跃遗漏细节事实错误表达含糊加一轮自我检查能显著提升质量相当于人写完东西自己再看一遍代价是至少一次LLM调用token消耗和延迟都会增加所以只在质量要求高的关键节点启用反思不是每步都做评估prompt任务{task}当前输出{current_output}请评估以上输出1.有没有事实错误或逻辑问题2.有没有遗漏重要内容3.表达是否清晰准确 如果输出已经足够好回复「PASS」 否则指出具体问题并给出改进建议。改进prompt原始任务{task}当前输出{current_output}评估意见{reflection}请根据评估意见改进输出两个粒度步骤级错误发现的早但开销大任务级能看到整体问题但前期做的无效工作难以挽回工程权衡输出质量要求高、错误代价大的关键节点比如最终报告生成、重要决策的推理过程开反思简单直接的任务比如格式转换、简单问答加反思不值得实时性要求高的场景也一样最重要的是防死循环必须需要设最大轮次通常设2-3轮绝对不能依赖LLM自己判断停止原因是LLM有时会陷入为了改而改的循环多agent互评比自我反思效果更好同一模型对自己的输出有自洽偏见如何设计多 Agent 的协作与动态切换机制协作靠两件事消息传递和共享状态。消息传递Agent完成自己的工作后把结果发出去下一个Agent取用共享状态是所有Agent共同读写一个状态对象记录进展和中间结果状态管理多 Agent 共享状态的设计要点状态结构要分层通常会把状态分成「全局状态」和「局部状态」两层写入规则要明确。最简单也最可靠的做法是「只追加不覆盖」每个 Agent 完成工作后把结果追加到状态里而不是修改已有的字段错误状态的处理。如果某个 Agent 执行失败了它的错误信息也应该写入状态而不是悄悄吞掉如果各 Agent 之间的依赖关系比较强前一步的结果要直接传给后一步用共享状态更直接。如果你希望 Agent 之间尽量解耦互相不知道对方的存在用消息传递更合适。动态切换靠Orchestrator来做有两种方式一种是静态路由提前写好规则一种是让LLM动态决策根据当前情况实时判断改把任务交给谁动态切换要说出静态路由和动态路由各自的优缺点静态路由稳定可预测但覆盖不了没预料到的边缘情况动态路由灵活但每次多一次 LLM 调用且行为不可预测。工程上怎么用实践中最稳健的做法是两种路由组合用主流程用静态路由把确定性的节点切换都写成规则保证绝大多数情况下系统行为稳定可预测只在遇到没有匹配规则的边缘情况时才交给 LLM 动态决策。这样静态路由负责「保底」动态路由负责「兜住异常」两者互补。面试总结首先协作机制要说出两种通信方式的本质区别消息传递的核心是解耦发送方不需要知道接收方是谁适合 Agent 之间需要独立运行的场景共享状态的核心是直接所有 Agent 读写同一个对象LangGraph 就是这个思路适合各步骤依赖关系明确的流水线型任务。RAG面试题什么是 RAG详细描述一个完整 RAG 系统的详细工作流程检索增强生成。他解决的核心问题是LLM的知识在训练之后就固定了遇到到私有数据或者最新的消息他就答不上来。Rag的做法是在生成答案之前先在外在知识库里检索相关内容然后把检索结果和用户的问题一起交给LLM,让他基于这些上下文来回答。本质上就是给大模型开了一个开卷考试的口子不用再考靠死记硬背了。离线阶段文档加载文档切割实践中一般用500-1000token作为一个chunk,同时做一定的重叠前后各重叠100 token,避免把一段完整的语义从中间切断Embedding入库把每个chunk的向量和原始文本一起存进向量库在线阶段用户提问时实时检索query 处理继续Query改写让LLM把用户的问题改写成更适合检索的形式或者从对话历史中补充必要的上下文。向量检索粗排把用户的问题也转成向量然后去向量库里做相似度搜索向量检索本质上只是比较两个向量的距离它没有深度理解查询和文档之间的语义关系所以召回的结果里难免混入一些「看着近但其实不相关」的内容。Rerank精排把用户问题和每个候选chunk拼在一起深度理解他们之间的相关性然后重新排序把不相关的结果过滤掉生成把用户问题精排后的chunk拼成prompt交给LLM生成最终答案。Prompt 里通常会明确告诉 LLM「只根据提供的资料回答资料里没有就说不知道」这样能有效抑制 LLM 瞎编的倾向。核心价值知识可热更新知识可溯源大模型的 RAG 主要用来解决什么问题知识时效性LLM训练完知识就固定了训练截止日期后发生的事他一无所知私有知识覆盖公司内部文档、行业专有数据根本没有机会进训练集LLM 对这些内容是空白的幻觉问题没有知识依据时 LLM 容易「自己发挥」编出一个听起来合理但实际错误的答案给了它参考资料之后幻觉就少很多。知识被固定在了模型参数里。RAG的解法是把知识存到外部 用的时候实时检索注入彻底绕开参数里的知识限制。幻觉是知识缺失的副产品RAG解决的是根源不是单独在治幻觉相比直接微调 LLMRAG 解决了什么问题微调和 RAG 各自的优劣势是什么我的理解这两个东西解决的不是一个层面的问题不是谁替代谁的关系微调是把新知识直接烧进模型参数里适合改变模型的行为风格或者培养深度的专业能力RAG是在推理的时候实时检索注入知识适合知识需要频繁更新、或者需要有溯源的场景。知识库类的问答系统我会首选RAG成本低而且可以随时更新如果是要让模型学会特定的输出格式或者行业语气那微调更合适。实际上这两个方案也可以综合用先微调再套RAG先对基础模型做一轮微调让它学会输出格式、语气风格、行业术语再用 RAG 来提供具体的知识内容。微调解决「怎么说」RAG 解决「说什么」各司其职调优优先级先提检索不是先换模型面试总结面试官问 RAG 和微调的区别你要先说清本质微调是改模型参数RAG 是不改参数、推理时注入知识。然后各说优劣微调擅长定制输出风格、培养深度专业能力但成本高、更新慢、不可溯源RAG 擅长知识频繁更新、答案可溯源的场景但多了检索延迟、检索质量卡住上限。最后一定要提到两者可以组合使用微调解决「怎么说」RAG 解决「说什么」。能把这个组合思路讲出来面试官就知道你不只是背了定义而是真正理解了怎么在工程里做选型。RAG 中的文档是怎么存的粒度是多大详细说说文档切割Chunking策略文档不能直接存进向量库必须先切成小块也就是chunk每个chunk分别向量化之后存进一条记录每条记录我理解有三个核心部分向量用于相似度检索原始文本是检索命中之后塞给LLM读的内容metadata是来源文件、页码这些附加信息用于过滤和溯源切割粒度没有固定答案通常500-1000个token是一个合理的起点但更重要的是根据文档类型来选策略普通文本用固定大小加重叠有标题结构的文档按语义边界切代码按函数切如果既要检索精度又要上下文完整的话会用父子切割就是小块检索、大块返回向量索引卡用来找原文书页LLM真正读的metadata书签过滤和溯源文本切割策略固定大小切割语义边界切割维护一个分隔符优先级列表先尝试按段落切然后句子再然后标点。。。特殊内容专项处理代码按函数和类切分表格按整块保留转成markdown格式存储父子切割面试总结500-1000是起点关键是根据文档类型选策略。用的实际策略固定大小加重叠做兜底对结构化文档用语义边界切割对高质量要求的场景用父子切割怎么规避语义被切割掉的问题第一切的时候就不要在语义中间截断用重叠切割和语义边界切割来保证每个chunk内容是完整的也就是按句子、段落这些自然的边界来切第二、切完之后用检索策略把上下文补回来核心方案是句子窗口检索命中一个句子就把周围几句一起返回给LLM另外还有父子切割小块检索命中大块内容输出还有一个比较有价值的方案是Contextual retrieval在做Embedding之前先让大模型看着整篇文档为每个chunk生成一段背景说明把这段背景和chunk拼在一起再向量化从根本上解决独立chunk没头没尾的问题和上面句子窗口检索对比句子窗口是检索命中后动态扩展上下文父子切割是提前把父子关系存好。两者思路相近父子切割更灵活父 chunk 大小可以精确控制句子窗口实现更简单不需要维护父子 ID 关系。在 RAG 中 Embedding 究竟是什么如何选择和评估一个 Embedding 模型Embedding是把一段文本转成一串固定的浮点数向量的过程。他有一个关键的特性就是语义相近的文本转出来的向量在数学空间里的距离也近RAG的语义检索就是靠这个实现的不是关键词匹配而是看两段内容的意思相不相近。选模型主要看三个维度第一是中文支持中文场景优先选BGE系列,中英文比例text-embedding-3-small第二是向量维度维度越高精度越高但存储成本也越大,1024,1536第三是最大输入长度决定能处理多长的chunkOpenAI的text-embedding BGE Qwen3-Embedding正确的评估方法准备几百条业务相关的【问题正确答案chunk】对分别用候选模型最检索看正确的chunk有没有出现在前K条结果里指标为HitKEmbedding 有哪几种算法你了解过吗Embedding算法大致经历了三代演进第一代是静态词向量以Word2Vec和GloVe为代表每个词映射成向量但同一个词不管上下文是什么向量永远不变处理不了多义词第二代是以Bert为代表的上下文相关向量同一个词在不同语境下有不同的向量表达能力提升但Bert本身输出的是token级别的向量两个句子要比较相似度就必须拼在一起跑百万条文档就要跑百万次检索速度不可接受第三代是SBert、SimCSE、BGE为代表的句子级对比学习Embedding专门为两段文本有多相似这个任务优化提前把所有文档向量算好存起来查询时只算一次是RAG场景的标配。什么是向量数据库有没有做过向量数据库的对比选型向量数据库是专门用来存储和检索高维向量的数据库核心能力是近似最近邻搜索也叫ANN,能在百万甚至亿级的向量里快速找出最相似的几条普通关系型数据库的索引结构是对高维向量基本是失效的需要专门的数据库来处理本地开发阶段用Chroma配置上手极快生产环境中的中小规模推荐Qdrant,性能不错API也比较简洁如果到了超大规模就要考虑Milvus,字节和小米都在用不想自己运维就用Pinecone云托管如果项目中已经有PostgreSQL,也可以直接用pgvector不用引入新组件核心索引算法HNSWHierarchical Navigable Small World构建一个多层图结构查询时能从最上层的稀疏图开始导航逐层收缩范围最终在最底层找到最近邻。优点是召回率高、查询速度快缺点是建索引时内存消耗大不适合内容极度受限的场景。几个参数M(每个节点最多认识几个邻居)ef_construction建图时每个节点考察多少候选ef查询时搜索的候选集大小IVFInverted File Index先对向量做聚类把相似的向量分进一个桶中查询时只搜最相关的几个桶不是全量遍历。优点是占用内存小、适合超大规模缺点是精度比HNSW略低需要调参。HNSW 精度高、速度快为什么还需要 IVF原因很简单HNSW 的内存消耗和向量数量成正比到了亿级规模内存可能扛不住。IVF 用聚类换内存牺牲一点精度就能处理超大规模数据两者各有适用场景。向量数据库的核心能力metadata过滤先过滤在检索实时更新与关键词检索融合纯向量检索对一些精确词语比如产品型号「GPT-4o」、专有名词的效果不好有些向量数据库同时支持向量检索 BM25 关键词检索做混合召回效果更好。讲讲你用的向量数据库数据量级是多大性能如何遇到过性能瓶颈吗生产环境用的是Milvus,数据量在百万条向量左右每条是1024维用HNSW索引单次查询的延迟在20-50ms。选Milvus主要是因为他支持分布式部署和读写分离适合数据量大并发高的场景。给出具体的数据量级和性能指标150 万条 1024 维向量HNSW 索引P50 延迟 20msP99 延迟 60ms100 QPS 并发稳定。这些数字要有不能说「感觉挺快的」遇到两个典型的瓶颈第一个是内存压力百万级1024维向量原始数据就要好几个GB后来开启了标量量化SQ8,把float32压成int8,内存直接降到原来的1/4第二个是大批量写入的时候会触发后台Segment合并把多个小的增量 Segment 合并成大的封存 Segment 并建好索引影响查询延迟解法是批量写入改到业务低峰期分批小批次写入你使用 RAG 给大模型一个输入系统是怎样的工作流程系统先对问题做预处理改写成更适合检索的形式然后把问题向量化去向量库里找最相关的文档片段再经过精排筛掉噪声最后把筛选出来的片段和问题一起拼成Prompt交给大模型基于这些参考资料生成最终答案。让大模型在回答时有真实的知识作为依据而不是凭空发挥。第一步Query 预处理Query Rewrite简单改写把口语化问题改写成更正式、独立完整的检索句。HYDEHypothetical Document Embeddings让 LLM 先「假设」一个可能的答案用这个假设答案的向量去检索。你可能会觉得奇怪不用问题去搜反而用假设答案去搜原因很简单问题和答案的用词往往差异很大但假设答案和真实答案的用词更接近它们的语义空间天然更匹配命中率往往更高。多角度改写把同一个问题扩展成 3-5 种不同表述分别检索后合并结果覆盖面更广第二步Query Embedding问题向量化第三步向量检索ANN 搜索 多路召回向量检索负责捕获语义相似性BM25/全文检索负责捕获关键词精确匹配两路各有所长。多路结果通过 RRF互倒排名融合算法合并最终召回的结果比单路覆盖面更广、质量更高。第四步Rerank 精排Cross-Encoder把用户问题和每个候选片段拼在一起输入深度理解他们之间的语义匹配程度第五步Prompt 拼装promptf 你是一个专业助手请根据以下参考资料回答用户的问题。 如果参考资料中没有相关信息请回答「根据现有资料无法回答」不要自行猜测。 参考资料 [1]{chunk_1}[2]{chunk_2}[3]{chunk_3}用户问题{user_query}第六步大模型生成 溯源整个链路串起来工程上常见的优化手段是缓存高频 Query 的检索结果以及把向量检索和 BM25 检索并行执行把两路召回的延迟从串行叠加变成取最大值。请你介绍一下向量检索和关键词检索的区别关键词检索BM25 这类靠的是词频统计看查询词在文档里出现了多少次擅长精确命中向量检索靠的是语义空间里的距离能理解「换了种表达方式的同一个意思」擅长模糊语义匹配。两者各有盲区BM25 遇到同义词就没辙向量检索遇到专有名词、产品型号这类精确词就容易漏。所以 RAG 系统里通常两路都跑向量检索捕获语义相关的内容BM25 精准命中关键词再用 RRF 算法把两路结果合并这样覆盖面比单路宽很多。它的基本思路可以用一个类比来理解想象一个巨大的图书管理员他给每本书建了一张「词汇卡片」记录这本书里每个词出现了几次。用户来查「手机 截图」管理员就把包含「手机」的书挑出来再把包含「截图」的书挑出来然后看哪些书同时被挑中、被挑中的词出现频率高这些书就排前面。这个「词汇卡片」系统就是倒排索引它记录的不是「每篇文档里有哪些词」而是反过来记录「每个词出现在哪些文档里」。打分的时候看两个指标词频IF和稀缺度IDFRRF(Reciprocal Rank Fusion)互倒排名融合RRF 的思路很巧妙它不看各路的原始分数只看排名。你可能会问为什么不直接把两路的分数加权平均呢原因是向量相似度0 到 1 的余弦值和 BM25 分数可能是任意正数的量纲完全不同就像拿摄氏度和华氏度直接加在一起没有意义。RRF 用排名的倒数来打分排名越靠前倒数越大最终按总分降序排列。这样两路都认为相关的文档会排在最前面只有一路认为相关的文档也不会被完全丢掉。defreciprocal_rank_fusion(results_list,k60): results_list: 多路检索结果每路是一个 [doc_id, ...] 的有序列表 k: 平滑参数防止排名第 1 的文档权重过大通常取 60 scores{}forresultsinresults_list:forrank,doc_idinenumerate(results):ifdoc_idnotinscores:scores[doc_id]0# 排名越靠前rank 越小倒数越大scores[doc_id]1/(rankk)# 按总分降序排列取 Top-Kreturnsorted(scores.items(),keylambdax:x[1],reverseTrue)# 使用示例vector_results[doc_a,doc_b,doc_c]# 向量检索的排序结果bm25_results[doc_b,doc_d,doc_a]# BM25 的排序结果mergedreciprocal_rank_fusion([vector_results,bm25_results])# doc_b 两路都高排doc_a 也两路命中会排在前面如何润色用户的 QueryQuery Rewrite目的是什么。。。