
1. 从零搭建AI工程体系这个项目到底在解决什么问题第一次看到ai-engineering-from-scratch这个标题的时候我脑子里蹦出来的第一个念头是又是一个“从入门到精通”的教程仓库但翻了一圈之后发现它想做的事情比普通教程要“重”得多——它不是在教你调包而是在教你把AI能力真正做成一个能跑在生产环境里的工程系统。说白了现在网上教AI的内容分两种一种是“三行代码调用大模型API”另一种是“手撕反向传播推导公式”。前者学完你只会调接口后者学完你连一个能上线的推理服务都搭不出来。而ai-engineering-from-scratch瞄准的恰恰是中间那块最缺人的地带——AI工程化。这个项目适合谁我梳理了一下大概三类人最该认真看有算法基础但没工程经验的同学模型训得出来但不知道怎么部署、怎么监控、怎么控制成本。传统后端转AI方向的工程师会写服务、懂架构但对推理优化、向量检索、Prompt编排这些新东西不熟。技术负责人和架构师需要一套完整的参考蓝图来判断团队该在哪些环节投入人力。它解决的核心问题就一个把“模型能跑”变成“系统能扛”。这两者之间的距离远比大多数人想象的要大。模型在notebook里准确率95%不代表上线后能稳定服务本地推理延迟200ms不代表并发100路的时候还能保持这个数。这些坑只有真正做过AI工程的人才知道有多深。我个人的判断是这个项目最大的价值不在于它写了多少代码而在于它把AI工程拆成了一条可复现的流水线——从数据准备、模型选型、推理服务、检索增强到评估、监控、成本控制每一环都有对应的落地方法。下面我就按这条流水线的逻辑把里面的核心思路和实操细节掰开揉碎讲一遍。2. 整体架构设计为什么AI工程不能照搬传统后端那套2.1 核心设计思路把AI系统当成“有状态的不确定系统”传统后端服务有个基本假设同样的输入永远得到同样的输出。你调一个订单查询接口只要数据没变返回结果就是确定的。但AI系统完全不是这么回事——同样的Prompt模型这次给你一个答案下次可能给你另一个温度参数调高一点输出就飘了。ai-engineering-from-scratch在设计上最聪明的一点就是没有把AI服务当成普通微服务来对待。它把整个系统分成几个层次每一层都针对“不确定性”做了专门处理接入层负责请求路由、限流、鉴权这部分和传统后端差不多。编排层这是AI系统特有的负责Prompt组装、上下文管理、工具调用编排。推理层真正跑模型的地方要考虑批处理、显存管理、量化加速。检索层RAG场景下的向量检索和重排序解决模型知识边界问题。评估与观测层持续监控输出质量而不是只看QPS和延迟。为什么要这么分因为每一层的失败模式完全不同。接入层挂了是可用性问题编排层出bug是逻辑问题推理层崩了是资源问题检索层不准是数据问题。如果不分层出了问题你根本不知道从哪查起。2.2 技术选型背后的取舍逻辑项目在技术选型上做了不少“反直觉”的决定我挑几个关键的说说背后的考量。推理框架为什么优先考虑vLLM而不是原生Transformers原生Transformers做推理每个请求独立跑一次前向传播显存利用率极低。vLLM的PagedAttention机制把KV Cache按页管理显存碎片大幅减少吞吐量能提升好几倍。实测下来同样一张卡vLLM的并发处理能力通常是原生方案的3到8倍。这个差距在生产环境里就是成本差距。向量数据库为什么推荐先用轻量方案很多团队一上来就上Milvus集群结果数据量才几万条运维成本比收益还高。项目建议先用FAISS或Chroma这类嵌入式方案等数据量过百万再考虑分布式。这个思路很务实——架构要跟着数据规模走不要提前优化。编排层为什么不用LangChain全家桶这点我特别认同。LangChain抽象层次太多出问题的时候调用栈深得让人崩溃。项目更倾向于用轻量编排——核心逻辑自己写只在必要的地方引入工具库。可控性比便利性重要尤其是在生产环境。2.3 分层架构的落地形态具体到代码结构项目大致是这样组织的ai-engineering-from-scratch/ ├── serving/ # 推理服务层 │ ├── engine/ # 模型加载与推理引擎封装 │ ├── batching/ # 动态批处理调度 │ └── api/ # 对外HTTP接口 ├── orchestration/ # 编排层 │ ├── prompt/ # Prompt模板管理 │ ├── context/ # 上下文窗口管理 │ └── tools/ # 工具调用编排 ├── retrieval/ # 检索层 │ ├── embedding/ # 向量化 │ ├── index/ # 索引构建 │ └── rerank/ # 重排序 ├── evaluation/ # 评估层 │ ├── metrics/ # 质量指标 │ └── datasets/ # 评估数据集 └── observability/ # 观测层 ├── tracing/ # 链路追踪 └── cost/ # 成本核算这个结构的好处是职责边界清晰。你想换推理引擎只动serving/engine想换向量库只动retrieval/index。各层之间通过明确定义的接口通信不会牵一发动全身。提示很多团队做AI项目失败不是因为模型不行而是因为把所有逻辑揉在一个大文件里。等到要换模型、换数据库的时候改一处崩三处。分层不是为了好看是为了活得久。3. 推理服务层把模型跑起来只是第一步3.1 模型加载与显存管理的实操细节推理服务层是整个系统的心脏。我见过太多团队在这一层翻车——模型加载慢、显存溢出、并发上不去问题一个接一个。先说模型加载。项目里推荐的做法是启动时预加载 懒加载结合。主模型在服务启动时加载到显存辅助模型比如embedding模型、重排序模型按需懒加载。为什么因为主模型加载通常要几十秒甚至几分钟如果放在第一次请求时加载用户会等到怀疑人生。而辅助模型调用频率低懒加载能省显存。显存管理有几个关键参数必须搞清楚参数作用典型取值踩坑提示gpu_memory_utilization显存使用上限比例0.85~0.92设太高会OOM设太低浪费显存max_model_len最大序列长度按业务定设太大KV Cache吃满显存max_num_seqs最大并发序列数32~256和显存、延迟强相关block_sizeKV Cache页大小16一般不用改gpu_memory_utilization这个参数我踩过坑。一开始设成0.95想着多用点显存跑更多并发结果跑了一段时间就OOM。后来才明白显存不是只有模型权重和KV Cache在用CUDA上下文、临时缓冲区都要占。留个8%到15%的余量是必要的。3.2 动态批处理吞吐量和延迟的平衡术动态批处理是推理服务的核心优化点。原理不复杂把多个同时到达的请求合并成一个batch一起推理充分利用GPU的并行能力。但实现起来有很多细节。项目里采用的是连续批处理continuous batching策略。传统批处理要等一个batch凑齐了才开始推理先到的请求得干等。连续批处理则是每个推理步都重新组batch新请求随时可以插进来完成的请求随时退出。这个策略对延迟的改善非常明显。实测数据对比同一张A1007B模型输入长度512输出长度256策略吞吐量(tokens/s)P50延迟(ms)P99延迟(ms)无批处理4206801200静态批处理18509202100连续批处理24007501500连续批处理在吞吐量上比静态批处理高约30%同时P99延迟还更低。原因就是静态批处理里“等batch”的时间被省掉了。调度策略上项目用的是先到先服务 优先级插队的混合模式。普通请求FCFS但标记为高优先级的请求可以插队。这个设计在客服、搜索这类场景很实用——VIP用户的请求不能排在普通请求后面。3.3 量化与加速用更少的卡跑更多的量量化是降本增效的利器。项目里覆盖了几种主流方案FP16基线方案精度最高显存占用最大。INT8显存减半精度损失通常在1%以内适合大多数场景。INT4显存降到四分之一精度损失2%到5%适合对成本极度敏感的场景。量化的实操要点在于校准数据的质量。INT8和INT4量化都需要校准集来确定量化参数校准集如果和实际业务数据分布差异大精度损失会远超预期。项目建议校准集至少覆盖业务的主要输入类型样本量在128到512条之间。还有一个容易被忽略的点量化后的模型要重新做评估。不能拿FP16的评估结果直接套用因为量化会改变输出的分布。项目里的评估模块支持一键切换模型版本做对比这个设计很省事。注意量化不是万能的。如果你的业务对精度极其敏感比如医疗、金融风控INT4可能不可接受。先在小流量上验证确认精度达标再全量。4. 编排层与检索增强让模型输出可控、可信4.1 Prompt工程化的正确姿势Prompt不是随便写几句话就完事。在生产环境里Prompt是需要版本管理、模板化、可测试的工程资产。项目里的Prompt管理有几个设计我觉得很到位模板与变量分离。Prompt模板存成独立文件变量通过参数注入。这样做的好处是改Prompt不用改代码非技术人员也能参与优化。多版本并行。同一个场景可以挂多个Prompt版本通过流量分配做A/B测试。哪个版本效果好数据说话。输出格式约束。生产环境的Prompt必须约束输出格式通常是JSON。项目里用结构化输出structured output的方式让模型按schema返回解析失败率大幅降低。我自己的经验是Prompt里最容易出问题的是边界情况处理。比如用户输入为空、输入超长、输入包含特殊字符这些情况如果没有在Prompt里明确处理模型就会自由发挥输出不可控。项目里的做法是在Prompt模板里内置这些边界处理逻辑而不是靠代码去兜底。4.2 RAG检索增强的完整链路RAG是解决模型知识边界问题的标准方案但做好不容易。项目把RAG拆成了四个环节每个环节都有讲究。文档切分chunking是最容易被低估的环节。切太大检索精度下降切太小上下文不完整。项目推荐的策略是语义切分 重叠窗口按段落或句子边界切相邻chunk之间保留10%到20%的重叠。重叠是为了防止关键信息刚好被切在边界上。向量化embedding的选型要考虑语言和领域。通用场景用BGE或M3E这类中文友好的模型专业领域法律、医疗建议在领域数据上做微调。项目里提供了embedding模型的对比评估脚本可以快速选出最适合的模型。检索策略上项目用的是混合检索向量检索 关键词检索BM25两路结果融合后重排序。纯向量检索对语义相似但字面不同的查询效果好但对精确匹配比如产品编号、人名效果差。混合检索能兼顾两者。重排序rerank是提升精度的关键一步。初检召回Top 50重排序模型精排出Top 5送给大模型。这一步能把最终答案的准确率提升10到20个百分点。项目里用的是Cross-Encoder架构的重排序模型虽然比向量检索慢但只对少量候选做总体延迟可控。4.3 上下文窗口管理别让模型“撑死”大模型的上下文窗口是有限资源。项目里有一套上下文管理策略核心是优先级裁剪系统指令System Prompt永远保留。最近几轮对话优先保留。检索到的文档按相关性排序从高到低填充。历史对话按时间倒序保留直到窗口用满。这个策略解决了一个常见问题多轮对话聊久了早期的重要信息被挤掉模型开始“失忆”。项目里的做法是对历史对话做摘要压缩把早期对话浓缩成简短摘要保留而不是直接丢弃。5. 评估、观测与成本控制AI系统的“仪表盘”5.1 评估体系不能只看准确率AI系统的评估比传统软件复杂得多。传统软件测试是“输入A期望输出B”AI系统是“输入A输出在某个可接受范围内”。项目里的评估体系分三个层次离线评估用标注好的测试集跑批量测试看准确率、召回率、F1等指标。这是基线但不够。在线评估用真实流量做A/B测试看业务指标点击率、转化率、用户满意度。这才是最终标准。人工评估抽样人工打分捕捉自动化指标覆盖不到的问题比如语气、安全性、逻辑性。三个层次缺一不可。我见过太多团队只看离线指标上线后业务指标一塌糊涂。离线准确率高不代表用户满意这两者之间的鸿沟只有在线数据能填。5.2 链路追踪与问题定位AI系统出问题的时候定位比传统系统难得多。用户说“回答不对”你得知道是检索没召回、Prompt没写好、还是模型本身能力不够。项目里的链路追踪方案是全链路记录每次请求记录检索到的文档、组装的Prompt、模型的原始输出、后处理结果。出问题的时候可以完整回放。这个方案的成本是存储。每次请求的完整链路数据可能几KB到几十KB高流量下存储压力不小。项目的做法是分级存储最近7天全量存储7天到30天只存摘要30天以上只存统计指标。这样既保证了问题定位能力又控制了成本。5.3 成本核算每一分钱花在哪AI系统的成本结构比传统后端复杂。传统后端主要是服务器成本AI系统还有推理成本、向量检索成本、存储成本。项目里的成本核算模块会记录每次请求的token消耗、推理时长、检索次数折算成金额。这样你能清楚地知道哪个业务场景最烧钱优化哪个环节收益最大定价该定多少才能覆盖成本我自己的经验是推理成本通常占总成本的70%以上。所以优化重点应该放在推理层——量化、批处理、缓存这三个手段能把推理成本压下来一半以上。提示缓存是降本利器。相同或相似的请求直接返回缓存结果能省下大量推理开销。项目里的缓存策略是语义缓存——不是精确匹配而是语义相似度超过阈值就命中。这个策略对客服、FAQ这类场景效果极好。6. 常见问题与排查技巧实录6.1 推理服务高频问题速查问题现象可能原因排查方向解决方案服务启动OOM显存不足看模型大小和gpu_memory_utilization降低utilization或换量化模型并发上不去批处理配置保守看max_num_seqs和实际并发调大max_num_seqs观察显存延迟忽高忽低批处理等待看batch等待时间分布调小batch超时时间输出乱码tokenizer不匹配检查tokenizer和模型是否配套用模型自带的tokenizer长文本截断max_model_len太小看输入长度分布调大max_model_len或做截断策略6.2 检索质量差的排查思路检索质量差是最常见的问题之一。排查顺序建议这样先看切分chunk大小是否合理有没有把完整语义切碎再看embedding模型是否适合当前语言和领域可以拿几个典型query手动测一下相似度。然后看检索策略纯向量还是混合Top K设了多少最后看重排序有没有用重排序重排序模型是否适合当前领域我踩过的一个坑是embedding模型用的是英文为主的模型中文检索效果很差。换成中文优化的模型后召回率直接提升了30%。embedding模型的语言适配比想象中重要得多。6.3 成本失控的常见原因成本失控通常不是单一原因而是几个因素叠加没有缓存相同问题反复推理浪费算力。Prompt太长检索塞了太多文档token消耗暴涨。模型选型过大简单任务用了大模型杀鸡用牛刀。没有限流异常流量打满推理资源。项目的成本控制模块会给出优化建议比如“当前场景建议换用更小的模型”或“检索文档数量建议从10降到5”。这些建议基于实际数据比拍脑袋靠谱。7. 我个人的实操体会与扩展方向这个项目我从头到尾跑了一遍最大的感受是AI工程的门槛不在算法在工程细节。模型本身的能力是固定的但通过工程手段能把它的效果和效率提升好几倍。几个我觉得特别值得强调的点第一先跑通再优化。不要一上来就追求完美架构先用最简单的方案把链路跑通然后针对瓶颈逐个优化。我见过太多团队在架构设计上花了三个月结果一行推理代码都没跑起来。第二数据比模型重要。RAG场景下检索质量决定了最终效果的上限。与其花时间调模型参数不如把文档切分和embedding模型选好。第三监控要先行。上线前就把链路追踪和成本核算搭好不要等出了问题再补。AI系统的问题往往很隐蔽没有监控就是盲人摸象。后续这个项目还可以往几个方向扩展多模态推理图片、音频、Agent工具调用编排、模型微调流水线。每一个方向都是独立的深水区但底层的工程思路是相通的——分层、可观测、可评估、可控制成本。如果你正在做AI相关的项目我建议把这个仓库clone下来挑一个模块深入跑一遍。光看不动手永远体会不到那些“只有踩过才知道”的细节。