1. 从零搭建AI工程能力为什么大多数人第一步就走偏了聊到从零开始做AI工程这个话题我见过太多人一上来就扎进模型训练里买显卡、配环境、跑微调折腾两个月发现连一个能稳定对外服务的接口都没搭出来。这个现象非常普遍但方向其实从一开始就偏了。ai-engineering-from-scratch这个标题里的关键词是AI Engineering不是 AI Research也不是 Machine Learning。这两者之间的差别决定了你整个学习路径和技术栈的选择。AI工程的核心命题是把已经存在的模型能力变成可靠、可维护、可扩展的产品功能。它关心的是数据怎么流、服务怎么部署、延迟怎么控制、成本怎么算、效果怎么评估而不是发明一个新的网络结构。所以这篇文章面向的是这样一群人你可能已经会写Python懂一点深度学习的基本概念能看懂Transformer的论文大意但当你真正要把一个AI功能落地到项目里时发现到处都是坑——模型选哪个、Prompt怎么管、输出不稳定怎么办、上线之后怎么监控、成本怎么压下来。这些问题在学术论文里找不到答案在框架文档里也只是一笔带过。我自己的经历是最早做AI功能的时候把80%的时间花在了调模型上结果上线后发现真正的问题全在工程侧接口超时、并发上不去、输出格式偶尔崩、用户输入触发奇怪行为、账单月底一看吓一跳。后来才慢慢意识到AI工程是一门独立的手艺它有自己的分层结构、自己的最佳实践、自己的踩坑清单。接下来的内容我会按照一个真实的从零搭建路径来展开先讲清楚AI工程的能力地图长什么样再逐个拆解数据层、模型层、服务层、评估层、成本层这几个核心模块每个模块都会给出具体的工具选型理由、实操步骤、以及我在实际项目中踩过的坑。不管你是要做一个内部工具还是要做面向用户的产品这套框架都能直接套用。2. AI工程的能力地图五个层次和它们的依赖关系2.1 为什么不能跳过任何一层很多人问我能不能直接学LangChain然后做应用。我的回答是可以但你会在第三个需求变更的时候崩溃。因为AI工程是一个有严格依赖关系的分层系统上层的能力建立在下层的稳定性之上。我把它分成五层从下往上依次是数据层负责原始数据的采集、清洗、切分、向量化、存储。这一层决定了你的AI能看到什么。模型层负责模型选型、Prompt设计、微调策略、输出解析。这一层决定了AI能做什么。服务层负责接口封装、并发处理、缓存、重试、降级。这一层决定了AI能不能稳定地被调用。评估层负责效果度量、回归测试、A/B对比、人工审核。这一层决定了你怎么知道AI做得好不好。成本层负责Token核算、缓存命中率、模型路由、预算告警。这一层决定了这件事能不能持续做下去。这五层不是并列的而是严格依赖的。数据层没做好模型层再强也是垃圾进垃圾出服务层没做好评估层拿到的数据全是超时和报错成本层没做好项目跑到一半预算烧完直接停摆。2.2 每一层的核心产出物我习惯用产出物来定义每一层是否做到位了而不是用学了什么技术。因为技术会过时产出物的标准相对稳定。层次核心产出物判断标准数据层可复现的数据管道 向量索引给定原始数据能一键重建索引模型层Prompt模板库 输出Schema同一输入输出结构稳定可解析服务层带监控的API服务能扛住预期QPS有降级方案评估层自动化评估集 回归报告每次改动都能量化对比成本层成本看板 预算告警能预测下月账单误差小于20%这张表是我自己在带团队时用来做能力盘点的工具。每次项目复盘我就对着这张表看哪一层还是空的。通常来说从零开始的项目数据层和服务层是最容易被忽略的而这两层恰恰是后期返工成本最高的。2.3 从零开始的推荐推进顺序虽然依赖关系是从下往上的但实际推进的时候我建议的顺序是先打通一条最窄的端到端链路再逐层加固。具体来说第一步不是去搭完整的数据管道而是拿几十条样本数据手动跑通输入→模型→输出→展示的完整流程。这一步的目的是让你快速看到全貌知道每一层大概长什么样。然后再回头把数据层做扎实把服务层做稳定把评估层建起来。这个顺序的好处是你不会在数据层陷入无限优化的泥潭。我见过有人花三个月做数据清洗结果发现模型选型根本不对前面的工作全白费。先跑通窄链路能让你在早期就发现方向性问题。3. 数据层从原始文本到可检索知识库的完整链路3.1 文档切分最容易被低估的环节数据层里文档切分Chunking是决定检索质量的第一道关卡。我见过太多项目检索效果差排查到最后发现是切分策略有问题。切分的核心矛盾是切得太碎单块信息不完整模型拿到手里答不出问题切得太粗单块包含太多无关信息检索时噪声大而且会浪费Token。我的经验法则是按语义边界切按Token长度兜底。具体操作上优先按段落、标题、列表项这些自然边界切分然后对超长的块做二次切分保证每块在200到500 Token之间。这个区间是实践出来的太短了语义不完整太长了检索精度下降。# 一个实用的切分策略示例 def smart_chunk(text, max_tokens400, overlap50): # 先按自然段落切 paragraphs text.split(\n\n) chunks [] current for para in paragraphs: if count_tokens(current para) max_tokens: if current: chunks.append(current) current para else: current \n\n para if current: chunks.append(current) # 对超长块做滑动窗口二次切分 final [] for chunk in chunks: if count_tokens(chunk) max_tokens: final.append(chunk) else: final.extend(sliding_window(chunk, max_tokens, overlap)) return final这里有个细节值得说overlap重叠不是越多越好。我一开始设置100 Token的重叠结果检索时经常返回高度相似的重复块浪费了上下文窗口。后来降到50效果反而更好。重叠的目的是防止关键信息正好被切在边界上50 Token足够覆盖大多数句子的长度。3.2 向量化模型的选择逻辑向量化模型Embedding Model的选择很多人只看排行榜这是不对的。排行榜上的模型往往是在通用语义相似度任务上评测的而你的实际场景可能是法律文书、医疗记录、或者代码仓库分布完全不同。我的选型逻辑是三步走先确定语言和领域中文场景优先选中文优化过的模型代码场景选代码训练过的模型多语言场景选多语言模型。再看维度和成本维度越高检索精度通常越好但存储和计算成本也越高。768维和1536维在实际场景中的差距往往没有成本差距那么大。最后做小规模实测拿你自己业务的100条查询人工标注正确答案然后对比几个候选模型的召回率。这一步花不了多少时间但能避免选错模型后的大规模返工。提示向量化模型一旦选定后续更换的成本极高因为所有数据都要重新向量化。所以这一步值得多花时间做实测不要拍脑袋决定。3.3 向量数据库的部署与索引调优向量数据库这块我的建议是小规模用本地库大规模用服务化方案。数据量在百万级以下用FAISS或者Chroma这种嵌入式方案就够了部署简单没有网络开销。数据量上去了或者需要多副本、高可用再考虑服务化的方案。索引调优方面最关键的参数是ef_construction和ef_search以HNSW索引为例。前者影响建索引的时间和索引质量后者影响查询时的精度和速度。我的经验值是ef_construction设200ef_search设100起步然后根据实际召回率和延迟做调整。这里有个反直觉的点索引不是建得越精确越好。精确索引查询慢在高并发场景下会成为瓶颈。适当降低索引精度换取查询速度往往整体体验更好。我一般会做一组对比测试找到召回率和延迟的平衡点。4. 模型层Prompt工程与输出稳定性的实战方法4.1 Prompt模板化从随手写到可维护刚开始做AI功能的时候Prompt都是随手写在代码里的字符串。项目一复杂问题就来了同一个Prompt在三个地方出现改了一处忘了另外两处不同版本的Prompt混在一起出了问题不知道是哪个版本导致的。我的做法是Prompt模板化 版本管理。具体来说把每个Prompt抽成一个独立的模板文件用占位符表示变量然后给每个模板打版本号。代码里引用模板时明确指定版本。# prompt_templates/qa_v2.yaml name: qa version: 2 template: | 你是一个知识库问答助手。请根据以下参考资料回答用户问题。 如果参考资料中没有相关信息请明确说明根据现有资料无法回答。 参考资料 {context} 用户问题{question} 回答要求 - 只使用参考资料中的信息 - 回答简洁不超过200字 - 如果引用了资料标注来源编号这样做的好处是Prompt的改动可以走代码审查流程可以回滚可以做A/B测试。我踩过的坑是有一次为了快速修复一个问题直接在线上改了Prompt结果引入了新的问题而且没有记录排查了半天。从那以后所有Prompt改动都必须走版本管理。4.2 输出格式约束让模型输出可解析的结构模型输出不稳定是AI工程里最头疼的问题之一。你要求它输出JSON它有时候给你加个markdown代码块有时候字段名拼错有时候干脆输出一段自然语言。解决这个问题我有三个层次的方案按可靠性从低到高第一层Prompt里明确格式要求。这是最基础的在Prompt里写清楚只输出JSON不要有任何其他文字并给出示例。这能解决大部分问题但不是100%。第二层使用结构化输出能力。现在很多模型API支持JSON Mode或者Function Calling能强制模型输出符合Schema的结构。这个可靠性比纯Prompt高很多优先使用。第三层输出解析 重试。即使有前两层仍然可能失败。所以代码里必须有解析逻辑解析失败时触发重试重试时在Prompt里加上错误信息让模型自我修正。def get_structured_output(prompt, schema, max_retries3): for attempt in range(max_retries): response call_model(prompt) try: return parse_json(response, schema) except ParseError as e: prompt f{prompt}\n\n上次输出解析失败{e}\n请严格按照Schema输出。 raise OutputError(多次重试后仍无法解析)注意重试次数不要设太多一般3次足够。重试太多会显著增加延迟和成本而且如果模型连续失败说明Prompt本身有问题应该去修Prompt而不是无限重试。4.3 微调还是Prompt一个务实的决策框架经常有人问什么时候该微调什么时候用Prompt就够了。我的决策框架很简单按顺序问三个问题Prompt能不能达到可接受的效果如果能就不要微调。微调的成本远高于Prompt调优。任务是否有大量标注数据微调需要至少几百条高质量样本没有数据就不要谈微调。任务是否对延迟和成本极度敏感微调后的小模型可以显著降低延迟和成本如果这是核心诉求微调才有必要。大多数场景下Prompt工程加上RAG检索增强生成就能解决问题。微调是最后的手段不是第一选择。我见过太多项目一上来就想着微调结果数据不够、效果不好、还浪费了大量时间。5. 服务层让AI功能扛住真实流量的工程细节5.1 接口设计同步、流式还是异步AI服务的接口设计第一个决策是同步还是流式。这个决策直接影响用户体验和系统架构。同步接口最简单请求发出去等模型生成完一次性返回。适合短输出、对延迟不敏感的场景。问题是如果生成需要10秒用户就要盯着loading转10秒。流式接口Streaming边生成边返回用户能很快看到第一个字体验好很多。适合对话、长文本生成这类场景。代价是服务端实现复杂一些需要处理SSE或者WebSocket。异步接口适合超长任务比如批量处理、文档分析。请求发出去立即返回一个任务ID客户端轮询或者通过回调获取结果。我的建议是面向用户的对话类功能一律用流式。这是体验差异最大的地方。内部批处理任务用异步。同步接口只在输出很短比如分类、打标签的时候用。5.2 缓存策略省钱和提速的关键AI服务的缓存比普通Web服务的缓存复杂因为同样的输入可能有不同的输出模型有随机性而且缓存命中率直接影响成本。我的缓存策略分三层精确缓存输入完全一致时直接返回缓存结果。适合FAQ、固定查询这类场景。实现简单用Redis就行。语义缓存输入语义相似时返回缓存结果。需要把输入向量化然后做相似度匹配。适合用户问法多样但意图相同的场景。前缀缓存对于长System Prompt很多模型API支持前缀缓存能显著降低成本和延迟。这个不需要自己实现但要在设计Prompt时注意把固定部分放在前面。语义缓存的阈值设置很关键。设太高命中率低设太低返回不相关的答案。我的经验是相似度阈值设在0.92到0.95之间然后根据实际效果微调。这个值需要通过实际数据来校准没有万能值。5.3 降级与熔断模型不可用时的兜底方案模型API不是100%可用的网络会抖动服务会限流偶尔还会出故障。如果没有降级方案模型一挂你的整个功能就挂了。我的降级策略是分级的故障级别降级方案用户体验单次超时重试一次无感知延迟略增持续超时切换到备用模型质量可能略降主备都不可用返回缓存结果或预设话术功能降级但不报错完全不可用关闭AI功能展示静态内容功能缺失但页面正常这里的关键是熔断器。当错误率超过阈值时自动切断对故障服务的调用直接走降级逻辑避免大量请求堆积导致雪崩。我用的是类似Hystrix的熔断模式错误率超过50%且请求数超过20时触发熔断30秒后进入半开状态试探。6. 评估层怎么证明你的AI功能真的在变好6.1 建立评估集从零到一的实操步骤没有评估集所有的优化都是盲目的。你改了一个Prompt感觉效果好了但真的好多少不知道。建立评估集是AI工程里投入产出比最高的事情之一。从零建立评估集的步骤收集真实查询从日志里捞从用户反馈里找从业务方那里要。目标是覆盖主要的使用场景。人工标注答案每条查询人工写出标准答案或者标注哪些是正确答案。这一步最费时间但省不得。分类组织把查询按类型分组比如事实查询、推理查询、多轮对话、边界情况。这样评估时能看出哪类问题表现差。持续扩充每次发现bad case就加进评估集。评估集会越来越大越来越能反映真实分布。我的经验是100条高质量评估样本比10000条低质量样本有用得多。起步阶段50到100条就能看出很多问题。6.2 自动化评估指标的选择评估指标分两类基于参考答案的和基于模型的。基于参考答案的常用的是精确匹配、F1、ROUGE这些。适合有明确标准答案的场景比如分类、抽取。缺点是对于开放式生成这些指标和人类判断的相关性不高。基于模型的就是用一个强模型来给输出打分。常见的是让模型判断回答是否忠实于参考资料是否回答了用户问题是否有害。这个和人类判断的相关性更高但成本也更高而且有偏见。我的做法是两者结合能用规则判断的用规则规则判断不了的用模型评估模型评估的结果定期抽样人工复核。这样兼顾了成本和准确性。6.3 回归测试每次改动都不掉链子评估集建好之后最重要的用途是回归测试。每次改动Prompt、换模型、调参数都跑一遍评估集对比改动前后的指标。这个流程要自动化。我的做法是把评估集和评估脚本放进CI流程每次提交代码自动跑。指标下降超过阈值就阻断合并。这样能防止修了一个问题引入三个新问题的情况。# 评估脚本示例 python evaluate.py \ --eval-set data/eval_set_v3.jsonl \ --prompt-version v2.1 \ --model gpt-4 \ --output reports/eval_$(date %Y%m%d_%H%M).json提示评估集的版本也要管理。每次扩充评估集都要记录版本这样对比历史数据时才知道是模型变了还是评估集变了。7. 成本层把AI功能的账单控制在预算内7.1 Token核算钱到底花在哪里了AI功能的成本主要就是Token成本。要控制成本首先要能算清楚钱花在哪里了。我的做法是在服务层埋点记录每次调用的输入Token、输出Token、模型、耗时、以及业务标识。有了这些数据就能做多维度的成本分析哪个功能最费钱、哪个用户最费钱、哪个时间段最费钱。我做过一个分析发现80%的成本集中在20%的功能上而那20%的功能里有一半是可以优化的。Token核算的粒度要细到单次调用但汇总分析要按业务维度。这样才能既看到细节又看到全局。7.2 模型路由不同任务用不同档位的模型不是所有任务都需要最强的模型。分类、抽取、格式转换这类任务小模型完全够用成本可能只有大模型的十分之一。模型路由的核心是任务分级。我会把任务分成三档简单任务分类、打标签、格式转换。用小模型。中等任务问答、摘要、简单推理。用中等模型。复杂任务多步推理、代码生成、长文档分析。用大模型。路由的实现可以基于规则按任务类型也可以基于模型判断先让小模型判断难度再决定用哪个模型。规则简单可靠模型判断更灵活但增加了延迟。我一般先用规则等数据积累够了再考虑动态路由。7.3 预算告警别等账单出来才后悔成本控制最重要的是实时可见。我见过太多团队月底账单出来才发现超支但已经来不及了。我的做法是设置多级告警日预算告警当日成本超过预算的80%时告警。周预算告警当周成本超过预算时告警。异常告警单小时成本超过历史均值的3倍时告警这通常意味着有异常调用。告警要发到团队群里让所有人都能看到。成本意识是团队的事不是某一个人的事。8. 从零搭建过程中我踩过的那些坑8.1 数据层的坑切分策略改了三次才稳定最开始做知识库的时候我按固定长度切分每500字符一刀切。结果检索出来的块经常从句子中间断开模型拿到手里理解不了。后来改成按段落切又遇到超长段落的问题。最后才形成按语义边界切超长兜底适度重叠的策略。这个过程中最大的教训是切分策略没有银弹必须结合你的数据特点来调。技术文档、法律合同、聊天记录最佳切分策略完全不同。不要照搬别人的参数要自己实测。8.2 服务层的坑流式接口的背压问题流式接口上线后遇到一个诡异的问题并发一高服务就卡死。排查后发现是背压问题——模型生成速度快于客户端消费速度数据在服务端堆积内存暴涨。解决方案是加背压控制当客户端消费慢时暂停从模型读取数据。这个逻辑在流式处理里很容易被忽略但高并发下是致命的。8.3 评估层的坑评估集泄露有一次做优化效果提升特别明显评估指标涨了20个点。高兴了没两天发现是因为评估集里的样本在训练数据里出现过模型背下了答案。这就是评估集泄露。避免这个问题的方法是评估集和训练数据严格隔离评估集里的样本不能出现在任何训练、微调、Prompt示例中。这个纪律要严格执行否则评估结果就是自欺欺人。8.4 成本层的坑缓存穿透导致成本飙升有一次上线了一个新功能成本突然涨了5倍。排查发现是缓存设计有问题大量不同的输入都miss了缓存直接打到模型。而这些输入其实语义相似只是措辞不同。后来加了语义缓存命中率从30%提升到70%成本降了一半多。这个教训是缓存策略要和实际查询分布匹配精确缓存适合固定查询语义缓存适合多样化查询。9. 一些让AI工程更顺手的个人习惯做了这么多AI工程项目我慢慢形成了一些自己的习惯分享出来供参考。第一永远先跑通最窄链路。不管多复杂的项目先拿10条数据跑通端到端再逐步加固。这能让你在早期发现方向性问题避免大规模返工。第二所有Prompt都进版本管理。不要有临时改一下的Prompt所有改动都走版本都能回滚。这个习惯救过我很多次。第三评估集是资产要持续投入。每次发现bad case就加进去评估集会越来越值钱。我现在的项目评估集已经积累了上千条成了最宝贵的资产之一。第四成本监控要前置。不要等账单出来才看成本要在服务层就埋点实时可见。成本意识要贯穿整个开发过程。第五降级方案是必需品不是奢侈品。模型API一定会出问题没有降级方案你的功能就是建在沙子上。降级方案要在设计阶段就考虑不要等出事了才补。这套框架和这些习惯是我从多个项目中总结出来的。AI工程这个领域变化很快模型在变、工具在变、最佳实践也在变但底层的工程原则是相对稳定的。把数据、模型、服务、评估、成本这五层都做扎实不管上层技术怎么变你都能快速适应。