1. 先拆标题:AI工程不是“学会调接口”
打开你的浏览器收藏夹,数一数有多少个AI学习资源静静躺在里面,再也没有被打开过。这几年我一直在做AI工程方向的落地实践,也带过不少半路转行的新人,发现大家缺的往往不是资料数量,而是一个能从上到下把知识串成系统的框架。第一次看到“ai-engineering-from-scratch”这个标题时,我就觉得它把三个关键词放得很准:ai、engineering、from scratch。这不是又一个“三天速成AI课程”式的标题,它真正想表达的是:从零开始,把AI做成一门可以被稳定交付、持续迭代、经得起线上检验的工程。这篇复盘我会沿着这个思路,把从零起步做AI工程需要的知识体系、必须亲手完成的项目,以及那些只有踩过坑才会明白的经验,完整梳理一遍。适合正在转行做AI从业者、独立开发者,以及想在企业里把AI能力落到产品里的技术负责人。
1.1 从AI研究到AI工程:为什么Demo一到线上就崩
先说一个每个做过AI落地的人都会遇到的场景:文本分类模型在验证集上准确率92%,信心满满上线后,第一周线上效果直接掉到70%出头。这类事情太常见,以至于很多团队现在听到“AI项目”第一反应不是兴奋,而是PTSD。原因不外乎几种:训练数据分布和线上真实数据分布不一致;单机同步的notebook调用换到高并发接口后延迟和稳定性全都失控;模型或提示词被某个人偷偷改了一版,又没有回归机制,结果某一个模块的调整把整条链路带崩。
研究是探索能力的边界,开发是让某个功能跑通,而工程是在真实约束下稳定复现效果。一个AI系统的demo和产品之间,隔着数据治理、评测闭环、部署监控、成本控制、异常兜底这些大量“看不见的活”。这也是“ai-engineering-from-scratch”这个标题最想强调的一点:工程不是调个API、套个框架就结束,而是要把整条链路变成可重复、可观测、可改进的体系。
1.2 “From Scratch”的工程含义:不是从零手写论文,是从零建立判断力
很多人看到from scratch第一反应是“那我得从数学开始学,从手写Transformer开始”,然后直接被吓退。实际上,这里的“从零开始”更像是在说:你要真正理解你正在用的每个环节,而不是把框架当成黑盒。我常用开车和修车来打比方:会开车的人能把车开走,但AI工程要求你至少具备在路上做紧急排查的能力。比如你用某个RAG框架搭了一个知识库问答系统,它突然开始答非所问,这时候你得能定位到底是文档切分的问题、召回排序的问题、还是生成环节的Prompt约束不够,而不是把整个链路删了重来。
所以from scratch的落地方式是:关键环节至少亲手实现一遍最小版本。手写一个逻辑回归,感受损失函数收敛的曲线;手写一个极小的GPT,观察训练集和验证集的损失差;手写一个最朴素的检索器,再一点一点加上向量召回和重排。这个过程不需要做到生产级别,但它会给你后续排查问题的直觉。没有这层直觉的人,遇到问题只能靠试,有这层直觉的人,遇到问题能直接判断方向。
1.3 这条路径会影响哪些角色和场景
“AI工程化”这四个字在不同人眼里的分量完全不同。半路转行的开发者想要的是从“会用AI工具”进阶到“能开发AI产品”;企业内部的AI平台团队需要把模型能力变成可供多个业务方复用的服务;独立开发者需要知道如何把一个会调API的手艺活,变成能稳定提供价值的AI应用;技术负责人则更关心AI项目的ROI、风险边界和质量抓手。这几类人读进来,应该都能从“ai-engineering-from-scratch”这种从零构建系统的视角里拿到自己缺的那块拼图。需要提醒的是,不管角色是什么,如果你想跳过的步骤总会绕回来找你。跳过评测,线上效果崩的时候会回来找你;跳过数据治理,模型越训越偏的时候会回来找你;跳过安全过滤,真正出事的时候你连反应时间都没有。
2. 从零开始的核心知识地图:五块地基一块都不能少
我见过太多人把AI入门变成了一场旷日持久的知识囤积:线性代数从头啃到尾,概率论做完一整本习题,深度学习花三个月看网课,然后发现一旦要动手做一个真实产品,还是不知道从哪里下手。根据我的经验,正确的策略不是“学完再干”,而是“边干边学”,按最小闭环来选知识集合。下面这五块地基,每块我都列了最小够用范围、掌握标准、以及一个能检验自己是否真正理解的小项目。
2.1 数学与机器学习基础:够用比精通重要
先说数学。绝大多数AI工程问题需要的不是数学家的深度,而是判断力和排查能力:看到损失曲线不下降能想到是梯度问题还是数据问题,看到某个embedding距离异常能想到空间分布的含义。最小够用集合包括:向量与矩阵乘法的几何直觉、范数的作用、特征值和SVD在降维里的意义;条件概率、贝叶斯公式和极大似然;梯度下降和反向传播的基本思路;MSE、交叉熵、KL散度这几个常见损失函数。
入门阶段最容易犯的错是想一次学完“完整”的数学体系。真没必要,AI工程用得最频繁的其实是线性代数和概率统计里很基础的部分。抽象的数学概念一定要配合代码去理解。用numpy手写一个逻辑回归,在公开的二分类数据集上训练,观察损失值随迭代次数的变化,直到准确率能到85%以上。这个过程比做一百道习题都管用,因为你能真正看到数学公式在一个可运行的模型里是怎样工作的。
2.2 编程与工程基础设施:让代码可以被重跑
AI工程师首先得是一个合格的软件工程师。Python基础至少要到能熟练使用函数、类、异常、装饰器、生成器的程度,虚拟环境和依赖管理也必须形成肌肉记忆。其次是Git工作流:分支、提交、回滚、代码评审。这些听着不性感,但AI实验的复现性完全依赖这种基础功底。很多时候不是模型跑不出来,而是环境装不上了;不是效果变差了,是某个依赖版本被悄悄升级了。
我对实验管理的最低要求是“config加seed加数据版本加指标记录”。不一定要上MLflow、WandB这类重型工具,但至少要形成固定习惯:每个实验一个目录,记录模型参数、数据版本、运行结果。我自己一直坚持用类似“exp_20250220_lr3e5”的目录命名方式,并写一个简短的README记录实验想法。这样做最大的好处是:三个月后你还能精确知道某个效果是怎么来的。检验标准很简单:把你的逻辑回归实验完整存进Git仓库,让一个完全不了解项目的人照着README跑通,就算过关。
2.3 数据分析与数据工程:AI系统真正的胃和肠道
凡是做过真实项目的人都会承认,AI系统里最花时间的不是调模型,而是处理数据。公开数据集的典型状态是:带HTML标签、有重复段落、混入广告水印、各种奇怪编码、标签规则不一致。我处理文本数据的第一步永远是做净化:统一换行、去重、清洗无效符号,然后记录清洗前后的数据量变化。
数据切分也有讲究。九十条培训小技巧里经常写“8:1:1随机切分”,但真实项目里更推荐按时间或按文档切分,否则随机切分会把同一篇文档的内容同时分进训练集和验证集,造成数据泄漏,最后验证集指标漂亮得虚假。类别不平衡时,准确率这个指标会骗人,需要改用F1、AUC这类对少数类更敏感的指标,并考虑重采样或类别权重。最后一定要写数据卡,把数据集来源、字段定义、采集方式、清洗规则、已知偏差记录清楚。数据卡看起来是文档工作,但它能拦住后续一大半的“为什么模型行为这么怪”问题。
2.4 深度学习与Transformer核心:建立规模与表现的直觉
训练模型这件事,本质上就是三板斧:数据、损失函数、优化器。数据决定了模型学的上限,损失函数决定了优化方向,优化器里的学习率则决定了模型能不能有效收敛。学习率太大,训练直接发散;太小,收敛慢到怀疑人生。一般我试模型时会把学习率按数量级去探一遍:从1e-4这样的小步长开始,往1e-3方向试探,观察loss曲线的变化,找到“下降最快且稳定”的区域。
Transformer的最小理解版本其实没有传说中那么难:注意力机制本质上就是一个可学习的加权平均,多头注意力是让不同头去关注不同的关系维度,位置编码是给序列里的每个词打上顺序标签。干理解容易困,边做边学就不会。建议用一个小型语料训练一个极小的GPT——三层以内、embedding维度在128到256之间。观察训练loss和验证loss之间的差距什么时候开始拉大,然后尝试改一改学习率、数据增强或者模型规模,看指标怎么变。这一步等于把深度学习最核心的“训练—过拟合—改进”闭环亲手走了一遍。
2.5 产品化与部署运维:从Notebook到API服务
模型在Notebook里能跑是一回事,能成为服务被用户调用是另一回事。产品化这块的核心工作包括:把模型推理封装成稳定函数,用FastAPI这样的框架提供HTTP接口,加上请求日志、异常处理和超时控制,用Docker固定运行环境,再给接口加限流和缓存。线上一定要监控三样东西:推理延迟、错误率、资源消耗。在大模型应用里还得额外盯token消耗,否则月底账单会吓你一跳。
另一个关键认知是区分离线评测和线上观察。离线评测是你在固定评估集上验证效果,线上观察是真实用户和真实数据带来的反馈。两者出现差距是常态,不是意外。检验标准是:把你的文本分类器包成一个FastAPI接口,用curl实际调用一次,把服务容器化,再写一个简单监控脚本。走完这一圈,你才真正从“做模型”切换到“做系统”。
3. 五步实战:从零构建一个知识库问答系统
为了不把上面的框架讲成空话,我用一个贯穿式项目来演示从零到一的完整链路:本地知识库问答系统。这个项目足够小,不需要GPU也能跑;又足够完整,数据、检索、生成、评测、部署全都有。它就是“ai-engineering-from-scratch”的一个浓缩实践。
3.1 定题与数据准备:先定评估集再写代码
第一步不是急着装模型,而是先定义“什么叫做好”。选一个你熟悉的文档集,比如几十篇行业报告或者你自己的技术笔记,然后花半天时间整理出50到100个问答对,每个问题标注标准答案所引用的段落。这就是你的Golden Set,后续所有实验的锚。
数据清洗这一步不能省:统一换行、去空白、去多余链接标签。对超长文档再按语义边界切块。切块参数用chunk_size=512字符、overlap=64字符起步,然后做一个消融实验,比较不同切分参数下的召回命中率。切块太大,单块信息太杂,检索噪音高;切块太小,上下文被截断,答案不完整。没有这个调参过程的RAG系统,后续效果不会好到哪里去。
3.2 基线再基线:从BM25到混合检索
很多人上来就跳过检索直接调大模型,这是RAG项目里最常见的失败模式。正确顺序是先把检索做扎实。第一个基线用BM25关键词检索,把用户问题和文档块做词频匹配,返回最相关的若干个块,然后看“正确答案所在块是否进入返回结果”。别小看这个朴素算法,在垂直领域知识库里它经常能到60%以上的命中率,而且能快速验证你的文档切分结构是否合理。
第二个基线加向量检索:用embedding模型把问题和文档块都转成向量,做余弦相似度召回。小规模知识库用几百MB的embedding模型就够,维度在384到1536之间都有不错表现。第三步做混合检索:BM25和向量召回的结果用RRF或加权方式合并,取top 10到20,再用一个重排模型把候选段落精排到top 5。这一套组合下来,检索质量会有一个非常明显的跃升,最后的生成质量自然水涨船高。
3.3 生成环节:把检索到的资料组织成可靠回答
检索端稳定之后,生成端只需要做一件事:严格约束模型只能依据给定资料回答。Prompt结构我一般包含四块:角色边界、检索段落、用户问题、输出要求。具体会写“只基于以上资料回答;如果资料中没有相关信息,请明确回答‘资料中未找到’”。温度设置在0.1到0.3之间,保证事实性优先。
还要做引用溯源。把送入模型的段落标成[1][2][3],要求回答里必须像“根据资料[1]”这样引用来源。这不仅是用户体验问题,更是后期审计和质检的基础。没有引用的RAG回答,出了问题你都不知道是哪儿来的,有了引用你才能追溯每一次错误对应的数据源头。
3.4 评测与回归闭环:让每一次改动都可对比
评测集是AI工程里最重要的资产。每次改动Prompt或检索逻辑,我都会先在同一个Golden Set上跑一遍,记录三类指标:检索命中率(正确答案来源是否进入前列)、回答正确率(语义是否一致)、忠实度(是否出现资料里没有的信息)。这三个指标各有侧重,缺一不可。
在评测方式上可以采用人工加LLM-as-judge结合。大模型当裁判虽然高效,但本身也有偏差,所以至少每周要抽取一定比例的结果做人工复核。同时把Prompt像代码一样管理起来:版本化、变更记录、回归测试。很多人把Prompt Engineering理解为“措辞玄学”,其实它是“面向语言模型的需求工程”,核心恰恰是评测和回归。
3.5 部署与监控:灰度发布,给系统留后路
评测通过后,用FastAPI把RAG管线打包成接口。接口层要加的东西包括:请求ID用于追踪、每次调用的耗时日志、后端异常重试、超时熔断。对用户输入还要做长度限制和频率限制,防止恶意调用把token账单打到爆。发布时不要一把梭,灰度一批用户,观察错误率和用户反馈再全量放开。
每天从线上日志里抽样一些真实问题,回填到Golden Set里。这样你的评测集会越来越接近线上真实分布,离线效果和线上效果的差距也会越来越小。整个项目走完,你手里留下的不只是一个问答机器人,而是一套完整且可持续迭代的AI系统。
4. 常见问题与排查技巧实录
做AI工程和做普通软件最大的不同是:普通软件的故障通常有明确的异常栈,AI系统的故障往往是一个“效果变差”的模糊信号。这里把我踩过和带人时常遇到的坑整理成一张速查表,再展开讲两个最典型的排查过程。
| 现象 | 可能原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| 离线效果好,线上效果差 | 数据分布漂移、query表达差异 | 抽样线上日志重建评测集 | 定期用线上样本微调模型,冷却高频query |
| RAG回答偏离资料 | 检索不相关、生成幻觉 | 把生成替换成“直接返回原文最相似段落” | 引入重排、引用约束、拒绝回答逻辑 |
| 高并发后延迟飙升 | 同步调用阻塞、连接池耗尽 | 压测并观测调用链耗时 | 异步化、连接池、批处理、结果缓存 |
| Prompt措辞一改,结果整体变化 | 评测集没有覆盖风格维度 | 对比新旧Prompt在相同评测集上的输出 | Prompt版本化,增加维度化评测集 |
| 训练loss完全不降 | 标签错误或学习率不合适 | 打印batch样本和标签 | 检查数据,从1e-4开始重试学习率 |
| 新增文档后旧问题反而答错 | 切分策略对新文档不友好 | 对新文档单独验证召回 | 增加块质量过滤,调整切分参数 |
第一个典型案例:知识库问答系统频繁引用错段落。我先抽取了10个失败case,发现所有错误回答都指向同一个模式:top1段落得分虚高但内容不对。接着在检索阶段单独打印top5段落的得分,发现向量模型对超长段落给出的相似度分数偏高,这是embedding模型的一个常见偏差。解决办法是引入重排模型对召回结果做精排,同时对超长段落重新切分,再加一道最低分数过滤。整个排查过程的核心就一句话:把链路切出数据、检索、排序、生成、输出五个环节,每段打印中间产物,问题就会自己现形。
第二个典型案例更有意思:升级系统Prompt之后,线上客服机器人的事实准确率只波动了1%,但用户投诉率明显上升。原因在于现有评测集只关注事实正确,完全没有评估回答的语气和温度。后来我在评测集里加了风格维度,把“礼貌”“简洁”“同理心”变成可打分项,并且规定以后任何Prompt变更都要同时跑事实、安全、风格三个维度的回归。这提醒我,AI系统的线上体验是复合的,评测维度如果只有准确率,就是在用一把尺子量所有东西。
5. AI工程的下半场:Agent、AI编程与多模型协作
到这里,你已经有了一个能稳定运行的AI系统。但视野再拉开一点,2025年之后的AI工程早就超出了单模型调用的范畴。Agent、AI编程、多模型协作正在把AI从“问答工具”变成“能自主完成任务的执行体”。这一层不是简单的技术叠加,而是一整套新的工程约束。
5.1 Prompt Engineering与Agent开发:从“提需求”到“控过程”
Prompt Engineering现在是一个热词,但很多人理解偏了。它不止是“把话说清楚让大模型给你正确回复”,而是面向语言模型的需求工程:任务定义要明确,输入输出Schema要清晰,边界约束要给足,失败情况要有预案。当单次对话不能解决问题时,就该Agent上场了。
一个最小Agent由模型、工具、执行循环三部分组成:模型负责理解和规划,工具负责获取外部信息,循环负责不断修正。伪代码大概是:
while not task_finished: plan = model.plan(context) # plan 可能是调用工具,也可能是直接回答 if plan.requires_tool: result = call_tool(plan) context = append_to_context(context, result) else: return model.final_answer(context)工程上真正难的不是搭循环,而是给Agent设边界:最大步数必须限制,防止它在一个错误分支上打到天荒地老;每个工具调用都要超时,任何外部请求都可能挂起;整条执行路径必须记trace,事后才能回放和审计。没有这些约束,Agent在开发环境里再聪明,到生产环境也是个定时炸弹。
5.2 AI编程与编码智能体:杠杆的另一面是护栏
AI辅助编程已经走过了自动补全阶段,进入编码智能体阶段:给AI一个Issue,它自己改代码、跑测试、提交PR。这时候工程上出现一个新名词:Harness Engineering。我把它理解成“给编码智能体装上护栏系统”,具体包括沙箱执行环境、自动化测试守卫、代码风格检查、最小权限授权、任务完成标准的定义。
一个非常直观的对比:有的团队让AI直接改代码,出了Bug人肉兜底;有的团队要求AI在测试全绿之后才能改代码,并且任何AI变更都要走同一套CI管道。后者看起来很慢,但真正跑起来以后团队的交付效率反而更高,因为每条AI改动都在受控范围内。我用AI写代码前,一定会先建好单测,再给Agent喂足够上下文,但不会把所有文件都塞给它。AI写得越快,人工审查的门槛就越不能降,这是这个阶段最重要的原则。
5.3 多AI协作与工作流编排:善用“模型组合”
没有一个模型能解决所有问题,但把不同能力的模型串成一个工作流,往往可以。一个典型的内容生产流水线可以这样设计:小模型做意图识别或热点发现,大模型做正文生成,专用模型做事实核查,内容安全模型做输出过滤,最后人工抽检。这就是AI工作流和多AI协作形态。
编排多个模型时要重点考虑四件事:模型之间的消息协议、失败重试策略、成本与token预算、整条链路的SLA。如果某一环失败,是降级返回上一版结果,还是直接终止请求,都要提前定义清楚。不要只顾着优化单个模型的质量,整条流水线的质量、成本、延迟和失败率才是最终指标。
5.4 AI系统安全与可信:这是工程的一部分,不是可选项
最后必须说一个很多人回避但工程上逃不掉的环节:安全与可信。AI系统进入生产环境之后,内容安全、数据隐私、提示词注入防御都是实打实的工程问题。我坚持的做法是从输入和输出两侧同时设防。输入侧做长度限制、敏感信息检测、注入特征识别;输出侧做关键词加语义双通道过滤,再配合分类模型审核和人工抽检。数据侧坚持最小化采集和脱敏处理。
安全评测集要和效果评测集放到一起跑回归。不要平时不管,出事再救火。一个没有任何护栏的AI系统,越成功风险越大,这是这个行业用无数次教训换来的共识。做AI工程,不仅要让系统“能干活”,还要让系统“可控、可信、可追溯”,这才是真正的从零到一。
我个人走到今天,最有价值的经验就是把上面这条完整链路亲手走了一遍。如果你现在也是收藏了一堆资料、迟迟不知道从哪里开始,我的建议是别再规划了,直接挑一个你自己工作或生活里真实的场景,造一个哪怕很粗糙的AI助手。过程中遇到问题就拆链路、打印中间产物、记录改动。最后分享一个小习惯:每次实验都在笔记里记三行——这次改了什么、为什么改、结果和预期差在哪。三个月后再回头看,你会发现自己对AI工程的理解已经不只是“会调接口”而已。