有人一听到“AI engineering from scratch”,第一反应就是“我又不搞研究,学这个干嘛”,或者“现在大模型都封装好了,我直接调API不就行了”。说实话,我在刚接触这个领域时也是这么想的,直到自己动手做了一个完整项目才发现——能写Prompt和能做一个稳定的AI应用,是完全两回事。所谓从零开始做AI工程,不是从线性代数开始啃论文,而是从“怎么把一个模型真正用起来、跑通、部署出去、扛住真实请求”开始。
这篇文章就是一份我自己走过的路线总结,适合那种已经会用Python、写过几年代码、但没正经做过AI项目的开发者。也适合刚入行的新人,如果你连Python都不熟,那可能需要先花两周补一下基础语法再回来。我会把AI工程涉及的技能栈、学习路径、第一个项目的选型思路、以及我在实操中反复踩过的坑,一次性讲透。我不会给你列一长串书单,而是告诉你:哪些东西必须学,哪些可以放着不管,以及为什么。
1. AI工程到底是什么:先理清边界再动手
1.1 搞懂AI工程和AI研究的区别
很多人把“做AI”等同于“训练模型”,这是最大的误解。AI工程的核心目标不是发明新算法,而是把已有的模型、工具和框架组合起来,构建出稳定、可维护、能解决实际问题的软件系统。这么说吧,AI研究者负责造发动机,AI工程师负责把发动机装进车里,还要保证这车能上路、能省油、能过检。
实际工作里,AI工程涉及的东西非常杂:数据处理管道、模型推理加速、接口设计、缓存策略、监控告警、成本控制、提示词调优、RAG(检索增强生成)流程、向量数据库选型、模型微调……每一项都不是“调一个库”那么简单。我见过不少从算法岗转过来的同事,写模型的时候很溜,但一到了线上服务就头疼——并发一上来就超时,显存不够用,日志乱成一锅粥,出了问题都不知道怎么查。
所以在从零开始之前,你先要建立正确的预期:AI工程师首先是工程师,其次才是懂AI的工程师。你得具备扎实的软件工程功底,包括代码组织、单元测试、CI/CD、容器化部署这些基本功。很多教程不强调这一点,导致大家一上来就撸模型代码,最后做出个demo容易,做出产品难。
1.2 先画技能树:哪些要学、哪些可以暂时放下
我建议按照“够用就行的原则”来分配学习精力。AI工程领域大得吓人,你不可能什么都学,但有一条主线必须打通:数据处理到模型调用再到服务化部署。我画过一份自己的技能清单,一直在用,后来也给团队新人用:
- 语言基础:Python是主力,但建议额外掌握一种强类型语言(我选的是Go),因为Python服务的性能和部署方式有天花板,后续做高并发推理服务时,Go或Java是常见补充。
- 机器学习基础:不要急着啃深度学习,先把“特征、标签、训练集/测试集划分、过拟合”这些概念吃透,至少能看懂sklearn里的常用模型怎么用。
- 深度学习框架:PyTorch是入门首选,TensorFlow除非你所在公司明确要求,否则可以放一放。重点不是背API,而是理解张量、自动求导、模型定义这三大件。
- 大模型应用开发:包括Prompt Engineering、RAG、函数调用(Function Calling)、Agent框架。这个板块是当前AI工程需求最密集的部分,也是从零开始最容易获得成就感的方向。
- 工程化能力:Docker、Linux基本命令、Git、CI/CD、日志与监控。这些看似和AI无关,但恰恰决定了一个AI项目能否活过“demo阶段”。
- 数据工程基础:SQL必须熟练,还要了解Airflow或同类调度工具,因为AI应用的数据管道往往比模型本身更耗时。
至于深度学习的数学原理、反向传播公式推导、从头训练一个大模型、分布式训练这些,现阶段完全可以先放一放。它们不是不重要,而是在你还没做过完整项目之前,学了也用不上,反而容易劝退。
1.3 重新定位你的学习目标:做出来比学完更重要
从零开始学AI工程最容易犯的错是什么?是一直在“学习”而不是“做”。我见过太多人收藏了几百个教程,看了几十小时的视频课,可代码一行没写。学AI工程,本质上是一门手艺活,和学游泳或学开车没有任何区别——你看再多的驾驶教学视频,不上路就永远学不会。
给自己定一个“60分目标”:三个月内,把一个端到端的AI应用跑上线。什么叫端到端?就是从用户输入、到中间的处理逻辑、再到模型推理、最后把结果返回给用户,整个过程走通,并且布置到公网或内网上真能被访问。这个目标不需要你懂分布式训练,也不需要你精通数学,但需要你把上述技能全部过一遍——这就够了。
2. 从零开始的路径规划:按项目驱动的三阶段学习法
2.1 阶段一:用最小成本跑通第一个模型调用(第1-2周)
这一阶段的目标只有一个:让代码成功调用一次人工智能接口,并在本地拿到结果。不要去管什么架构设计、性能优化,就做一件最简单的事——发送请求、接收响应、处理输出。
我建议你从调用现成的大模型API接口(比如OpenAI、Claude、通义千问等,选择你和你的网络环境最容易获取的那个)开始。这个阶段的重点是熟悉“模型接口长什么样”,而不是训练模型。装好OpenAI的Python库,写一个最简脚本,向模型发一句话,把回复打印出来。就这么简单的事情,我第一次做的时候还是卡住了:环境变量没配好,key写错了位置,模型名输错,折腾了一个多小时才跑通。
跑通之后,立刻加一点复杂度:让程序读取一个文件内容,把它作为上下文发给模型,再把模型的回答写入新文件。这一步是在模拟真实场景中“程序自动读取数据、交给模型处理、保存结果”的基本模式。完成后你会对AI应用的运行机制有一个直观认识:模型本身是无状态的,它不保存你的历史信息,是人在外面控制数据的流向。
对于这一阶段,不要纠结于是不是一定要用“最先进”的模型。目前市面上的主流模型API在文本理解与生成方面都足够优秀,真正拉开差距的,往往是工程师如何组织上下文、如何设计请求流程。选择一个生态成熟、文档齐全的模型服务商才是关键。
2.2 阶段二:补上“工程四件套”并用它重构项目(第2-6周)
跑通一个脚本之后,你就开始体会到差距了:这个脚本能不能给别人用?如果模型挂了怎么办?API密钥配置写死在代码里安全吗?怎么让它每天自动运行一次?要回答这些问题,你需要补齐四样工程能力。
第一是Python虚拟环境与依赖管理。别再用全局环境跑项目了,为每个项目建一个虚拟环境是基本功。我推荐用poetry管理依赖,它能同时解决包版本锁定和打包发布的痛点。没有这个习惯的话,项目隔两周就“跑不起来了”是非常常见的。
第二是Docker容器化。AI项目最头疼的就是环境一致性——“我本机跑得好好的,怎么到你那就报错?”Docker解决的就是这个问题。你只需要写一个Dockerfile,把Python版本、依赖包、代码一起打成一个镜像,无论部署到哪台机器上,行为都是一致的。这一步是很多半路出家的开发者容易忽略的,但他们迟早会为此付出代价。
第三是数据的获取与清洗。真实世界的数据比你想象得脏得多。格式不统一、编码混乱、字段缺失、噪声干扰……在做AI应用时,数据清洗通常占据40%以上的工作量。你需要学会用pandas做基本的探查和清洗:去掉空值、去除重复项、统一格式,并且把清洗逻辑写成可复用的函数。你知道吗?实际工作中大量代码并不是在调用模型,而是在花费精力“准备数据的形状”,让它刚好符合模型的输入要求。
第四是数据库操作。你的AI应用不可能每次都对模型发起外部API调用,那样既慢又费钱。本地缓存、用户历史记录、知识库内容、向量索引,这些都需要存储。你得掌握至少一种关系型数据库(SQLite对个人项目来说足够了)和一种向量数据库(我推荐先学Qdrant或Chroma,接着可以了解一下Milvus)。
学这些工具的时候,很多人会觉得很烦:“我是来做AI的,为什么要学Docker和数据库?”这里我说句实在话——因为AI应用也是应用,只要是应用,就绕不开工程问题。你能找到那些成熟AI产品背面的工程复杂度,往往比算法本身高一个量级。
2.3 阶段三:做深度绑定业务场景的完整项目(第6-12周)
第三阶段就是把前面学的所有东西缝在一起做一个完整的项目,项目选题直接决定这一阶段的学习效果。我后面会专门用一整节来讲项目怎么选、怎么做,这里先讲一个原则:不要做“大家都在做”的通用项目。
聊天机器人、文章总结器、文档问答助手……不是说不能做,而是这类项目已经多到没有辨识度,你做完之后的收获有限。更好的选择是找到一个具体的垂直场景,哪怕是很小的场景也行。比如“针对某本技术书的问答机器人”、“帮助跨境电商卖家生成商品描述的辅助工具”、“把会议录音转成结构化会议纪要的管道”。具体场景会逼你面对一系列真实问题:数据从哪里来?用户的使用习惯是什么?模型的输出格式怎么约束?如何评估效果?
边界清晰、目标具体、能用起来的项目,才能真正锻炼你的AI工程能力。做的时候记得拆成几个增量版本:第一版只做核心链路,能用就行;第二版加缓存和错误处理;第三版优化效果和速度;第四版加上简单的用户界面。每次迭代你都会发现新的问题,这些问题才是最有价值的学习材料。
3. 第一个AI项目的完整实操拆解:文档问答机器人
3.1 项目选型思路:为什么选“个人知识库问答”题材
我不打算泛泛而谈,直接用我做过的一个项目来举例:一个基于RAG的“个人知识库问答机器人”。选择这个题材有三个原因:第一,它能完整覆盖AI工程的核心链路——文档加载、文本切分、向量化存储、检索召回、生成回答;第二,技术栈成熟、资料丰富,遇到问题时容易查;第三,每个人都可以用它解决真实需求,比如把自己的笔记变成一个AI助手。
这个项目的能力概括起来就是:你把一堆PDF、Markdown、TXT文档扔进去,机器人可以对这些文档内容进行提问,回答的时候还会标注出处。这本质上就是一个轻量版的私有知识库GPT。
项目中我会用到以下技术组件:
- 文本处理:用LangChain或LlamaIndex来加载文档、做文本切分。LangChain生态更全,例子也多,初学建议用它。LlamaIndex则更专注于文档处理,两者选一个就行,不必两个都学。
- 嵌入模型:文本要交给模型检索对比,必须先变成向量。可用OpenAI的文本嵌入接口,也可用本地嵌入模型如BGE或MiniLM。考虑到成本和学习难度,自己动手的话,本地部署一个嵌入模型是更好的选择。
- 向量数据库:文本切分后的文档块,经过嵌入模型后变成向量,存入向量数据库。Chroma本地就能跑,安装方便,对个人项目很友好。
- 大模型:负责根据检索到的文本片段生成回答。这一层的接口就是“塞进上下文,让模型回答”这么简单。
- 应用框架:用一个Web框架(我用的是FastAPI,后来加了Streamlit做界面)把整个流程包成HTTP服务。
整体流程是这样组织的:先离线把一批知识文档建立索引——切分、向量化、入库;运行时,用户提问,系统把问题向量化并在向量数据库中找出最相近的若干个文本片段,把它们作为上下文连同用户问题一起发送给大模型生成回答。
3.2 文档加载与文本切分细节
文档加载,听起来简单,做起来全是坑。PDF有扫描版和文本版之分,扫描版要用OCR(文字识别),文本版直接解析就行。Word、Markdown、HTML各是各的格式,你要针对每种格式写对应的Loader,或者找一个现成库封装掉这些差异。
以PDF举例,最常用的是PyPDF2或pypdf库,那些“扫描版PDF”则需要配合OCR工具。建议一开始就用文本型的PDF或Markdown文件来调试,把扫描版的处理放到后面再说。
文本切分更是隐藏着大量细节。模型调用有输入长度限制,你不能把整本厚书一股脑塞进去,需要先切成适当大小的chunk(文本块)。切得太小会丢失上下文导致理解不了,切得太大又超出了模型输入限制或浪费token,还会引入无关信息降低检索精度。我测试下来,对于一般的技术文档和图书章节,200到500个字符左右通常比较合适。
切分时还要注意避免“段落腰斩”。我的经验是,最好先按段落切,段落太长再按句子边界二次切分,不要粗暴地按固定长度硬切。像LangChain的RecursiveCharacterTextSplitter就是这个思路,先按大分隔符(比如两个换行)切,再逐级缩小到标点、字符边界。它默认的参数不一定适合你的文档,建议针对自己的语料库调一下,别偷懒。
3.3 向量化与检索的关键选择
文本块切好之后,每一块都要过一个嵌入模型,转成一个高维向量。选嵌入模型时,最重要的指标不是“分高”,而是“对你这批语料的领域词汇敏感”。通用类的嵌入模型对日常话语还行,但对专业术语的判别力可能偏弱。理想状态是拿一批你自己的问题做评测:每个问题应该有对应的标准答案片段,看看改造后的系统能不能把这个片段检索出来。
向量数据库选型方面,初学者建议用Qdrant或Chroma,这两者在个人电脑上就能跑得很舒服。我在项目初期用的是Chroma,纯本地启动、代码API简洁,对原型验证非常友好。如果你的数据量到了几百万条向量,又需要高并发访问,再考虑Milvus或专门的向量数据库云服务也不迟。
需要注意的是,检索效果和“数据质量”强相关。如果切出来的文本本身很乱,或者你的提问方式过于宽泛,再好的向量数据库也救不了。实际项目里,我会先手工检查几条检索结果——看召回的片段到底是不是用户真正需要的信息。如果不相关,优先检查句子切分逻辑是否合理、嵌入模型是否匹配领域,而不是急着换向量数据库。
3.4 组装问答流程与输出约束
检索到相关片段之后,就要把它们组装成Prompt发送给大模型。Prompt的写法直接决定回答的质量,我踩过不少坑后总结了几个要点:
- 上下文与回答的关系要讲明白。告诉模型“只依据参考资料回答,不要使用参考资料之外的信息”,能有效减少幻觉。
- 如果检索结果中没有相关内容,必须让模型明确说“根据提供的资料无法回答”,而不是硬编一个答案。
- 要求引用出处。让回答带上“根据《XXX》第X章的描述……”这样的表述,可靠性会强很多。
组装Prompt时,还需要注意控制token总量。假设模型上下文窗口是8k,其中系统提示词、历史对话、检索到的文档块、用户问题再加回答预留,加起来不能超过上限。如果文档块太多太大,最直接的办法是提高向量检索的相似度阈值,只保留置信度最高的两到三块。粗调之后,可用递归方法进一步压缩或在过程中明确提示模型聚焦回答方向。
以下是提问主流程的代码示意,供参考:
def answer_question(question: str, k: int = 3) -> str: # 1. 将用户问题向量化 q_vec = embed_model.encode(question).tolist() # 2. 从向量库中检索最相似的文本块 results = vector_db.query( query_embeddings=[q_vec], n_results=k ) contexts = [doc for doc in results["documents"][0]] # 3. 组装Prompt prompt = build_rag_prompt(question, contexts) # 4. 调用LLM response = llm_client.chat.completions.create( model=MODEL_NAME, messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt} ], temperature=0.2, # 低温度让回答更稳定 ) return response.choices[0].message.content这里的temperature参数很关键。问答场景追求准确,temperature调低到0.2以下就可以明显减少“自由发挥”空间。如果是做创意写作或头脑风暴,才需要调高。
3.5 加上缓存层和前端界面
经过前面几步,一个文档问答的雏形已经能用了。但要在真实场景里用起来,还得解决两个体验问题。
一是性能与成本:同样的问题被反复问到是常态,每次都去调用大模型接口,既费钱又慢。解决思路是加一层缓存——把问题+检索结果的哈希值当作key,回答存在本地,命中就直接返回,只有没命中时才发模型请求。我在实践里发现这一步能让响应延迟从“几秒”降到“毫秒级”,而且显著降低在线成本。
二是用户界面。对命令行不熟的人没法用你的服务。用Streamlit写个极简页面,一个输入框、一个回答展示区、再加一个相关文档片段列表。Streamlit代码量小、见效快,五分钟就能让项目“看起来像个产品”。我前期一直觉得后端做完就够了,加完UI才发现,“能给人演示”这件事,对一个项目的完成度和后续动力影响远比你想象的大。
4. 工具链选型解析:我踩过坑之后的推荐组合
4.1 Python项目环境与依赖管理
AI项目的依赖管理,是所有新手过不去的一道坎。回想一下这种画面:你用pip install装了一堆包,因为某个包版本冲突,项目起不来了。于是想把环境搞干净一点,重装Python、重配环境变量,又浪费了一个下午。
我现在每个项目都用poetry,它把虚拟环境和依赖打包统一管理。pyproject.toml一个文件搞定项目元数据和所有依赖声明,锁文件保证团队成员安装的版本完全一致。成本是学习一个新命令:poetry add、poetry install、poetry run,半天就能适应。如果你是纯新手,用venv加requirements.txt也能跑,但poetry迟早要学,倒不如一步到位。
4.2 本地开发与远程调试的建议
写AI代码时,本地调试和远程调试是两套逻辑。本地开发时,模型相关代码一定要做小样本测试,时刻关注有没有“悄悄调用远程接口”的情况发生。你写了一个批量处理代码,没注意里面循环里调模型,单测一跑,钱花了几十块。这种事我见过不止一次,包括我自己也干过。
所以,请尽早养成设置一个开关的习惯:一个环境变量控制“是否真正请求大模型接口”,在测试阶段始终把它设为False或使用虚拟响应。这个习惯能在未来大规模迭代中为你节省大量心智成本。另外,别忘了给模型调用加日志:记录请求的模型名、输入token数、输出token数、响应时间、错误码。这些日志非常重要,既是为了排查问题,也是为了做成本统计。
4.3 版本控制与协作的基本规范
AI项目里最容易被忽略的是“数据与代码的版本控制”。代码你当然会放进Git,但存放模型参数、向量数据库、数据集的目录一不小心就会搞出几十GB的东西。我的处理规则是:小文件(几MB以内)可以直接入库,大文件一律不入库,用dvc(Data Version Control)或者干脆用对象存储管理。纯粹为了个人项目的话,至少要把版本号和更新时间写清楚,你才不会在两周后困惑:“这批索引是用哪个版本的数据构建的?”
协同方面,即使是个人项目也建议用feature分支开发。不要觉得一个人写代码不需要Git分支——当你同时要改数据管道和Prompt模板时,分支能让你在两件工作之间清爽切换。CI/CD可以先不上,但至少配一个pre-commit钩子,自动格式化代码和检查语法错误,这一点点前期投入会长期回报。
5. 实操中的经典故障与排查手册
5.1 模型返回空或超时
这是最经典的问题。超时的原因通常是网络不稳、请求体太大、或模型服务端过载。我先建议排查网络,curl测试一下接口的连通性和延迟;再做分级排查——用最小的prompt去请求,排除是不是上下文太长导致超时;最后检查超时参数,requests库或OpenAI客户端默认超时都比较短,你需要把它调长一些,比如30秒以上。
如果明明请求成功但返回内容是空的字符串,先检查是不是Prompt指令导致的——有些风格指令要求模型“只输出JSON”,模型理解出的空结果也常有。这种时候可以加一条“如果没有答案,返回空对象而不是不返回”之类的显式指令。
5.2 检索结果不相关
RAG项目十有八九会撞上这个问题。先把检索本身和生成拆开排查:直接打印向量数据库返回的top-3片段,看内容是不是和问题相关。如果片段不相关,问题大概率出在向量化和切分上,而非大模型。
我已经开展排查时,看几个因素:第一,你的提问方式和构建索引的文档语言是否一致?中文提问对应中文索引比较稳;第二,chunk是不是切得太碎了?一些长段落被切得只剩半句话,语义信息不完整,导致检索不准;第三,嵌入模型对你这批数据是不是不太够用?这时可以换一个更大的模型,或试试关键词检索和向量检索的混合检索方式。
5.3 成本的突然飙升:预算监控的机制
个人项目也可能花很多钱,我身边就有朋友因为忘了关掉写了个死循环,一个晚上烧掉好几百美元的API调用费。ArcAI项目中可以立即上线的最小成本保护机制至少包含三层:
第一,代码中加调用次数限制,比如单日最多调用N次,超过了就直接拒绝本地运行;第二,每次调用前计算预估token,超了预设计费上限就中止;第三,定期对所有模型调用做账单统计,用一张简单的表格记录每天、每周、每月的花费。现在各家大模型厂商都有用量配额设置,我建议你从建号第一天起就把硬预算上限设好,不要觉得麻烦,这点麻烦比月底账单惊喜小太多了。
5.4 部署后无法访问或内存过高
本地跑通和部署上线之间是有很多隐蔽鸿沟的。部署到服务器后访问不了,先检查三个因素:进程是否真的存活(很多时候一退出SSH进程就挂了,需要nohup或systemd托管)、端口是否对外开放(防火墙或云安全组拦截)、代码中监听的地址是否是0.0.0.0(监听127.0.0.1的外部无法访问)。
内存过高通常是加载模型导致。一个7B参数的中等模型量化后要占几个GB内存,一台2G内存的云服务器根本跑不动。如果你要跑本地开源模型,建议先了解模型参数对应的大致显存占用。模型层若使用API接口,则可显著降低部署资源需求。实在不行就换更小的模型,或用外部API来替代本地推理。
6. 从第一个项目到工程化进阶:三个扩展方向
做完了文档问答这个项目之后,你对AI工程的主干链路已经有了体感,这时候再看那些“进阶”概念,就不慌了。
第一个方向是往Agent方向走。让大模型不只是“回答问题”,而是能调用工具、执行动作。你可以给机器人加一个搜索工具、一个查询数据库的工具,让它根据用户意图自动决定调用哪个工具。这个方向的技术核心是“函数调用”,即把可用的工具列表描述给模型,由模型输出要调用的具体函数和参数。
第二个方向是往微调方向走。当你觉得“提示词已经榨不出更好的效果了”,或者你希望模型稳定输出特定格式、特定风格时,可以考虑微调。个人项目不太建议从零训练,用开源大模型做LoRA微调在人力和算力上都更切实际。微调的数据集准备又是另一个庞大话题,先知道方向即可。
第三个方向是往数据管道方向走。把“离线文档加载、切分、向量化入库”这套流程扁平化,当知识库有大量文档要定期更新时,你需要搭建一个定时任务管道。边界拉大之后,会涉及数据库增量更新、版本回退、调度监控等问题。这是从“做一个功能”到“维护一个系统”的质变点。
7. 写给从零开始的你:学习资源的取舍建议
正式收尾前,还想给大家一个额外小建议。AI领域的信息量实在爆炸,每天都有新模型、新框架、新论文出来,很多人光是在“追踪热点”这件事上就耗尽了精力。我的策略很简单:锁定一个主线和两三个核心工具,其他新东西只保持基本了解。比如你的主线是“Python+PyTorch+RAG流程”,那就把这个组合玩透,新出的什么“某某新的Agent框架”,了解它解决什么问题就足够了,不必立刻上手。
遇到问题时的搜索习惯:报错信息直接复制到搜索引擎。这是最高效的排错方法。不要在群里问“有没有大佬帮我看看这个bug”,十有八九要被别人拿去喂搜索,还欠人情。好的习惯是把报错信息当作查询词,再附上你的关键配置(Python版本、库版本、操作系统),通常三五分钟就能找到答案。如果实在找不到,就要学会精确定位问题:逐行二分排查代码,把“大概率出错的代码段”单独抽出来跑一遍。
至于要不要看论文或系统教程,取决于你的目标。如果是为了找工作,那任选一个大厂的岗位要求,把要求里的技术栈逐个学到位,比啃十篇顶会论文更有效;如果是为了做自己的产品,那“跑通”比“学透”更重要。市面上90%的基础教程和框架官方文档都够好了,选了哪个就不要随意跳来跳去。
根据我个人经验,真正拉开差距的不是天赋,而是完成项目的数量。每完整交付一个AI应用,你对数据、模型、工程这三者之间复杂关系的理解就会深一层。也不要觉得“从零开始”意味着要准备到完美状态才动手——恰恰相反,做得越多,你在看文档、调接口、部署服务时的判断力和直觉才会越强。开始做就对了。