从零搭建AI工程能力栈:RAG系统开发的技术路径与实践
发布时间:2026/10/3 15:30:22 锦皓数字建站

很多人第一次接触“AI工程”这个词脑子里浮现的都是一堆云里雾里的概念比如大模型、微调、RAG、Agent然后下意识觉得这是算法研究员才能碰的东西。实际上AI工程AI Engineering和算法研究完全是两条技能树。我过去这十来年从前端到后端再从后端一头扎进AI应用开发最深的感触就是AI工程本质上是“软件工程 机器学习 数据工程”的交叉学科它解决的不是“模型怎么训练出来”的问题而是“模型怎么用起来、用得稳、用得起”的问题。这篇博文我就结合自己从零搭建AI工程能力栈的完整经历聊聊我理解的“ai-engineering-from-scratch”以及如果你也想走这条路应该怎么下手。这篇内容适合三类人看一是被各种AI概念轰炸、想入行却不知道从哪开始的转行者二是已经在写业务代码、想在项目中引入AI能力但怕hold不住的后端开发者三是刚招了AI工程师、但不知道如何让团队高效协作的技术管理者。我会尽量用大白话把我踩过的坑、验证过的路径、以及核心的实操细节都摊开来讲希望能给同路人一个参考。1. AI工程的整体技术全景与思路拆解1.1 AI工程到底在解决什么问题先说一个反常识的结论AI工程里最不值钱的反而是“训练模型”。早些年大家都迷信算法觉得模型训练出来就万事大吉但实际上一个模型从实验室到生产环境中间隔着的不是“准确率提升1个点”而是一整套系统工程。我给一个生活化的类比。假设你开餐厅菜谱模型算法只是基础后厨怎么备菜数据处理、厨师怎么按标准流程炒菜推理服务、服务员怎么上菜API网关、顾客吃完怎么反馈优化监控与迭代这整条链路才是AI工程要管的事。单一某个环节再强只要其他环节拖后腿顾客体验照样崩。所以AI工程的核心目标有三个可用性模型能不能稳定对外提供服务算力资源够不够延迟高不高。可靠性输入数据的分布发生变化时模型会不会突然“失灵”服务挂掉后能不能自动恢复。可维护性模型版本怎么管理特征怎么保障线上出问题时怎么快速定位是模型原因还是数据原因。这三件事每一项都对应着具体的工程化手段而不是靠拍脑袋或者堆硬件能解决的。1.2 从AI到AI应用落地的完整链路拆解我习惯把一条完整的AI应用链路拆成七个环节任何一个环节出问题整个应用都跑不起来数据获取与清洗数据是一切AI应用的原材料这步没做好后面全是白费。特征工程或Prompt设计决定把原始数据变成什么样模型才能“看懂”传统机器学习靠特征工程大模型时代靠Prompt模板和思维链设计。模型的训练、微调或选择对于中小团队大多数场景是用基座大模型 少量业务数据微调或者干脆用开源模型做适配。模型评估与准入在把模型部署到生产环境前要用一套评估集验证效果测评不只是准确率还有成本、延迟和安全维度。模型部署与推理优化在线的API服务、批处理任务、模型量化都是这一环节的活。应用集成与产品化模型要和你的业务系统打通封装面向用户的功能这步需要大量的后端工程能力。监控、反馈与持续迭代模型上线只是开始不仅监控系统状态还要监控模型在真实数据上的表现持续用新数据迭代。我刚入行时最大的误区就是过度关注环节3和5也就是模型训练和部署觉得这两块是“技术含量”最高的地方。后来被现实教育了很多次才悟出在工业界数据环节环节1、2和监控迭代环节7往往是决定项目成败的关键也是真正拉开普通团队和成熟团队差距的地方。1.3 为什么选择“从零开始”这条路径市面上已经有很多现成的框架比如LangChain、LlamaIndex、LangSmith或者云平台的一键部署工具。那为什么我现在特别强调“from scratch”也就是从零开始的路径这绝不是为了故作高深而是因为AI技术栈的“封装层”太厚了。如果你一上来就用LangChain你会发现确实很快几个函数调用就能拼出一个基于大模型的问答应用。但一旦遇到问题比如改Prompt怎么不生效、为什么某个回调没有触发、上下文管理到底怎么工作的你会发现自己非常无助因为框架帮你做的封装同时也屏蔽了底层原理。这种“知其然而不知其所以然”的状态在快速验证想法的时候没问题但在生产环境一定出大问题因为你没法排查问题也没法从根源上做性能优化。从零开始的路线本质上是让你在“什么都不知道”的状态下亲手走一遍AI应用的最小链路。哪怕你最终还是会使用框架但到那时框架对你来说只是“提升效率的工具”而不是“离了就不会写代码的黑盒”。这种底层的理解是AI工程师跟“调包侠”的分水岭。2. 核心技能栈拆解与工具选型要点2.1 编程基础Python是起点但绝不止于Python几乎所有AI项目的首选语言都是Python原因是它的生态实在太完善了NumPy做数值计算、Pandas做数据处理、PyTorch做模型训练、FastAPI做服务化几乎每个环节都有成熟的库。但如果你只会Python在做AI工程时会经常卡壳因为现实世界的AI系统从来不是孤立运行的。我给你列一下我在实际项目中真正用到的编程语言和场景Python数据处理、模型推理服务、实验脚本80%的AI工作流都靠它。SQL数据提取、特征加工、结果分析很多AI工程师居然不重视SQL这在真实工作中非常吃亏因为你的数据大概率在数据仓库里。Bash / Shell环境搭建、任务调度、日志排查不会写Shell脚本你连基础的数据清理任务都自动化不了。Docker / Kubernetes配置镜像构建、容器编排、资源管理这决定了你的模型能否被团队里的其他人一键拉起。如果你是完全的编程新手我的建议是别一上来就啃算法书直接用项目驱动的方式先写Python脚本处理一个CSV文件再用FastAPI把它变成一个接口然后慢慢扩展到其他技能。编程的“手感”比“概念”重要得多。2.2 机器学习与深度学习不需要成为数学专家很多转行者最大的心理障碍是“数学不好”。这里我可以负责任地说一句AI工程所需要的数学知识远没有你想的那么高深。你不需要自己能推导复杂的损失函数你只需要理解它们是什么、什么时候该用哪个、以及参数调整的大致方向。以我个人的经验真正高频使用的数学知识其实就这三块线性代数理解向量、矩阵运算这是掌握Embedding向量的核心也是理解Transformer里自注意力机制的基础。不需要会手算能看懂Shape变化就够了。概率统计理解分布、均值方差、置信区间这在做评估和异常检测时特别有用。微积分基础理解梯度下降的直观概念知道学习率是干什么的。至于链式法则、反向传播的具体推导绝大多数AI工程师也用不到。我的学习策略是“用到再学”。当你跑通了第一个模型发现loss不下降去查学习率是怎么影响更新步长的时候你对梯度的理解会比死磕一个月教科书来得深刻得多。2.3 工具链与平台从零搭建你的AI地基实操之前先把地基打好。我用一套开源为主的工具链搭建了我的AI工程环境整套组合灵活且零授权成本非常适合个人学习和中小企业起步开发环境VS Code Jupyter Notebook。Notebook做实验探索VS Code写正式代码两者互补非常顺手。数据生态Pandas Polars SQLite。小数据量用Polars性能好关系型数据结构我用SQLite后续要上生产再平滑迁移到PostgreSQL。模型框架PyTorch HuggingFace Transformers。PyTorch的生态和资料丰富度都远好于其他选择HuggingFace提供了一个巨大的模型仓库极大地降低了大家接触各种模型的门槛。服务化FastAPI。自带OpenAPI文档、异步支持结合uvicorn就能把模型包成一个服务学习和生产都能用。容器化Docker。约束环境、保持一致性你想让别人或者另一台机器也能跑起来你的项目Docker是最基本的保障。编排与调度Kubernetes生产环境 Airflow任务调度。这块学习曲线很陡建议先搞懂Docker和单机部署再逐步接触K8s否则容易劝退。工具选型的核心原则是“新手友好 社区活跃 能平滑迁移到生产”。我在搭建时刻意忽略了诸如SQLite不该用于生产这类耳闻因为对从零起步的场景快速验证往往比一步到位更重要先把流程跑通再逐一替换成更专业的组件。3. 实操过程亲手搭建一个完整的AI工程最小系统3.1 Step 1定义场景与目标纸上谈兵没意义我直接以“搭建一个面向技术文档的智能问答机器人”为目标演示从数据到服务全流程。为什么选这个场景因为技术文档的数据干净、结构清晰、容易获取而且问答这个任务可以直观感受到AI的能力边界特别适合练手。我们的任务定义是输入一篇Markdown格式的技术文档输出一个API接口允许用户提问关于文档内容的自然语言问题并得到带出处的回答。技术上我决定采用“检索增强生成RAG”路线也就是先根据用户问题检索最相关的文档片段再把片段和问题拼在一起输入到大模型里让它总结回答。3.2 Step 2环境准备与依赖安装首先创建一个干净的Python虚拟环境这能避免不同项目之间的依赖冲突是我一开始被教训过好多次才开始坚持的习惯。然后安装必要的软件包mkdir ai_engineering_demo cd ai_engineering_demo python -m venv .venv source .venv/bin/activate # Windows下用 .venv\Scripts\activate pip install fastapi uvicorn sentence-transformers faiss-cpu openai说明一下这几个包的选择理由FastAPI和uvicorn是服务层sentence-transformers用来做文本向量化faiss-cpu是向量检索库我在这里用CPU版本做本地学习生产时再替换成GPU或更专业的向量数据库openai包里封装了调用大模型API的代码方便我快速接入推理能力。3.3 Step 3数据处理与向量化在RAG链路中第一步是把文档切分成“块”Chunk并对每块进行向量化。这里有一个直接决定效果好坏的细节切分策略。我用一个最直观的方法是按标题层级切分而不是固定字符长度。因为文档的语义边界通常在章节处比如“## 3. 实操过程”下的内容围绕同一个主题。如果机械地每隔500个字符切一刀很容易把一个完整的话题切得支离破碎。下面是我用的核心代码import re from typing import List def split_by_headings(markdown_text: str) - List[str]: 按Markdown的二级和三级标题切分文档 把每个标题及下面跟着的内容拼成一个chunk。 # 找到所有标题及其行号 heading_regex re.compile(r^(#{2,3})\s(.)$, re.MULTILINE) matches list(heading_regex.finditer(markdown_text)) chunks [] for idx, match in enumerate(matches): start match.start() end matches[idx 1].start() if idx 1 len(matches) else len(markdown_text) chunk markdown_text[start:end].strip() if chunk: chunks.append(chunk) return chunks切完之后用sentence-transformers将每个文本块编码成向量再将向量写入Faiss索引from sentence_transformers import SentenceTransformer import faiss import numpy as np model SentenceTransformer(BAAI/bge-small-zh-v1.5) chunks split_by_headings(open(docs/example.md, encodingutf-8).read()) chunk_vectors model.encode(chunks, normalize_embeddingsTrue) # 构建Faiss索引 dimension chunk_vectors.shape[1] index faiss.IndexFlatIP(dimension) # 内积点积索引配合规范化等价于余弦相似度 index.add(np.asarray(chunk_vectors.astype(float32))) # 保存元数据 import json meta [{text: c} for c in chunks] with open(chunks.json, w, encodingutf-8) as f: json.dump(meta, f, ensure_asciiFalse)这里我特意选了中文向量模型bge-small-zh-v1.5它对中文语义的理解能力强于很多通用模型而且体积小约100MB适合本地学习和部署。如果你处理的文档是英文可以换用bge-base-en-v1.5或e5系列选择依据是尽量匹配你的语种检索效果会差很多。3.4 Step 4检索与生成的完整实现向量化完成后就到了问答环节。RAG最核心的地方在这里它不只靠模型“死记硬背”答案而是每次回答都从你的文档里实时检索背景知识再让模型基于检索到的内容作答。这一下就解决了大模型“编造事实”的常见问题因为答案是来源可控的。我用Faiss检索出与问题最相关的几个文档块拼进Prompt里再调用大模型APIfrom fastapi import FastAPI from pydantic import BaseModel from openai import OpenAI import faiss, json, numpy as np app FastAPI() client OpenAI() # 如果调用OpenAI官方API需要设置OPENAI_API_KEY环境变量 index faiss.read_index(vector_index.faiss) meta json.load(open(chunks.json, encodingutf-8)) encoder SentenceTransformer(BAAI/bge-small-zh-v1.5) TOP_K 3 class Query(BaseModel): question: str def retrieve(question: str, k: int TOP_K): q_vec encoder.encode([question], normalize_embeddingsTrue) distances, indices index.search(np.asarray(q_vec.astype(float32)), k) return [meta[i][text] for i in indices[0]] def generate_answer(question: str, context_docs: list): context \n\n---\n\n.join(context_docs) prompt f你是一个严谨的技术顾问。请根据下面提供的文档片段如实回答用户问题。 如果文档片段中没有足够信息请明确回答“文档中未涉及该内容”不要编造。 文档片段 {context} 用户问题 {question} response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: 你是严谨的技术问答助手。}, {role: user, content: prompt} ], temperature0.2, ) return response.choices[0].message.content app.post(/qa) def qa(query: Query): docs retrieve(query.question) answer generate_answer(query.question, docs) return {answer: answer, sources: docs}注意几个细节检索出来的TOP_K我默认设成3这个值太少了可能漏信息太多了后面的模型会被无关信息干扰反而降低效果建议在测试集上调temperature设置成0.2是为了让回答尽量确定、少发散Prompt里特别强调了“没有就直说”这能显著降低模型的幻觉问题。3.5 Step 5容器化与一键启动本地运行没问题后就要把整个服务打包让团队其他成员也能快速跑起来。Dockerfile的内容用最简单的方案FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD [uvicorn, server:app, --host, 0.0.0.0, --port, 8000]构建并启动docker build -t ai-qa-demo . docker run -p 8000:8000 -e OPENAI_API_KEY你的Key ai-qa-demo这里有一个我在真实项目中反复踩坑的经验不要在Docker镜像里包含模型文件尤其是当你用的是几GB的大模型时。正确做法是把模型下载到单独的对象存储或模型仓库在容器启动时拉取或者挂载为外部卷。这样镜像体积小、启动快而且模型更新时不用重新构建整个镜像。3.6 Step 6效果评估与迭代方向系统跑通之后你一定得做评估不然根本不知道系统的真实水平。我在这个Demo里用的评估方法是准备20个标准问答对人工打分回答的完整性和引用准确性。我试过用大模型自动评估但效果不够稳定小规模人工评估又客观又省事。实测结果给了我很深的印象一开始检索准确率大约70%原因是文档切分时有些表格和代码块被截断了导致没检索到关键内容。我针对性地调整了切分逻辑在切分前先把表格和代码块单独抽出来作为特殊Chunk不参与正文切分同时对标题层级做了一定程度的窗口合并让每个Chunk包含更完整的上下文。这轮调整后检索准确率提升到85%以上。这充分说明在RAG系统里数据管道的优化空间远比换一个大模型更大也更便宜。4. 常见问题与排查技巧实录4.1 “相似度检索结果不相关”的排查思路这是RAG系统最高频的问题。每次遇到优先按下面这个顺序排查先看问题本身是否歧义比如“它是什么”这种代指不清的问题检索策略设计得再好也没用。再看Chunk切分是否合理检查你召回出来的文档片段是否真的包含了关键信息。如果答案分散在好几个不同的章节检索目标本身就不清晰。如果召回结果确实没有相关信息就检查向量编码是否用了匹配的模型比如中文问题配了英文模型效果一定很差。最后看是否需要给不同段落加权重例如标题命中应该比正文命中更重要。这需要引入BM25关键词检索做融合或者使用更高级的Rerank模型。我自己的经验是70%的“检索不相关”问题都不是模型不行而是文档切块策略和检索前处理的问题解决顺序不要搞反了。4.2 模型回答“胡编乱造”时怎么办AI应用的幻觉问题非常常见我的处理原则从高优先级到低优先级排下来是在Prompt里明确限定“只能依据上下文回答不确定就直说”这一步成本最低能挡掉相当多的幻觉。在检索环节提高召回的准确性如果相关上下文都没找到模型就只能“自由发挥”了。把回答中的每个关键结论配上引用来源让用户能自己判断可信度这也能倒逼系统提升质量。如果场景很重要就把温度降到接近0并且用更严格的大模型做一次“事实一致性”审核。4.3 服务延迟过高如何优化AI应用用户体验差大部分原因是延迟。一个完整的RAG链路延迟大头通常在三块向量编码Encoder推理、检索、大模型生成。我实际用的是这样几种优化招数给向量模型也加上GPU或者用ONNX Runtime进行推理加速别让编码速度拖后腿。对Faiss索引做量化处理比如用IndexIVFFlat替代IndexFlatIP牺牲一点召回率换大幅提速。LLM生成阶段开流式输出Streaming用户先看到文字一个字一个字出来整体的主观等待感会好很多——这一点常常被完全忽略但体验提升立竿见影。如果文档规模不大干脆全量加载进内存避免每次问答都查数据库。4.4 自主搭建过程中遇到的经典坑我把这两三年实践里踩过、也看人反复踩的“经典坑”列成一个速查表你对照着规避就能少走弯路坑的类型具体表现避免方法Chunk切分不考虑语义一句话、半张表被切散优先按结构标题、段落、表格切分向量模型不匹配语言中文文档用英文模型选同语言的向量模型并测实际对齐效果提示词不约束来源模型自由发挥导致胡编乱造Prompt里强制指定“只依据文档回答”从不测试评估集上线后才发现效果烂小规模人工评估集至少准备30条先过一遍跳过Docker直接在本地跑换机器后依赖冲突、环境崩溃项目第一天就配好容器化环境为了“灵活”引入超大框架框架学习成本淹没业务逻辑小项目先从零写起理解后再用框架4.5 关于算力和成本的实用建议聊成本之前先说一件不少AI初学者的误区把“用大模型”等同于“一定要买顶级GPU”。在绝大多数业务场景下选择一条“适中模型 优秀检索 工程优化”的路线成本会比直接上超大模型低一个数量级这就是AI工程存在的重要价值。在这个Demo的成本账是向量化模型在CPU上运行一次推理不到0.1秒Faiss检索在几千个Chunk里查一次是毫秒级真正花钱的是调用大模型API的每千tokens费用其实即使每天跑几百次问答成本也在可接受范围。所以如果你在为企业设计AI功能别一上来就规划数百万的预算。先用最小方案跑起来用数据说话再决定是否提高算力投入这是理性且可持续的方式。5. 从Demo到生产环境的进阶之路5.1 数据层从离线仓库到实时管道在学习Demo里我们用的是一个静态Markdown文件向量库构建一次后就固定了。但在生产环境文档是持续更新的今天加了新章节明天改了旧接口。这时候就需要一套数据管道定期增量更新用Airflow或Cron定时任务扫描文档仓库的变化对新增和修改的文档块重新向量化并更新索引。元数据管理每个Chunk除了文本内容还要带上文档名称、版本、更新时间、作者等元数据。这对后续追溯来源、做权限控制至关重要也能在检索后做精细过滤。数据血缘记录“这个向量是从哪个文件的哪个段落生成的”这能帮你快速定位线上问题究竟来自哪份文档的哪段内容。我在接手过一个AI问答系统的时候最痛苦的并不是模型效果差而是文档更新了三版向量库还是旧版导致用户问到的全是过时信息。这让我养成了一个习惯任何RAG系统上线第一天就必须设计好“刷新”机制。5.2 模型服务层从单机到高可用生产级模型服务需要考虑三件事多副本、弹性伸缩、安全管控。多副本是Kubernetes里做水平扩展的基础能力把同一套模型服务部署成多个Pod前面挂负载均衡请求分发到不同副本上。弹性伸缩是根据请求量自动增减副本数高峰时多开几个Pod扛住流量低谷时缩回去节省资源这个用Kubernetes的HPAHorizontal Pod Autoscaler组件能实现。安全管控则包括API Key鉴权、限流Rate Limiting、请求内容审计。模型服务一旦裸奔在公网上分分钟会被刷爆配额这不是危言耸听。5.3 监控与评估层没有监控的AI系统走不远传统Web服务的监控看CPU、内存、QPS、错误率就差不多了AI系统在这之上还额外关注数据分布漂移和结果质量。我的经验是至少要监控四个指标响应延迟分布不仅看平均值还要看P95、P99因为AI应用的延迟往往有长尾。输入数据分布比如问答系统里用户的句子长度、主题分布一旦出现异常波动往往预示业务变化或者垃圾流量攻击。检索命中率在日志里记录每次是否有文档被检索到如果大量请求检索不到文档说明知识库严重缺失。用户反馈信号点赞/点踩、复制行为、二次追问率都是天然的隐式反馈通道比任何离线评估都真实。5.4 一个关键心态AI工程是持续运营不是一次性交付把上面这些环节全部打通之后你基本可以称得上“从零起步的AI工程入门者”了。但我要泼一盆经验冷水AI系统的维护成本在相当长一段时间内都不会显著下降。因为现实世界的数据在变、业务需求在变、模型技术在变任何一个变化都可能让昨天的效果变成明天的Bug。这也是为什么我从不建议团队一次性追求“完美系统”。更符合现实的做法是快速搭出第一版用真实流量验证价值然后持续监控、持续迭代。AI工程不是一个有终点线的项目而是像运营一个餐厅菜谱可以变、服务员可以换但保证每一桌顾客都吃满意这件事永远没有终点。写在最后我实践中的一点私人体会如果让我给正在从零起步学AI工程的朋友一句忠告我会说“别等准备好了再出发先做一个丑但能用的东西。”我见过太多人花三个月刷课、记笔记、背概念却始终没跑通过一个哪怕最简单的问答接口。真正的学习密度发生在你动手搭建、发现bug、查阅文档、逐步优化这个反复循环里。还有一个小习惯特别值得分享我会在每次完成一个小项目后专门写一份“复盘文档”记录三类内容当时卡住我的问题是什么、我通过什么线索找到的解决方案、如果重来一次我会在哪个环节提前做什么准备。这份文档比任何课程笔记都珍贵因为它记录的就是你自己的能力增长轨迹。也很建议你试试在社区里公开分享你的项目过程和踩坑记录这是我实践下来提升最快的方式没有之一。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。