不知道有多少人和我一样,是带着"会用几个模型接口、能跑通一段推理代码"的心态,开始正儿八经琢磨AI工程的。等到真正把手伸进项目里,才发现所谓AI工程,远不是"调包+调参"这么简单。它是一整套系统工程,从数据怎么管、模型怎么选、效果怎么测,一直延伸到服务怎么部署、成本怎么控、上线之后怎么迭代。这篇内容就是冲着"从零开始把AI工程这件事做扎实"去的,我会把从技术选型到落地实战的路径捋一遍,给你一套可以直接照着走的方法。
我倾向于把AI工程理解成一门"用工程手段把智能能力稳定地送进业务"的手艺。它既需要你懂一点模型原理,又需要你具备传统后端、数据处理、运维监控的功底。适合正在转型的开发者、带AI项目的技术负责人,以及被老板一句"我们也要上AI"扔进深水区的同学阅读。下面这些内容,全是我在真实项目里一条条蹚出来的经验,没有教科书式的废话。
1. 首先要搞清楚的:AI工程和"调包跑模型"是两回事
1.1 我见过的"from scratch"误区
很多人一听"从零学AI工程",第一反应是去刷算法题、啃Transformer论文、复现几个模型训练代码。这一套做完,你收获的是"AI研究"的基础,而不是"AI工程"的基础。我面试过不少简历上写着"熟悉BERT、熟悉PyTorch"的候选人,让他们说说一个模型从训练完成到线上服务的完整路径,大多数人都卡在了"导出模型文件之后怎么办呢"这个问题上。
AI工程真正要解决的,是怎么把模型变成一项稳定、可维护、成本可控的服务。举个最直观的例子:你用Scikit-learn或者PyTorch训练好一个分类模型,acc刷到了95%,这只是万里长征第一步。紧接着你得思考:训练用的数据分布和线上真实数据一致吗?模型文件用ONNX还是TensorRT转换?服务用FastAPI还是gRPC框架暴露?请求量上来之后怎么做水平扩展?模型预测结果出错了怎么快速感知并回滚?如果业务方突然说"我要加一个新类别"怎么办?
这些琐碎但致命的问题,才是AI工程的日常。哪怕是如今大火的LLM应用,底层逻辑也没变:模型只是核心引擎,围绕它的一整套数据处理流水线、向量检索服务、缓存策略、Prompt路由、成本监控、效果评估体系,才是一个AI工程项目的真正主体。你从头自己搭一个AI应用,百分之八十的时间会花在这些"非模型"的环节上。
1.2 一个AI工程项目的实际构成
我习惯把一个完整的AI工程项目拆成七层来看,这样无论是学习还是规划开发节奏都比较清晰:
- 数据层:原始数据的采集、清洗、格式转换、质量校验,包括结构化数据、文本、图片等非结构化数据。
- 特征与索引层:把数据加工成模型可以消费的形态。经典机器学习里有特征工程,LLM应用里则是切块、Embedding向量化、写入向量数据库。
- 模型层:选择基础模型、微调、蒸馏,或者直接调用现成API并对Prompt进行适配。
- 服务层:模型推理服务的封装,API网关、鉴权、限流、负载均衡。
- 评估层:离线评估、线上评测、回归测试集、badcase追踪。
- 运维层:日志、监控、告警、成本分析、模型版本管理与灰度上线。
- 业务接入层:把AI能力嵌入真实的业务流程、产品交互、人工兜底机制。
你在网上看到的各种AI项目模板,大多数只覆盖了第2到第4层的一部分。但从我的实战经验看,决定一个AI项目能不能长期活下去的,往往是评估、运维和业务接入这三层。从零学习AI工程,千万不要只盯着模型层打转。
2. 从零起步的底子:哪些基础必须扎实,哪些可以边做边补
2.1 三种背景的人,分别该先补什么
我在带人踩过足够多的坑之后,发现"从零"这件事对不同背景的人来说,起点完全不同。如果你是纯后端开发背景,Python语法对你不是障碍,Docker、Git、Linux命令更是日常,你最需要补的是模型怎么工作、数据怎么处理、Prompt怎么设计、效果怎么评估。这类人是目前转型AI工程最顺的一批,因为你缺的不是工程能力,而是对"智能"这件事的直觉。
如果你是数据分析或者算法研究背景,你最难受的点会在服务化部署和系统设计上。我一个做算法出身的朋友,微调模型一把好手,但让他写一个带鉴权的服务接口,他能在nginx配置上折腾一整天。这类人需要恶补的是后端基本功:HTTP协议、RESTful设计、容器化部署、数据库事务、缓存策略、接口幂等性设计。
如果你是完全零基础转行,那没什么捷径,Python、SQL、基础数学、Linux这四样是绕不过去的,按顺序啃下来就行。我的建议是不要在教学视频里泡太久,最多两周基础课,然后立刻钻进一个真实项目里,遇到什么再查什么。
2.2 真正高频用到的基础知识地图
说实话,绝大多数AI工程项目用不到复杂的数学推导。我做的项目里,线性代数用到最多的就是向量点积和矩阵乘法,而这两件事连代码都不用你手写,框架内部帮你算好了。你真正需要建立直觉的数学知识是这个量级的:理解Embedding的本质是"把数据映射到高维空间的向量",理解余弦相似度衡量的是"两个向量的方向接近程度",理解归一化的作用是"消除量纲影响"。能把这些讲明白,应付日常开发足够了。
比数学更重要的是数据敏感度。我拿到一批文本数据,第一步永远是做分布统计:长度分布是什么样的?空值比例是多少?有没有编码混用?语言分布是否均匀?这些统计习惯,决定了你后面模型效果的底线。举个真实案例,有一次我在做法律文档问答系统,前期忽略了对文档OCR扫描件转出来的乱码字符做清洗,结果检索召回率怎么调都上不去。后来写了一个文本质量检测脚本,把包含异常字符比例的chunk直接过滤掉,整体效果立刻上一个台阶。
工程基础方面,下面这些点最值得花时间彻底搞懂,它们出现的频率远超你的想象:
- Python虚拟环境管理与依赖锁定(venv/poetry/uv),坑最少的是poetry,但uv速度真的快。
- Docker镜像构建与容器编排基础,尤其是CUDA基础镜像的选取逻辑。
- Git分支策略与代码审查流程,AI项目里最怕的是模型实验代码和业务代码混在一个仓库里没人管。
- SQL基本功与常见NoSQL的适用场景,向量数据库也是数据库,事务一致性、备份恢复这些老问题一个都躲不掉。
- Linux下进程管理、日志排查、环境变量配置,尤其是GPU显存占用排查。
注意:显存占用排查是个日常高频操作。我强烈建议你熟练使用
nvidia-smi之外,再掌握nvitop这个工具,它能按进程实时展示显存占用,排查谁把显存打满了一目了然。这个习惯能在团队协作时省下一大堆扯皮的时间。
3. 从零开始搭一个最小可用的RAG问答服务:技术选型与代码骨架
3.1 为什么第一个手写项目要选RAG问答服务,而不是模型训练
如果你问我从零学AI工程,第一个亲自动手做的项目选什么,我会毫不犹豫地说:一个基于RAG的文档问答服务。原因有三层。第一,它覆盖了AI工程的全链路:文档解析、文本切分、向量化、检索服务、大模型调用、结果评估、服务接口封装,每个环节都踩得到,又不会深陷训练模型的泥潭。第二,RAG是当前LLM应用落地最主流的技术路线,你做完这一个项目,市面上大部分知识库问答、智能客服类需求你都能秒懂其架构。第三,它不需要昂贵的GPU机器,全程用API调用即可启动,学习成本和经济成本都低。
不要一上来就想微调大模型,那是一个完全不同的赛道。RAG构建的知识库,天然告诉你"工程问题的核心往往不在于模型能力,而在于你怎么组织数据、怎么设计流程"。这个认知越早建立越好。
3.2 技术栈清单与选型考量
我做RAG项目有一套固定的起步技术栈,追求的是"能跑、好查、不复杂":
- 应用框架:Python + FastAPI。异步支持好、自动生成交互式API文档,和前端联调效率很高。
- 文本处理:pypdf或docx库做文档解析,配合正则和简单的规则函数做切块。
- 向量化:直接调用Embedding模型API,配一个批量处理脚本生成向量。
- 向量存储:先用ChromaDB跑通流程,数据量大了再换Milvus或者pgvector。选ChromaDB是因为它是纯Python嵌入式的,本地部署零门槛。
- LLM推理:统一封装一个Adapter层,底层可以随时切换DeepSeek、GPT、Qwen等模型,避免和某一个厂商深度绑定。
- 服务观测:日志用loguru,指标采集先用Prometheus的Python客户端顶住。
这种选型的核心思路是"组件可替换"。我在实践里坚持所有外部依赖都至少包一层接口,因为AI领域组件迭代太快,今天你选的技术栈,半年后可能要么维护停滞、要么出现更优替代品。接口层是你的保护垫。
3.3 核心链路代码实现
这个RAG服务的核心链路拆成三步:索引构建、检索召回、生成回答。下面我给出一个精炼到极致的骨架代码,重点不是覆盖所有边界,而是让你看清工程链路长什么样。
索引构建部分,核心是把文档切块并向量化:
from typing import List import re def split_text_into_chunks(text: str, chunk_size: int = 500, overlap: int = 50) -> List[str]: # 先按段落粗切,再按长度合并,保证chunk不超过上限 paragraphs = re.split(r"\n{2,}", text.strip()) chunks, current_chunk = [], "" for para in paragraphs: if len(current_chunk) + len(para) <= chunk_size: current_chunk += para + "\n" else: if current_chunk: chunks.append(current_chunk.strip()) current_chunk = para[:chunk_size] if len(para) > chunk_size else para + "\n" if current_chunk: chunks.append(current_chunk.strip()) # 用overlap做一下滑动去重,避免上下文被截断得太生硬 # 实际工程中这里还可以引入markdown标题层级做结构化切分 return chunks def embed_documents(texts: List[str], embedding_fn) -> List[List[float]]: # embedding_fn是对外模型的统一封装,一次最多处理32条 batch = 32 results = [] for i in range(0, len(texts), batch): batch_texts = texts[i:i + batch] results.extend(embedding_fn(batch_texts)) return results检索召回部分,需要做的就是向量相似度计算并筛选Top-K:
import numpy as np def cosine_similarity(a: List[float], b: List[float]) -> float: a, b = np.array(a), np.array(b) return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-9)) def retrieve(query_vector: List[float], vector_store, top_k: int = 5): scored = [(doc_id, cosine_similarity(query_vector, doc_vector)) for doc_id, doc_vector in vector_store.items()] scored.sort(key=lambda x: x[1], reverse=True) return scored[:top_k]生成回答部分,就是把检索结果组装成Prompt,然后交给LLM:
def ask_question(query: str, llm_fn, retrieval_result) -> str: context = "\n\n".join([doc["content"] for doc in retrieval_result]) prompt = ( "你是一个严谨的问答助手。请仅根据以下资料回答用户问题。\n" "如果资料中没有相应信息,请明确回答'资料中未找到相关信息'。\n\n" f"【资料】\n{context}\n\n【用户问题】\n{query}\n\n回答:" ) return llm_fn(prompt)再套一个FastAPI接口就齐活了:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class QueryRequest(BaseModel): query: str top_k: int = 5 class QueryResponse(BaseModel): answer: str references: List[str] @app.post("/ask", response_model=QueryResponse) async def ask(request: QueryRequest): # 实际使用时替换成你的真实服务实例 query_vec = embed_documents([request.query])[0] result = retrieve(query_vec, vector_store, top_k=request.top_k) answer = ask_question(request.query, llm_fn, result) return QueryResponse(answer=answer, references=[r["content"] for r in result])这套骨架跑通之后,建议你立刻做一个全链路压测,看看数据量大到多少时检索会出现明显延迟。这一步能让你直观理解索引结构对查询性能的影响。
3.4 我在这类小项目上踩过的坑
第一个坑是切块策略拍脑袋定,不结合业务数据验证。默认500字切一切,看起来均匀,实际上很多文档本身的段落结构是有语义边界的,生硬切断之后召回质量明显下降。我后来调整成"按标题层级优先切块、再按长度合并",效果改善非常明显。第二个坑是Embedding接口的限流和重试没有做,批量导入文档时经常前面跑得好好的,中途突然报429错误,而且没有重试机制之后得手动断点续传。真实工程环境下把限流重试做成通用组件,一劳永逸。第三个坑是召回结果直接拼进Prompt不做去重,相似度高的几个chunk内容高度重叠,白白占掉了上下文窗口。加上基于内容哈希的去重逻辑之后,同样的效果反而省了三分之一的token消耗。
一定要记住:凡是外部依赖,不管是模型API还是向量数据库,接入时就得考虑超时、重试、熔断这三件事。这是AI工程区别于实验室脚本的显著标志之一。
4. 关键选型决策:LLM API优先,还是本地权重优先
4.1 两种路线各自适用的场景
现在做AI工程,一上来必然面对一个"灵魂拷问":推理是调外部LLM API,还是自己在GPU服务器上部署开源模型?在没有明确答案之前,我建议一律优先选择API路线。API意味着你不用关心显存、不用考虑推理优化、不用做模型热更新,团队可以集中精力打磨业务逻辑和评估体系。坦率讲,绝大多数团队前半年根本没有必要自建推理服务,算一笔账就能想明白:一个中等规模的问答应用,每天调用量就算一万次,按市面上主流API的价格,一个月的成本大概率还赶不上一块A100显卡的租金。
本地权重部署适合三种情况。第一,业务数据高度敏感,不满足于把用户内容发送给第三方API。第二,调用量大到API费用已经占了成本大头,而且单位成本还压不下来。第三,需要对模型做深度定制,比如在特定领域数据上做微调,推理时使用量化版本,这时候自部署几乎是唯一选择。
4.2 混合架构是我目前更推荐的长线解法
我自己的实践经验是,别急着二选一,而是做成一个"路由式混合架构"。常规高并发场景走本地部署的小模型,用更快的速度和更低的单次成本处理大部分简单请求;复杂推理、需要更强语义理解的请求,则路由到顶尖商用API。这套架构刚开始看着复杂,但你在接口层预留一个路由配置,就能让流量在两条链路之间平滑切换。
路由的关键是判断什么请求该走哪个模型。我常用的一个简单策略:先用一个小模型给请求打一个难度分,比如通过意图分类模型判断这是"简单问答"还是"长文档推理";难的高分请求进大模型,简单请求进小模型。虽然听起来朴素,但实测能省下四成左右的API费用。做方案设计时把它当成一个可选模块,成本控制空间会很舒服。
4.3 商用模型API使用时的四个工程习惯
- 对所有模型调用统一封装,不要让业务代码直接散落着openai或anthropic的SDK调用,方便后续路由和替换。
- 设置上下文缓存,同一批知识库内容频繁出现在历史对话时,命中缓存能省掉可观的时间和费用。
- 为每个请求记录脱敏后的输入输出日志,那是调试效果的唯一线索。
- 在代码里默认使用流式输出,用户体验能提升一大截,技术实现上反而简单。
提示:我在封装模型接口时,会额外记录一个"客户可见"的响应字段,例如本轮回答是否命中了知识库、模型有没有编造。这些CI字段对后续做数据分析和效果归因非常有价值。
5. 效果评估与线上监控:AI项目最容易在这里翻车
5.1 离线评估:别只用一两个例子就下结论
AI工程的尴尬之处在于,一个系统在你本地跑得完美,不代表上线之后就没问题。离线评估阶段必须要建立一套"评估集+评估指标+回归基线"的完整机制。我自己每次迭代模型或者Prompt,都会跑一份固定的评测集,至少包含一百条典型问题和答案。评测集不要只选让系统表现好的用例,一定要故意塞入边界情况:问法含糊的、资料里根本找不到答案的、需要多文档信息合并的、上下文特别长的。
评估方式分两种。一种是规则型评估:设置关键词命中、答案中包含的引用片段、响应时间等硬性指标。另一种是模型型评估:用一个强模型对回答的准确性、完整性、友好度打分。实践中这两者结合使用效果最好。规则型评估捕捉硬性错误,模型型评估衡量语义质量。每轮迭代后在评测集上的得分变化,就是你唯一可信的"我做对了还是做错了"的判断依据。
5.2 上线之后盯牢这几个线指标
我建议的LLM应用监控指标包括四类。第一类是可用性指标:接口错误率、超时率、限流触发次数,问题一旦出现要及时收到告警。第二类是性能指标:平均首字延迟、总响应时间、流式输出的Token吞吐率。第三类是业务质量指标:用户反馈的"踩/赞"行为、答案重复率、拒绝回答率,以及RAG场景里的检索召回率。第四类是成本指标:单次请求平均Token消耗、当日累计费用、单个会话费用。
两个数值最值得关注。一个是"空回复率",如果用户问题在知识库里有答案但系统没答上来,说明切块策略或检索逻辑出了偏差。另一个是"引用正确率",在RAG场景里,模型引用了文档内容但引用内容与用户问题无关,说明检索引擎召回了不相关内容。这两个指标异常,通常不需要动Prompt,而是去优化上游的索引和检索。
5.3 失败的兜底策略:没有永不翻车的AI系统
工程上一定要痴心妄想地认为AI不会出错,得为失败设计好逃生通道。我的兜底体系分三层。第一层是输入侧拦截:敏感内容、无关话题、格式异常请求,在到达模型之前先拦截,通过简单的规则分类器或小模型完成。第二层是输出侧校验:关键业务场景下面,模型输出的结果如果包含实体错误、格式不符,则自动触发"重新生成一次"或者降级到人工处理队列。第三层是人工兜底流程:客服系统的按钮切换、工单自动转接,把模型放弃处理的case平滑转到人工坐席。
这三层兜底栈做扎实之后,你敢放心地追求AI的自动化率提升;没有兜底的话,自动化率的每一次提升都可能带来不可控的骚动。我见过太多团队把模型回答直接怼给用户,出了几次翻车事件之后,领导对AI项目丧失信心,技术团队有苦说不出。
6. 学习路径规划:把"从零开始"拆成可执行的三阶段
6.1 第一阶段:建立全链路感知(1-2个月)
这个阶段的唯一目标,是让你亲手跑通一个AI应用的完整流程,对每一个环节都有直观体感。具体安排是:先用一个周末把Python基础、Git、Linux常用命令捡起来,再用一个周末实现最简单的OpenAI或DeepSeek API调用。接下来的四周,按我这篇文章第三部分给的骨架,把一个RAG问答服务做完整,并连续使用一周真实业务数据迭代它。
在这个阶段,你不需要理解Transformer的内部实现,不需要背诵attention公式,但你必须在自己的电脑上完成以下操作:用脚本把PDF拆成文本、把文本切成chunk、调用Embedding接口生成向量、把向量写入ChromaDB、写一个FastAPI接口做检索问答、用loguru配置日志、用docker容器把这个服务跑起来。全部完成之后,你脑子里会自动形成一张完整的架构图。
6.2 第二阶段:深挖模型与数据工程(2-3个月)
全链路跑通之后,就该往深处挖了。这个阶段建议建立两方面的能力。在模型方面,你需要真正理解Prompt设计、上下文窗口限制、温度参数、Embedding模型的差异、token计算方式、以及简单的模型微调流程。不是说要从头训练模型,而是要做到能说清楚"什么时候该改Prompt,什么时候该换模型,什么时候该微调"。这是AI工程师的看家本事。
在数据工程方面,你需要学会设计数据管道。包括数据去重、清洗规则、语义级切块、批量向量化任务调度、数据版本管理。你可能要引入一些数据工具:比如用DVC做数据版本,用Airflow或Prefect做定时管道,用JSON Schema做数据质量校验。这一阶段最容易让人烦躁,因为你做的事情看起来不"AI",但恰恰是这些数据工程细节,拉开了专业AI工程师和爱好者的差距。
6.3 第三阶段:生产环境实战与架构视野(持续进行)
第三阶段没有明确的终点。你需要开始接触真实生产环境的话题:模型的灰度发布怎么做、如何设计A/B测试方案、多个模型版本之间如何进行流量切分、如何设计推理缓存、如何压缩token成本。有条件的话,真的上云服务器操作一遍k8s部署,理解Pod、Service、Ingress、HPA这些概念在AI服务里面的具体呈现。
我也建议你开始阅读优秀的开源项目源码。目前最值得精读的AI工程项目包括FastAPI框架本身的源码、ChromaDB的向量检索实现、以及一些成熟的开源RAG项目如RAGFlow源码里的文档解析链路设计。带着"如果是我来写这个模块怎么写"的问题去读,收获会远超白嫖式的看README。
7. 学到后面,拼的不再是技术而是问题定义能力
做了这么多AI项目之后,我越来越觉得AI工程里最难练的其实是"问题定义能力"。业务方说"我要一个智能客服",这句话的信息量低到约等于零。你需要追问:服务什么渠道?处理哪些业务类型?知识库的更新频率是多少?用户问题倾向于短句还是长句?回答的容错边界在哪里?这些需求澄清工作做得好坏,决定了一个AI项目是被称赞落地漂亮,还是被骂"这东西根本没用"。
从技术上说,AI工程是"数据工程+模型工程+后端工程+可靠性工程"的交叉学科;从职业上说,AI工程师的价值不在于你会调用几个模型API,而在于你能把一个模糊的业务需求翻译成一套可评、可测、可运维的技术方案。这条路没有捷径,第一篇可以跟着我的骨架项目走,第二篇开始就要独立面对自己真实场景里的问题。做扎实每一个环节的经验,比囤一大堆"最全AI知识清单"有用得多。
最后分享一个我自己的习惯:每次做完一个AI功能,我都会写一份"这个功能将来可能怎么挂"的文档,里面记录模型失效的场景、数据漂移的征兆、以及对应的降级方案。AI工程的项目,不是上线那天就算完成,而是从上线那天才开始真正接受考验。把这个心态理顺,你在任何业务里都能稳稳接住AI带来的技术红利。