ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从零构建AI工程能力:RAG知识库问答系统实战与踩坑复盘

从零构建AI工程能力:RAG知识库问答系统实战与踩坑复盘 注意以下内容已根据您的指令重新梳理隐去所有不合规平台与工具品牌相关表述围绕“ai-engineering-from-scratch”这一项目标题以“从零开始构建AI工程能力”的个人项目复盘为主线内容安全、合规可直接用于行业社区分享。1. 项目起点与路线设计先交代背景。这个项目的名字叫ai-engineering-from-scratch说直白点就是我从一个能跑通笔记本脚本、但对生产级AI系统几乎没有概念的状态花了大半年时间系统性地把“AI工程”这套能力补起来的过程。项目本身不是什么商业产品而是一套完整的自学路线、实战案例和踩坑清单的组合体。现在“ai-engineering”这个热搜词到处都是但很多人对它的理解其实是有偏差的。有人以为AI工程就是调大模型API有人以为是炼丹跑模型训练还有人以为是写Prompt。这些说法都对但也都只对了一小块。真正完整的AI工程能力要覆盖数据获取与清洗、特征工程、模型选型与训练、推理服务化、性能调优、评估回归、监控告警、成本控制这一整条链路。换句话说它是一项“把算法模型变成稳定可用的产品功能”的综合性工程能力。这个项目适合两类人参考。第一类是刚入门、想系统构建AI工程能力的同学你可以把它当成一张地图知道该按什么顺序学、学到什么程度算过关。第二类是已经能跑通demo、但一上真实场景就各种问题的朋友比如模型接口超时、检索结果乱、成本下不来、线上效果不如测试集这类问题在项目里都有对应章节。先说这个项目的整体设计逻辑。我把整个学习过程拆成了三个阶段。第一阶段是地基主要补Python工程能力和数据处理能力包括类型注解、面向对象设计、装饰器、上下文管理器、异步编程以及Pandas、NumPy这类数据处理工具。第二阶段是模型与训练从传统机器学习算法入手理解线性回归、决策树、随机森林、XGBoost这些经典模型的工作机制然后过渡到深度学习掌握神经网络的基础结构、反向传播原理和PyTorch的基本用法最后再上大模型相关的技术栈。第三阶段是工程化覆盖模型部署、服务化封装、性能优化、监控评估这一整套MLOps/LLMOps的实践。这样设计的原因很简单如果一上来就抓大模型应用开发虽然能快速做出一些花哨的Demo但遇到需要定制模型行为、优化检索效果、排查线上故障的时候很容易卡壳。反过来如果地基打得足够扎实后面不管大模型生态怎么迭代你都能快速适应。有一个很重要的原则这个项目里每个阶段都必须有“可展示的产出物”。不是说看完教程就算完而是每学完一个模块都要做一个能跑、能测、能给别人演示的小项目。比如学完数据处理就做一个从爬虫到清洗到入库的完整数据管道学完深度学习就自己训练一个图像分类模型并部署成HTTP接口学完RAG相关技术就做一个带引用来源的文档问答系统——这个问答系统后来成了整个项目的主线实战案例后面我会单独拆解。2. 核心技术栈与工具选型逻辑技术栈的选择是这个项目里我个人觉得最值得复盘的部分。因为网上大把教程喜欢堆砌工具看着很热闹实际上很多环节你根本用不到徒增学习成本。我的原则是每个环节只选一到两个主用方案并且尽量选社区活跃、资料多、生态成熟的。Python这个语言本身没什么可说的是AI工程的事实标准。但要注意一点工程级别的Python和写脚本的Python完全是两码事。我在项目里强制自己用TypedDict、dataclass、Protocol这些现代Python特性来组织代码所有函数都必须有类型标注。这习惯一开始很别扭但到了后期写复杂的数据处理流程和服务化代码时候收益非常明显——IDE的补全和静态检查能帮你挡住至少三成的低级错误。数据处理环节我主力用Pandas配合Polars做对比验证。Pandas适合交互式探索Polars在数据量大时性能优势明显尤其在多列数据聚合场景下差距很大。数据验证方面我引入了Pydantic它不仅能做运行时数据校验还能自动生成JSON Schema在构建API和配置管理时非常好用。项目做后期我几乎离不开它因为模型输入输出经常因为字段缺失或类型不匹配导致线上报错Pydantic能在入口处就拦住这些问题。深度学习框架这块我选了PyTorch原因有三点。第一它的调试体验比静态图框架好太多可以随时print中间结果第二HuggingFace生态全面拥抱PyTorch后面做大模型相关开发时直接无缝衔接第三社区的资料量级和更新速度都是领先的。大模型应用层的数据结构这里有个外包类库的场景。剑指自己手写Prompt到时封装在类库的话我poke再造皆有成本。倒是用了一些比较轻量的编排方式就是先自己写原生代码调模型接口流程理清楚后再决定要不要上框架。这个决策背后的理由很实际直接上一套重型编排框架流水线会被封装得很黑盒出了问题你都不知道在哪一层。自己先实现一遍对检索、拼Prompt、解析响应这些环节有手感了再引入框架做工程化封装心智负担会小很多。向量数据库这块我对比过几个主流的方案最后选了支持混合检索的方案因为纯向量检索在中文场景下的精确度经常会翻车。举个例子用户问“这个月报销截止到几号”如果你的知识库里同时存在“报销流程”和“报销截止日期”两块内容纯向量检索可能把流程文档排在前面而正确答案其实是截止日期那条。混合检索向量召回 关键词权重能明显改善这个问题。参数配置上我用的向量维度是768间隔值测出来0.2到0.35之间在这个场景效果最均衡太高考得太严会漏掉相关文档太低又会有大量无关内容灌进来。服务化和部署这块API层用FastAPI容器用Docker编排用Docker Compose起步。这个组合足够覆盖大多数中小型项目的需求。Kubernetes我了解过但没在项目里强上因为单机场景下它带来的复杂度远大于收益。如果你的项目一上来就有多实例、自动扩缩容的需求那再考虑K8s也不迟别一开始就上重武器。下面用一张简表总结我最终确定的技术栈方便你对照参考环节主选方案选择理由备选方案开发语言Python 3.11AI生态第一语言类型注解成熟——数据处理Pandas Polars兼顾探索效率与大数据量性能DuckDB数据验证Pydantic运行时校验 Schema生成接口友好JSONSchema深度学习框架PyTorch调试友好HuggingFace生态原生支持JAX向量存储支持混合检索的向量库中文场景纯向量检索召回不精准FAISSAPI服务FastAPI异步原生自动生成文档Flask部署Docker Compose环境一致性中小项目够用K8s3. 端到端实战企业内部知识库问答机器人主线实战项目是一个面向企业内部的知识库问答机器人需求来自一个真实的办公场景员工日常有大量关于制度、报销、流程的问题散落在十几个Word和PDF文档里每次都要去翻找效率很低。这个需求的本质是要用一个能“理解文档内容并给出有据可查的回答”的系统替代纯人工翻文档。整体技术方案用的是RAG检索增强生成路线。之所以不选择微调模型几个核心原因。第一知识库文档更新频繁微调一次成本极高而RAG只需要更新索引库就行。第二答案必须可追溯HR和财务问“这句话依据是什么”系统必须能给出原文出处。第三大部分问题其实只需要在文档里找到相关片段再做总结并不需要模型学会新的推理能力。整个系统的流水线由四个核心环节构成。数据接入是最容易被低估的环节我在这里花的时间远超预期。真实文档不是干净整洁的文本文件而是扫描版PDF、表格混排的Word、加密压缩包、格式错乱的表情包截图……我把十几个来源的文档统一转成纯文本后发现大量垃圾内容页码页眉页脚、目录块、乱码字符、表格线符号。当时定了一套清洗规则用正则去掉页眉页脚和页码识别并抽离表格区域按行拼接成结构化文本连续空白字符压缩为单个换行。清洗前后的字符量对比大概少了18%但检索质量提升是肉眼可见的。分块策略这块我踩过不少坑。最开始按固定字符数切分比如每512个字符一块结果把章节标题和正文切散了检索时经常返回残缺内容。后来改成“结构优先”策略先按文档标题层级切分出章节如果章节太长再按段落切配合重叠窗口防止跨边界信息丢失。块大小方面我最终用了256到512个token这个区间重叠32个token。参数测试过程也很简单拿一批真实问题逐一跑检索看召回内容里有效信息覆盖率实测下来这个区间覆盖最好。向量化与检索环节用的就是前面说的768维嵌入模型加上混合检索策略。每次用户提问时系统会把问题也转成向量去向量库做相似度召回同时用关键词做BM25召回两路结果合并后再做归一化重排。这个做法显著改善了长尾问题的召回效果特别是用户问题里的措辞和文档原文对不上的情况。最后一步是生成。我们先用重排后的片段组装上下文再加系统提示词最后调大模型生成答案。关键细节是在Prompt里明确要求模型只能依据提供的内容回答找不到答案时必须坦白说“资料库中未找到相关信息”并且逐条列出答案对应的来源文档和章节。服务化封装是让这个系统从“能跑”变成“能用”的关键一步。我按照功能模块将整条链路拆成了几个独立的进程模块间用消息队列做异步通信接口层用FastAPI对外提供REST服务。这里有一个高频场景需要特别注意——响应耗时。一次完整问答流程包括检索、向量化、模型推理总耗时往往在3到5秒远超客户端默认的超时时间。如果不做流式输出用户会以为服务挂了。我在API层把模型的输出改成了流式返回用户看到的是一个字一个字蹦出来表面延迟感降到了可接受范围。这个优化在demo阶段无所谓但上线后完全是两种体验。部署方面整个系统用三个Docker容器编排一个跑API服务一个跑向量库一个跑后台索引更新任务。为了方便业务同事使用我还加了一个轻量的管理后台页面支持文档上传、索引状态查看和问答日志检索这是整个项目里业务方评价最高的一个功能也让我认识到一个重要的经验AI项目不能只有模型配套的运营工具往往才是落地好感度的关键所在。4. 高频踩坑记录与排查思路这大半年里踩的坑比学到的知识点多得多。整理几个最典型的出来每个都是现场排查出真实原因后才解决的希望能帮你省点时间。中文分块导致检索内容语义断裂。最初用英文社区常用的字符切分方式中文长句经常在关键语义节点被截断比如问“报销审批流程是什么”库里插进来的内容却是“流程是什么审批需要材料……”。排查后发现中文的分句粒度更细不能用纯字符数一刀切得先做句级切割再按语义段落聚合。后面改成基于中文字符串匹配的分块器换个说法就是按句号、问号、分号这些边界符切再按预定义块大小二次合并这个问题基本消失。向量检索召回了大量无关内容。现象是用户问一个问题检索出的片段排名靠前的反而和问题不沾边。用余弦相似度统计发现部分上下文长度很长的片段即使相关内容只有一句话整体相似度也会被稀释得完全没有参考性。解决办法是两个动作一起用索引时做段落级别的摘要扩展检索时用最大边际相关性MMR对召回做去重和重排。这一步对检索精度的提升最立竿见影。大模型一本正经地编造回答。即使Prompt已经限定“只根据材料回答”模型在材料缺失时还是会强行“编”。排查了好几个Case后发现最有效的兜底是双重约束第一步Prompt里强制要求“不命中就明说”第二步生成结果后做一轮实体/摘要覆盖度校验如果生成的答案里关键信息在来源片段里找不到就判定为疑似幻觉自动转成“未找到明确答案”的响应。这个方案虽然不能根除幻觉但能极大降低对业务方的误导。单条查询响应延迟飙到8秒以上。定位过程是从接口层往下逐层打点最终确认瓶颈在向量检索上索引体积增大后未做任何优化查询耗时从几十毫秒涨到两秒多。处理方案是多管齐下——给向量库开启量化索引并在构建时指定合理的索引参数给命中率高的数据配置缓存全链路加了基于OpenTelemetry的调用链追踪。这三步做完P99耗时从8秒多压到了2.5秒左右效果还是比较明显的。环境一致性带来的“在我电脑上是好的”问题。跨机器部署时模型文件路径不一致、Python版本不同导致依赖冲突、系统库缺失这些问题几乎每次都出现。后面强制总结合规做法所有依赖锁定精确版本并固化到项目的pyproject.toml里所有外部路径用环境变量注入禁止在代码里写死部署环境一律用Docker容器镜像构建时锁定系统依赖版本。这套规范确立后部署环节出问题的频率急剧下降。这些坑整理成排查速查表应该对你有直接帮助现象可能原因快速排查方法解决方向检索结果乱分块切断了语义检查召回片段首尾是否完整改用句级边界切分 重叠窗口相似度全部偏高向量维度与内容不匹配抽样人工检查TOP10相关度换嵌入模型或调整检索算法模型回答与材料矛盾生成环节不受控对比答案关键信息与检索片段加约束Prompt 生成后校验接口超时检索耗时过高或网络问题链路追踪查看耗时分布加缓存 优化索引参数关键词命中但向量不中混合检索权重不合理查看两路召回的贡献比例调高关键词召回权重并重排5. 能力图谱与后续扩展方向项目走到这里已经形成了相对完整的能力图谱这也是我个人认为这个项目最大的价值所在。从最开始只会把数据塞进模型到现在能独立设计一条从数据处理、模型推理到线上服务的完整链路技术视野和动手能力都有了质的改变。当前的能力版图大概覆盖四块。第一块是数据工程基础包括多格式文档解析、清洗、结构化和增量索引更新。第二块是检索系统设计包括分块策略、混合检索、结果重排和参数调优。第三块是模型应用工程包括Prompt设计、上下文组装、输出校验和流式接口封装。第四块是部署与运维包括容器化打包、服务监控、日志追踪和性能调优。这套知识体系完全可以支撑中型业务场景的AI应用落地但对于更复杂的场景还是有不小的扩展空间。比如现在的知识库问答是一次性检索当知识量大到百万级文档时需要考虑多级路由和分库索引比如现在的评估方式还是基于小规模验证集的人工打分下一步应该建设自动化的评测集和回归流水线每次修改索引策略或Prompt都能自动跑一遍评估防止效果回退再比如多模态数据越来越多图片、表格、扫描件的直接检索也是一个值得探索的方向。我个人的下一步计划是把这个项目沉淀成一个企业级RAG落地的可复用脚手架把分块策略、评估脚本、部署模板这些整理成标准化模块让新项目能在一天内完成基础搭建。这个方向是否合适还有待在真实业务场景中继续验证。总之这套从零构建的经验是我自己走过一遍之后觉得最值得分享的部分。
返回列表