1. 先给"AI工程"祛个魅:它不是调库,是搭系统
这几年"AI工程"四个字被讲得太玄了。打开招聘网站,AI工程师的JD能列十几条技能树,从Transformer源码到K8s部署全要会,看着就让人想打退堂鼓。但真在行业里做久了你会发现,AI工程从零起步这件事,难的不是某个算法推不出来,而是大多数人一开始就把方向搞错了。
先说个我反复跟新人强调的观点:AI工程不是"用AI做东西",是"把AI做成产品"。这两者的差别非常大。前者是你在笔记本上跑通一个notebook,模型输出了看起来很聪明的话,你发给朋友看,朋友说哇。后者是你把这些能力封装成一个服务,别人能稳定地用、出错了能查、流量来了不崩、模型升级了不影响旧功能。这背后涉及的不只是模型本身,还有数据怎么管、成本怎么控、效果怎么评、系统怎么运维。
说个生活化的类比。会炒一道拿手菜,和开一家餐厅,是完全不同的两件事。炒菜是模型,餐厅是工程——你得管采购、排菜单、定流程、培训厨师、处理差评、控制翻台率。AI工程做的就是"把一道好菜变成一家能稳定营业的餐厅"的活儿。
这篇文章就围绕"ai-engineering-from-scratch"这条路来写。我不会一上来就给你扔一堆论文链接,也不会让你先啃三个月的线性代数再动手。我会按我实际走过的路径,告诉你哪些东西是真必须的、哪些是可以后面补的、哪些坑是几乎所有人都会踩的。适合正在转行做AI应用、或者刚入职做AI相关开发但觉得"什么都还不会"的读者参考。
2. 从零起步到底要先学什么:三层地基,别搞反顺序
网上关于AI学习路线的争议,比甜咸豆腐脑还大。有人说数学不好别碰AI,有人说Python不熟别碰AI,也有人说直接干就完了。我的答案是:都要学,但顺序和深度极其重要。
2.1 第一层地基:Python工程习惯,不是Python语法
如果你现在连Python都不会,那确实得先补语法基础。但请务必搞清楚一个点:你需要的不是"能写脚本"的Python,而是"能协作"的Python。这两者的差距在真实项目里会被无限放大。
我看过太多新人,函数写了两百行不拆、变量名叫a1/b2/c3、没有任何类型注解、错误处理全靠try-except吞掉。这种代码在notebook里跑没问题,一旦要上服务、接监控、有人review,基本就是灾难现场。
所以第一步,除了基础语法外,你至少要建立这几个工程习惯:
- 项目用虚拟环境管理依赖,requirements.txt或者pyproject.toml写清楚
- 代码用函数和类组织,一个函数只干一件事
- 关键路径上写类型注解,方便自己和别人读代码
- 配置和代码分离,API Key这类敏感信息绝不硬编码
这些建议看起来平平无奇,但它们决定了你能不能在真实团队里存活。我可以负责任地说,一个人Python基础是否扎实,不用聊算法,看他的目录结构就八九不离十。
2.2 第二层地基:机器学习常识,但别陷进去
AI工程确实需要懂模型,但"懂"的程度需要拿捏。我见过两类极端的人:一类是完全不懂模型原理,把AI当黑盒,出了问题只能瞎猜;另一类是沉浸在数学推导里出不来,一个self-attention能推三天,问到工程上怎么做缓存就摇头。
正确的姿态是:把模型当工具,但理解工具的脾气。你不需要从零实现一次反向传播,但你需要清楚这几个问题:
- 大语言模型本质上是"根据上文预测下文",所以它的"理解"和你不一样
- 模型有上下文窗口限制,不是所有信息都能塞进去
- 同样的问题,换一种问法,输出质量可能天差地别,这就是提示工程存在的意义
- 模型输出不是确定性的,同样的输入每次可能都不一样,工程上必须处理这种不确定性
这些认知不需要三个月,两周就能建立。但它们是后续所有工作的地基。
2.3 第三层地基:系统工程思维,最容易被忽略
如果你去问一个算法研究员和一个AI工程师最大的区别是什么,我的答案是:算法研究员追求的是模型效果的上限,AI工程师追求的是系统运行的确定性。
这句话怎么理解?模型效果再好,如果调用一次要等30秒、偶尔还给你返回一段乱码、一个月要烧掉几十万API费用,那这个产品就是不合格的。AI工程的核心矛盾,就是要在一个充满不确定性的模型之上,构建一个确定性的系统。
所以在动手做第一个AI项目之前,请你先在脑子里植入一个框架:任何AI功能,落到工程上都要拆成这几个环节——输入处理、模型调用、输出校验、失败兜底、效果评估、成本监控。你后续所有工作,都是围着这个框架转的。
3. 第一个能跑的项目:用LLM API搭一个最小可用系统
好多教程让你第一步就训练模型、微调模型,我觉得这是劝退新手最快的方式。从零开始做AI工程,第一个项目选错了,热情就烧没了。我的建议是:第一枪务必选一个"投入低、反馈快、能看到完整链路"的项目。
3.1 项目选型:为什么是"文档问答机器人"
我在带新人时,最推荐的第一项目是"基于自有文档的问答机器人"。原因有三:
第一,它不需要训练数据。训练、微调LLM需要准备数据集,这对新手来说是巨大的隐性成本,很多人卡在这一步就放弃了。而文档问答走的是检索增强生成路线,也就是常说的RAG,不需要你准备标注数据,你只需要有文档就行。
第二,它覆盖了AI工程的核心链路。这个看似简单的项目,实际上包含了文本加载、内容切分、向量化、向量存储、检索召回、大模型生成、流式输出、对话管理、效果评估,几乎覆盖了所有AI应用开发的环节。做完这一个项目,你对AI工程的整个流程就有了体感。
第三,它有着清晰的应用价值。做完之后你可以真的把它用起来,比如把你的博客文章做成一个问答机器人,或者把你的学习笔记做成一个知识库助手。我希望你的第一个AI项目做完之后是真有用的,不是跑完demo就扔在那里吃灰。
3.2 选型清单:新手少踩坑的推荐组合
说几个我用下来最顺手的组合,直接抄作业就行:
- 模型调用:OpenAI的GPT-4o-mini,或者国产的DeepSeek、通义千问都行,选你有渠道能稳定调用的那个
- 向量化:文本向量嵌入用OpenAI的text-embedding-3-small,或者BGE系列开源模型
- 向量存储:先别上Milvus、Weaviate这些重量级选手,用Chroma或者FAISS就够,本地跑通全链路再说
- RAG框架:LangChain或者LlamaIndex都可以,但我更建议第一遍先别用框架
最后一条多说两句。LangChain早期版本封装得太狠,新手出了问题根本不知道背后的机制,我身边不少人被它折磨得够呛。我的建议是:第一个版本不用任何RAG框架,直接用脚本方式把链路写出来——文档加载、切分、调向量化接口、存入向量库、检索、拼prompt、调LLM。这个过程写下来大概两百行代码,你得亲手摸一遍之后,再上框架就能理解它替你做了什么。这个"先裸写、再框架"的顺序,值得每个从零开始的人都试一试。
3.3 核心代码骨架:两百行摸清全链路
下面这段代码展示了最小闭环的核心逻辑,我把每一步都写了注释,你照着搭就能跑通:
# 步骤1:读取文档内容 from pathlib import Path text = Path("my_notes.md").read_text(encoding="utf-8") # 步骤2:按固定长度切分文本块 # 注意:切分是RAG效果的根基,块太小语义不完整,块太大检索不精准 chunk_size = 500 chunks = [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)] # 实践中更推荐按章节/段落结构切分,不要无脑按字符切 # 步骤3:调用向量化接口,为每个文本块生成向量 from openai import OpenAI client = OpenAI() def embed_texts(texts): resp = client.embeddings.create(model="text-embedding-3-small", input=texts) return [item.embedding for item in resp.data] vectors = embed_texts(chunks) # 步骤4:存入本地向量库 import chromadb chroma_client = chromadb.Client() collection = chroma_client.create_collection("my_docs") collection.add( documents=chunks, embeddings=vectors, ids=[f"chunk_{i}" for i in range(len(chunks))] ) # 步骤5:用户提问 -> 检索 -> 组装上下文 -> 生成回答 question = "我的博客上关于Python虚拟环境的最佳实践是什么?" q_vec = embed_texts([question])[0] results = collection.query(query_embeddings=[q_vec], n_results=3) context = "\n\n".join(results["documents"][0]) prompt = f"""请基于以下资料回答问题。如果资料中没有相关内容,请直接说明不知道,不要编造。 资料: {context} 问题: {question} """ response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}] ) print(response.choices[0].message.content)这段代码看着简单,其实信息量很大。你仔细品一下第2步的切分逻辑和第5步的检索逻辑,它们决定了整个系统的回答质量。后面我展开讲。
3.4 跑通之后别急着欢呼:先做三件"不性感"的事
Demo跑通只是万里长征第一步,很多人就是死在这个节点上。接下来这三件"不性感"的工作,才是从"跑通"到"能用"的真正分水岭。
第一,写一个最小化的测试集。准备20个问题,一半是文档里明确有的,一半是文档里完全没提的。跑一遍,把答案记下来。这是你后面所有改进的基准线。
第二,给API调用加上日志。每次调用记下:用了哪个模型、输入了多少token、输出了多少token、耗时多久、花了多少钱。没有这些数据,你的系统就是个黑洞,出了问题完全无从下手。
第三,做一个最简陋的Web界面。不用花里胡哨,Flask起个页面,能输入问题、显示答案就行。哪怕你自己一个人用,这个界面也会逼着你去思考"用户会怎么用"——而这个过程,就是产品思维的起点。
4. 真正卡住我的三个问题:工程化视角下的隐形陷阱
进入AI工程这个领域之后,你会发现真正让你掉头发的往往不是模型效果本身,而是一些"看起来应该很简单"的工程细节。我挑三个几乎所有人都会碰到的典型问题,把排查链路完整讲一遍。
4.1 文档问答答非所问:检索环节失效了
这是我第一个项目最大的翻车现场。我把一篇技术文章做成知识库,问"如何配置环境变量",模型回答的内容跟文章完全不沾边。第一反应是"模型不行",但我换了更强的模型后问题依旧,才意识到根本不是生成环节的锅。
排查过程是这样的。我先手动把用户问题拿去向量库里检索,看召回的前三条结果到底是什么。结果发现召回的文本块内容跟"环境变量"这个主题完全无关。再往下查,发现文章的正文里虽然频繁出现"环境变量",但切分后的文本块把标题和正文拆散了,每个块里只有零散的句子,语义不完整,检索自然匹配不准。
这个坑的根源就在切分策略上。我当时是按500字符硬切,把完整段落从中间一刀切断了。后来改成按Markdown的标题层级和段落结构切分,先按"##"分割大章节,再按段落分割成块,召回效果立刻就好起来了。
这件事给我的教训是:在RAG系统里,检索效果决定了系统效果的上限,而切分策略是检索效果的基石。你问得再好,模型再强,检索出的资料是错的,答案就不可能对。优化顺序一定是先优化数据侧,再考虑模型侧。
4.2 成本失控:一个月的API账单翻了三倍
第二个问题来得更隐蔽。系统上线两周后我查账单,吓了一跳——API费用高得离谱,而且还在加速增长。当时第一反应是"是不是有用户疯狂调用",结果一查日志,调用频率没有明显异常。
后来我把费用拆解到每次调用才发现,真正的问题在对话历史里。我的问答系统会在每次请求时把完整的对话历史回传给模型,看起来是为了多轮上下文连贯,但对话一旦长了,历史里的token数量指数级膨胀。用户问10轮之后,光是回传历史就要消耗几万token,而真正对回答有用的,往往只有最近两三轮的内容。
这不是个例,几乎每个初做对话系统的人都会栽在这里。解决方式也很直接:做滑动窗口,只保留最近N轮对话;同时定期做摘要压缩,把久远的对话内容概括成几句话再塞进上下文。另外还有一个习惯要养成:所有prompt模板里的固定内容也占token,模板写得越啰嗦,成本越高,精简模板能省出一笔不小的钱。
4.3 同样的输入,答案忽好忽坏:输出不确定性被低估了
第三个问题是最容易让非技术背景的人崩溃的:同一个问题,早上问和晚上问,答案风格不一样;同一分钟问两次,一次好一次差。
这在LLM应用里是常态,模型的采样参数决定了输出天然有随机性。工程上怎么处理?首先把不该随机的地方固定下来:调用API时设置temperature参数,需要稳定输出的场景把它调到0甚至更低。其次,如果你对回复格式有严格要求,比如需要JSON输出、需要固定字段,那必须在prompt里给出严格的格式说明,并在代码侧做输出格式校验,解析失败就重试一次。
但还有一层更深的问题:模型版本会变。你昨天调试好的prompt,今天可能因为模型供应商升级了后端模型而效果突变。这个问题几乎无解,唯一的应对措施是:把prompt和模型版本都纳入版本管理,每次模型升级后都跑一遍评估集,用数据说话,而不是凭感觉。这也是为什么我前面让你准备20个测试问题——它们就是你的回归测试集。
5. 从"最小可用"迈向"真正可用":部署、评估与Agent实践
如果你已经跑通了一个完整项目,并且把前面那三个坑都踩了一遍、填平了,那恭喜你,你已经完成了从0到1的过程。接下来这个阶段,是从1到100,核心工作是让系统真正"可交付"。
5.1 部署的克制:别一上来就上K8s
说句实在话,现在很多教程特别喜欢让你上Kubernetes、容器化加微服务,我觉得这是严重的本末倒置。作为一个从零起步的人,你最大的敌人是复杂度——它会把你的精力从功能开发上全部抽走,让你陷入YAML配置的泥潭里。
我建议的部署路径是分层的。第一层:单体应用加一个普通Linux服务器。用systemd管理Python服务进程,加一个Nginx做反向代理,再配一下HTTPS证书,这就够了。第二层:当你真的需要隔离环境、快速扩容时,再引入Docker。第三层:当你的服务需要自动伸缩、多实例管理时,再去碰Kubernetes。我的经验是,90%的AI应用垂直场景,走到第二层就够了。
这里有一个具体的建议:部署之后,一定要配一套最基础的可观测体系。至少包括三块——错误日志(进程报了哪些异常)、性能指标(接口响应时间、模型调用耗时)、业务数据(每天有多少次调用、答了多少问题)。这三样配齐,你才有资格说这个系统是"可运维"的。
5.2 用评估集倒逼效果提升:让改prompt不再靠感觉
很多人在优化AI应用效果时,做法非常随缘:觉得效果不好就换个措辞再试,试了几次效果似乎好了,就收工了。这种做法最大的问题在于,你根本不知道"变好"是真的变好了,还是只是这次碰运气。
正确的姿势是:建立一个可持续的评估机制。我做评估的方式很简单,但也够用。先是准备一个评估集,大概50到100条,覆盖正常问题、边界问题、不该回答的问题这些类型。然后每次改动prompt、调整检索参数、更换模型版本时,都跑一遍评估集,记录每次的得分情况。
评估打分不需要太复杂,初期用"三档制"就够:完全正确、基本可用、完全错误。你不需要给分数,只需要一个相对标准。为了让打分者更客观,我建议先把预期答案写好,再跑模型输出,逐个对比。凡是"完全错误"的案例,一律拉出来归因:是检索没召回到正确资料,还是模型没理解资料,还是prompt没说清楚输出要求。这样每轮迭代都有明确的方向,不再是你跟模型之间的一场玄学博弈。
5.3 从"单次问答"到"Agent":记住,复杂度是渐进长出来的
RAG做的问答机器人本质上是一次检索加一次生成,它没有"做事"的能力。当你开始不满足于此,想让AI帮你查天气、订机票、查数据库、自动执行多步骤任务时,就进入了AI Agent的范畴。
Agent的核心机制是什么?拆开来看,无非是三件事:让模型理解当前任务、给模型提供可调用的工具列表、让模型在循环里决定"下一步该调用哪个工具"。中间涉及任务规划、工具调用、结果解析、循环终止判断等机制。但我要提醒你的是:Agent的每一步都引入了新的不确定性。模型可能选错了工具、可能循环不终止、可能生成了格式正确的调用但参数是错的。
我见过太多人看完Agent的概念之后热血沸腾,一上来就要做一个全自动的智能体。我的建议非常保守:从"单步工具调用"开始。先让模型学会"根据用户意图调用一个查询函数";稳定之后,再加"多步规划";再稳定,才考虑"多个Agent分工协作"。每一步都要用你的评估集卡一遍效果,别让复杂度跑在你的掌控力前面。这个道理放在Agent上也成立:复杂度是长出来的,不是设计出来的。
5.4 关于模型微调:先别急,等你真的撞到天花板再说
随着项目深入,你一定会动"要不要微调一个自己的模型"的念头。很多人在这个念头上一头扎进去,花了几周时间准备数据、租GPU、训练,最后发现效果提升极其有限。
我要非常坦诚地说:基于我见过的大量案例,绝大多数人在做AI应用时,真正需要的是更好的prompt、更好的检索、更好的上下文管理,而不是微调模型。微调适合什么场景?你的任务形态很稳定——比如你只要模型输出固定格式的JSON,或者你的问答风格非常固定——同时提示工程无论如何都达不到你的要求,那时候才轮得到微调上场。在那之前,把精力花在数据侧和检索侧,性价比高得多。
6. 从零到一之后,我的几点掏心窝建议
文章写到最后,不打算再给你灌输什么全景路线图,就说说我自己走过来之后,普遍会对后来者说的几句话。
第一句话是,AI工程从零开始,最重要的不是学会某一个具体的工具,而是建立"用系统视角看AI"的思维习惯。当你面对任何一项AI能力时,脑子里自动浮现出"输入处理、模型调用、输出校验、失败兜底、效果评估、成本监控"这条链路,就算入门了。这个思维的建立,不靠刷教程,靠的是亲手把一个项目跑起来再反复打磨它。
第二句话是,一定要善待你的评估集和日志。这两样东西是你最忠实的同事。你改prompt时它在、你换模型时它在、你调检索参数时它还在。有了它们,你的每一次优化都是确定性动作,而不是掷骰子。
第三句话是,保持好奇和动手的习惯。AI这个领域迭代速度快得惊人,上个月还在用的工具,下个月可能就过时了。但只要你已经建立起了"拆解一条链路"的能力,任何新工具本质上都是往这条链路的某个环节填一个实现而已。我在实际使用中最大的体会就是,有了从零搭建一次系统的经验兜底,再学什么东西都快。
最后再分享一个让这个项目可以继续扩展的小技巧:把跑通的RAG项目改造成支持多知识库版本。同一个框架,接不同的文档目录,就能变成不同场景的问答助手。这一步做完之后,你会发现AI工程的套路感一下子就出来了——原来不同的应用场景,本质上是在复用同一套工程骨架。这也是我最想让你从这篇文章里带走的东西:骨架在你手里,剩下的事情,就是往里填你想要的内容了。