很多人第一次看到ai-engineering-from-scratch这个项目名时,都会问同一个问题:AI工程从零开始,到底意味着什么?是要先把Transformer的数学推导刷一遍,还是直接把K8s、Docker、MLflow这些工具全都部署一遍?我在这个项目里把过去几年踩过的坑重新整理成了一条可执行的学习和实操路径,不是那种“收藏了等于学会了”的清单,而是每个阶段都有明确产出、可以直接照着做的工程路线。
这个项目解决的痛点是:市面上讲算法原理的资料很多,讲工具命令的也不少,但很少有一条主线能把“数据、模型、检索、部署、监控”串成一个完整的AI产品闭环。它适合正在转行的开发者、刚入门想找方向的应届生,以及想把业务中的模型真正跑成服务的后端工程师。今天我把这条路线里的核心思路、实操过程、和那些文档里不会写的坑,完整拆开聊一聊。
1. 先搞明白:AI工程到底在做什么
1.1 AI工程师不是只会训练模型的程序员
我在项目初期犯过一个很典型的错误:以为把几个主流模型的API调通、在Jupyter Notebook里跑出一个漂亮的精度数字,就算入了AI工程的门。后来真正把项目推到线上才发现,模型精度只是整个系统的一小块拼图。AI工程的核心任务,是让模型在一个真实业务环境里稳定、可度量、低成本地运转。
这里我习惯用一个盖房子的类比:模型本身相当于预制板,算法同学能生产出最高质量的预制板,但AI工程师要做的是把这块预制板放进建筑物里,接好水电、设计好承重结构、做好验收标准,还要在楼塌的时候知道从哪里开始排查。所以AI工程师既要懂模型的脾气,又要懂系统的约束,两头都得站得住。
和纯算法工程师相比,AI工程师更关注模型之外的那圈“包围层”:数据从哪来、怎么清洗、如何切分、上线后如何观测、效果变差怎么定位。和纯后端工程师相比,AI工程师又多了一层对模型推理、检索召回、提示词策略等AI特性问题的敏感度。这也是为什么很多团队里算法和工程互相甩锅,本质上是缺少一个能把两边翻译成同一套语言的人,AI工程师恰好就是那个角色。
1.2 从零开始需要掌握的五项核心能力
我把整个能力模型拆成了五个域,每个域都有明确的输入和产出。这么拆的好处是,你可以随时定位自己卡在哪一层,而不至于面对茫茫多技术名词感到失控。
| 能力域 | 入门重点 | 优先级 |
|---|---|---|
| Python与工程基础 | 函数、类、异常、虚拟环境、git、模块化 | 高 |
| 数据处理能力 | pandas、SQL、清洗、去重、结构化 | 高 |
| 机器学习与深度学习基础 | scikit-learn、PyTorch、模型评估方法 | 高 |
| 大模型应用开发 | API调用、Prompt工程、RAG、Agent基础 | 高 |
| 部署与MLOps | Docker、FastAPI、监控、版本管理、CI/CD | 中后期补上 |
这里想多说一句:很多人一上来就买一堆深度学习的课,结果连Python的虚拟环境都没搞明白,这是把顺序搞反了。工程能力的核心不是懂多少模型结构,而是能不能稳定地把一段代码变成别人能复用的服务。数据能力排在深度学习前面也是有意的,因为无论你将来做微调还是做RAG,数据质量都直接决定效果天花板。我在项目里反复强调,先练好前两项,再碰模型,你的进步速度反而会快很多。
2. 零基础的AI工程学习路线图:三个月起步,六个月上线
2.1 起步阶段:把基础补到能自己动手
我给零基础同学规划的起步期是三个月,每周大概投入10到15个小时。这个强度不算大,适合在职或者在校的人长期坚持。第一到第二周,集中攻克Python里最常用的部分,不是去背语言教科书,而是围绕真实任务去写:写一个脚本批量重命名文件,爬一个静态网页,用pandas做一个简单的数据分析报表。练到“看得懂报错、能自己搜出解法”就算过关。
第三到第四周,补SQL和数据清洗。AI工程里最耗时间的往往不是模型训练,而是数据整理。我建议你把重点放在join、group by、窗口函数,以及pandas里的缺失值处理、重复值去重、字段类型转换上。这些技能在你后续做评估集、构造训练数据、分析线上日志时都会反复用到。
第五周到第八周,进入机器学习基础。不用一上来啃深度学习,先把sklearn的线性回归、决策树、随机森林跑通,重点搞懂训练集和测试集的划分、交叉验证、过拟合的判断方法。这一段的核心不是背公式,而是建立“模型效果是可以被度量、被比较”的直觉。
第九周到第十二周,接触PyTorch。我建议只做一个小项目收尾,比如英文影评的情感二分类。别贪多,能走通“数据加载-模型定义-训练-评估-导出模型”这条链路就完成了起步目标。这个最小闭环会成为你理解后面所有AI工程的脚手架。
2.2 进阶阶段:从“会跑通”到“能上线”
起步阶段结束标志是你已经不再害怕代码报错,能用模型做简单的预测。接下来三个月,重心从“跑通单点技术”转到“组装完整产品”。
第十三周到十六周,值得投入到大模型应用开发。建议选一个主流大模型API,系统学习Prompt工程的常见模式,比如思维链、Few-shot、角色设定和输出格式约束。这一阶段的练习不要停留在聊天界面里,而是写成函数:输入一段文本,返回一份结构化的JSON结果,让模型成为你程序里一个可调用的模块。
第十七周到二十周,完成RAG(检索增强生成)的入门实现。这是我认为目前AI工程里性价比最高的练习项目,因为你需要接触文档解析、向量化、相似度检索、提示词组装、答案质量评估一整条链路。你不需要训练任何模型,但锻炼到的工程能力覆盖了AI应用开发的绝大多数日常。
第二十一周到二十四周,把之前写的RAG服务部署到真实环境。引入FastAPI做接口层、Docker做环境一致性、再加上简单的日志和错误统计。做完这一步,你就有底气把自己做的东西展示给别人用,而不是只说“我在本地跑通了”。
进阶阶段最忌讳的是不停换新框架。我在项目里特意定了一条规矩:哪怕向量库选型不是最优的,也要坚持把一个方案用到上线,再回头优化。这个习惯能帮你建立非常宝贵的全局观,否则很容易陷入工具的浅层漩涡,永远在入门。
3. 实操演练:从零搭一个RAG问答系统
3.1 为什么选择RAG作为第一个工程练习
我见过不少零基础同学第一个项目是写图像分类或者文本生成Demo,这当然也有价值,但问题在于它们太“单机”了,缺少一个真实后端服务该有的数据流和模块边界。RAG系统不一样,它几乎覆盖了AI工程全链路的关键节点,而且每个节点都相对独立,适合迭代式开发。
我们用一个具体的场景来设计:把自己的个人博客或者产品文档变成一个“内部问答助手”。用户输入问题,系统从文档库里检索相关内容,再让大模型基于检索到的上下文生成答案,并且要求它标出信息来源。这个场景足够小,但五脏俱全:有文档采集、有数据清洗、有离线索引、有在线检索、有外部模型依赖、有API服务、有评估回环。
模块划分也很自然:文档处理、离线索引、检索、生成、服务封装。每一块都能单独替换,比如今天用这个Embedding模型,明天可以换另一个;今天用向量检索,明天可以加BM25做混合检索。这种模块化的设计,就是你未来在真实项目里做技术迭代的基本盘。
3.2 文档处理与向量化:检索质量的第一步
很多人以为RAG效果不好是模型问题,其实大部分情况下是文档处理没做到位。我经历过最典型的翻车现场:直接把PDF按页转成文本塞进向量库,结果检索出来的内容全是页眉页脚。文档处理的目标,是把非结构化的原始文件,切成适合检索的“语义块”。
分块大小是第一步要确定的参数。分块太小,比如每段只有100个字符,语义会被切碎,检索时经常找不到完整答案;分块太大,比如整个章节作为一块,向量化后的向量表示会过度平均化,相似度区分度变差。我的常见做法是从512到1024个字符之间做测试,如果是技术文档这种信息密度高的,倾向于512左右;如果是产品介绍这种口语化较强的,可以放宽到768或者1024。同时设置128到256的字符重叠,避免关键句刚好被切在边界上。
Embedding模型的选择也很讲究。我当时先用了一套本地的中文向量模型,因为免费、可离线使用,隐私风险低;后来对比了一个商用API向量模型,发现有些专业术语的语义召回更好,但成本会随着数据量上升。你在练习阶段建议直接选一个稳定的开源模型跑通,不用反复横跳。向量化之后,我用FAISS建索引,因为它简单直接,适合起步;索引文件落地到本地,启动服务时加载,查询响应能在几十毫秒内返回。
3.3 检索与生成:让模型“拿证据说话”
检索模块的核心不只是“找相似”,而是“找到对回答真正有用的证据”。我用一个简单的例子来说明:用户问“这个项目支持哪些部署方式”,他查询向量化之后可能和文档里介绍架构的段落相似度很高,但真正回答问题的内容在“部署指南”这一节。如果你只取分数最高的前三块,很可能返回的都是无用内容。
所以我在项目里加了两道保障。第一道是TopK检索后加一个重排序步骤。先用向量检索召回20条候选内容,再用一个重排序模型或者基于规则的方法,结合查询和候选内容的匹配度重新打分,最终只选前5条交给大模型。实测下来,加不加重排序,答案准确率差距非常明显,尤其当文档库超过几百个切片之后。
第二道是Prompt设计。我会在系统提示词里明确规定:只能依据上下文内容回答,如果上下文里找不到答案,直接说“我不知道”,不能编造。同时要求模型在答案末尾用数字标注引用了第几条上下文,方便用户核查。这种设计能大幅降低大模型“一本正经胡说八道”的概率。
核心检索生成的代码骨架也不复杂:
from sentence_transformers import SentenceTransformer import numpy as np embedder = SentenceTransformer("BAAI/bge-m3") query_vec = embedder.encode(query, normalize_embeddings=True) scores, indices = index.search(query_vec, k=20) candidates = [chunks[i] for i in indices[0]] top_k = rerank(query, candidates)[:5] prompt = f"""请只依据下面的上下文内容回答问题。 如果上下文中找不到答案,请直接回答“我不知道”。 上下文: {chr(10).join(top_k)} 问题:{query} """ answer = llm_complete(prompt)3.4 部署上线:从Jupyter到稳定服务
本地能跑通只是第一步,要变成可用的服务还需要完成三层改造。第一层是把业务逻辑封装成函数,再暴露成HTTP接口。我当时直接用FastAPI,代码量很小:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Query(BaseModel): text: str top_k: int = 8 @app.post("/ask") def ask(q: Query): return run_pipeline(q.text, q.top_k)第二层是用Docker固定运行环境。这一步能避免“在我电脑上能跑”的经典尴尬。一个最小可用Dockerfile长这样:
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]启动命令也一并写进项目文档:
docker build -t rag-service . docker run -p 8000:8000 rag-service第三层是加上日志和错误监控。大模型API调用有超时风险,网络抖动、返回格式异常、内容审核拦截,这些都是真实世界里高频出现的问题。我在代码里给每一次调用加上了耗时统计、状态码记录,并把错误分类输出到结构化日志里。上线后你会明显感觉到,没有这些观测手段,你根本无从判断线上问题是出在检索、模型还是网络。
4. 从零到一最容易踩的坑:问题排查与避坑实录
4.1 数据清洗阶段的三个隐蔽问题
第一个坑是PDF解析乱码。很多PDF的文本层不是按正常阅读顺序存储的,直接解析会得到大量错乱字符或者表格碎片。我的建议是优先找源文档的Markdown或HTML版本,实在只有PDF时,用支持OCR的解析方案,并且把解析结果按页面做一次人工抽检,别盲目信任工具的默认输出。
第二个坑是重复内容导致检索偏置。文档里常见一种情况:同一个介绍段落在一级页面和二级页面各出现一次,索引里就有两份高相似度切片,结果任何查询都优先命中它,真正的细节内容反而被排到后面。解决方法是基于内容哈希对文档做去重,同时对语义高度一致的句子做归一化处理。
第三个坑是短文本干扰。导航栏、版权声明、“了解更多”这类无意义短句也会被向量化,它们的向量往往很偏。在过滤阶段我加了一条规则:去除字符数少于15的纯文本块,除非它们是列表项且包含信息量。这些小细节看着不起眼,但对检索准确率的影响比换一个Embedding模型还明显。
4.2 检索效果不佳时先别急着换模型
我在项目运行过程中经常收到两类反馈:“我换了一个更大的Embedding模型,效果还是不行”和“我把TopK从5调到10,结果答案反而更差了”。这类问题的根源,绝大多数时候都不在模型和参数,而在倒查链路顺序。
正确的排查顺序应该是:先看切片质量,再看召回条件,最后才动重排序和TopK。你可以把TopK先调到20,把召回的候选块直接打印出来人眼观察。如果候选块里根本没有相关内容,说明问题在文档处理或Embedding模型;如果候选块里有正确答案但被排得很靠后,才需要优化重排序。盲调TopK只会让结果更糟,因为TopK越大,喂给模型的噪音就越多。
另外我一直建议做混合检索:向量检索擅长语义相关但字面完全不同的情况,BM25关键词检索则擅长精确匹配和代码片段。把两条路线的结果合并后再去重和重排,能覆盖绝大多数真实查询场景。这是我从一个真实项目里学到的经验,只靠向量检索时,用户问一个文档中完全没有同义词的简短缩写,返回结果基本是废的。
4.3 上线之后的性能与资源陷阱
部署上线后第一波性能问题往往出在并发上。如果你用普通同步接口调用大模型API,一个请求阻塞过程中,后续请求全部排队,用户体验就是“转圈圈”。我后来把管道里耗时较长的模型调用改成异步,并且加入了简单的请求级缓存:相同问题的答案在十分钟内直接复用,命中率在线上一度超过三成,响应速度提升非常明显。
第二个是资源预估问题。本地Embedding模型虽然推理很快,但扛不住高并发,尤其是在CPU机器上,多路并发的推理延迟会被放大好几倍。如果你的场景查询量不大,用API向量化更省心;如果查询量高,就一定要把向量化服务独立部署,单独扩容,别和主业务服务抢资源。
第三个是慢索引拖垮发布流程。最开始我在服务启动时自动重建向量索引,数据一多,每次发布都要重新跑一遍,既容易失败又浪费时间。后来我改成离线构建索引、产物存到对象存储、服务启动时读取最新索引文件。这套“离线构建、在线读取”的模式,是几乎所有AI应用上生产环境的必经之路。
4.4 评估缺失带来的失控局面
最隐蔽也最危险的问题,是没有评估集就开始优化。我见过一个团队凭用户反馈反复修改Prompt,改了几十版也没建立一条量化衡量标准,最后既说不清效果变好还是变坏,也无法解释为什么某些老用户问题突然回答异常。我在项目里很早就建立了一个包含50条真实问题的回归评估集。
每一条问题都预先标注了期望答案和回答该问题的文档来源。每次调整Prompt、更换Embedding模型或者修改分块策略,我都会跑一遍这个评估集,记录“完全正确、部分正确、错误、拒绝回答”四类结果的比例。平时可能看不出什么,但当你纠结“方案A到底比方案B好多少”的时候,这份数据能直接拍板。
我还建议把你调参的每一项改动都记录在项目笔记里,包括改动原因、改动内容、评估结果。我在项目里为这个动作专门建了一个表格,后来复盘时发现,很多当初觉得“效果变好了”的改动,其实只是随机波动。有了记录和评估,你的每次迭代都会变得可解释、可回滚,这是从“能跑”到“会维护”的分水岭。
5. 我个人实操后的一些建议
这套路线我带过几轮人走下来,最大的体会是:AI工程里真正拉开差距的,不是模型知识量,而是对全链路的掌控感和排查问题的效率。你能不能让一个答案从用户提问到生成回复稳定地走完整个管道,并且出了问题能在半小时内定位到具体环节,这才是工程能力的本质。
最后分享一个我一直在用的小技巧:每次完成一个阶段的练习,都尝试把代码重新整理成“一键可复现”的状态。也就是别人拿到你的项目,只要按文档执行两条命令就能把服务跑起来。这个动作会逼你把环境依赖、启动脚本、数据准备这些容易偷懒的部分补齐,也让你未来的自己不至于对着三个月前的代码抓狂。AI工程这条路很长,但每完成一个能上线的项目,你对它的掌控感就会多一分,这种积累是任何人都拿不走的。