AI全景图与工程化学习路线:从问题到交付
把 AI 项目做成“能上线、可持续迭代的产品”,和把一个模型在离线数据上跑出漂亮指标,是两件不同的事。中级读者最容易遇到的瓶颈往往不在算法本身,而在“接口处”:业务目标如何落到可验收的指标?数据如何避免泄漏?离线评估为什么上线就掉点?实验为什么复现不了、回滚不了、交接不了?本章的目的,就是先建立一套贯穿全书的共同语境:当我们说“AI 工程化”,到底在工程什么;当我们说“交付”,交付物到底有哪些;当我们说“成功”,成功标准如何被定义、被监控、被迭代。
从“问题”到“交付”:你真正要跑通的主线
一个可交付的 AI 项目,最稳定的主线不是“选模型 → 调参”,而是:
- 业务目标 → 数据与标注 → 表示/特征 → 训练与调参 → 评估与解释 → 部署与推理 → 监控与迭代(回到数据)
这条主线之所以重要,是因为它强迫你把每一步的“输入、输出、责任人、验收标准”说清楚。一旦这些定义不清,就会出现典型的工程灾难:口径不一致、指标争论、数据版本混乱、线上线下差异、无法复现、上线不可回滚、无人负责监控等。
下面这张图是全书反复引用的“端到端闭环”。建议你把它当成项目的默认骨架:每当遇到争议或卡点,就回到这张图,问一句:我们卡在哪个环节?上一环节的输出是否可用、可追溯、可验收?
```mermaid graph LR A[业务问题]-->B[数据与标注] B-->C[特征/表示] C-->D[训练与调参] D-->E[评估与解释] E-->F[部署与推理] F-->G[监控与迭代] G-->B ```
AI / ML / DL / LLM:边界、关系与工程含义
很多团队在沟通时把这些词混用,导致需求、方案、成本预期全部错位。这里给出工程视角的“可操作定义”,并强调它们对交付流程的影响。
AI:以结果为导向的“智能系统”集合
AI(人工智能)在工程语境里不是某一类模型,而是“能感知、能决策、能生成、能优化”的系统总称。一个 AI 系统通常包含:
- 数据管线(采集、清洗、标注、质量监控)
- 模型(一个或多个:分类/回归/生成/排序/检索等)
- 规则与策略(阈值、约束、回退逻辑、业务规则)
- 服务与基础设施(在线推理、批处理、缓存、队列)
- 监控与运营机制(指标、告警、A/B、灰度、回滚)
工程含义:AI 的“交付”是系统级的,不是单一模型文件。
ML:从数据中学习映射关系的范式
ML(机器学习)强调“用数据学出函数 $f(x)\rightarrow y$”。它天然要求:
- 明确定义输入/输出与标签
- 明确训练、验证、测试的划分与统计假设
- 明确评价指标与优化目标的一致性
工程含义:ML 项目必须以“数据版本 + 训练配置 + 评估口径”作为最小可复现单元。
DL:表示学习与规模化训练的工程问题
DL(深度学习)是 ML 的子集,强调通过多层网络学习表示。它带来三类工程变化:
- 训练成本更高(算力、分布式、混合精度、显存优化)
- 数据依赖更强(数据规模、分布、噪声、增强策略)
- 部署形态更复杂(加速、量化、蒸馏、端侧推理)
工程含义:DL 的关键不只是“网络结构”,更是“训练-推理一体化”的工程闭环(包括加速与监控)。
LLM:以“通用能力 + 指令对齐”为核心的模型平台
LLM(大语言模型)可以看作 DL 的特定家族,但工程形态往往更接近“平台能力”:
- 数据形态从结构化特征转向“文本/多模态语料 + 指令/偏好数据”
- 评估从单一指标转向“多维度能力谱系”(事实性、遵循度、安全性、鲁棒性)
- 部署从单模型服务转向“检索增强(RAG)、工具调用、长上下文、缓存、路由、多模型编排”
- 风险从过拟合转向“幻觉、越权、提示注入、隐私泄露、合规”
工程含义:LLM 项目的交付物通常不是“一个 checkpoint”,而是一套“能力边界清晰、可观测、可控、可回滚”的应用系统。
角色分工:谁对什么负责,产出什么可验收的东西
很多失败项目不是技术不行,而是“责任与产出”不清。下面用一张 UML(可用于需求评审或立项文档)把最常见的角色与职责串起来:
```plantuml @startuml actor PM actor DS actor MLE rectangle "AI交付流程" { PM --> (定义目标/指标) DS --> (数据获取/清洗/标注) DS --> (探索分析/特征) MLE --> (训练/评估/部署) MLE --> (监控/告警/回滚) } @enduml ```
把“谁做什么”进一步落到“交付物”层面,你可以用下表做项目的最小对齐(建议在 Kickoff 时就写进协作文档):
| 角色 | 核心责任 | 关键交付物(可验收) | 常见失败模式 | |---|---|---|---| | PM(产品/业务) | 目标与约束、上线策略、验收口径 | 目标指标定义、灰度策略、风险清单、回退策略 | 只讲功能不讲指标;验收口径反复变 | | DS(数据科学/算法) | 数据与方法、离线评估、误差分析 | 数据卡、标注规范、基线实验、误差分析报告 | 指标好看但不可上线;数据泄漏 | | MLE(机器学习工程) | 训练工程、服务化、可观测性、稳定性 | 训练流水线、模型包、推理服务、监控告警、回滚方案 | 线上线下不一致;不可复现;无监控 | | DE(数据工程,若有) | 数据管线、质量、时效、权限 | 数据血缘、ETL、质量监控、权限审计 | 特征口径漂移;延迟不可控 | | SRE/平台(若有) | 可用性、容量、成本 | SLA、容量评估、弹性策略、事故复盘 | 高峰崩溃;成本失控 |
一个实用建议:把“模型效果”从单一团队的 KPI 中抽离出来,让“端到端业务指标 + 稳定性指标”成为共同目标,否则组织结构会诱导出“离线刷分、线上甩锅”的行为模式。
指标选择:从业务目标到可验收的量化标准
指标选择是中级读者最常卡住的接口之一:业务说“要更智能”,算法说“我 AUC 提升了 0.02”,上线后却发现投诉增加或成本暴涨。根因通常是“业务指标、离线指标、线上指标”之间缺了映射。
三层指标:业务指标、产品指标、模型指标
建议按三层来定义,并明确每层的“负责人 + 数据来源 + 统计窗口”。
1. 业务指标(业务最终要的结果)
- 例:转化率、留存、GMV、客诉率、风控损失、人工成本
2. 产品/策略指标(系统行为的可控变量)
- 例:召回率、拦截率、通过率、曝光量、响应时延、命中率
3. 模型指标(离线可复现、可诊断)
- 例:AUC、PR-AUC、F1、TopK Recall、NDCG、RMSE、BLEU/ROUGE、WinRate、拒答率
关键原则:离线指标必须能解释线上业务指标的变化路径。如果解释不了,离线提升很可能是“无效提升”或“口径问题”。
常见任务的指标选择速查
- 二分类(极度不均衡):优先看 PR-AUC、Recall@Precision、成本敏感指标
- Precision:$P=\frac{TP}{TP+FP}$
- Recall:$R=\frac{TP}{TP+FN}$
- F1:$F1=\frac{2PR}{P+R}$
当正例稀少时,AUC 可能虚高,PR-AUC 更敏感。
- 排序/推荐:NDCG、MAP、Recall@K,并配套线上 CTR/CVR
- 回归/预测:MAE、RMSE、分位数损失(对长尾更稳)
- 检索/RAG:Recall@K、MRR、答案正确率、引用覆盖率(是否引用到关键证据)
- 生成式(LLM):多维评估(事实性、遵循度、毒性、安全),配合人工或模型裁判(但要防“评估偏差”)
案例 1:风控模型“指标更高但损失更大”的反直觉
场景:提升通过率以减少误杀,DS 把 AUC 从 0.78 提到 0.80。上线后,坏账损失上升。
常见原因:
- AUC 提升来自“排序更好”,但阈值策略未重新校准
- 业务成本函数不是对称的:放过一个坏人(FN)的成本远高于误杀一个好人(FP)
- 线上分布漂移:新客比例上升,模型对新客不稳定
工程化解法:
- 把“成本”写成明确的目标函数或验收表:
$$\text{ExpectedCost}=C_{FP}\cdot FP + C_{FN}\cdot FN$$
- 离线评估不只给单点指标,而给“阈值-成本曲线”“通过率-损失曲线”
- 上线前做阈值回归测试:在历史回放(replay)上验证策略级指标
案例 2:推荐系统“离线 NDCG 提升,线上 CTR 不动”
常见原因:
- 离线标签与线上目标不一致(用点击做标签但业务要的是转化)
- 训练样本选择偏差(只用曝光过的数据)
- 线上策略链路复杂(召回、过滤、规则、探索)掩盖了模型收益
工程化解法:
- 明确“优化目标层级”:召回模型优化 Recall@K,排序模型优化 NDCG@K,策略层优化业务指标
- 引入反事实评估或校正(IPS 等)至少在分析层面解释偏差来源
- 小流量 A/B + 分层实验:新客/老客、品类、时段分别看
数据泄漏:最隐蔽、最致命、最常见的“假提升”
数据泄漏(Data Leakage)指训练过程中使用了在真实预测时不可获得的信息,或用不正确的方式把未来信息带入了训练,从而让离线指标虚高、上线崩盘。你可以把它看成“评估体系被破坏”,而不是单纯的数据 bug。
为了便于团队自查,我们把泄漏分成三类:目标泄漏、时间泄漏、群组泄漏。
目标泄漏(Target Leakage):特征里藏着答案
典型例子:
- 用“是否退款”预测“是否欺诈”,但特征里包含“退款处理状态”
- 用“是否违约”预测“风险”,但特征里包含“催收次数”(发生在违约后)
自查问法:这个特征是在预测时刻之前就存在的吗?它是否由标签直接或间接生成?
时间泄漏(Temporal Leakage):训练看到了未来
典型例子:
- 用全量用户日志构造特征(包含预测时刻之后的行为)
- 标注窗口与特征窗口重叠,导致“先有结果再有原因”
工程建议:
- 对有时间属性的数据,**默认用时间切分(time-based split)**,而不是随机切分
- 明确每条样本的“观测时间点(as-of time)”,所有特征只能来自该时间点之前
可以在特征工程层引入一个硬规则:任何特征计算函数都必须显式传入 `as_of_time`,并在数据层做校验(特征时间戳不得超过 as_of)。
群组泄漏(Group Leakage):同一对象跨集合导致“背题”
典型例子:
- 同一个用户的多条样本同时出现在训练与测试
- 同一设备、同一商户、同一病人(医疗)跨集合
工程建议:
- 使用 GroupKFold 或按实体 ID 切分
- 在评估报告中强制输出:训练/验证/测试的实体重叠率(必须为 0 或可解释)
一页式“泄漏检查清单”(建议贴进项目模板)
- 标签定义是否包含未来信息?
- 特征是否在预测时刻可得(权限、延迟、依赖链路)?
- 切分方式是否符合线上时序(时间切分/实体切分)?
- 是否有全局统计特征(例如全量均值)误用了测试集信息?
- 是否存在“样本去重失败”导致同一记录泄漏?
- 是否用到了人工审核结果、处理状态等“事后变量”?
线上线下不一致:训练-服务偏差(Skew)的工程根因
“离线挺好,上线掉点”往往不是模型突然变差,而是训练与服务环境不一致。常见的四类不一致如下:
1. 特征计算不一致:离线用 Spark/SQL,线上用 Python/Java 手写了一份 2. 数据口径不一致:离线用 T+1 的完整数据,线上只有实时流的一部分 3. 样本分布不一致:离线数据来自旧策略曝光,线上策略改变后分布漂移 4. 预处理不一致:缺失值填充、分桶、归一化、分词版本不同
工程化的核心目标:同一份逻辑、同一份配置、同一份版本,在训练与推理两端复用。
案例 3:客服 LLM 上线后“幻觉飙升”,离线评估却很好
场景:离线用一批静态问题集评估,模型回答准确率 85%。上线后用户反馈“编造政策、乱引用链接”。
常见根因:
- 离线评估题目分布过于“干净”,线上问题更开放、更长尾
- 上线接入了工具/检索,但检索召回不稳定;离线评估没覆盖“检索失败”情形
- 提示词(prompt)线上被动态拼接,导致注入或上下文污染
工程化解法:
- 把评估分成“无检索/有检索/检索失败/工具失败”四种场景覆盖
- 引入“引用一致性”指标:回答中的关键结论是否能在证据中定位
- 线上记录可回放:保存输入、检索结果摘要、工具调用、输出与版本号,支持事后复盘与回归测试
可复现:让“做过的实验”变成“可交接的资产”
不可复现的后果不是“再跑一次麻烦”,而是:
- 无法确认提升来自哪里(数据?代码?随机性?)
- 无法安全回滚(线上出问题不敢切回)
- 无法规模化协作(换人就重来)
可复现不是玄学,它依赖三件事:版本化的数据、版本化的代码、版本化的配置,再加上最少的运行环境记录。
最小可复现单元(MRU):你至少要能回答四个问题
1. 这次实验用的数据版本是什么? 2. 这次实验用的代码提交(commit)是什么? 3. 这次实验的配置参数(超参、特征开关、阈值)是什么? 4. 这次实验的产物(模型文件、评估报告)在哪里,如何对应回去?
推荐做法:把“实验记录”当作产线日志
你可以用最朴素的方式开始:一个 `experiments/` 目录 + 一张表。关键是强制记录与可追溯,而不是一上来追求最重的工具链。
示例(Markdown 表格,适合纸书与电子版阅读,也便于机器解析):
| exp_id | 日期 | 数据版本 | 代码版本 | 配置文件 | 指标摘要 | 结论 | |---|---|---|---|---|---|---| | exp_024 | 2026-03-10 | data_v12 | a1b2c3 | configs/churn.yaml | PR-AUC 0.42→0.46 | 修复泄漏后小幅提升 |
项目模板:贯穿全书的“可交付”目录结构与文档约定
下面给出一个贯穿全书的项目模板。它的目标不是“最流行”,而是覆盖端到端交付需要的核心资产:数据、代码、配置、实验记录、模型卡/数据卡、部署与监控。
```text project/ README.md docs/ problem.md # 业务问题与验收口径 metrics.md # 指标定义与口径(含线上/离线映射) data_card.md # 数据卡(数据来源、权限、偏差、风险) model_card.md # 模型卡(用途、限制、训练数据、评估结果) risk_register.md # 风险清单(泄漏、偏差、安全、合规) runbook.md # 运维手册(告警、回滚、常见故障处理) data/ raw/ # 原始数据(只读,带版本) interim/ # 中间产物(清洗、拼表) processed/ # 可用于训练的最终数据 src/ data/ # 数据处理与校验 features/ # 特征/表示 training/ # 训练脚本与回调 evaluation/ # 离线评估与误差分析 serving/ # 推理封装(与线上一致) monitoring/ # 指标计算、漂移检测、告警规则 configs/ base.yaml # 全局默认配置 train.yaml # 训练相关参数 eval.yaml # 评估口径与切分方式 serving.yaml # 推理资源、阈值、回退策略 experiments/ log.md # 实验总表(可机器解析) exp_024/ # 单次实验记录(产物与报告) config.yaml metrics.json report.md artifacts/ model.bin plots/ tests/ test_data_contract.py # 数据契约测试(schema、范围、缺失率等) test_training_skew.py # 训练-推理一致性测试 scripts/ make_dataset.sh train.sh evaluate.sh package_model.sh ```
数据卡(Data Card)模板要点
`docs/data_card.md` 建议包含以下字段(既利于审计,也利于团队协作):
- 数据来源与采集方式(含权限与合规依据)
- 时间范围与更新频率(T+1 / 实时 / 批次)
- 样本定义与过滤规则(谁被包含、谁被排除)
- 标注规则与一致性(标注指南、冲突处理、抽检结果)
- 数据偏差与代表性(覆盖盲区、长尾、历史策略影响)
- 潜在风险(隐私、敏感字段、泄漏点、可解释性要求)
模型卡(Model Card)模板要点
`docs/model_card.md` 建议包含:
- 模型用途与非用途(明确“不能用来做什么”)
- 训练数据版本与时间窗口(对应数据卡)
- 训练配置摘要(关键超参、特征开关、随机种子)
- 评估结果(分人群/分场景,含置信区间或方差)
- 已知限制(对冷启动/长尾/漂移的脆弱点)
- 上线策略(阈值、回退、A/B、灰度、回滚条件)
- 监控项(效果、稳定性、成本、安全)
结构化 Markdown 约定:为后续章节统一“机器可读”的元数据块
为了让电子版可导航、也方便后续自动化处理(如生成术语表、章节依赖图、知识图谱),建议每章都包含一个统一格式的元数据块。注意:这不是 YAML front matter,而是 HTML 注释,便于多种渲染器兼容。
```markdown <!-- m