AI工程从零到生产:构建可维护、可迭代的机器学习系统
我一直觉得,喊着“要学AI”的人不少,但真正能说自己“会做AI工程”的人不多。这两年我带过不少新人,也看过很多自学路径,发现大多数人从第一天就拐进了岔路:要么一头扎进数学公式里,三个月后还在推导梯度;要么直接找现成的代码库跑一遍,发现换个场景就完全失效。
这个项目“ai-engineering-from-scratch”之所以让我特别有动力去整理,恰恰是因为它没有走上面任何一条路。它把AI当成一门正经的工程学科来对待——先搞清楚要解决什么问题,再选择合适的技术方案,最后让系统稳定、可维护、可迭代地跑在生产环境里。这篇内容会把我从零开始搭建AI工程能力的心得、踩过的坑,以及一套能直接复用的实操路径完整地分享出来。无论是刚入行的开发者,还是已经被业务逼着“必须上AI”的工程师,这篇应该都能帮你少走很多弯路。
1. 学AI工程,第一件事不是跑模型,而是搞清楚“工程”两个字
1.1 为什么入门者会卡在同一个地方
我问过很多想转AI方向的工程师同一个问题:你第一次跑通一个模型花了多久?答案通常是一两天。但接着问——你花多久把这个模型稳定地用在一个真实场景里?答案就五花八门了,从“两周”到“还没做到”的都有。
卡住他们的从来不是算法的理解,而是那些算法之外的环节。数据从哪来、怎么清洗、标注质量怎么把控、训练一个模型要多少算力、模型上线之后准确率会不会往下掉、掉了我怎么知道、知道了怎么回滚、怎么快速更新——这一连串问题,才是AI工程从零到一真正要解决的东西。
如果把做AI比作做饭,算法教程教的是“怎么炒这盘菜”。而AI工程解决的是“怎么开一家能稳定出菜的餐厅”:要考虑供应链、菜品标准、厨房动线、出餐速度、顾客反馈,甚至厨师临时请假时谁来替补。这套系统性的思维,恰恰是零散的教程给不了你的。
1.2 从零开始不等于从公式开始:先画出完整的链路
我见过最高效的学习方式,不是先啃三本书再动手,而是先给自己画一张完整的技术链路图。不需要理解每一个细节,但必须知道一个AI系统从无到有需要经过哪些环节。
一条完整的链路大概长这样:业务问题定义 → 数据获取与清洗 → 特征工程或数据标注 → 模型选型与训练 → 离线评估 → 部署上线 → 线上监控与反馈 → 模型迭代更新。
这个链路里,真正涉及“算法”的部分其实只占一小段。数据环节看的是工程能力和业务理解,部署和监控看的是后端功底,迭代更新看的是流程设计。任何一环掉链子,整个系统都跑不起来。
所以从零开始的第一步,不是“把梯度下降推导一遍”,而是“把一条链路完整走通一遍”。用什么工具、手写还是调库都不重要,关键是自己亲手把每一个环节摸一遍,知道哪里痛、哪里容易出错、哪里藏着隐性成本。
1.3 AI工程与算法研究的分界线
初学者最容易混淆的一个概念,就是把“AI工程”和“算法研究”混为一谈。它们的工作目标、评判标准、做事方式都有本质区别。
算法研究的目标是突破已知边界,追求在公开数据集上刷新纪录,或者提出前人没想过的方法。而AI工程的目标是稳定、可控、高效地解决真实业务问题。这意味着在工程实践里,“最新最好的模型”往往不是最优解,反而是那些成熟、稳定、社区完善、踩坑少的方案更受青睐。
举个实际的例子:几年前某个场景下,换上当时号称更先进的模型架构后,离线指标确实涨了两个点,但线上服务响应时间从80毫秒飙到300毫秒,同时推理成本翻了四倍。最后整个方案被叫停,换回了原来的方案,业务一点没受影响。这就是典型的研究视角和工程视角的差别——工程关心的不是“能不能更强”,而是“整体系统能不能更稳、更省、更好维护”。
2. 打地基:先把这四块技能铺到位
2.1 工具链:哪怕是“不写代码”也要有工程武器
说自己做AI工程,但连最基本的开发环境都搭不顺,那后面每一步都会很难受。这里说的工具链不是某个具体框架,而是一整套写代码、管数据、跑实验、看结果的能力。
第一步是环境管理。建议从第一天就养成用虚拟环境隔离项目依赖的习惯,把项目依赖锁在版本级,避免“在我电脑上是好的”这种经典尴尬。第二步是版本控制,写代码的每一个阶段性成果都要有记录,这样模型跑出好结果时,你能确切知道自己改了什么。第三步是学会用脚本管理机器学习任务的“训练—评估—记录”循环,别让手动操作成为常态。
还有一个常被低估的工具是命令行。很多AI相关的工具链在命令行下的优雅程度远胜图形界面,学会基础的组合操作、批处理、日志查看,能让你在排查问题时快上不少。
2.2 数据能力决定了模型的上限
在实际工程里,数据对模型效果的影响常常大于模型本身。这句话听起来像套话,但真做起来你才会懂它的分量。
准备数据时有几个基本功:
- 做数据探查之前先想清楚业务定义。比如“垃圾评论”的定义是什么?“重复内容”的定义是什么?没有清晰定义,标注出来的数据就是各标各的。
- 清洗数据要保留完整的操作记录。哪个字段因为什么规则被删掉了,样本量从多少变到了多少,每一步都要有记录。这样后续发现效果不对时,能反向追踪是不是数据出了偏差。
- 数据划分要小心“数据泄露”。很多新手会把全量数据直接打乱后划分测试集,但如果同一个用户的多条行为记录分散在训练集和测试集里,评估结果就会虚高,因为模型相当于“见过”测试用户了。
我曾经因为时间排序没处理好,把一个时间序列问题硬做成随机划分,离线指标漂亮得吓人,线上效果却惨不忍睹。后来才意识到训练集里包含了未来信息,评估完全失真。这种问题,没有足够的工程意识是发现不了的。
2.3 机器学习的核心“手感”:不是调参,是误差分析
很多自学的人把精力花在“调参”上:学习率、层数、Batch size,来回试,仿佛找到一组神奇参数就能拯救一切。
但真正做工程的老手,投入最多时间的其实是误差分析。模型预测错了,你先别急着调参——先挑一批错误的样本,逐条去看模型为什么错。是因为训练数据里这一类样本太少?是因为样本本身的标注就有问题?还是因为特征里缺少了关键的区分信息?
误差分析的意义,是让你从“盲目调参”转向“有方向的迭代”。我记得有一次做文本分类模型,离线AUC一直在0.93左右卡着上不去。逐条看错误样本后,发现大量错分样本都集中在“短文本”类别——一句话里只有两三个关键词,确实非常容易被误判。找到这个规律后,我给这类样本单独做了数据增强,离线指标直接跳到0.96,线上效果也跟着涨了。如果当初一上来就埋头调参,恐怕调一个月也未必能想到这个方向。
2.4 传统软件工程是AI工程的地基
这一条听起来有点反直觉,但恰恰是我最想强调的。很多AI项目失败,不是死在“模型效果不好”,而是死在“代码烂得没法迭代”。
模型训练和业务代码不同,它充满了实验性质,很容易被写成“一本糊涂账”:实验参数写死在代码里、数据预处理逻辑散落在各处、实验结果只存在于终端输出里、跑过的脚本一改就再也没法复现。
解决这个问题不需要什么高深技巧,把传统软件工程的基本功搬过来就行:
- 把训练流程拆成边界清晰的函数或模块:加载数据、特征处理、模型定义、训练循环、评估逻辑各管各的事。
- 为每个实验记录一组可复现的配置:数据集版本、特征版本、模型结构、超参数、随机种子,缺一不可。
- 把评估结果序列化保存,方便跨实验比较,而不是靠脑子记“上次好像跑得不错”。
- 隔一段时间回头看看自己一两个月前写的代码,如果连自己都看不懂,说明抽象还不够。
这些习惯一开始做会觉得麻烦,但越到后面你越会发现,它们才是让模型效果可持续提升的真正发动机。机器学习模型的迭代速度,很大程度上取决于你重构和复现一次实验的速度。
3. 一条从零开始的主线:从内置实现到亲手搭建
3.1 前期阶段:别自己造轮子
刚开始接触AI工程时,最容易犯的一个错误是“过度造轮子”:什么都想自己从头写一遍,觉得这样才能学得透彻。
但“从零开始”不等于“从零制造”。我见过有人为了给数据集做个归一化,硬是手写了全套实现,结果在高维稀疏特征上出了问题,调了一晚上没解决。其实专业的工具库处理这类场景非常成熟,而且经过了大规模工业实践的检验。你的时间应该花在“理解它的工作原理”和“学会正确调用”上,而不是重复制造已有的轮子。
前期阶段要做的是:选择一套主流的、社区活跃的技术栈,把基本操作练熟。能调用成熟的工具解决问题,本身就是工程能力的一部分。等到你真正理解了底层的逻辑,再去考虑“自己实现一个”,那时候的造轮子才是有价值的——因为它不再是重复劳动,而是为了满足某些特定场景的定制需求。
3.2 中期阶段:把业务问题翻译成建模问题
掌握工具之后,接下来的关键一步是把业务问题翻译成一个可求解的建模问题。这一步听起来简单,实际做起来却需要大量经验。
比如业务方说“我们希望识别出用户的不满情绪”。这个需求翻译成分类问题后,要想想标签怎么定义——“不满”和“中立”、“不满”和“生气”的边界在哪?这直接决定标注标准的写法。再比如“我们希望预测用户的转化概率”,那正样本怎么定义?是“点击了购买按钮”就算,还是“完成了支付流程”才算?定义不同,模型学到的完全不是一个东西。
这一步我特别想强调一个词:“反馈闭环”。建模问题定义得好不好,最终要看它能不能指导业务决策。有些团队把模型预测分数做得非常精细,但业务方根本不知道怎么用这个分数来采取行动,模型做得再漂亮也是白搭。好的问题定义,应该是在建模之前就已经想好了“预测结果出来之后,我们要针对不同分数段做什么动作”。
3.3 后期阶段:写一次可复现、可维护的代码
从零开始搭建AI工程,到后期阶段,你的关注点要从“能不能跑通”转向“能不能复现”和“能不能维护”。
“可复现”意味着三个月后,给你同样的数据和相同的配置,你能跑出完全一样的结果。这需要你把随机种子固定、依赖库版本锁定、数据版本和代码版本绑定。“可维护”意味着新接手的同事能通过阅读你的代码和文档,理解一个模型的训练过程并顺利开始改进它——而不是只能打电话问你。
这里我给大家推荐一个习惯:每次跑实验的时候,把模型结构、预处理参数、训练参数和评估结果像“实验报告”一样记录下来。这份记录不一定要非常正式,一个结构化文本文件就够了。重要的是保证“结果可回查、参数可对比、过程可追溯”。
做好这一步,你的AI工程能力才算真正从“能用”进阶到“好用”。
4. 一个可复盘的实战:文本分类任务的完整推进
4.1 任务定义和数据准备
理论说得再多,不如完整拆解一个实际项目。我选一个最常见也最适合入门的场景:文本分类任务。整个推进流程我会按一个真实AI工程项目的标准来展开,而不是按教程里那种“加载数据集—跑模型—出结果”的理想化流程。
第一步是明确分类目标和操作定义。假设业务需求是“识别工单内容属于哪个问题类别”。那么最开始需要拉业务方一起确定类别体系:一共分几类?每个类别的判定标准是什么?如果一个工单同时属于两类,该怎么处理?这些问题不锁定,标注质量和模型效果就无从谈起。
第二步是收集和探查数据。需要摸清历史工单的存量规模、各类别分布情况、有没有明显的数据稀疏类别、有没有大量重复样本。这一步我习惯用一些直观的小工具做可视化,看一眼分布心里就有底了。
第三步是制定标注规范并小规模试标。先挑一两百条样本,让两个标注者分别按规则打标,然后对比一致率。如果一致率低于90%,说明标注规则还有歧义,直接返工优化规则,比后期发现标注质量问题再清洗要省钱得多。
4.2 从简单基线到改进模型
数据准备就绪后,我不会急着上重型模型,而是先建立一个“简单基线”。最简基线可以是基于词频统计的方法,甚至是“全都预测样本量最大的类别”这种傻瓜方案。基线不需要多聪明,它的价值在于提供一个对比锚点,让你后续每一步的改进都能量化出增量。
我用过的最简基线是用词频加权重做的,跑完一看,准确率大概在82%左右。这个数字看起来不算差,但它暴露了一个问题,预测结果高度偏向高频类别,少数类基本全军覆没。于是我把改进方向锁定在“如何提升少数类的召回率”上,而不是盲目追求整体的准确率。
接下来才进入模型迭代阶段。考虑到部署成本和响应速度,我选择的是轻量级的预训练模型做微调。微调的过程里,一个关键技巧是分阶段调优,先用较小的学习率跑几个Epoch看看收敛趋势,再根据验证集的表现决定学习率衰减策略;同时注意控制训练轮数,避免在小数据集上过拟合。
这一阶段最大的收获,往往是发现“更多的数据比更好的模型更有效”。我在迭代过程中发现,模型在某个特定类别上一直有系统性错分,补充了两三百条该类别的样本后,这一类的F1直接提升了7个百分点。这个经验也成了我在后续所有项目里的一个默认前提:先看数据,再看模型。
4.3 结果评估与错误分析
评估阶段不能只看一个综合指标。除了整体准确率,还应该看每个类别的精确率、召回率、F1,以及混淆矩阵。混淆矩阵能暴露很多系统性问题:模型是不是把A类和B类搞混?如果是,那通常是这两个类别的定义边界模糊,或者训练样本的特征高度相似。
我在这个文本分类项目里就发现了A类和B类的严重混淆。打开错误样本一看,很多A类工单里写着“无法登录”“收不到验证码”之类的关键词,而B类完全是另一个问题领域。这种错分说明我的预处理或标注规则有漏洞,而不是模型本身不行。调整标注规则、重新清洗数据之后,这两类的区分度明显改善。
还有一个评估细节容易被忽略:测试集的构建方式。最理想的方式是模拟线上真实的时间分布来划分数据。如果线上跑的是最近半年的新工单,完全没理由拿两年前的数据来评估当前模型的表现。“用和线上相符的数据做测试”是一条评估铁律。
4.4 上线前的小规模验证
模型的离线指标达到预期之后,别急着全套上线。我比较推荐“影子模式”和“小流量灰度”两个阶段。
“影子模式”是指模型和现有系统并行运行,但模型预测结果不外显、不影响业务,只是被记录下来。这个阶段的目标是收集模型的“真实环境输出”和“真实用户反馈”,同时验证模型在线上数据上的表现是否和离线评估一致。很多模型在离线评估时表现很好,一上线上就露馅,就是因为线上数据分布和离线数据分布存在偏差。
“小流量灰度”则是先把模型切到1%到5%的真实流量上,跑一段时间观察核心业务指标,确认无异常后再逐步放大流量。这里有个很重要的建议:灰度期间一定要有明确的“回滚预案”和“观察指标”。如果事先没定义好“什么情况算异常”,出了问题只能手忙脚乱甚至造成线上故障。
5. 工程化落地:让模型在真实环境里稳定运行
5.1 模型上线前后的思维转变
模型上线是AI工程和算法实验之间最明显的一道分水岭。它意味着你的模型从一个“有趣的项目”变成了一个“需要负责的系统”,而你作为工程师的关注点,也随之从“提高分数”变成“保障可用”。
上线后首先要关注的是模型服务的性能和稳定性。模型推理的延迟、吞吐量、并发能力,这些指标直接决定了用户体验。如果一个模型质量很高但跑一次要几百毫秒甚至几秒,很多实时业务场景压根扛不住。因此经常需要在模型质量和推理性能之间做权衡,比如模型压缩、蒸馏、量化,都是在性能受限的场景下保住大部分效果的常用手段。
第二个要关注的是依赖管理。模型依赖的算法库版本、基础环境、硬件驱动,任何一个升级都可能影响线上效果。我见过不少团队因为一次库的升级,模型输出突然多了个偏差,排查了大半天才找到原因。养成“锁版本”的习惯,比事后排查要省太多心力。
5.2 监控与数据漂移
监控能发现你“不知道出了问题”的问题。对于一个已经上线的AI系统来说,最重要的两类监控是“模型性能监控”和“数据分布监控”。
模型性能监控的前提是你得能拿到真实标注或结果反馈。比如推荐模型的点击率、风控模型的拦截量、文本模型的后台人工修正率——这些反馈可以相对较低频地获取,但必须定期拉取对比,看模型效果有没有随时间下滑。
数据分布监控则更前置。它盯着输入特征的分布,比如某个特征在某个时间段的平均值、方差、缺失率有没有明显变化。数据漂移很隐蔽,可能不是一下子爆发的,而是缓慢漂移,等到模型质量肉眼可见地变差时,其实早就漂移很久了。因此,用一套周期性任务自动计算分布指标、设置告警阈值,是非常有必要的工程投入。
5.3 迭代机制与版本管理
最后一个让模型长期保持生命力的关键,是建立一套可持续的迭代机制。这里说的“迭代”不只是重新训练,而是整个循环:发现问题 → 收集新数据 → 更新标注 → 重新训练 → 离线评估 → 灰度上线 → 验证效果。
为了支撑这个循环,模型和数据的版本管理必不可少。每一版模型要有唯一的版本号,并且要能追溯到它对应的训练数据集、特征工程代码和训练参数。上线后一旦线上效果异常,能快速定位是哪一轮迭代引入的问题,并回滚到上一个稳定版本。
这套机制听起来是常规操作,但真正坚持做下来的团队并不多。很多团队“有空了才做模型迭代”,结果模型半年没更新,线上数据已经漂得面目全非。AI系统不是一个“上线就结束”的项目,它是一个持续运营的服务。给它配上一套顺手的迭代工具链,你后期的维护成本会直线下降。
6. 我踩过的一些坑,以及最后想说的话
6.1 第一个坑:照着教程跑通了,换了自己的数据就废
这是入门阶段最普遍的坑。教程里的数据集已经迭代到任何模型都能跑出高分,核心问题都提前被清洗干净了。一换到自己的业务数据,各种脏数据直接教你做人。
踩过这个坑后我彻底想明白了一个道理:任何教程的核心价值都不在于“它跑出来的那个漂亮结果”,而在于“它的初始数据处理流程”。所以我现在看任何开源项目或教程,第一件事是看它的数据清洗和预处理部分,看它设计了哪些规则、做了什么检查。这部分才是工程经验的精华。
6.2 第二个坑:把离线指标当成了线上效果
相信每个做AI工程的人都经历过这种沮丧:离线评估明明跑得很好,一上线效果就垮掉。原因几乎总是数据分布不一致——要么样本选择有偏,要么时间窗口不对,要么特征在线上获取不到同样的值。
这个坑的教训是:离线评估只能告诉你模型“在你看过的数据上”的表现,永远不能直接代表线上。想降低这种偏差,就要在设计评估集时尽量贴近线上的真实形态、模拟线上的特征获取方式,并在上线初期多用影子模式和灰度来获取反馈。
6.3 第三个坑:追求模型复杂度,而不是业务的确定性
做技术的人天然容易被“新模型、炫技术”吸引,但如果业务只需要一个简单的规则或者一个浅层模型就能解决,你花大力气上的深度学习模型反而是坏事——它让系统变得更难维护、更难排查。
我现在做技术选型的原则是:先想清业务的确定性需求,再反推技术方案。如果规则的准确率已经够用、人工成本可控,那就踏踏实实用规则;如果规则解决不了,再考虑机器学习;如果简单模型已经能满足性能瓶颈,就别盲目堆大模型。技术的价值在于高效解决问题,不在于“用得多高级”。
6.4 最后想说的话
做AI工程这几年,我最大的体会是:这个领域的护城河不是你会用某个模型框架,而是你面对一个模糊的业务问题时,能拆解它、定义它、用数据度量它,并最终用一套系统化方案稳定地解决它。这条路没有捷径,最好的走法就是动手做,把前面这整个链路自己走通一遍。踩过的坑、补过的数据、优化的每一次迭代,最后都会变成你真正的核心竞争力。