1. 从零搭建AI工程体系为什么我劝你别一上来就调包“ai-engineering-from-scratch”这个标题第一次看到的时候我愣了一下。市面上讲AI的教程铺天盖地但绝大多数都是教你import torch然后跑一个预训练模型或者调个API做个聊天机器人。真正讲“从零开始搭建AI工程体系”的内容少得可怜。我自己在这个方向上摸索了挺长时间踩过的坑不算少。最开始我也觉得AI工程嘛不就是数据丢进去、模型跑起来、结果拿出来后来真正接手了一个需要端到端落地的项目才发现事情远没有那么简单。数据管道怎么设计、特征怎么存储、模型版本怎么管理、推理服务怎么部署、线上效果怎么监控——每一个环节单独拎出来都够写一本书。所以这篇内容我想认真聊聊“从零构建AI工程体系”这件事。它适合谁看如果你是一个有一定编程基础、想系统了解AI项目从实验到生产全流程的开发者或者你正在负责一个AI项目的工程化落地再或者你单纯对“AI工程”这个方向感兴趣但不知道从哪里下手那这篇内容应该能给你一些实在的参考。我不会只讲概念也不会堆砌工具名。我会把每个环节背后的“为什么”讲清楚把我在实际项目中积累的经验和教训分享出来。你能看到完整的思路拆解、关键细节的实操要点、常见问题的排查方法以及一些只有真正动过手才知道的避坑技巧。2. 整体架构设计先想清楚数据怎么流再考虑用什么工具2.1 为什么“从零”不等于“从轮子造起”很多人看到“from scratch”这个词第一反应是什么都自己写。自己实现矩阵运算、自己写梯度下降、自己搭一个神经网络框架。说实话如果你是为了学习原理这么做没问题。但如果你的目标是构建一套能支撑实际业务的AI工程体系从零造轮子是极其低效的。我这里说的“从零”指的是从零开始规划和搭建整个工程体系而不是从零实现每一个算法。就像盖房子你不需要自己烧砖、自己炼钢但你需要知道地基怎么打、承重墙在哪里、水电怎么走。AI工程体系也是一样你需要理解每个环节的核心逻辑然后选择合适的工具去实现它。那为什么还要强调“从零”因为很多开发者习惯了“拿来主义”——看到一个开源项目clone下来就跑遇到问题就懵了。你不知道数据是怎么预处理的不知道模型为什么选这个架构不知道推理服务的瓶颈在哪里。一旦线上出了问题你连排查的方向都没有。从零构建的意义在于你对整个系统有完整的掌控力。你知道每一个环节的输入输出是什么知道哪里可能出问题知道怎么优化。这种掌控力在AI项目真正落地的时候比会调几个包重要得多。2.2 分层架构把复杂问题拆成可管理的模块AI工程体系说到底是一个软件系统只不过它比普通的CRUD应用多了几个特殊环节。我习惯把它分成五层来看第一层是数据层。这是整个体系的地基。数据从哪里来、怎么清洗、怎么存储、怎么版本化这些问题如果一开始没想清楚后面会非常痛苦。我见过太多项目模型效果不好排查了半天发现是训练数据和推理时的数据分布不一致。数据层要解决的核心问题是让正确的数据在正确的时间以正确的格式到达正确的地方。第二层是特征层。特征工程是AI项目中极其重要但又容易被忽视的环节。好的特征能让简单的模型跑出不错的效果烂的特征能让复杂的模型表现糟糕。特征层要解决的是如何高效地计算特征、存储特征、复用特征以及保证训练和推理时特征的一致性。第三层是模型层。包括模型训练、调参、评估、版本管理。这一层是大家最熟悉的但也是最容易出问题的。模型训练不是跑一个fit()就完事了你需要考虑实验管理、超参数搜索、模型评估的指标体系、模型版本的回滚机制等等。第四层是服务层。模型训练出来只是第一步怎么把它变成可用的服务才是关键。推理服务的延迟、吞吐量、并发能力、资源占用这些都是需要仔细设计的。而且线上服务要考虑容错、降级、灰度发布等一系列工程问题。第五层是监控层。模型上线不是终点而是起点。你需要监控模型的预测分布、特征分布、业务指标及时发现数据漂移和模型退化。没有监控的AI系统就像没有仪表盘的飞机飞得起来但不知道什么时候会出事。这五层不是孤立的它们之间有大量的交互和依赖。数据层为特征层提供原料特征层为模型层提供输入模型层为服务层提供产物服务层为监控层提供数据监控层的反馈又反过来指导前面四层的优化。理解这个闭环是从零构建AI工程体系的第一步。2.3 技术选型的核心原则合适比先进更重要在技术选型上我见过太多团队犯同一个错误什么新用什么。今天看到某个新出的特征存储框架明天看到某个新的模型服务方案恨不得全部集成进来。结果就是系统复杂度爆炸维护成本极高真正核心的业务问题反而没解决。我的选型原则很简单成熟度优先、团队熟悉度优先、社区活跃度优先。一个工具再先进如果社区不活跃、文档不完善、出了问题搜不到解决方案那它就不适合用在生产环境。相反一个工具可能不是最新的但它稳定、文档齐全、社区活跃那就是更好的选择。具体到每个环节我的建议是这样的环节选型考量常见方案数据存储数据量级、查询模式、一致性要求对象存储关系型数据库组合特征计算批处理还是流处理、实时性要求批处理用Spark流处理用Flink实验管理团队规模、实验频率MLflow或WB模型服务延迟要求、并发量、模型类型FastAPIONNX Runtime或Triton监控告警监控指标类型、告警渠道PrometheusGrafana这张表不是标准答案只是一个参考。关键是要根据你自己的业务场景和团队情况来做选择。比如你的团队只有两三个人那搞一套复杂的特征存储平台就是自找麻烦用数据库表存特征完全够用。3. 数据管道搭建AI工程里最脏最累但最重要的活3.1 数据采集别急着写代码先把数据源摸清楚数据采集是数据管道的第一步也是最容易被低估的一步。很多人的做法是拿到数据源就开始写爬虫或者ETL脚本。但我的经验是在写任何代码之前先花时间把数据源摸清楚。你需要回答几个问题数据源有哪些每个数据源的更新频率是什么数据格式是什么有没有缺失值、异常值数据量有多大增长速度如何这些问题看起来简单但如果不提前搞清楚后面会吃大亏。我举个例子。之前有个项目数据源是一个业务系统的数据库。我们直接写了个脚本定时拉取增量数据。结果上线后发现业务系统在某些时段会做批量数据修正这些修正不会更新“更新时间”字段导致我们的增量拉取完全漏掉了这些修正。后来不得不改成全量对比的方式成本高了很多。所以数据采集阶段一定要做这几件事数据源盘点列出所有数据源标注更新频率、数据量、负责人数据质量摸底抽样检查数据的完整性、一致性、准确性数据量估算估算日增数据量、存储需求、处理时间窗口异常情况确认了解数据源可能出现的异常情况如批量修正、系统维护等这些工作看起来繁琐但能帮你避免后面大量的返工。3.2 数据清洗规则要可配置过程要可追溯数据清洗是数据管道中最耗时的环节。我粗略估算过在一个典型的AI项目中数据清洗相关的工作能占到整个项目时间的40%到60%。而且这部分工作很难自动化因为每个数据源的清洗规则都不一样。我的经验是数据清洗的规则一定要可配置化清洗过程一定要可追溯。什么意思就是不要把清洗逻辑硬编码在代码里而是把它抽象成配置。比如“去掉年龄大于150的记录”这条规则应该是一个配置项而不是写死在代码里的if age 150: drop。这样做的好处是当业务规则变化时你只需要改配置不需要改代码、重新测试、重新部署。而且配置化的清洗规则更容易做版本管理你能清楚地知道每条数据经过了哪些清洗步骤。具体实现上我推荐用配置化的方式定义清洗规则# 清洗规则配置示例 cleaning_rules [ { name: remove_invalid_age, type: range_filter, field: age, min: 0, max: 150, action: drop }, { name: fill_missing_city, type: fill_na, field: city, value: unknown, action: fill }, { name: normalize_phone, type: regex_replace, field: phone, pattern: r[^0-9], replacement: , action: transform } ]每条规则有名称、类型、作用字段、参数和动作。清洗引擎读取这些配置按顺序执行。每次清洗后记录每条数据经过了哪些规则、发生了什么变化。这样出了问题可以快速定位也方便做数据审计。3.3 数据存储分层存储冷热分离数据存储的设计直接影响整个系统的性能和成本。我的建议是分层存储、冷热分离。热数据层存放最近经常访问的数据用高性能的存储介质比如SSD或者内存数据库。这一层的数据量不大但访问频率高要求低延迟。温数据层存放最近一段时间的数据用普通的磁盘存储比如关系型数据库或者列式存储。这一层的数据量中等访问频率中等。冷数据层存放历史归档数据用对象存储成本低但访问延迟高。这一层的数据量最大但访问频率很低。分层存储的核心是生命周期管理。数据从热层逐渐冷却到温层再到冷层这个过程应该是自动化的。比如最近7天的数据在热层7天到90天的数据在温层90天以上的数据归档到冷层。除了分层还要考虑数据的组织方式。对于AI项目来说训练数据通常需要按批次读取所以列式存储如Parquet格式比行式存储更合适。列式存储的压缩率高读取特定列时不需要扫描整行数据IO效率高很多。3.4 数据版本管理别让“数据变了”成为玄学问题数据版本管理是很多团队容易忽略的环节。大家习惯了用Git管理代码但数据呢数据也是会变的。今天清洗了一遍数据明天又清洗了一遍两次清洗的结果不一样模型效果也不一样。如果你不记录每次训练用的是哪个版本的数据出了问题根本没法排查。数据版本管理不需要搞得很复杂。最简单的做法是每次数据清洗后给输出数据打一个版本号记录清洗规则、输入数据版本、输出数据路径、清洗时间、数据量等信息。这些元数据存在一个数据库表里方便查询。CREATE TABLE data_versions ( version_id VARCHAR(64) PRIMARY KEY, parent_version VARCHAR(64), cleaning_rules TEXT, input_path TEXT, output_path TEXT, row_count BIGINT, created_at TIMESTAMP, description TEXT );这样每次训练模型时记录用的是哪个数据版本。如果模型效果出现异常可以追溯到具体的数据版本对比不同版本的数据差异快速定位问题。4. 特征工程与模型训练从实验到可复现的工程化4.1 特征计算批流一体是目标但别一步到位特征计算有两种模式批处理和流处理。批处理适合离线训练场景流处理适合在线推理场景。理想情况下训练和推理用同一套特征计算逻辑保证线上线下一致性。这就是所谓的“批流一体”。但说实话批流一体说起来容易做起来难。批处理和流处理的计算引擎不同、API不同、调试方式不同要统一起来需要不少工作量。我的建议是如果你的业务对实时性要求不高先做批处理把特征计算逻辑封装成可复用的模块。等业务真的需要实时特征了再考虑流处理方案。特征计算模块的设计要点输入输出明确每个特征计算函数有清晰的输入和输出定义幂等性同样的输入多次计算结果应该一致可测试每个特征计算逻辑都能单独测试可组合多个特征可以组合成一个特征组class FeatureCalculator: def __init__(self, name, input_schema, output_schema): self.name name self.input_schema input_schema self.output_schema output_schema def compute(self, data): raise NotImplementedError def validate(self, data): # 校验输入数据是否符合schema pass class UserAgeFeature(FeatureCalculator): def __init__(self): super().__init__( nameuser_age, input_schema{birth_date: date}, output_schema{age: int} ) def compute(self, data): today datetime.now().date() data[age] data[birth_date].apply( lambda x: (today - x).days // 365 ) return data这种设计的好处是每个特征计算逻辑都是独立的、可测试的、可复用的。当特征数量增多时可以方便地组合和编排。4.2 特征存储训练和推理的桥梁特征存储是AI工程体系中一个关键但容易被忽视的组件。它的核心作用是存储计算好的特征供训练和推理使用。没有特征存储训练时算一遍特征推理时又算一遍不仅浪费资源还容易出现线上线下不一致的问题。特征存储需要解决几个问题特征注册每个特征有唯一的名称、类型、描述、负责人。特征注册表让团队成员知道有哪些特征可用避免重复开发。特征物化把计算好的特征存储起来训练时直接读取不需要重新计算。物化可以是全量的也可以是增量的。特征服务提供在线和离线两种读取方式。离线读取用于训练通常是批量读取在线读取用于推理要求低延迟。一致性保证确保训练时用的特征和推理时用的特征是一致的。这需要特征计算逻辑统一、特征版本管理、时间点对齐等机制。特征存储的实现可以很简单也可以很复杂。小团队用数据库表就能实现基本功能大团队可能需要专门的特征平台。关键是根据自己的需求来不要为了用特征存储而用特征存储。4.3 模型训练实验管理是核心模型训练环节最重要的不是模型架构有多先进而是实验管理是否规范。我见过太多团队模型训练过程一团糟今天调了个参数明天换了个数据集后天改了特征最后效果好不知道为啥好效果差不知道为啥差。实验管理要记录什么至少包括代码版本用的是哪个commit的代码数据版本用的是哪个版本的数据特征版本用了哪些特征特征计算逻辑是什么版本超参数学习率、批次大小、训练轮数等环境信息Python版本、依赖包版本、硬件配置评估指标训练集、验证集、测试集上的各项指标模型产物模型文件、检查点、日志这些信息如果靠人工记录几乎不可能坚持下来。所以一定要用工具自动化。MLflow、WB、TensorBoard都是不错的选择。我个人比较推荐MLflow因为它开源、轻量、和现有代码集成简单。import mlflow mlflow.set_experiment(my_experiment) with mlflow.start_run(): # 记录超参数 mlflow.log_params({ learning_rate: 0.001, batch_size: 32, epochs: 10 }) # 训练模型 model train_model(params) # 记录指标 mlflow.log_metrics({ train_loss: train_loss, val_loss: val_loss, val_accuracy: val_accuracy }) # 保存模型 mlflow.sklearn.log_model(model, model) # 记录数据版本 mlflow.set_tag(data_version, v1.2.3) mlflow.set_tag(feature_version, v2.0.1)这样每次实验都有完整的记录随时可以复现。而且MLflow提供了UI界面可以方便地对比不同实验的结果。4.4 模型评估别只看准确率模型评估是模型训练中极其重要但容易被简化的环节。很多人只看一个准确率或者AUC觉得指标高就行了。但实际上模型评估需要从多个维度来看。业务指标模型最终是要服务于业务的所以业务指标是最重要的。比如推荐系统看点击率、转化率风控系统看欺诈拦截率、误杀率。技术指标好不代表业务指标好。技术指标准确率、精确率、召回率、F1、AUC等。不同的业务场景关注不同的指标。比如风控场景更关注召回率尽量抓住坏人搜索场景更关注精确率尽量不返回无关结果。鲁棒性模型在不同数据分布下的表现。比如在不同地区、不同时间段、不同用户群体上的表现是否稳定。公平性模型对不同群体的预测是否存在系统性偏差。这在涉及用户权益的场景中尤为重要。可解释性模型的预测结果是否可解释。在某些场景下如金融风控可解释性是硬性要求。我的建议是在模型评估阶段就建立一个多维度的评估框架每次训练后自动生成评估报告。这样不仅能全面了解模型表现还能在模型上线后快速对比线上效果。5. 模型部署与服务化让模型真正产生价值5.1 推理服务设计延迟、吞吐、并发的三角平衡模型训练出来只是第一步把它变成可用的服务才是真正产生价值的地方。推理服务的设计需要在延迟、吞吐量和并发能力之间做平衡。延迟是指单个请求从发出到收到响应的时间。对于实时交互场景如搜索、推荐延迟要求通常在几十毫秒以内。对于离线批量场景延迟要求可以放宽到分钟甚至小时级别。吞吐量是指单位时间内能处理的请求数量。吞吐量和延迟通常是矛盾的提高吞吐量往往会增加延迟。需要根据业务需求找到平衡点。并发能力是指同时处理多个请求的能力。并发能力受限于硬件资源CPU、内存、GPU和软件架构同步还是异步、线程模型等。优化推理服务性能的几个方向模型优化量化、剪枝、蒸馏减小模型体积和计算量推理引擎使用ONNX Runtime、TensorRT等专用推理引擎比原生框架快很多批处理把多个请求合并成一个批次推理提高GPU利用率缓存对重复请求缓存结果减少计算异步处理对非实时请求用异步方式处理避免阻塞# FastAPI推理服务示例 from fastapi import FastAPI import onnxruntime as ort import numpy as np app FastAPI() session ort.InferenceSession(model.onnx) app.post(/predict) async def predict(features: dict): # 特征预处理 input_data preprocess(features) # 推理 outputs session.run( None, {input: input_data} ) # 后处理 result postprocess(outputs) return {prediction: result}这是一个最简单的推理服务示例。实际生产中还需要考虑请求校验、错误处理、日志记录、监控埋点、限流熔断等一系列问题。5.2 模型版本管理与灰度发布模型上线不是一锤子买卖而是一个持续迭代的过程。新模型上线需要经过严格的测试和灰度发布流程。模型版本管理每个上线的模型都要有明确的版本号记录训练数据、特征版本、超参数、评估指标等信息。模型文件存储在版本化的存储中支持快速回滚。灰度发布新模型不要一次性全量上线而是先让小部分流量走新模型观察效果。如果效果符合预期逐步扩大流量比例如果效果不佳快速回滚到旧模型。灰度发布的实现方式有几种按用户分流根据用户ID的哈希值决定走哪个模型按流量比例分流随机分配一定比例的流量到新模型按条件分流根据请求的某些特征决定走哪个模型import hashlib def route_model(user_id, model_versions): 根据用户ID决定使用哪个模型版本 model_versions: {v1: 0.9, v2: 0.1} 表示v1占90%v2占10% hash_value int(hashlib.md5(str(user_id).encode()).hexdigest(), 16) normalized (hash_value % 1000) / 1000.0 cumulative 0 for version, ratio in model_versions.items(): cumulative ratio if normalized cumulative: return version return list(model_versions.keys())[-1]灰度发布期间要密切监控新模型的表现包括技术指标延迟、错误率和业务指标点击率、转化率。如果发现异常立即回滚。5.3 监控与告警模型上线只是开始模型上线后监控是保证系统稳定运行的关键。AI系统的监控比普通软件系统更复杂因为除了常规的系统指标还需要监控模型相关的指标。系统指标CPU使用率、内存使用率、GPU使用率、网络IO、磁盘IO、请求延迟、错误率、QPS等。这些是基础监控和普通服务一样。模型指标预测分布、特征分布、置信度分布等。这些指标反映模型的行为是否正常。比如预测分布突然偏移可能意味着输入数据分布发生了变化。业务指标点击率、转化率、收入等。这些指标反映模型对业务的实际影响。数据漂移检测监控输入数据的分布是否发生变化。如果训练数据和推理数据的分布差异过大模型效果会下降。常用的检测方法包括PSIPopulation Stability Index、KL散度等。import numpy as np from scipy import stats def detect_drift(reference_data, current_data, threshold0.05): 使用KS检验检测数据漂移 statistic, p_value stats.ks_2samp(reference_data, current_data) if p_value threshold: return True, f数据漂移检测KS统计量{statistic:.4f}, p值{p_value:.4f} else: return False, 未检测到显著数据漂移监控数据要可视化展示方便快速了解系统状态。Grafana是一个不错的选择可以方便地创建各种监控面板。告警规则要合理设置避免告警风暴也避免漏报。6. 常见问题与排查技巧实录6.1 训练和推理效果不一致怎么办这是AI工程中最常见的问题之一。训练时模型表现很好上线后效果大打折扣。原因通常有几种特征不一致训练时用的特征和推理时用的特征计算方式不同。比如训练时用了未来信息数据泄露推理时没有这些信息。或者训练时特征做了某种变换推理时忘了做同样的变换。数据分布不一致训练数据的分布和线上推理数据的分布不同。比如训练数据是历史数据线上数据是实时数据两者分布有差异。预处理不一致训练时的预处理逻辑和推理时的预处理逻辑不同。比如训练时做了归一化推理时忘了做。排查方法在训练和推理时分别记录特征的统计信息均值、方差、分布等对比两者是否一致。如果不一致逐步排查是哪个环节出了问题。6.2 推理服务延迟高怎么优化推理服务延迟高是另一个常见问题。优化方向有几个模型层面模型太大、计算量太大。可以考虑模型量化FP32转FP16或INT8、模型剪枝、知识蒸馏等方法减小模型体积和计算量。推理引擎层面使用专用的推理引擎。比如ONNX Runtime比PyTorch原生推理快不少TensorRT在NVIDIA GPU上性能更好。服务层面优化服务架构。比如使用异步处理、批处理、缓存等技术。检查是否有不必要的序列化/反序列化开销。硬件层面升级硬件。比如用GPU替代CPU推理用更快的SSD增加内存等。排查延迟问题首先要定位瓶颈在哪里。是模型推理慢还是数据预处理慢还是网络传输慢用 profiling 工具如py-spy、cProfile分析各个阶段的耗时找到瓶颈后再针对性优化。6.3 数据漂移导致模型效果下降怎么处理数据漂移是模型上线后效果下降的主要原因之一。处理方式取决于漂移的程度和原因轻度漂移模型效果略有下降但仍在可接受范围内。可以继续观察同时准备重新训练。中度漂移模型效果明显下降需要尽快处理。可以用新数据对模型进行微调或者重新训练。严重漂移模型效果大幅下降甚至不可用。需要立即回滚到旧模型同时排查漂移原因。预防数据漂移的措施定期用新数据重新训练模型、监控输入数据分布、设置数据漂移告警、建立模型快速迭代的流程。6.4 常见问题速查表问题现象可能原因排查方向解决方案训练效果好线上效果差特征不一致对比训练和推理的特征统计统一特征计算逻辑推理延迟高模型太大/推理引擎不合适profiling分析各阶段耗时模型优化/更换推理引擎模型效果逐渐下降数据漂移监控输入数据分布重新训练/微调模型服务不稳定偶尔超时资源不足/并发过高监控系统资源使用扩容/限流/异步处理模型预测结果异常输入数据异常检查输入数据质量增加输入校验/异常处理实验无法复现环境/数据/代码版本不一致检查实验记录完善实验管理6.5 几个只有踩过坑才知道的经验第一日志要打够但不要打太多。日志是排查问题的关键但日志太多会影响性能也会让真正重要的信息被淹没。我的做法是关键路径打INFO日志异常情况打ERROR日志调试信息用DEBUG级别并且默认关闭。第二配置要外置不要硬编码。数据库连接、模型路径、阈值参数这些都应该放在配置文件或环境变量里。硬编码的配置在环境切换时会非常痛苦。第三监控要提前做不要等出了问题再加。很多团队是出了问题才想起来加监控但那时候已经造成了损失。监控应该在系统设计阶段就考虑进去。第四文档要写但不要写废话。文档的目的是让其他人包括未来的自己能快速理解系统。写清楚架构图、数据流、关键决策的原因就够了不需要写成长篇大论。第五测试要覆盖核心逻辑不要追求100%覆盖率。特征计算逻辑、数据清洗规则、模型预处理和后处理这些核心逻辑一定要有测试。至于一些边缘的辅助函数测试的优先级可以低一些。7. 关于工具链和团队协作的一些个人体会聊完了技术层面的东西我想再分享一些关于工具链和团队协作的体会。这些内容可能不像具体的技术方案那么“硬核”但在实际项目中同样重要。工具链的选择上我的核心原则是减少工具数量降低维护成本。每引入一个新工具就多了一份学习成本、维护成本和出故障的风险。所以能用现有工具解决的问题就不要引入新工具。比如特征存储如果你的数据量不大用数据库表就能搞定没必要专门部署一个特征存储平台。团队协作上AI项目和普通软件项目有一个很大的不同AI项目的不确定性更高。模型效果好不好很多时候要试了才知道。所以团队协作方式也要适应这种不确定性。我的建议是小步快跑快速迭代。不要憋大招不要等所有东西都完美了才上线。先上线一个能用的版本然后根据反馈持续优化。另外AI项目中算法工程师和工程工程师的协作非常重要。算法工程师关注模型效果工程工程师关注系统稳定性和性能。两者视角不同容易产生摩擦。解决方式是让算法工程师了解工程约束让工程工程师理解算法需求。在项目早期就让双方参与设计避免后期返工。还有一个容易被忽视的点AI项目的技术债务。为了快速上线很多团队会走捷径硬编码、临时方案、跳过测试。这些技术债务如果不及时偿还会越积越多最终拖慢整个团队的效率。我的建议是每个迭代留出一定比例的时间来还技术债务不要等到积重难返。最后说一个我自己的教训。早期做AI项目时我总想把系统设计得很完美考虑各种边界情况结果开发周期拉得很长上线后发现很多设计根本用不上。后来我学乖了先做一个能跑通的最小版本然后根据实际需求逐步完善。这个思路在AI工程中特别适用因为AI项目的不确定性太高你很难在前期就预判所有问题。快速上线、快速反馈、快速迭代才是更务实的做法。这个方向后续还可以往很多地方扩展比如自动化机器学习管道、模型压缩与加速、联邦学习环境下的工程挑战等等。每一个方向都值得单独拿出来深入聊。如果你也在做类似的事情欢迎一起交流踩过的坑和总结的经验。