ARTICLE DETAIL

资讯详情

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

从零手搓AI工程核心链路:分块、检索、推理与评估实战

从零手搓AI工程核心链路:分块、检索、推理与评估实战 1. 从零搭建AI工程能力为什么“手搓一遍”比调包更值钱这两年AI应用开发的门槛肉眼可见地降低了。一个刚入行的开发者借助现成的框架和API可能一个下午就能跑通一个对话机器人或者一个RAG问答系统。但如果你真的在团队里带过人、做过线上项目就会发现一个很尴尬的现象很多人能跑通Demo却说不清楚一次推理请求背后到底发生了什么模型加载慢在哪里、显存为什么爆了、token是怎么被切分的、向量检索的召回率为什么上不去一问三不知。“ai-engineering-from-scratch”这个标题本质上说的就是一件事把AI工程里那些被框架封装掉的环节自己动手实现一遍。它不是让你去从头训练一个大模型那既不现实也没必要而是让你把推理服务、数据处理、检索增强、评估监控这些工程链路的核心模块用最朴素的方式亲手搭一遍。做完之后你对整个系统的掌控力和只会调包的人完全不在一个层次。这篇文章适合三类人一是刚转行做AI应用、只会调API想补底层认知的开发者二是有后端或数据工程背景、想切入AI方向的工程师三是带团队的技术负责人想搞清楚AI工程到底有哪些坑、该怎么给团队定技术规范。我会把整条链路的搭建思路、关键取舍、实测踩过的坑都摊开讲尽量让你看完就能自己动手复现。需要先说明一点下面涉及的具体参数、工具选型都是基于我在实际项目中的常见实践给出的合理方案不是唯一答案。你要根据自己的硬件条件、数据规模、团队技术栈去调整重点是理解每一步“为什么这么做”。2. 动手之前先想清楚AI工程到底在工程什么2.1 把“模型”和“工程”分开看很多人一上来就纠结模型选型觉得模型选对了项目就成功了一半。实际做下来你会发现在一个真实的AI应用里模型只是其中一个组件而且往往是相对稳定的那个。真正消耗你80%精力的是模型之外的那一圈东西数据怎么进来、怎么切、怎么存、怎么检索、怎么拼装成prompt、怎么控制并发、怎么监控质量、怎么迭代。我习惯把AI工程拆成四层来看。最底层是基础设施层包括算力、显存管理、模型加载与推理引擎往上是数据层包括文档解析、分块、向量化、存储与检索再往上是编排层负责把检索结果、对话历史、系统指令组装成最终输入并管理多轮状态最上面是应用与评估层面向具体业务场景同时负责质量监控和效果评估。从零搭建就是把这四层里最核心的模块各实现一个最小可用版本。这样拆的好处是你不会被某个框架的抽象概念绕晕。任何一个AI框架你都能把它对应到这四层里看它到底帮你做了什么、隐藏了什么。当你遇到问题时也能快速定位是哪一层出了毛病。2.2 最小可用系统该包含哪些模块如果你时间有限我建议优先实现这四个模块它们覆盖了AI工程最核心的能力文本分块器把长文档切成适合模型处理的片段这是RAG的地基切得好不好直接决定检索质量。向量化与检索把文本转成向量存起来并实现相似度检索理解embedding和索引的基本原理。推理服务封装把模型加载、请求处理、并发控制、超时重试封装成一个稳定的服务。评估脚本用一批标注好的问答对量化你的系统到底好不好而不是凭感觉。这四个模块做完你就有了一个能跑、能测、能迭代的完整闭环。后面再往上加缓存、加多路召回、加重排序都是在坚实的地基上做增量。2.3 一个容易被忽略的前提先定义“好”的标准我在早期项目里犯过一个典型错误花了两周把系统搭起来跑起来感觉“还行”但老板问“准确率多少”我答不上来。因为没有评估标准你根本不知道系统是在进步还是在退步。所以在动手写代码之前先花半天时间做一件事准备一个评估集。哪怕只有50条数据每条包含一个问题和一个标准答案或者标准答案的关键要点。这个评估集会贯穿你整个开发过程每次改动后跑一遍看指标是涨是跌。没有它你的所有优化都是盲人摸象。这是我从零搭建AI系统时认为最重要、也最容易被跳过的一步。3. 文本分块RAG效果的天花板往往在这里就被决定了3.1 为什么固定长度分块是个陷阱大部分教程教你分块就是按固定字符数切比如每500字一块重叠50字。这个方法实现简单但在真实文档上效果很差。原因很简单文档是有语义结构的一个完整的论述可能横跨800字你从中间切断前半块讲了一半的论点后半块接着讲结论两块单独看都不完整检索时匹配到的都是残缺信息。我实测过一个技术文档库固定长度分块和按语义分块在同一个评估集上的召回准确率差了将近20个百分点。这个差距不是靠换更好的embedding模型能补回来的因为信息在切分阶段就已经被破坏了。正确的思路是按语义边界切分。最基础的做法是按段落切段落本身就是作者划分的语义单元。如果段落太长再在段落内部按句子切。句子边界识别可以用简单的标点规则也可以用轻量的分句工具。核心原则是尽量保证每一块是一个语义完整的单元而不是机械地凑字数。3.2 分块大小的权衡没有标准答案只有场景答案分块大小到底设多少是问得最多的问题。我的经验是它取决于你的检索粒度和模型上下文窗口两个因素。块太小比如100字检索时匹配很精准但单块信息量不足模型拿到后可能答不完整。块太大比如2000字信息量够了但检索时噪声变多而且一块里可能包含多个主题相似度计算会被稀释。我一般会在300到800字之间做实验用评估集跑一遍看哪个区间的召回和答案质量最好。还有一个技巧是分层分块。把文档同时切成大块和小块小块用于精准检索检索到之后把对应的大块或者大块加上相邻块喂给模型。这样兼顾了检索精度和上下文完整性。这个思路在工程上实现起来不复杂但效果提升很明显。3.3 元数据分块时顺手做的事后面能省大力气分块的时候千万别只存文本内容。至少要把这些元数据一起存下来来源文档ID、块在文档中的位置序号、所属章节标题、块的字符数。这些信息在后续检索、去重、展示引用来源时都会用到。我踩过一个坑早期分块只存了文本后来要做“引用溯源”功能需要知道每个答案来自哪篇文档的哪一段结果发现根本追溯不了只能把整个库重新处理一遍。所以分块阶段多存几个字段成本极低收益极高。另外如果文档有标题层级结构把章节标题拼接到块内容前面一起做向量化能显著提升检索效果。因为标题本身就是对内容的强概括相当于给每个块加了一个语义标签。4. 向量化与检索把“找相似”这件事做扎实4.1 Embedding模型选型别只看排行榜选embedding模型很多人直接看公开榜单排名。榜单有参考价值但你的场景和榜单的评测场景可能完全不同。榜单大多测的是通用语义相似度而你的业务文档可能有大量专业术语、缩写、内部黑话。我的做法是选两三个候选模型用你自己的评估集各跑一遍检索看召回率。候选模型里至少要有一个是支持中文或多语言的因为很多英文榜单冠军在中文上表现会打折。另外要考虑模型的维度和推理成本维度越高检索越慢、存储越大如果效果差距不大优先选维度低的。还有一个实际因素模型能不能本地部署。如果你的数据敏感、不能出内网那就只能选能本地跑的模型。这个约束会直接砍掉一批候选所以要在选型早期就确认清楚。4.2 相似度计算余弦相似度不是唯一选择向量检索最常用的是余弦相似度它衡量的是方向上的接近程度对向量长度不敏感。这在大多数场景下是合理的因为embedding模型通常会把语义相近的文本映射到相近的方向上。但有些场景下欧氏距离或者点积可能更合适。点积在向量已归一化时等价于余弦相似度计算更快。如果你的embedding模型输出已经归一化直接用点积就行省一次计算。我实测下来在归一化向量上点积和余弦的结果完全一致但点积的矩阵运算更快尤其在大规模检索时差距明显。实现检索时最朴素的做法是暴力遍历所有向量算相似度。数据量小的时候比如几千条完全够用而且结果精确。数据量上万之后就要考虑近似最近邻索引了。但我的建议是先用暴力检索跑通全流程确认效果达标后再考虑换索引优化速度。过早引入复杂索引调试成本高而且可能引入精度损失。4.3 检索质量差先别怪模型检索效果不好很多人第一反应是换更好的embedding模型。但根据我的经验问题往往出在更前面分块没切好、查询和文档的表述方式差异太大、或者没有做查询改写。一个立竿见影的技巧是查询扩展。用户的问题往往很短比如“怎么配置超时”而文档里写的是“超时参数的设置方法”。直接拿短查询去检索可能匹配不上。可以在检索前用一个小模型或者规则把查询扩展成几个同义表述分别检索后合并结果。这个改动不大但召回率提升很明显。另一个技巧是混合检索向量检索负责语义匹配关键词检索比如BM25负责精确匹配。两者结果加权融合。对于包含专有名词、型号、代码的查询关键词检索能补上向量检索的短板。我在实际项目里基本都会上混合检索纯向量检索在专业领域文档上经常漏召。5. 推理服务封装让模型稳定跑起来比调通难得多5.1 模型加载显存、精度与启动速度的三角把模型加载起来跑通一次推理和把它封装成一个能扛住并发、稳定运行的服务中间隔着一整个工程。第一个要面对的就是显存问题。模型加载占用的显存主要取决于参数量和精度。以常见的7B模型为例FP16精度下大约需要14GB显存INT8量化后降到7GB左右INT4量化后只要4GB上下。如果你的显卡显存有限量化是必选项。但量化会带来精度损失需要评估损失是否可接受。加载策略上我建议服务启动时一次性加载常驻显存而不是每次请求都加载。每次加载模型动辄几十秒请求响应时间根本没法看。常驻显存虽然占资源但换来了稳定的低延迟。如果显存实在紧张可以考虑多模型共享或者按需加载加缓存但复杂度会上升不少。5.2 并发控制别让请求把服务打垮模型推理是计算密集型任务同时处理太多请求会导致显存溢出或者响应时间飙升。必须做并发控制。最直接的方式是限制同时处理的请求数用一个信号量或者队列来控制。超出的请求排队等待而不是直接拒绝。队列长度也要设上限超过上限就快速失败返回“服务繁忙”避免请求无限堆积拖垮整个服务。另一个关键是批处理。如果多个请求同时到达可以把它们拼成一个batch一起推理能显著提升吞吐量。但批处理会增加单个请求的延迟因为要等凑批。所以要在吞吐和延迟之间找平衡点通常设一个很小的等待窗口比如几十毫秒窗口内到达的请求合并处理。超时和重试也要设计好。推理请求设一个合理的超时时间超时后释放资源。对于可重试的错误比如临时资源不足做有限次数的重试但要注意重试不能加剧拥塞最好带退避策略。5.3 流式输出体验提升的关键细节对话类应用如果等模型全部生成完再返回用户要盯着屏幕等好几秒体验很差。流式输出让token一个个吐出来用户马上能看到反馈感知延迟大幅降低。实现流式输出需要在推理引擎层面支持逐token返回然后在服务层用SSE或者WebSocket推给前端。这里有个坑流式输出时如果中途出错已经吐出去的内容没法收回所以要在开始流式输出前做好参数校验和资源检查尽量把错误挡在前面。还有一个细节是首token延迟。用户感知的响应速度主要取决于第一个token多久出来。优化首token延迟可以从prompt长度、模型预热、KV缓存复用几个方向入手。prompt越短首token越快所以检索回来的上下文要精简别一股脑全塞进去。6. 评估与迭代没有度量就没有优化6.1 评估集怎么建才靠谱评估集的质量直接决定你优化的方向对不对。我的建议是评估集要覆盖三类问题事实型答案在文档里有明确出处、推理型需要综合多处信息、边界型文档里没有答案系统应该拒答。每类问题都要有比例根据你的业务场景调整。如果业务里大部分是事实型查询那事实型占比就高一些。边界型问题特别重要因为很多系统在遇到不知道的问题时会胡编评估集里必须有这类样本才能测出系统的“诚实度”。标注答案时不要只写一个标准答案最好把关键要点列出来。因为模型生成的答案表述可能和标准答案不同但要点覆盖了就算对。评估时可以用要点召回率来衡量比精确匹配更合理。6.2 自动化评估用模型评模型人工评估准确但慢不适合快速迭代。可以用一个能力较强的模型来做自动评估给它问题、标准要点、系统答案让它判断答案覆盖了哪些要点、有没有编造。用模型评估要注意几点评估用的模型能力要明显强于被评估的系统否则评不准评估的prompt要写清楚评分标准最好给几个示例评估结果要做抽样人工复核确认自动评估和人工判断的一致性。我一般会抽10%的样本人工核对如果一致性低于90%就要调整评估prompt。除了答案质量还要监控检索命中率正确文档有没有被检索到和拒答准确率该拒答的有没有拒答。这两个指标能帮你定位问题出在检索层还是生成层。6.3 迭代的优先级先修召回再调生成系统效果不好时优化顺序很关键。我的经验是先确保检索能召回正确文档再优化生成质量。如果正确文档根本没被检索到生成模型再强也答不出来这时候调prompt是白费力气。判断方法很简单看评估集里答错的样本正确文档是否在检索结果里。如果不在就是召回问题去优化分块、embedding、查询扩展、混合检索。如果在但答案还是错才是生成问题去优化prompt、上下文组织、模型选型。这个排查顺序能帮你避免在错误的方向上浪费时间。我见过太多团队一上来就疯狂调prompt结果发现根因是分块把关键信息切碎了。7. 那些文档里不会写的实操心得7.1 关于工具选型的一点个人偏见从零搭建不等于什么都自己写。向量存储、推理引擎这些轮子该用现成的就用自己写一遍是为了理解原理不是为了重复造轮子。我的原则是核心逻辑自己实现通用基础设施用成熟方案。比如向量检索的索引结构自己实现一个暴力检索理解原理就够了生产环境还是用成熟的向量库。但有一个东西我建议自己写评估脚本。因为评估逻辑和你的业务强相关现成工具往往不够灵活。自己写一个评估脚本想加什么指标就加什么指标迭代起来最顺手。7.2 数据清洗的投入被严重低估大家聊AI工程都在聊模型、聊框架很少有人聊数据清洗。但实际项目里数据清洗占的时间经常超过一半。PDF解析出来的文本可能带乱码、页眉页脚、表格错位网页抓下来的内容有导航栏、广告、无关链接。这些噪声不清理后面分块和检索全是垃圾进垃圾出。我的建议是在数据清洗阶段多花时间建立一套可复用的清洗规则。比如统一去除页眉页脚、合并被错误换行切断的句子、过滤过短的碎片块。这些规则一旦建好后续所有文档都能受益。7.3 日志和可观测性要提前埋系统上线后出问题如果没有日志排查起来就是灾难。从第一天起就要把关键环节的日志埋好每次请求的查询内容、检索到的文档ID和相似度分数、最终prompt的长度、模型输出的token数、各阶段耗时。这些日志不仅能用于排错还能用于分析。比如你发现某类查询的检索相似度普遍偏低就知道这类查询需要特殊处理。可观测性不是上线后才考虑的事而是从搭建第一天就要设计进去的。7.4 版本管理不只是代码AI系统里除了代码要版本管理数据、prompt、模型、索引都要版本管理。你换了一版分块策略重新生成了索引如果没记录过两周你都不知道线上跑的是哪版。prompt改了一个词效果变了没有版本记录就无从对比。我的做法是给每次重要的变更打一个版本号记录变更内容、对应的评估指标。这样任何时候都能回溯也能快速回滚到效果最好的版本。这个习惯看起来麻烦但能帮你省下大量“到底哪版效果好”的扯皮时间。8. 从能跑到好用下一步可以往哪走把上面这套最小系统搭完你已经超过了大多数只会调包的人。但AI工程的深度远不止于此。如果还想继续深入我建议往这几个方向走。第一个方向是性能优化。研究KV缓存复用、连续批处理、投机解码这些推理加速技术把吞吐和延迟再压一压。这些技术在大规模服务里收益非常明显。第二个方向是多路召回与重排序。在向量检索和关键词检索之外加入基于知识图谱的检索、基于规则的检索再用一个重排序模型对多路结果统一打分。这是提升复杂场景效果的有效手段。第三个方向是Agent化。让系统不只是被动问答而是能调用工具、拆解任务、多步推理。这需要在编排层做大量工作也是当前AI应用最活跃的方向。但无论往哪走底层那套“分块、检索、推理、评估”的基本功都是绕不开的。把地基打牢上面的楼才盖得高。我自己从零搭过几套系统之后最大的体会是AI工程没有魔法所有的效果提升都来自对每个环节的扎实理解和反复调优。那些看起来“聪明”的系统背后都是这些笨功夫堆出来的。
返回列表