
说了你可能不信我写了六年常规后端真正转向AI工程之后最颠覆我认知的不是那些花哨的模型能力而是“AI工程从零开始”这句话的含金量。很多人以为from scratch就是从头啃一遍Transformer论文或者把某个开源模型微调一把。但等到我亲手把一个AI应用从空目录撸到生产环境才发现真正的门槛根本不在模型侧而在于完整的交付链路——数据准备、检索设计、评估体系、成本控制、可观测性每一环都能把你按在地上摩擦。这篇文章我就把这套从零到一的路数完整摊开包括我当时怎么选型、怎么搭骨架、怎么踩坑又怎么补回来的全过程。如果你正准备入行AI engineering或者已经在做AI应用但总觉得差点体系感这篇应该能帮你省下不少弯路。1. 为什么说“from scratch”的起点不是模型而是交付链路1.1 我理解的AI工程不是“调API”也不是“训模型”先明确一个容易混淆的前提。AI工程AI engineering和算法研究、数据分析是三条完全不同的路。算法研究要的是在某个benchmark上刷分核心工作是改进模型结构、优化训练策略数据分析要的是从数据里找规律、出结论而AI工程的核心交付物是“跑在生产环境里、被真实用户使用、具备可维护性和可控性的AI系统”。调API只是AI工程里最表层的一环。当你好不容易把模型接口调通后面还有一串没人替你操心的问题这个模型输出的内容怎么保证可靠用户乱问的时候系统怎么兜底知识库更新了检索结果怎么跟着变模型调用成本上去了怎么优化出了问题怎么定位是提示词的问题、检索的问题还是模型本身的问题这些才是AI工程真正要解决的。我见过不少从传统开发转过来的同事上手第一周就兴冲冲地把GPT-4接进项目结果上线两天就被老板叫停——不是因为模型答得不好而是因为用户问了一个知识库之外的问题系统一本正经地编了个答案差点闹出事故。那一刻我才明白一个AI应用能用和能用得住之间隔着整整一个工程化的距离。1.2 从传统后端转向AI领域时的思维转换这个思维转换是我踩坑之后才顿悟的值得先说透。传统后端的核心思想是确定性。你写一个接口输入固定输出就是固定的。测试也简单——构造几个用例断言返回结果就行。但AI系统天生不确定同一个问题同一个模型稍微改几个字输出就可能不一样昨天跑得好好的今天模型服务端一更新行为又变了。这种不确定性带来的第一个冲击就是——你的测试怎么写你的上线流程怎么定我的答案是把AI工程拆成“确定性的壳”和“不确定性的核”。壳的部分——API接口、数据库访问、权限控制、消息队列、部署流程全部沿用传统工程的严格规范该测试测试该CI/CD就CI/CD。核的部分——模型调用、提示词、检索逻辑单独做成可插拔的模块用评估指标来约束而不是用断言来约束。打个不太严谨的比方传统开发像造机械手表零件公差必须以微米计AI工程像驯鹰你管不了它每一秒怎么扇翅膀但你得保证它该回的时候能回来、该抓的时候能抓住。你要建立的是“控制边界评估回收”的能力而不是追求对每个输出像素级掌控。这个认知不扭转后面所有步骤都会走形。2. 动手前先画地图AI工程的路线拆解与第一个项目选择2.1 从业务需求逆推技术栈我们常说技术选型但AI领域里很容易被“流行”带跑。今天LangChain火了就学LangChain明天LlamaIndex火了又换后天RAG要退休了又开始搞Agent最后一年过去啥都会一点啥都没落地。我的习惯是先画一张从业务需求逆推的路线图每一步都问自己“这一步到底解决什么问题”。先列需求再列能力点再落技术选型。举个例子假设你要做一个企业内部知识库问答系统需求拆出来是这样的用户提问系统基于指定文档回答 → 需要RAG检索增强生成回答必须注明出处不能编造 → 需要引用溯源与幻觉检测文档会持续更新 → 需要文档切片、入库、版本同步的流水线上线后要监控回答质量 → 需要离线评估集与在线反馈埋点用户量增长后成本要可控 → 需要模型分级、缓存、检索优化这一套拆下来你自然就知道该学什么了文档解析、向量化、向量数据库、检索策略、提示词工程、评估体系、可观测性。每一项都有明确指向不再是为了学而学。我个人的建议是第一个AI项目不要选得太复杂。做Agent多智能体协作先放着。第一项目就做RAG文档问答它覆盖了AI应用里80%的通用工程问题数据、检索、生成、评估、迭代。把一个RAG做到生产级比搭十个玩票的Demo值钱得多。2.2 选择第一个落地项目时我考量的三条标准我当初选项目给自己定了三条硬标准分享给你可以直接抄业务价值必须立竿见影。做出来的东西要么让自己日常提效要么让同事愿意用。我做的是一个团队内部的项目文档问答机器人把散落在几十个文档仓库里的知识统一收口搜索效率提升是能直接感受到的。这比做一个“天气助手Demo”更有动力撑到上线。数据范围必须可控。一开始不要接全公司的数据先选三五个稳定、格式规整的文档源。数据范围越小排查问题越容易。等流程跑通再逐步扩。评估能闭环。这个项目有没有做对必须有一个可重复验证的方式。我给自己定的标准是每次改完提示词或检索策略至少跑一遍固定的测试集分数不能下降。这条标准后来救了我无数次。3. 工具链搭建实录从零配置一套用得住的AI工程环境这一节全是实操。我从空目录开始把每一步的记录和当时的思考完整写出来。环境是macOSPython版本管理用的是pyenv项目依赖管理用的Poetry这套组合在团队协作和CI环境里都很稳。3.1 Python环境、依赖管理与项目结构先搞定Python版本。AI生态对Python版本有很强的依赖有些库在3.9上有问题有些在3.12上还没适配所以千万别用系统自带的Python。我锁的是Python 3.11兼容性最好主流AI库基本都跟上了。pyenv install 3.11.9 pyenv local 3.11.9 poetry init poetry env use 3.11.9项目结构我直接给你看这是我迭代了好几版之后稳定下来的ai-engineering-from-scratch/ ├── app/ │ ├── api/ # FastAPI路由、请求/响应模型 │ ├── core/ # 配置、日志、异常处理 │ ├── models/ # 数据模型ORM实体 │ ├── services/ # 业务逻辑层问答服务、检索服务 │ ├── providers/ # 模型Provider抽象与实现 │ └── utils/ # 工具函数 ├── data/ │ ├── raw/ # 原始文档 │ ├── processed/ # 清洗后的Markdown │ └── vector_store/ # 向量数据库存储路径 ├── scripts/ │ ├── ingest.py # 文档入库流水线 │ └── evaluate.py # 离线评估脚本 ├── tests/ ├── pyproject.toml └── .env.example # 环境变量模板这个结构的核心思想是把“模型相关”和“应用逻辑”隔离。providers这个目录名很早就起好了意思是将来不管接OpenAI、Claude还是本地模型都只动这一层其他代码尽量不动。3.2 模型接入层的抽象设计别把供应商SDK写进业务代码这是我从第一个Demo转向工程化时改得最彻底的地方。当时图省事直接在业务逻辑里调用OpenAI的SDK后面想换Claude的时候差点把整个service层重写。后来我把模型调用抽象成Protocol接口所有业务代码只跟这个接口打交道。# app/providers/base.py from typing import Protocol class ChatMessage(TypedDict): role: str content: str class ModelProvider(Protocol): provider_name: str def chat( self, messages: list[ChatMessage], temperature: float 0.2, max_tokens: int 1024, ) - str: ...然后分别实现OpenAIProvider、ClaudeProvider。业务层——比如问答服务——永远只需要这样调用provider: ModelProvider get_provider(config.active_provider) answer provider.chat(messagesconversation_history)这样一来换模型的成本被压缩到“新增一个provider实现改一行配置”。我自己后面从GPT-4切换到更便宜的模型做分流测试整个过程没动过一行业务代码。3.3 向量数据库与检索组件的取舍向量数据库的选择我建议按数据量来分档。个人项目或者内部小团队直接用Qdrant的本地模式就够了它也可以无缝升级成docker容器模式。如果是百万级向量起步的企业级项目再去考虑Milvus或者专门的向量检索云服务。docker run -p 6333:6333 qdrant/qdrant为了不在开发环境里反复折腾服务依赖我Map了本地模式来写单元测试集成环境再用Qdrant容器。本地模式用法很简单内存目录指定一下就是临时数据库测试跑完数据自动消失。# 本地模式示例适合开发和测试 from qdrant_client import QdrantClient, models client QdrantClient(path./data/vector_store) client.create_collection( collection_nameknowledge, vectors_configmodels.VectorParams( size1536, distancemodels.Distance.COSINE, ), )向量维度为什么是1536因为后端默认用的text-embedding-3-small模型输出就是1536维。这里的教训是Embedding模型的版本和维度一定要在代码里写死不能悄悄升级否则你之前所有入库的向量和新的向量直接没法比检索效果会瞬间崩掉。切片策略我简单说一下正式环境的文档切片我用的是按Markdown标题结构切分每个二级标题下的内容作为一个独立语义块如果块太长再按固定长度截断同时保留50个字的重叠区。这样检索到的片段在语义上是完整的而不是简单按字符数硬切。embedding模型用的OpenAI的text-embedding-3-small性价比在文档数量不大的场景下非常能打。4. 从零跑通一个端到端AI应用文档问答系统的完整落地4.1 需求定义与数据准备先把输入侧管干净需求定义看似平淡但这里有个坎你觉得需求很清晰等做出来用户就说不是他们想要的。我建议在项目第一天就花半天时间和核心用户对齐“系统必须能回答的三个问题类型”和“绝对不能胡说的边界”。我的项目是团队内部的项目文档问答机器人定下来三个核心场景“这个项目的部署流程是什么”“这个API的认证方式是怎样的”“最近一次发布的变更记录有哪些”边界是涉及内部敏感信息、尚未定稿的设计方案一律回答“知识库中没有相关内容”并引导用户查阅指定文档入口。数据准备的细节别小看。原始文档格式五花八门Word、PDF、Markdown、Confluence导出的HTML。我统一把它们转成Markdown再清洗掉页眉页脚、导航栏、表格里多余的换行。清洗过程中最大的坑是PDF里的多栏文本直接转Markdown后会左右两栏的内容交错在一起检索出来的片段无法阅读。这个问题的解法是用PDF解析库开启双栏检测模式或者用视觉模型做版面识别后再重排。我的文档里PDF占比不高所以先用开源库做转换遇到版面混乱的文档单独人工标记后续再考虑上专门的版面分析服务。入库流程我写成了一个独立的脚本也就是早期只有几十行、后来迭代到几百行的ingest.py。它会做这几件事读取文档 → 转Markdown → 清理 → 按标题结构切片 → 批量embedding → 写入Qdrant。整个流程用Hash记录文档版本文档更新时只重新处理变更部分避免每次全量重跑。4.2 RAG架构的落地细节检索与生成的粘合RAG跑通的完整链路是用户问题 → 向量化 → 向量检索 → 拼装Prompt → 模型生成 → 返回并记录评估数据。当时让我在“手感上好用”和“架构上可演进”之间做权衡的分叉点是要不要用LangChain这类框架。我最后的决定是直接用原生代码实现一个轻量RAG管线不用框架的现成Chain。原因有三项目数据流其实不复杂原生代码几十行就能写清楚框架的抽象反而增加一层理解成本出问题时框架黑盒难排查原生代码里每一步都在自己掌控下我们后续要自定义评估逻辑和检索策略原生代码改造起来最灵活。检索核心就两件事查询向量化和相似度搜索。def retrieve(query: str, top_k: int 4) - list[DocumentChunk]: query_vector embedding_model.embed(query) hits vector_store.search( collection_nameknowledge, query_vectorquery_vector, limittop_k, ) return [chunk_from_hit(hit) for hit in hits]拼装Prompt的时候上下文顺序是有讲究的。按相关度从高到低排列然后用分隔符清楚标出参考资料和问题的边界。系统提示词里明确要求当且仅当参考资料能支持结论时才回答否则直接说不知道。这个看似简单的约束在后期评估里证明了它是降低幻觉最有效的一层防线。很多幻觉不是模型不会答而是提示词没告诉它“不回答也是一种合法的输出”。4.3 评估体系的搭建没有度量就没有迭代评估是AI工程里最容易被跳过的环节但恰恰是最值得投入的一环。没有评估你每次改提示词都是在掷骰子。我的评估分为两个层面。第一层是离线评估固定一个有代表性的问题答案集每次改动后跑一遍看指标变化。评估指标我用的是三方独立的开箱套件逻辑实现的忠实度faithfulness回答是否忠于参考资料、答案相关性answer_relevancy是否切题、上下文精度context_precision检索到的资料是否精准覆盖答案需求。第二层是在线监测用户在真实问答后对回答进行点赞/点踩点踩的样本自动沉淀到再评估池每周人工抽检一次识别系统性的失败模式。离线评估的脚本长这样# 先在评估集上跑 poetry run python scripts/evaluate.py --testset tests/fixtures/eval_set.json输出会按问题列出一个表格每个问题的faithfulness、answer_relevancy、context_precision以及综合判定是否通过。判定的阈值一开始可以放宽但一旦系统要发布就必须设定硬性门槛比如忠实度低于0.85就算失败不允许上线。有了评估体系之后我再也不怕改东西了。这可能是“from scratch”最关键的转变从一个“改了就慌、不改难受”的状态变成“一切改动都有度量结果背书”的稳定状态。5. 上线之后才明白的工程坑幻觉控制、成本与可观测性5.1 幻觉问题的工程化应对三层防线逐级设防幻觉是AI应用绕不开的话题。工程化的目标不是“完全杜绝幻觉”——这在当前技术条件下不现实——而是把幻觉出现的概率压到可接受范围且在幻觉发生时能及时发现。我搭的三层防线每层解决一个不同的问题第一层是入口约束。通过系统提示词和用户输入侧的检查给模型框定行为边界只基于参考资料回答、不知道就明说、禁止揣测内部信息。这一层解决的是“模型不知道自己在不知道”。第二层是溯源强绑定。每次回答必须在末尾列出引用的文档片段编号并且回答正文中涉及关键事实的地方通过检索出的上下文做交叉比对校验。具体实现是要求模型以结构化JSON输出答案和引用链服务端再校验引用是否真实存在、引用片段是否确实包含回答中的关键实体。如果校验失败就走兜底话术。这一层解决的是“模型编了一个看起来很像真的答案”。第三层是反馈闭环。前面说的在线点踩、人工抽检本质是把模型答错的样本持续收回来不断修正系统。这层解决的是“有些错只有真实用户会触发测试集发现不了”。三层叠完之后线上幻觉投诉率明显下降。虽然做不到零但至少事故从“用户发现”变成了“监控发现”。5.2 成本、延迟与可观测性AI应用上线后第二个难受点就是账单。模型调用是纯边际成本用户每次提问都在花钱而且这个钱和回答质量不直接挂钩。我做了三件事控制成本模型分级简单的检索型问题走便宜的轻量模型复杂的推理型问题才走旗舰模型。分级规则可以放在provider层判断也可以根据问题长度和类型做路由。缓存完全相同的用户问题在一定时间窗口内直接命中缓存不重复调用模型。这个要看业务场景文档问答里用户高频问同样问题的情况其实不少。上下文裁剪把检索回来的文档做硬上限控制比如最多送入4个片段、每个片段不超过500字。多出来的内容宁可丢了也不要全塞给模型。延迟方面最大的瓶颈往往是模型推理排队发生在模型服务端。工程上能做的就是并行检索不同数据源的片段、尽量减少Prompt长度、必要时用流式输出改善用户感知。流式输出体验要好很多用户第一句话往往一两秒内就能出来。可观测性这块除了常规的API监控之外AI应用最关键的是记录每一次请求的完整链路用户问题、检索到的片段ID列表、送入模型的Prompt全文、模型输出、耗时、token消耗、评估得分。我用结构化日志把这些数据全部落盘后面分析问题就全靠这个。没有这批数据出了问题你只能靠猜。logger.info( ai_request, extra{ question: question, retrieved_ids: retrieved_ids, prompt: built_prompt, answer: answer, latency_ms: latency_ms, tokens_prompt: tokens_prompt, tokens_completion: tokens_completion, evaluation: eval_scores, }, )6. AI工程能力的长期养法迭代节奏、复利清单与个人经验6.1 从“做出来”到“养起来”每周迭代节奏系统上线不是终点而是AI工程真正开始的地方。我给自己定了一个每周迭代节奏疫情之后也一直保持下来每周一看在线数据。前一天积累的用户问题、点踩样本、评估分数逐条过一遍挑出三个最典型的问题。每周二改一个方向。针对那三个问题要么调整提示词、要么优化检索策略、要么补数据。每次都只改一个变量不然没法归因。周三到周四跑评估集对比上一版的分数。分数不降就合并分数降了立刻回滚并复盘。周五更新测试集。把本周新发现的失败样本加入评估集防止未来回归。这套节奏听起来慢但复利效应很强。三个月以后评估集从最初的50条长到300条系统的稳定性和边界处理能力肉眼可见地提升。6.2 我的学习清单与持续输入策略关于学习我避免陷入“每天刷论文”的状态。论文当然要看但要带着问题看。我的输入策略是三层第一层是系统学习把RAG、Agent、微调、评估这几大块各找一本经典书或一份权威课程系统过一遍形成框架。第二层是源码阅读直接读LangChain、Qdrant这些核心工具的关键源码路径理解封装之下的真实逻辑。第三层是热点追踪关注一线工程团队的博客和案例复盘尤其是他们踩坑和回滚的部分这些往往是文档里读不到的。这个三层策略让我在信息爆炸的AI领域里保持了心态稳定。你没法什么都学但你可以保证学进来的东西是成体系的、能落地的。最后再分享一个小技巧把你所有踩过的坑、做过的决策、验证过的数据整理成一个自己的“工程决策日志”哪怕只是每次花五分钟记录。三个月后再翻你会发现自己已经路径清晰地走过了很多当初觉得步履维艰的路。AI engineering的道路很长但每一步扎实走下去回头看时会觉得所有付出都值得。