资讯中心

从零到一搭建AI工程:RAG应用开发与部署全流程复盘

📅 2026/10/6 17:55:43
从零到一搭建AI工程:RAG应用开发与部署全流程复盘
ai-engineering-from-scratch这个命名最初只是我硬盘里一个项目文件夹的名字。那阵子我反复被问到同一个问题没有科班背景、也不是算法岗位出身能不能从零开始把AI应用真正做出来、部署上线、稳定地跑起来大多数人止步于跑通Demo我把这个文件夹当成一次系统性的技术验证。现在回头复盘最值钱的不是某个模型的调用技巧而是一整套从学习路线到工程落地的闭环方法。这份复盘会把路径、系统设计、工程细节和踩坑过程全部拆开适合刚准备入门的开发者也适合已经在做AI应用但总觉得自己在调包的人。1. 为什么大多数人从零学AI最后都卡在半山腰1.1 卡住我们的不是数学而是学科式学习我见过太多人和当年的我一样一上来就买《深度学习》教材准备先把线性代数补齐再入门。结果线性代数补到一半微积分看到偏导数就破防了三个月后连一句我已经入门都说不出口。问题出在路径设计上——我们用的是学科逻辑而不是工程逻辑。学科逻辑的前提是把一门学问体系化地学完学到某个位置再应用。这条路对全日制学生没问题但对业余时间有限的开发者并不友好。更关键的是AI领域的技术栈迭代速度太快等按教材顺序学完主流实践方案早就换了几轮。工程逻辑则相反先锁定一个具体问题再倒推解决这个问题需要哪些技能然后以任务为单位逐个击破。比如目标只是做一个私有文档问答机器人倒推出来的技能链条是Python基础 - 调用模型API - 文本清洗 - 切块 - 生成向量 - 存进向量库 - 写检索函数 - 拼接Prompt - 封装接口 - 部署。这条链路上每一步都目的明确学起来完全不同于为了学分而学。1.2 从学完再干到边干边补倒逼式知识积累我后来把学习方法固化成一个循环定目标、做最小原型、记录缺口、补齐缺口、再迭代。每轮循环通常只补三五个知识缺口而且补完立刻就用遗忘率远低于之前刷课的状态。补齐缺口的顺序也有讲究。我习惯按能运行优先的原则来排先让一个最简单的调用跑通再慢慢往里面加文档、加检索、加生产环境要的可靠性。这样你始终有一个能展示的中间产物而不是等万事俱备之后才第一次见到真实模型输出。每次卡住时我会记录两个东西卡住的根因是什么以及这个根因属于哪一层技术栈。一个月后回看知识盲区不再是混沌一团而是清清楚楚的几块短板。2. 体系化盘点我从零搭建AI工程时用到的四层技术栈2.1 第一层Python与工程基础决定代码能不能被维护很多教程把调API视为最小技能但一个项目要长期演进而非跑一次就扔Python工程基础的权重极高。我这里说的不是语法而是虚拟环境、依赖管理、Git分支、日志、配置分离、简单的单元测试。最初我的代码只有一个app.py后来项目长到几千行才明白哪怕只是个人项目这层功底也直接决定迭代速度。具体做法上我用venv隔离环境用requirements.txt锁住依赖版本用环境变量而非源码保存密钥用dataclass集中管理模型参数和Prompt模板。这些动作单看都很普通但组合起来项目的可维护性会上一个台阶。一个不依赖全局环境的项目未来可以放心地被任何人重复运行这是工程化的起点。2.2 第二层模型原理够用就行的边界在哪里我不建议非科班读者一上来手推Transformer。但下面这几个概念必须真正理解而不是背定义token是什么、上下文窗口如何影响可用文本长度、温度与采样参数影响什么、embedding向量在做什么、为什么模型会产生幻觉。这些概念支撑你在选型、调参、写Prompt时有判断力。以token为例很多问题的根因是看不透token。上下文窗口不是字符数是token数不同语言、不同符号的token占用差别很大你发给模型的system prompt和数据开头的每轮请求都在按token计费。理解这几个事实就能解释为什么把整本手册塞进上下文的方案行不通为什么需要检索和缓存。2.3 第三层LLM应用开发相关组件的选型思维组件层有四个核心选择模型来源、框架、向量存储、编排方式。模型来源我按使用场景分三类第一类是托管API省心但成本随调用量线性上涨第二类是本地开源模型前期硬件成本高但单次调用边际成本接近零第三类是混合路由简单问题走小模型、复杂问题才调用大模型。起步阶段建议使用托管API把时间花在应用逻辑而不是环境维护上。框架选择上我的观点可能不太主流早期尽量少用重框架。我第一个RAG项目先用最原始的方式写一遍自己管理向量、检索和上下文拼接搞清楚流程之后再去对比LangChain/LlamaIndex这类框架做了什么。这样当框架抽象与实际需求冲突时你知道该改哪里而不是被框架牵着走。层级核心任务我惯用的方案什么时候该升级工程基础环境、依赖、配置、测试venv dataclass pytest多人协作或需要自动发布时模型理解概念与能力边界官方文档 精读深度拆解文章涉及训练或微调时应用组件检索、生成、编排自研流程 少量辅助库逻辑复杂、重复功能多时部署运维上线、监控、成本FastAPI Docker 结构化日志月费用高或需要稳定服务时2.4 第四层部署运维是Demo和产品的分水岭很多AI项目死在能跑与能用之间。Demo代码通常没有日志并发一高就超时模型服务挂掉无人感知月底token费用爆表才反应过来。这一层常见但不性感用FastAPI包一层HTTP服务写好统一的请求校验和异常处理容器化保证环境一致加缓存层避免重复请求重复花钱上线前加日志和指标。这些工作看起来离AI很远但恰恰是AI工程里工程的部分。没有工程化算法再先进也只是演示片。考虑到很多读者是个人开发者我会把工程化按成本排序日志和异常处理最优先缓存次之分布式能力最后再说。不要一上来就追求微服务那对本阶段大概率是负担。3. 完整案例从零搭一个私有知识库问答系统3.1 为什么第一个项目选RAG而不是微调当时评估两个方案RAG检索增强生成和微调。RAG的本质是把检索和生成拆开先从外部知识库里找到相关片段再把片段和问题一起交给语言模型生成答案。微调则是修改模型权重本身。我最终选了RAG理由是第一知识库内容会持续更新RAG只需要重新灌文档微调则要重新训练第二RAG可以在答案后面附上资料出处便于核对和建立信任第三RAG不需要GPU训练环境工程成本低一大截。微调真正擅长的是改变模型行为——比如固定的输出格式、特定的角色口吻、某个垂直任务的能力而不是注入一段一段的事实性知识。如果你想让模型学会公司的文档内容RAG是最合理的起点如果你想让模型永远用客服口吻回复微调更合适。3.2 数据准备与文档切块细节最多但最容易被忽略第一步是把非结构化文档转成干净文本。PDF、DOCX、PPT各种格式混在一起时不能统一交给一个解析库就完事。我当时的处理流程是按文件类型走不同解析器再统一做清洗去掉页眉页脚、多余换行、表格里的乱序内容按标题层级把长文档拆成章节。第二步是切块。切块参数直接影响检索质量但没有全局最优解只有基于资料形态的经验起点。我的习惯参数是chunk_size在400到800之间、overlap在64到128之间。为什么需要overlap因为一个语义完整的段落可能被硬切断overlap可以让关键信息在两个相邻块里都有残留防止它正好落在切口上。如果文档是代码或表格居多chunk_size反而要降下来如果是连贯的论述可以适度调大。3.3 Embedding与向量库的选型对比文本切好之后要做向量化。中文场景下我一般优先看三类通用托管接口、开源中文向量模型如bge系列、以及云厂商的接入服务。选型时关注的指标包括中文检索效果、向量维度与存储开销、是否支持私有化部署、单次批量向量化的延迟。向量库的选择与环境关系很大。个人项目和原型阶段我用Chroma或者直接FAISS本地运行迭代快数据量到百万级别并需要多人并发访问时才引入真正的向量数据库服务。我整理了一个简单的对照表方案适用规模上手成本说明FAISS百万级以内低本地库文件功能精简Chroma十万级内最低自带持久化适合原型Milvus/Qdrant百万级以上中高分布式、生产特性完整检索端还有一个容易忽略的参数top_k与相似度阈值。top_k决定带进上下文的信息量相似度阈值决定不够相关就不给模型。阈值设太低垃圾检索结果会挤占上下文阈值设太高很多次检索会空转。我通常先把top_k设为4到6阈值通过一小批验证问答样本调出来。3.4 Prompt组装把上下文变成模型能用的证据检索回来的是片段列表不能直接一股脑塞给模型。我当时的组装顺序是System指令、检索上下文、对话历史、当前问题。上下文里必须带序号和来源标记让模型知道引用第几条。Prompt里最好明确三个规则只用给定上下文回答、资料中没有就拒绝回答、答案给出引用。这三条规则是抑制幻觉的底线。def build_rag_prompt(context_chunks, question): context_text \n\n.join( f[片段{i}] {chunk} for i, chunk in enumerate(context_chunks, 1) ) system ( 你是一位严谨的文档助手。请仅根据下方资料回答用户问题。\n 如果资料中没有足够信息请明确回复资料中没有相关信息并给出可参考的资料关键词。\n 回答时请在相关句子后用[片段编号]标注出处。\n ) return f{system}\n\n资料\n{context_text}\n\n问题{question}组装时还有一个常被忽略的点上下文和问题的比例。当资料很长、问题很短时模型的注意力容易被大量资料稀释。我的做法是让检索阶段尽量聚焦宁可少给片段也不要把看起来相关但实际没用的资料堆进Prompt。3.5 怎么评估问答质量不靠感觉靠一组标准问题RAG项目上线前我先建了100条测试问题覆盖三类场景知识库内明确有答案、知识库内没有答案、问题涉及多个片段的综合推理。然后逐个记录模型的输出从三个维度打分答案正确性、答案是否忠实于资料、证据引用是否对得上。场景期望行为常见失败库内有确定答案给出准确答案并引用片段自说自话生成外部知识库内没有答案明确说资料没有强行编一个看起来合理的答案跨片段综合合并多个片段回答只依据第一个片段忽略后续信息这一步看起来费时间却是整个项目里收益最高的动作。因为很多问题不是程序bug而是模型输出看起来流畅但内容错得离谱。没有标准问题集你会被几次偶然的好回答误导。我后来还把评估脚本写成了半自动批量调用接口、生成报告、对比不同Prompt版本的得分。4. 从本地脚本到生产服务AI工程化里那些隐形工作4.1 模型调用层的统一网关与重试策略当系统里同时有多个模型、多个供应商时一定要在最外层做一个统一的模型调用封装不要让业务代码直接调第三方SDK。这个封装的职责包括统一接口签名、做请求级超时控制、根据错误类型决定重试策略、把每一次调用的模型名、token数、耗时记录下来。举一个很现实的例子第三方接口偶尔返回5xx或限流错误如果直接报错给用户体验会非常糟糕。但无脑重试更危险可能让限流更快触发。我惯用指数退避加一点随机抖动第一次200毫秒后重试第二次400毫秒第三次800毫秒超过三次就进入降级逻辑。降级逻辑可以是返回缓存结果也可以是换一个更小的模型。4.2 成本治理从跑通不管到每一百次调用都算得过来账AI应用的成本大头是按token计费的推理。影响费用的变量有三个单次请求上下文长度、系统预置的上下文长度、请求量。所以成本优化通常集中在三个地方第一控制system prompt和历史的长度不把无关内容长期挂在上下文里第二加缓存完全相同的请求命中后直接返回第三分级模型路由利用小模型处理简单问题。举一个粗糙但直观的估算假设每天一千次请求平均每次输入2000 token、输出300 token按常见按token计价的口径折算一个月成本在小几百到一两千元的量级。这个数字不精确但能给你一个感知成本不是反正很便宜也不是贵到不能做而是必须纳入设计。缓存做得好实际支出可能减掉一半以上。流式输出这里也值得说一句它不改变token总量但能显著改善用户体验因为首字延迟降低了。调度层面用异步并发时注意控制并发度避免突发流量打爆供应商配额。4.3 可观测性日志、指标、兜底策略一起上生产环境里模型输出不稳定所以光有普通后端监控不够还要记录模型层的可观测数据。每轮请求我至少记录请求ID、模型名、输入token数、输出token数、延迟、是否命中缓存、返回的片段编号、用户端评分如果有。这样你可以随时回答三个原始问题今天调用了多少次、花了多少钱、哪类问题总是失败。出现幻觉类投诉时有了片段编号和完整日志排查会非常快而不是重新跑一次碰碰运气。上线第一天我就撞到过一个经典场景用户反馈系统好慢我查日志发现90%的耗时在解析一个超大PDF而不是模型调用。把解析结果缓存之后响应时间直接从十几秒降到几百毫秒。这种问题没有可观测数据是永远找不到答案的。5. 踩坑复盘这个项目里我交过学费的地方5.1 幻觉的真正成因往往不是模型不聪明很多人把幻觉归结为模型不够强但我在生产跟踪中看到的更多是这三个原因上下文被无关内容污染、知识在资料里但与问题对齐得不好、Prompt里的指令模棱两可。资料里同时存在两种说法时模型会给出看起来合理但错误折中的答案资料里没有答案语气稍微含糊一点模型就会扩展出去编。对策有三个层级检索端更严格提高阈值、减少无关片段生成端更明确强制不知道就说不知道系统端补一层校验把关键实体或数字与原文片段做比对。三者叠起来幻觉率能明显下降但无法到零所以重要事实必须能查到出处应该做成产品需求而不是可选项。5.2 模型越大越好是新手最容易交的学费起步时我倾向于直接调用当时最大的模型觉得聪明一点总没错。但真实系统中很多请求根本不配用大模型知识库问答里如果检索质量差再大的模型也救不回来高并发的简单分类任务大模型和中等模型的效果差距很小但延迟和费用差距明显。后来我把请求按复杂度路由简单查询、固定格式任务走小模型多跳推理、冲突消解、长文总结才走大模型。整体效果几乎没有下降费用却下降了一截。这给我一个长期观点模型能力只是系统的一部分检索、上下文管理、评估体系往往更能决定结局。5.3 复现性是个魔鬼温度、种子和随机性调Prompt的时候我发现同一个Prompt同一批参数两次输出可以有明显差异。开始我以为是bug后来才意识到这是采样行为本身。它带来一个实际问题你无法用一两次手动测试来评价Prompt改得好不好。对策是给评估请求设置较低的温度来减少随机性在对比Prompt时尽量控制采样参数保持一致并且一次对比至少运行5到10次再下结论。这一步虽然枯燥但能避免大量我觉得改得更好了的主观错觉。我后来甚至给评估脚本加上了统计输出同一组Prompt跑十次记录正确率的平均值和波动范围。5.4 个人成长层面从0到1最该护住的节奏最后说一点和代码无关的经验。我从零开始做AI工程最重要的节奏是每两周完成一个看得见的小闭环而不是每天焦虑还有多少没学。小闭环指的是一个能运行的功能、一篇简短的复盘、一个明确的下一步。这样做的好处是知识缺口会被持续暴露和补齐而不是积压到让人放弃。实操上我会给每个闭环保留一份实验记录内容包括用什么模型、切块参数多少、观察到了什么问题、下次准备改什么。后面回看时这些记录比收藏夹里上百篇教程值钱得多。当项目跑完再回头那几百条知识点根本不是从课程里学来的而是从一次次失败里长出来的。如果把这次从头搭建的经验浓缩成一句话我会说AI工程不是从模型开始的而是从你想让系统完成什么闭环开始的。模型只是这个闭环里的组件组件会过时闭环和工程习惯不会。希望这份复盘能让你少走一点我走过的弯路。

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案